Index: uspace/srv/net/dnsres/transport.c
===================================================================
--- uspace/srv/net/dnsres/transport.c	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/dnsres/transport.c	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -52,9 +52,14 @@
 	size_t req_size;
 	struct sockaddr_in addr;
+	struct sockaddr_in laddr;
 	int fd;
 
 	addr.sin_family = AF_INET;
 	addr.sin_port = htons(53);
-	addr.sin_addr.s_addr = htonl((192 << 24) | (168 << 16) | (0 << 8) | 1);
+	addr.sin_addr.s_addr = htonl((10 << 24) | (0 << 16) | (0 << 8) | 1);
+
+	laddr.sin_family = AF_INET;
+	laddr.sin_port = htons(12345);
+	laddr.sin_addr.s_addr = INADDR_ANY;
 
 	req_data = NULL;
@@ -71,4 +76,8 @@
 	}
 
+	rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
+	if (rc != EOK)
+		goto error;
+
 	printf("fd=%d req_data=%p, req_size=%zu\n", fd, req_data, req_size);
 	rc = sendto(fd, req_data, req_size, 0, (struct sockaddr *)&addr,
@@ -76,4 +85,7 @@
 	if (rc != EOK)
 		goto error;
+
+	closesocket(fd);
+	free(req_data);
 
 	resp = NULL;
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -202,5 +202,5 @@
 		first = 0;
 	} else {
-		addr->naddr.ipv4 = (192 << 24) + (168 << 16) + (0 << 8) + 4;
+		addr->naddr.ipv4 = (10 << 24) + (0 << 16) + (0 << 8) + 2;
 	}
 	addr->naddr.bits = 24;
Index: uspace/srv/net/udp/assoc.c
===================================================================
--- uspace/srv/net/udp/assoc.c	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/udp/assoc.c	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -264,7 +264,13 @@
 
 	fibril_mutex_lock(&assoc->lock);
-	while (list_empty(&assoc->rcv_queue)) {
+	while (list_empty(&assoc->rcv_queue) && !assoc->reset) {
 		log_msg(LVL_DEBUG, "udp_assoc_recv() - waiting");
 		fibril_condvar_wait(&assoc->rcv_queue_cv, &assoc->lock);
+	}
+
+	if (assoc->reset) {
+		log_msg(LVL_DEBUG, "udp_assoc_recv() - association was reset");
+		fibril_mutex_unlock(&assoc->lock);
+		return ECONNABORTED;
 	}
 
@@ -308,4 +314,17 @@
 }
 
+/** Reset association.
+ *
+ * This causes any pendingreceive operations to return immediately with
+ * UDP_ERESET.
+ */
+void udp_assoc_reset(udp_assoc_t *assoc)
+{
+	fibril_mutex_lock(&assoc->lock);
+	assoc->reset = true;
+	fibril_condvar_broadcast(&assoc->rcv_queue_cv);
+	fibril_mutex_unlock(&assoc->lock);
+}
+
 static int udp_assoc_queue_msg(udp_assoc_t *assoc, udp_sockpair_t *sp,
     udp_msg_t *msg)
Index: uspace/srv/net/udp/assoc.h
===================================================================
--- uspace/srv/net/udp/assoc.h	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/udp/assoc.h	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -50,5 +50,5 @@
 extern int udp_assoc_recv(udp_assoc_t *, udp_msg_t **, udp_sock_t *);
 extern void udp_assoc_received(udp_sockpair_t *, udp_msg_t *);
-
+extern void udp_assoc_reset(udp_assoc_t *);
 
 #endif
Index: uspace/srv/net/udp/sock.c
===================================================================
--- uspace/srv/net/udp/sock.c	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/udp/sock.c	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -531,5 +531,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_sock_close()");
+	log_msg(LVL_DEBUG, "udp_sock_close()");
 	socket_id = SOCKET_GET_SOCKET_ID(call);
 
@@ -543,11 +543,22 @@
 	fibril_mutex_lock(&socket->lock);
 
+	fibril_mutex_lock(&socket->recv_buffer_lock);
+	log_msg(LVL_DEBUG, "udp_sock_close - set socket->sock_core = NULL");
+	socket->sock_core = NULL;
+	fibril_mutex_unlock(&socket->recv_buffer_lock);
+
+	udp_uc_reset(socket->assoc);
+
 	rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock,
 	    udp_free_sock_data);
 	if (rc != EOK) {
+		log_msg(LVL_DEBUG, "udp_sock_close - socket_destroy failed");
 		fibril_mutex_unlock(&socket->lock);
 		async_answer_0(callid, rc);
 		return;
 	}
