[MINOR] move the listener reference from fd to session

The listener referenced in the fd was only used to check the
listener state upon session termination. There was no guarantee
that the FD had not been reassigned by the moment it was processed,
so this was a bit racy. Having it in the session is more robust.
diff --git a/include/types/fd.h b/include/types/fd.h
index 97e14b1..c413245 100644
--- a/include/types/fd.h
+++ b/include/types/fd.h
@@ -3,7 +3,7 @@
   File descriptors states.
 
   Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
-  
+
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation, version 2.1
@@ -70,7 +70,6 @@
 	unsigned char ev;                    /* event seen in return of poll() : FD_POLL_* */
 	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 listener *listener;           /* the listener which created this fd, or NULL if unset */
 };
 
 /*
diff --git a/include/types/session.h b/include/types/session.h
index 574f933..eaa053f 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -155,6 +155,7 @@
 	struct list list;			/* position in global sessions list */
 	struct task *task;			/* the task associated with this session */
 	/* application specific below */
+	struct listener *listener;		/* the listener by which the request arrived */
 	struct proxy *fe;			/* the proxy this session depends on for the client side */
 	struct proxy *be;			/* the proxy this session depends on for the server side */
 	int conn_retries;			/* number of connect retries left */
diff --git a/src/client.c b/src/client.c
index a01bb52..a9625da 100644
--- a/src/client.c
+++ b/src/client.c
@@ -157,6 +157,7 @@
 		t->context = s;
 
 		s->task = t;
+		s->listener = l;
 		s->be = s->fe = p;
 
 		/* in HTTP mode, content switching requires that the backend
@@ -397,7 +398,6 @@
 
 		fd_insert(cfd);
 		fdtab[cfd].owner = &s->si[0];
-		fdtab[cfd].listener = l;
 		fdtab[cfd].state = FD_STREADY;
 		fdtab[cfd].cb[DIR_RD].f = l->proto->read;
 		fdtab[cfd].cb[DIR_RD].b = s->req;
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index ce0c43a..5a1424f 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -266,7 +266,6 @@
 	fdtab[fd].state = FD_STLISTEN;
 	fdtab[fd].peeraddr = NULL;
 	fdtab[fd].peerlen = 0;
-	fdtab[fd].listener = NULL;
  tcp_return:
 	if (msg && errlen)
 		strlcpy2(errmsg, msg, errlen);
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index b3bf754..d756750 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -270,7 +270,6 @@
 	fdtab[fd].state = FD_STLISTEN;
 	fdtab[fd].peeraddr = NULL;
 	fdtab[fd].peerlen = 0;
-	fdtab[fd].listener = NULL;
 	return ERR_NONE;
 }
 
@@ -438,6 +437,7 @@
 		t->nice = -64;  /* we want to boost priority for local stats */
 
 		s->task = t;
+		s->listener = l;
 		s->fe = NULL;
 		s->be = NULL;
 
@@ -518,7 +518,6 @@
 
 		fd_insert(cfd);
 		fdtab[cfd].owner = &s->si[0];
-		fdtab[cfd].listener = l;
 		fdtab[cfd].state = FD_STREADY;
 		fdtab[cfd].cb[DIR_RD].f = l->proto->read;
 		fdtab[cfd].cb[DIR_RD].b = s->req;
@@ -695,7 +694,6 @@
 void uxst_process_session(struct task *t, int *next)
 {
 	struct session *s = t->context;
-	struct listener *listener;
 	int resync;
 	unsigned int rqf_last, rpf_last;
 
@@ -937,14 +935,13 @@
 	}
 
 	actconn--;
-	listener = fdtab[s->si[0].fd].listener;
-	if (listener) {
-		listener->nbconn--;
-		if (listener->state == LI_FULL &&
-		    listener->nbconn < listener->maxconn) {
+	if (s->listener) {
+		s->listener->nbconn--;
+		if (s->listener->state == LI_FULL &&
+		    s->listener->nbconn < s->listener->maxconn) {
 			/* we should reactivate the listener */
-			EV_FD_SET(listener->fd, DIR_RD);
-			listener->state = LI_READY;
+			EV_FD_SET(s->listener->fd, DIR_RD);
+			s->listener->state = LI_READY;
 		}
 	}