Index: uspace/srv/net/tcp/Makefile
===================================================================
--- uspace/srv/net/tcp/Makefile	(revision 58e9dec38facb087ef357050fc85631d17323e92)
+++ uspace/srv/net/tcp/Makefile	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
@@ -28,4 +28,11 @@
 
 USPACE_PREFIX = ../../..
+
+LIBS = \
+	$(LIBNETTL_PREFIX)/libnettl.a
+
+EXTRA_CFLAGS += \
+	-I$(LIBNETTL_PREFIX)/include
+
 BINARY = tcp
 
Index: uspace/srv/net/tcp/conn.c
===================================================================
--- uspace/srv/net/tcp/conn.c	(revision 58e9dec38facb087ef357050fc85631d17323e92)
+++ uspace/srv/net/tcp/conn.c	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
@@ -36,9 +36,10 @@
 
 #include <adt/list.h>
-#include <stdbool.h>
 #include <errno.h>
 #include <inet/endpoint.h>
 #include <io/log.h>
 #include <macros.h>
+#include <nettl/amap.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include "conn.h"
@@ -56,10 +57,25 @@
 #define TIME_WAIT_TIMEOUT	(2*MAX_SEGMENT_LIFETIME)
 
-LIST_INITIALIZE(conn_list);
-FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
+static LIST_INITIALIZE(conn_list);
+static FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
+static amap_t *amap;
 
 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg);
 static void tcp_conn_tw_timer_set(tcp_conn_t *conn);
 static void tcp_conn_tw_timer_clear(tcp_conn_t *conn);
+
+/** Initialize connections. */
+int tcp_conns_init(void)
+{
+	int rc;
+
+	rc = amap_create(&amap);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		return ENOMEM;
+	}
+
+	return EOK;
+}
 
 /** Create new connection structure.
@@ -246,10 +262,24 @@
  * Add connection to the connection map.
  */
-void tcp_conn_add(tcp_conn_t *conn)
-{
+int tcp_conn_add(tcp_conn_t *conn)
+{
+	inet_ep2_t aepp;
+	int rc;
+
 	tcp_conn_addref(conn);
 	fibril_mutex_lock(&conn_list_lock);
+
+	rc = amap_insert(amap, &conn->ident, conn, af_allow_system, &aepp);
+	if (rc != EOK) {
+		tcp_conn_delref(conn);
+		fibril_mutex_unlock(&conn_list_lock);
+		return rc;
+	}
+
+	conn->ident = aepp;
 	list_append(&conn->link, &conn_list);
 	fibril_mutex_unlock(&conn_list_lock);
+
+	return EOK;
 }
 
@@ -261,4 +291,5 @@
 {
 	fibril_mutex_lock(&conn_list_lock);
+	amap_remove(amap, &conn->ident);
 	list_remove(&conn->link);
 	fibril_mutex_unlock(&conn_list_lock);
Index: uspace/srv/net/tcp/conn.h
===================================================================
--- uspace/srv/net/tcp/conn.h	(revision 58e9dec38facb087ef357050fc85631d17323e92)
+++ uspace/srv/net/tcp/conn.h	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
@@ -40,7 +40,8 @@
 #include "tcp_type.h"
 
+extern int tcp_conns_init(void);
 extern tcp_conn_t *tcp_conn_new(inet_ep2_t *);
 extern void tcp_conn_delete(tcp_conn_t *);
-extern void tcp_conn_add(tcp_conn_t *);
+extern int tcp_conn_add(tcp_conn_t *);
 extern void tcp_conn_remove(tcp_conn_t *);
 extern void tcp_conn_reset(tcp_conn_t *conn);
Index: uspace/srv/net/tcp/service.c
===================================================================
--- uspace/srv/net/tcp/service.c	(revision 58e9dec38facb087ef357050fc85631d17323e92)
+++ uspace/srv/net/tcp/service.c	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
@@ -335,5 +335,4 @@
 	tcp_conn_t *conn;
 	tcp_cconn_t *cconn;
-	inet_ep2_t cepp;
 	int rc;
 	tcp_error_t trc;
@@ -343,33 +342,6 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl");
 
-	cepp = *epp;
-
-	/* Fill in local address? */
-	if (inet_addr_is_any(&epp->local.addr)) {
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
-		    "determine local address");
-		rc = inet_get_srcaddr(&epp->remote.addr, 0, &cepp.local.addr);
-		if (rc != EOK) {
-			log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
-			    "cannot determine local address");
-			return rc;
-		}
-	} else {
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
-		    "local address specified");
-	}
-
-	/* Allocate local port? */
-	if (cepp.local.port == 0) {
-		cepp.local.port = 49152; /* XXX */
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
-		    "allocated local port %" PRIu16, cepp.local.port);
-	} else {
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
-		    "local port %" PRIu16 " specified", cepp.local.port);
-	}
-
-	inet_addr_format(&cepp.local.addr, &slocal);
-	inet_addr_format(&cepp.remote.addr, &sremote);
+	inet_addr_format(&epp->local.addr, &slocal);
+	inet_addr_format(&epp->remote.addr, &sremote);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create: local=%s remote=%s",
 	    slocal, sremote);
@@ -377,5 +349,5 @@
 	free(sremote);
 
-	trc = tcp_uc_open(&cepp, ap_active, tcp_open_nonblock, &conn);
+	trc = tcp_uc_open(epp, ap_active, tcp_open_nonblock, &conn);
 	if (trc != TCP_EOK)
 		return EIO;
Index: uspace/srv/net/tcp/tcp.c
===================================================================
--- uspace/srv/net/tcp/tcp.c	(revision 58e9dec38facb087ef357050fc85631d17323e92)
+++ uspace/srv/net/tcp/tcp.c	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
@@ -45,4 +45,5 @@
 #include <task.h>
 
+#include "conn.h"
 #include "ncsim.h"
 #include "pdu.h"
@@ -179,4 +180,11 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_init()");
 
+	rc = tcp_conns_init();
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing connections");
+		return ENOMEM;
+	}
+
 	tcp_rqueue_init();
 	tcp_rqueue_fibril_start();
Index: uspace/srv/net/tcp/ucall.c
===================================================================
--- uspace/srv/net/tcp/ucall.c	(revision 58e9dec38facb087ef357050fc85631d17323e92)
+++ uspace/srv/net/tcp/ucall.c	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
@@ -35,4 +35,5 @@
  */
 
+#include <errno.h>
 #include <fibril_synch.h>
 #include <io/log.h>
@@ -68,4 +69,5 @@
 {
 	tcp_conn_t *nconn;
+	int rc;
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open(%p, %s, %s, %p)",
@@ -74,5 +76,10 @@
 
 	nconn = tcp_conn_new(epp);
-	tcp_conn_add(nconn);
+	rc = tcp_conn_add(nconn);
+	if (rc != EOK) {
+		tcp_conn_delete(nconn);
+		return TCP_EEXISTS;
+	}
+
 	tcp_conn_lock(nconn);
 