+
+	log_msg(LVL_DEBUG, "udp_sock_close - broadcast recv_buffer_cv");
+	fibril_condvar_broadcast(&socket->recv_buffer_cv);
 
 	fibril_mutex_unlock(&socket->lock);
@@ -576,8 +587,9 @@
 	log_msg(LVL_DEBUG, "udp_sock_recv_fibril()");
 
+	fibril_mutex_lock(&sock->recv_buffer_lock);
+
 	while (true) {
 		log_msg(LVL_DEBUG, "[] wait for rcv buffer empty()");
-		fibril_mutex_lock(&sock->recv_buffer_lock);
-		while (sock->recv_buffer_used != 0) {
+		while (sock->recv_buffer_used != 0 && sock->sock_core != NULL) {
 			fibril_condvar_wait(&sock->recv_buffer_cv,
 			    &sock->recv_buffer_lock);
@@ -589,9 +601,12 @@
 		sock->recv_error = urc;
 
-		udp_sock_notify_data(sock->sock_core);
+		log_msg(LVL_DEBUG, "[] udp_uc_receive -> %d", urc);
+
+		if (sock->sock_core != NULL)
+			udp_sock_notify_data(sock->sock_core);
 
 		if (urc != UDP_EOK) {
+			log_msg(LVL_DEBUG, "[] urc != UDP_EOK, break");
 			fibril_condvar_broadcast(&sock->recv_buffer_cv);
-			fibril_mutex_unlock(&sock->recv_buffer_lock);
 			break;
 		}
@@ -600,9 +615,12 @@
 
 		sock->recv_buffer_used = rcvd;
-		fibril_mutex_unlock(&sock->recv_buffer_lock);
 		fibril_condvar_broadcast(&sock->recv_buffer_cv);
 	}
 
+	log_msg(LVL_DEBUG, "udp_sock_recv_fibril() exited loop");
+	fibril_mutex_unlock(&sock->recv_buffer_lock);
 	udp_uc_destroy(sock->assoc);
+
+	log_msg(LVL_DEBUG, "udp_sock_recv_fibril() terminated");
 
 	return 0;
Index: uspace/srv/net/udp/ucall.c
===================================================================
--- uspace/srv/net/udp/ucall.c	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/udp/ucall.c	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -105,5 +105,12 @@
 	log_msg(LVL_DEBUG, "%s: udp_uc_receive()", assoc->name);
 	rc = udp_assoc_recv(assoc, &msg, fsock);
+	log_msg(LVL_DEBUG, "udp_assoc_recv -> %d", rc);
 	switch (rc) {
+	case EOK:
+		break;
+	case ECONNABORTED:
+		return UDP_ERESET;
+	default:
+		assert(false);
 	}
 
@@ -125,6 +132,12 @@
 {
 	log_msg(LVL_DEBUG, "udp_uc_destroy()");
+	udp_assoc_reset(assoc);
 	udp_assoc_remove(assoc);
 	udp_assoc_delete(assoc);
+}
+
+void udp_uc_reset(udp_assoc_t *assoc)
+{
+	udp_assoc_reset(assoc);
 }
 
Index: uspace/srv/net/udp/ucall.h
===================================================================
--- uspace/srv/net/udp/ucall.h	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/udp/ucall.h	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -48,4 +48,5 @@
 extern void udp_uc_status(udp_assoc_t *, udp_assoc_status_t *);
 extern void udp_uc_destroy(udp_assoc_t *);
+extern void udp_uc_reset(udp_assoc_t *);
 
 #endif
Index: uspace/srv/net/udp/udp_type.h
===================================================================
--- uspace/srv/net/udp/udp_type.h	(revision e5e73af4cef1c6facc812dff70fb9402804baa31)
+++ uspace/srv/net/udp/udp_type.h	(revision 141a20dc6c36e09dab74a968f1a80bf74ddeacc6)
@@ -51,5 +51,7 @@
 	UDP_EUNSPEC,
 	/* No route to destination */
-	UDP_ENOROUTE
+	UDP_ENOROUTE,
+	/** Association reset by user */
+	UDP_ERESET
 } udp_error_t;
 
@@ -119,4 +121,7 @@
 	udp_sockpair_t ident;
 
+	/** True if association was reset by user */
+	bool reset;
+
 	/** True if association was deleted by user */
 	bool deleted;
