[MAJOR] session: remove the ->srv pointer from struct session

This one has been removed and is now totally superseded by ->target.
To get the server, one must use target_srv(&s->target) instead of
s->srv now.

The function ensures that non-server targets still return NULL.
diff --git a/src/backend.c b/src/backend.c
index 8367328..7a9e0c6 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -446,7 +446,7 @@
  *
  * This function MAY NOT be called with SN_ASSIGNED already set. If the session
  * had a server previously assigned, it is rebalanced, trying to avoid the same
- * server, which should still be present in s->srv before the call.
+ * server, which should still be present in target_srv(&s->target) before the call.
  * The function tries to keep the original connection slot if it reconnects to
  * the same server, otherwise it releases it and tries to offer it.
  *
@@ -459,8 +459,8 @@
  *   SRV_STATUS_INTERNAL for other unrecoverable errors.
  *
  * Upon successful return, the session flag SN_ASSIGNED is set to indicate that
- * it does not need to be called anymore. This means that s->srv can be trusted
- * in balance and direct modes.
+ * it does not need to be called anymore. This means that target_srv(&s->target)
+ * can be trusted in balance and direct modes.
  *
  */
 
@@ -468,7 +468,7 @@
 {
 
 	struct server *conn_slot;
-	struct server *prev_srv;
+	struct server *srv, *prev_srv;
 	int err;
 
 #ifdef DEBUG_FULL
@@ -479,7 +479,7 @@
 	if (unlikely(s->pend_pos || s->flags & SN_ASSIGNED))
 		goto out_err;
 
-	prev_srv  = s->srv;
+	prev_srv  = target_srv(&s->target);
 	conn_slot = s->srv_conn;
 
 	/* We have to release any connection slot before applying any LB algo,
@@ -488,12 +488,12 @@
 	if (conn_slot)
 		sess_change_server(s, NULL);
 
-	/* We will now try to find the good server and store it into <s->srv>.
-	 * Note that <s->srv> may be NULL in case of dispatch or proxy mode,
+	/* We will now try to find the good server and store it into <target_srv(&s->target)>.
+	 * Note that <target_srv(&s->target)> may be NULL in case of dispatch or proxy mode,
 	 * as well as if no server is available (check error code).
 	 */
 
-	s->srv = NULL;
+	srv = NULL;
 	clear_target(&s->target);
 
 	if (s->be->lbprm.algo & BE_LB_KIND) {
@@ -510,20 +510,20 @@
 		 */
 		switch (s->be->lbprm.algo & BE_LB_LKUP) {
 		case BE_LB_LKUP_RRTREE:
-			s->srv = fwrr_get_next_server(s->be, prev_srv);
+			srv = fwrr_get_next_server(s->be, prev_srv);
 			break;
 
 		case BE_LB_LKUP_LCTREE:
-			s->srv = fwlc_get_next_server(s->be, prev_srv);
+			srv = fwlc_get_next_server(s->be, prev_srv);
 			break;
 
 		case BE_LB_LKUP_CHTREE:
 		case BE_LB_LKUP_MAP:
 			if ((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_RR) {
 				if (s->be->lbprm.algo & BE_LB_LKUP_CHTREE)
-					s->srv = chash_get_next_server(s->be, prev_srv);
+					srv = chash_get_next_server(s->be, prev_srv);
 				else
-					s->srv = map_get_server_rr(s->be, prev_srv);
+					srv = map_get_server_rr(s->be, prev_srv);
 				break;
 			}
 			else if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI) {
@@ -544,18 +544,18 @@
 					goto out;
 				}
 		
-				s->srv = get_server_sh(s->be,
-						       (void *)&((struct sockaddr_in *)&s->req->prod->addr.c.from)->sin_addr,
-						       len);
+				srv = get_server_sh(s->be,
+						    (void *)&((struct sockaddr_in *)&s->req->prod->addr.c.from)->sin_addr,
+						    len);
 				break;
 
 			case BE_LB_HASH_URI:
 				/* URI hashing */
 				if (s->txn.req.msg_state < HTTP_MSG_BODY)
 					break;
-				s->srv = get_server_uh(s->be,
-						       s->txn.req.sol + s->txn.req.sl.rq.u,
-						       s->txn.req.sl.rq.u_l);
+				srv = get_server_uh(s->be,
+						    s->txn.req.sol + s->txn.req.sl.rq.u,
+						    s->txn.req.sl.rq.u_l);
 				break;
 
 			case BE_LB_HASH_PRM:
@@ -563,24 +563,24 @@
 				if (s->txn.req.msg_state < HTTP_MSG_BODY)
 					break;
 
-				s->srv = get_server_ph(s->be,
-						       s->txn.req.sol + s->txn.req.sl.rq.u,
-						       s->txn.req.sl.rq.u_l);
+				srv = get_server_ph(s->be,
+						    s->txn.req.sol + s->txn.req.sl.rq.u,
+						    s->txn.req.sl.rq.u_l);
 
-				if (!s->srv && s->txn.meth == HTTP_METH_POST)
-					s->srv = get_server_ph_post(s);
+				if (!srv && s->txn.meth == HTTP_METH_POST)
+					srv = get_server_ph_post(s);
 				break;
 
 			case BE_LB_HASH_HDR:
 				/* Header Parameter hashing */
 				if (s->txn.req.msg_state < HTTP_MSG_BODY)
 					break;
-				s->srv = get_server_hh(s);
+				srv = get_server_hh(s);
 				break;
 
 			case BE_LB_HASH_RDP:
 				/* RDP Cookie hashing */
-				s->srv = get_server_rch(s);
+				srv = get_server_rch(s);
 				break;
 
 			default:
@@ -592,11 +592,11 @@
 			/* If the hashing parameter was not found, let's fall
 			 * back to round robin on the map.
 			 */
-			if (!s->srv) {
+			if (!srv) {
 				if (s->be->lbprm.algo & BE_LB_LKUP_CHTREE)
-					s->srv = chash_get_next_server(s->be, prev_srv);
+					srv = chash_get_next_server(s->be, prev_srv);
 				else
-					s->srv = map_get_server_rr(s->be, prev_srv);
+					srv = map_get_server_rr(s->be, prev_srv);
 			}
 
 			/* end of map-based LB */
@@ -608,16 +608,15 @@
 			goto out;
 		}
 
-		if (!s->srv) {
+		if (!srv) {
 			err = SRV_STATUS_FULL;
 			goto out;
 		}
-		else if (s->srv != prev_srv) {
+		else if (srv != prev_srv) {
 			s->be->counters.cum_lbconn++;
-			s->srv->counters.cum_lbconn++;
+			srv->counters.cum_lbconn++;
 		}
-
-		set_target_server(&s->target, s->srv);
+		set_target_server(&s->target, srv);
 	}
 	else if ((s->be->options2 & PR_O2_DISPATCH) || (s->be->options & PR_O_TRANSP)) {
 		set_target_proxy(&s->target, s->be);
@@ -639,8 +638,8 @@
 	 * else if we don't need it anymore.
 	 */
 	if (conn_slot) {
-		if (conn_slot == s->srv) {
-			sess_change_server(s, s->srv);
+		if (conn_slot == srv) {
+			sess_change_server(s, srv);
 		} else {
 			if (may_dequeue_tasks(conn_slot, s->be))
 				process_srv_queue(conn_slot);
@@ -676,7 +675,7 @@
 		if (!(s->flags & SN_ASSIGNED))
 			return SRV_STATUS_INTERNAL;
 
-		s->req->cons->addr.s.to = s->srv->addr;
+		s->req->cons->addr.s.to = target_srv(&s->target)->addr;
 
 		if (!s->req->cons->addr.s.to.sin_addr.s_addr) {
 			/* if the server has no address, we use the same address
@@ -693,7 +692,7 @@
 
 		/* if this server remaps proxied ports, we'll use
 		 * the port the client connected to with an offset. */
-		if (s->srv->state & SRV_MAPPORTS) {
+		if (target_srv(&s->target)->state & SRV_MAPPORTS) {
 			if (!(s->be->options & PR_O_TRANSP) && !(s->flags & SN_FRT_ADDR_SET))
 				get_frt_addr(s);
 			if (s->req->prod->addr.c.to.ss_family == AF_INET) {
@@ -747,10 +746,10 @@
  * Returns :
  *
  *   SRV_STATUS_OK       if everything is OK.
- *   SRV_STATUS_NOSRV    if no server is available. s->srv = NULL.
+ *   SRV_STATUS_NOSRV    if no server is available. target_srv(&s->target) = NULL.
  *   SRV_STATUS_QUEUED   if the connection has been queued.
  *   SRV_STATUS_FULL     if the server(s) is/are saturated and the
- *                       connection could not be queued in s->srv,
+ *                       connection could not be queued at the server's,
  *                       which may be NULL if we queue on the backend.
  *   SRV_STATUS_INTERNAL for other unrecoverable errors.
  *
@@ -758,6 +757,7 @@
 int assign_server_and_queue(struct session *s)
 {
 	struct pendconn *p;
+	struct server *srv;
 	int err;
 
 	if (s->pend_pos)
@@ -765,7 +765,7 @@
 
 	err = SRV_STATUS_OK;
 	if (!(s->flags & SN_ASSIGNED)) {
-		struct server *prev_srv = s->srv;
+		struct server *prev_srv = target_srv(&s->target);
 
 		err = assign_server(s);
 		if (prev_srv) {
@@ -778,7 +778,7 @@
 			 *  - if the server remained the same : update retries.
 			 */
 
-			if (prev_srv != s->srv) {
+			if (prev_srv != target_srv(&s->target)) {
 				if ((s->txn.flags & TX_CK_MASK) == TX_CK_VALID) {
 					s->txn.flags &= ~TX_CK_MASK;
 					s->txn.flags |= TX_CK_DOWN;
@@ -796,22 +796,23 @@
 	switch (err) {
 	case SRV_STATUS_OK:
 		/* we have SN_ASSIGNED set */
-		if (!s->srv)
+		srv = target_srv(&s->target);
+		if (!srv)
 			return SRV_STATUS_OK;   /* dispatch or proxy mode */
 
 		/* If we already have a connection slot, no need to check any queue */
-		if (s->srv_conn == s->srv)
+		if (s->srv_conn == srv)
 			return SRV_STATUS_OK;
 
 		/* OK, this session already has an assigned server, but no
 		 * connection slot yet. Either it is a redispatch, or it was
 		 * assigned from persistence information (direct mode).
 		 */
-		if ((s->flags & SN_REDIRECTABLE) && s->srv->rdr_len) {
+		if ((s->flags & SN_REDIRECTABLE) && srv->rdr_len) {
 			/* server scheduled for redirection, and already assigned. We
 			 * don't want to go further nor check the queue.
 			 */
-			sess_change_server(s, s->srv); /* not really needed in fact */
+			sess_change_server(s, srv); /* not really needed in fact */
 			return SRV_STATUS_OK;
 		}
 
@@ -820,10 +821,10 @@
 		 * is set on the server, we must also check that the server's queue is
 		 * not full, in which case we have to return FULL.
 		 */
-		if (s->srv->maxconn &&
-		    (s->srv->nbpend || s->srv->served >= srv_dynamic_maxconn(s->srv))) {
+		if (srv->maxconn &&
+		    (srv->nbpend || srv->served >= srv_dynamic_maxconn(srv))) {
 
-			if (s->srv->maxqueue > 0 && s->srv->nbpend >= s->srv->maxqueue)
+			if (srv->maxqueue > 0 && srv->nbpend >= srv->maxqueue)
 				return SRV_STATUS_FULL;
 
 			p = pendconn_add(s);
@@ -834,7 +835,7 @@
 		}
 
 		/* OK, we can use this server. Let's reserve our place */
-		sess_change_server(s, s->srv);
+		sess_change_server(s, srv);
 		return SRV_STATUS_OK;
 
 	case SRV_STATUS_FULL:
@@ -863,10 +864,12 @@
 static void assign_tproxy_address(struct session *s)
 {
 #if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-	if (s->srv != NULL && s->srv->state & SRV_BIND_SRC) {
-		switch (s->srv->state & SRV_TPROXY_MASK) {
+	struct server *srv = target_srv(&s->target);
+
+	if (srv && srv->state & SRV_BIND_SRC) {
+		switch (srv->state & SRV_TPROXY_MASK) {
 		case SRV_TPROXY_ADDR:
-			s->req->cons->addr.s.from = *(struct sockaddr_in *)&s->srv->tproxy_addr;
+			s->req->cons->addr.s.from = *(struct sockaddr_in *)&srv->tproxy_addr;
 			break;
 		case SRV_TPROXY_CLI:
 		case SRV_TPROXY_CIP:
@@ -874,14 +877,14 @@
 			s->req->cons->addr.s.from = *(struct sockaddr_in *)&s->req->prod->addr.c.from;
 			break;
 		case SRV_TPROXY_DYN:
-			if (s->srv->bind_hdr_occ) {
+			if (srv->bind_hdr_occ) {
 				/* bind to the IP in a header */
 				s->req->cons->addr.s.from.sin_port = 0;
 				s->req->cons->addr.s.from.sin_addr.s_addr = htonl(get_ip_from_hdr2(&s->txn.req,
-										s->srv->bind_hdr_name,
-										s->srv->bind_hdr_len,
+										srv->bind_hdr_name,
+										srv->bind_hdr_len,
 										&s->txn.hdr_idx,
-										s->srv->bind_hdr_occ));
+										srv->bind_hdr_occ));
 			}
 			break;
 		default:
@@ -919,7 +922,7 @@
 
 /*
  * This function initiates a connection to the server assigned to this session
- * (s->srv, s->target, s->req->cons->addr.s.to). It will assign a server if none
+ * (s->target, s->req->cons->addr.s.to). It will assign a server if none
  * is assigned yet.
  * It can return one of :
  *  - SN_ERR_NONE if everything's OK
@@ -932,6 +935,7 @@
  */
 int connect_server(struct session *s)
 {
+	struct server *srv;
 	int err;
 
 	if (!(s->flags & SN_ADDR_SET)) {
@@ -957,13 +961,14 @@
 	if (err != SN_ERR_NONE)
 		return err;
 
-	if (s->srv) {
+	srv = target_srv(&s->target);
+	if (srv) {
 		s->flags |= SN_CURR_SESS;
-		s->srv->cur_sess++;
-		if (s->srv->cur_sess > s->srv->counters.cur_sess_max)
-			s->srv->counters.cur_sess_max = s->srv->cur_sess;
+		srv->cur_sess++;
+		if (srv->cur_sess > srv->counters.cur_sess_max)
+			srv->counters.cur_sess_max = srv->cur_sess;
 		if (s->be->lbprm.server_take_conn)
-			s->be->lbprm.server_take_conn(s->srv);
+			s->be->lbprm.server_take_conn(srv);
 	}
 
 	return SN_ERR_NONE;  /* connection is OK */
@@ -980,6 +985,7 @@
 
 int srv_redispatch_connect(struct session *t)
 {
+	struct server *srv;
 	int conn_err;
 
 	/* We know that we don't have any connection pending, so we will
@@ -987,6 +993,8 @@
 	 */
  redispatch:
 	conn_err = assign_server_and_queue(t);
+	srv = target_srv(&t->target);
+
 	switch (conn_err) {
 	case SRV_STATUS_OK:
 		break;
@@ -996,8 +1004,8 @@
 		 * and we can redispatch to another server, or it is not and we return
 		 * 503. This only makes sense in DIRECT mode however, because normal LB
 		 * algorithms would never select such a server, and hash algorithms
-		 * would bring us on the same server again. Note that t->srv is set in
-		 * this case.
+		 * would bring us on the same server again. Note that t->target is set
+		 * in this case.
 		 */
 		if (((t->flags & (SN_DIRECT|SN_FORCE_PRST)) == SN_DIRECT) &&
 		    (t->be->options & PR_O_REDISP)) {
@@ -1007,15 +1015,15 @@
 
 		if (!t->req->cons->err_type) {
 			t->req->cons->err_type = SI_ET_QUEUE_ERR;
-			t->req->cons->err_loc = t->srv;
+			t->req->cons->err_loc = srv;
 		}
 
-		t->srv->counters.failed_conns++;
+		srv->counters.failed_conns++;
 		t->be->counters.failed_conns++;
 		return 1;
 
 	case SRV_STATUS_NOSRV:
-		/* note: it is guaranteed that t->srv == NULL here */
+		/* note: it is guaranteed that srv == NULL here */
 		if (!t->req->cons->err_type) {
 			t->req->cons->err_type = SI_ET_CONN_ERR;
 			t->req->cons->err_loc = NULL;
@@ -1034,18 +1042,18 @@
 	default:
 		if (!t->req->cons->err_type) {
 			t->req->cons->err_type = SI_ET_CONN_OTHER;
-			t->req->cons->err_loc = t->srv;
+			t->req->cons->err_loc = srv;
 		}
 
-		if (t->srv)
-			srv_inc_sess_ctr(t->srv);
-		if (t->srv)
-			t->srv->counters.failed_conns++;
+		if (srv)
+			srv_inc_sess_ctr(srv);
+		if (srv)
+			srv->counters.failed_conns++;
 		t->be->counters.failed_conns++;
 
 		/* release other sessions waiting for this server */
-		if (may_dequeue_tasks(t->srv, t->be))
-			process_srv_queue(t->srv);
+		if (may_dequeue_tasks(srv, t->be))
+			process_srv_queue(srv);
 		return 1;
 	}
 	/* if we get here, it's because we got SRV_STATUS_OK, which also
@@ -1110,7 +1118,6 @@
 			if ((srv->state & SRV_RUNNING) || (px->options & PR_O_PERSIST)) {
 				/* we found the server and it is usable */
 				s->flags |= SN_DIRECT | SN_ASSIGNED;
-				s->srv = srv;
 				set_target_server(&s->target, srv);
 				break;
 			}
@@ -1414,12 +1421,12 @@
 acl_fetch_srv_id(struct proxy *px, struct session *l4, void *l7, int dir,
                 struct acl_expr *expr, struct acl_test *test) {
 
-	if (!l4->srv)
+	if (!target_srv(&l4->target))
 		return 0;
 
 	test->flags = ACL_TEST_F_READ_ONLY;
 
-	test->i = l4->srv->puid;
+	test->i = target_srv(&l4->target)->puid;
 
 	return 1;
 }