MEDIUM: fd/si: move peeraddr from struct fdinfo to struct connection

The destination address is purely a connection thing and not an fd thing.
It's also likely that later the address will be stored into the connection
and linked to by the SI.

struct fdinfo only keeps the pointer to the port range and the local port
for now. All of this also needs to move to the connection but before this
the release of the port range must move from fd_delete() to a new function
dedicated to the connection.
diff --git a/include/types/fd.h b/include/types/fd.h
index 559fa0e..0abd3ef 100644
--- a/include/types/fd.h
+++ b/include/types/fd.h
@@ -84,8 +84,6 @@
 struct fdinfo {
 	struct port_range *port_range;       /* optional port range to bind to */
 	int local_port;                      /* optional local port */
-	struct sockaddr *peeraddr;   /* pointer to peer's network address, or NULL if unset */
-	socklen_t peerlen;           /* peer's address length, or 0 if unset */
 };
 
 /*
diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h
index 8218eda..b11b398 100644
--- a/include/types/stream_interface.h
+++ b/include/types/stream_interface.h
@@ -112,6 +112,8 @@
 	} t;
 	int data_st;                  /* data layer state, initialized to zero */
 	void *data_ctx;               /* general purpose pointer, initialized to NULL */
+	struct sockaddr *peeraddr;    /* pointer to peer's network address, or NULL if unset */
+	socklen_t peerlen;            /* peer's address length, or 0 if unset */
 };
 
 struct target {
diff --git a/src/checks.c b/src/checks.c
index d0e5b6d..cf8b4eb 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1465,8 +1465,6 @@
 						fdtab[fd].owner = t;
 						fdtab[fd].cb[DIR_RD].f = &event_srv_chk_r;
 						fdtab[fd].cb[DIR_WR].f = &event_srv_chk_w;
-						fdinfo[fd].peeraddr = (struct sockaddr *)&sa;
-						fdinfo[fd].peerlen = get_addr_len(&sa);
 						fdtab[fd].state = FD_STCONN; /* connection in progress */
 						fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
 						EV_FD_SET(fd, DIR_WR);  /* for connect status */
diff --git a/src/peers.c b/src/peers.c
index a4ea915..c12dcf6 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1149,6 +1149,8 @@
 
 	s->req = s->rep = NULL; /* will be allocated later */
 
+	s->si[0].conn.peeraddr = NULL;
+	s->si[0].conn.peerlen  = 0;
 	s->si[0].conn.t.sock.fd = -1;
 	s->si[0].owner = t;
 	s->si[0].state = s->si[0].prev_state = SI_ST_EST;
@@ -1167,6 +1169,8 @@
 	s->si[0].applet.st0 = PEER_SESSION_CONNECT;
 	s->si[0].conn.data_ctx = (void *)ps;
 
+	s->si[1].conn.peeraddr = NULL;
+	s->si[1].conn.peerlen  = 0;
 	s->si[1].conn.t.sock.fd = -1; /* just to help with debugging */
 	s->si[1].owner = t;
 	s->si[1].state = s->si[1].prev_state = SI_ST_ASS;
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index ccd9e48..59b8bc5 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -410,7 +410,11 @@
                 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
 
 	si->flags &= ~SI_FL_FROM_SET;
-	if ((connect(fd, (struct sockaddr *)&si->addr.to, get_addr_len(&si->addr.to)) == -1) &&
+
+	si->conn.peeraddr = (struct sockaddr *)&si->addr.to;
+	si->conn.peerlen  = get_addr_len(&si->addr.to);
+
+	if ((connect(fd, si->conn.peeraddr, si->conn.peerlen) == -1) &&
 	    (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
 
 		if (errno == EAGAIN || errno == EADDRINUSE) {
@@ -465,9 +469,6 @@
 		fdtab[fd].cb[DIR_WR].f = si_data(si)->write;
 	}
 
-	fdinfo[fd].peeraddr = (struct sockaddr *)&si->addr.to;
-	fdinfo[fd].peerlen = get_addr_len(&si->addr.to);
-
 	fd_insert(fd);
 	EV_FD_SET(fd, DIR_WR);  /* for connect status */
 
@@ -583,7 +584,7 @@
 		 *  - connecting (EALREADY, EINPROGRESS)
 		 *  - connected (EISCONN, 0)
 		 */
-		if ((connect(fd, fdinfo[fd].peeraddr, fdinfo[fd].peerlen) < 0)) {
+		if ((connect(fd, si->conn.peeraddr, si->conn.peerlen) < 0)) {
 			if (errno == EALREADY || errno == EINPROGRESS)
 				goto out_ignore;
 
@@ -797,9 +798,6 @@
 	fdtab[fd].flags = FD_FL_TCP | ((listener->options & LI_O_NOLINGER) ? FD_FL_TCP_NOLING : 0);
 	fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
 	fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
-
-	fdinfo[fd].peeraddr = NULL;
-	fdinfo[fd].peerlen = 0;
 	fd_insert(fd);
 
  tcp_return:
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index dec91aa..2b4c4de 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -266,8 +266,6 @@
 	fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
 	fdtab[fd].owner = listener; /* reference the listener instead of a task */
 	fdtab[fd].state = FD_STLISTEN;
-	fdinfo[fd].peeraddr = NULL;
-	fdinfo[fd].peerlen = 0;
 	return ERR_NONE;
  err_rename:
 	ret = rename(backname, path);
diff --git a/src/session.c b/src/session.c
index 353fa66..43252b8 100644
--- a/src/session.c
+++ b/src/session.c
@@ -84,7 +84,11 @@
 
 	s->unique_id = NULL;
 	s->term_trace = 0;
+	s->si[0].conn.t.sock.fd = cfd;
+	s->si[0].conn.ctrl = l->proto;
 	s->si[0].addr.from = *addr;
+	s->si[0].conn.peeraddr = (struct sockaddr *)&s->si[0].addr.from;
+	s->si[0].conn.peerlen  = sizeof(s->si[0].addr.from);
 	s->logs.accept_date = date; /* user-visible date for logging */
 	s->logs.tv_accept = now;  /* corrected date for internal use */
 	s->uniq_id = totalconn;
@@ -161,12 +165,10 @@
 	}
 
 	/* this part should be common with other protocols */
-	s->si[0].conn.t.sock.fd = cfd;
 	s->si[0].owner     = t;
 	s->si[0].state     = s->si[0].prev_state = SI_ST_EST;
 	s->si[0].err_type  = SI_ET_NONE;
 	s->si[0].err_loc   = NULL;
-	s->si[0].conn.ctrl = l->proto;
 	s->si[0].release   = NULL;
 	s->si[0].send_proxy_ofs = 0;
 	set_target_client(&s->si[0].target, l);
@@ -281,8 +283,6 @@
 	fdtab[cfd].flags = 0;
 	fdtab[cfd].cb[DIR_RD].f = si_data(&s->si[0])->read;
 	fdtab[cfd].cb[DIR_WR].f = si_data(&s->si[0])->write;
-	fdinfo[cfd].peeraddr = (struct sockaddr *)&s->si[0].addr.from;
-	fdinfo[cfd].peerlen  = sizeof(s->si[0].addr.from);
 	EV_FD_SET(cfd, DIR_RD);
 
 	if (p->accept && (ret = p->accept(s)) <= 0) {