Index: uspace/lib/c/generic/inet/tcp.c
===================================================================
--- uspace/lib/c/generic/inet/tcp.c	(revision 204ba4771af4f0ec3835cd55586cdc002020f247)
+++ uspace/lib/c/generic/inet/tcp.c	(revision dc0d6e5d084de74e724a544d470b0b47aefde2de)
@@ -81,4 +81,6 @@
 	list_initialize(&tcp->conn);
 	list_initialize(&tcp->listener);
+	fibril_mutex_initialize(&tcp->lock);
+	fibril_condvar_initialize(&tcp->cv);
 
 	rc = loc_service_get_id(SERVICE_NAME_TCP, &tcp_svcid,
@@ -115,4 +117,10 @@
 
 	async_hangup(tcp->sess);
+
+	fibril_mutex_lock(&tcp->lock);
+	while (!tcp->cb_done)
+		fibril_condvar_wait(&tcp->cv, &tcp->lock);
+	fibril_mutex_unlock(&tcp->lock);
+
 	free(tcp);
 }
@@ -593,6 +601,6 @@
 
 		if (!IPC_GET_IMETHOD(call)) {
-			/* TODO: Handle hangup */
-			return;
+			/* Hangup*/
+			goto out;
 		}
 
@@ -621,4 +629,9 @@
 		}
 	}
+out:
+	fibril_mutex_lock(&tcp->lock);
+	tcp->cb_done = true;
+	fibril_mutex_unlock(&tcp->lock);
+	fibril_condvar_broadcast(&tcp->cv);
 }
 
Index: uspace/lib/c/generic/inet/udp.c
===================================================================
--- uspace/lib/c/generic/inet/udp.c	(revision 204ba4771af4f0ec3835cd55586cdc002020f247)
+++ uspace/lib/c/generic/inet/udp.c	(revision dc0d6e5d084de74e724a544d470b0b47aefde2de)
@@ -73,4 +73,6 @@
 
 	list_initialize(&udp->assoc);
+	fibril_mutex_initialize(&udp->lock);
+	fibril_condvar_initialize(&udp->cv);
 
 	rc = loc_service_get_id(SERVICE_NAME_UDP, &udp_svcid,
@@ -107,4 +109,10 @@
 
 	async_hangup(udp->sess);
+
+	fibril_mutex_lock(&udp->lock);
+	while (!udp->cb_done)
+		fibril_condvar_wait(&udp->cv, &udp->lock);
+	fibril_mutex_unlock(&udp->lock);
+
 	free(udp);
 }
@@ -343,6 +351,6 @@
 
 		if (!IPC_GET_IMETHOD(call)) {
-			/* TODO: Handle hangup */
-			return;
+			/* Hangup */
+			goto out;
 		}
 
@@ -356,4 +364,9 @@
 		}
 	}
+out:
+	fibril_mutex_lock(&udp->lock);
+	udp->cb_done = true;
+	fibril_mutex_unlock(&udp->lock);
+	fibril_condvar_broadcast(&udp->cv);
 }
 
Index: uspace/lib/c/include/inet/tcp.h
===================================================================
--- uspace/lib/c/include/inet/tcp.h	(revision 204ba4771af4f0ec3835cd55586cdc002020f247)
+++ uspace/lib/c/include/inet/tcp.h	(revision dc0d6e5d084de74e724a544d470b0b47aefde2de)
@@ -90,4 +90,10 @@
 	/** List of listeners */
 	list_t listener; /* of tcp_listener_t */
+	/** TCP service lock */
+	fibril_mutex_t lock;
+	/** For waiting on cb_done */
+	fibril_condvar_t cv;
+	/** Set to @a true when callback connection handler has terminated */
+	bool cb_done;
 } tcp_t;
 
Index: uspace/lib/c/include/inet/udp.h
===================================================================
--- uspace/lib/c/include/inet/udp.h	(revision 204ba4771af4f0ec3835cd55586cdc002020f247)
+++ uspace/lib/c/include/inet/udp.h	(revision dc0d6e5d084de74e724a544d470b0b47aefde2de)
@@ -37,7 +37,9 @@
 
 #include <async.h>
+#include <fibril_synch.h>
 #include <inet/addr.h>
 #include <inet/endpoint.h>
 #include <inet/inet.h>
+#include <stdbool.h>
 
 /** UDP link state */
@@ -81,4 +83,10 @@
 	/** List of associations */
 	list_t assoc; /* of udp_assoc_t */
+	/** UDP service lock */
+	fibril_mutex_t lock;
+	/** For waiting on cb_done */
+	fibril_condvar_t cv;
+	/** Set to @a true when callback connection handler has terminated */
+	bool cb_done;
 } udp_t;
 
