[MINOR] session: add a pointer to the new target into the session
When dealing with HTTP keep-alive, we'll have to know if we can reuse an existing connection. For that, we'll have to check if the current connection was made on the exact same target (referenced in the stream interface). Thus, we need to first assign the next target to the session, then copy it to the stream interface upon connect(). Later we'll check for equivalence between those two operations.
This commit is contained in:
parent
d6cc532ca1
commit
664beb8610
@ -171,6 +171,7 @@ struct session {
|
||||
struct server *srv; /* the server the session will be running or has been running on */
|
||||
struct server *srv_conn; /* session already has a slot on a server and is not in queue */
|
||||
struct server *prev_srv; /* the server the was running on, after a redispatch, otherwise NULL */
|
||||
struct target target; /* target to use for this session */
|
||||
struct pendconn *pend_pos; /* if not NULL, points to the position in the pending queue */
|
||||
struct http_txn txn; /* current HTTP transaction being processed. Should become a list. */
|
||||
|
||||
|
@ -452,7 +452,7 @@ struct server *get_server_rch(struct session *s)
|
||||
* It is illegal to call this function with a session in a queue.
|
||||
*
|
||||
* It may return :
|
||||
* SRV_STATUS_OK if everything is OK. Session assigned to ->srv
|
||||
* SRV_STATUS_OK if everything is OK. ->srv and ->target are assigned.
|
||||
* SRV_STATUS_NOSRV if no server is available. Session is not ASSIGNED
|
||||
* SRV_STATUS_FULL if all servers are saturated. Session is not ASSIGNED
|
||||
* SRV_STATUS_INTERNAL for other unrecoverable errors.
|
||||
@ -492,6 +492,9 @@ int assign_server(struct session *s)
|
||||
*/
|
||||
|
||||
s->srv = NULL;
|
||||
s->target.type = TARG_TYPE_NONE;
|
||||
s->target.ptr.v = NULL;
|
||||
|
||||
if (s->be->lbprm.algo & BE_LB_KIND) {
|
||||
int len;
|
||||
/* we must check if we have at least one server available */
|
||||
@ -612,14 +615,20 @@ int assign_server(struct session *s)
|
||||
s->be->counters.cum_lbconn++;
|
||||
s->srv->counters.cum_lbconn++;
|
||||
}
|
||||
|
||||
s->target.type = TARG_TYPE_SERVER;
|
||||
s->target.ptr.s = s->srv;
|
||||
}
|
||||
else if (s->be->options & PR_O_HTTP_PROXY) {
|
||||
if (!s->req->cons->addr.s.to.sin_addr.s_addr) {
|
||||
err = SRV_STATUS_NOSRV;
|
||||
goto out;
|
||||
}
|
||||
else if ((s->be->options2 & PR_O2_DISPATCH) || (s->be->options & PR_O_TRANSP)) {
|
||||
s->target.type = TARG_TYPE_PROXY;
|
||||
s->target.ptr.p = s->be;
|
||||
}
|
||||
else if (!(s->be->options2 & PR_O2_DISPATCH) && !(s->be->options & PR_O_TRANSP)) {
|
||||
else if ((s->be->options & PR_O_HTTP_PROXY) && s->req->cons->addr.s.to.sin_addr.s_addr) {
|
||||
/* in proxy mode, we need a valid destination address */
|
||||
s->target.type = TARG_TYPE_PROXY;
|
||||
s->target.ptr.p = s->be;
|
||||
}
|
||||
else {
|
||||
err = SRV_STATUS_NOSRV;
|
||||
goto out;
|
||||
}
|
||||
@ -910,7 +919,8 @@ static void assign_tproxy_address(struct session *s)
|
||||
|
||||
/*
|
||||
* This function initiates a connection to the server assigned to this session
|
||||
* (s->srv, s->req->cons->addr.s.to). It will assign a server if none is assigned yet.
|
||||
* (s->srv, 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
|
||||
* - SN_ERR_SRVTO if there are no more servers
|
||||
@ -932,16 +942,13 @@ int connect_server(struct session *s)
|
||||
|
||||
/* Prepare the stream interface for a TCP connection. Later
|
||||
* we may assign a protocol-specific connect() function.
|
||||
* NOTE: when we later support HTTP keep-alive, we'll have to
|
||||
* decide here if we can reuse the connection by comparing the
|
||||
* session's freshly assigned target with the stream interface's.
|
||||
*/
|
||||
stream_sock_prepare_interface(s->req->cons);
|
||||
s->req->cons->connect = tcpv4_connect_server;
|
||||
if (s->srv) {
|
||||
s->req->cons->target.type = TARG_TYPE_SERVER;
|
||||
s->req->cons->target.ptr.s = s->srv;
|
||||
} else {
|
||||
s->req->cons->target.type = TARG_TYPE_PROXY;
|
||||
s->req->cons->target.ptr.p = s->be;
|
||||
}
|
||||
s->req->cons->target = s->target;
|
||||
|
||||
assign_tproxy_address(s);
|
||||
|
||||
@ -1098,12 +1105,16 @@ int tcp_persist_rdp_cookie(struct session *s, struct buffer *req, int an_bit)
|
||||
if (*p != '.')
|
||||
goto no_cookie;
|
||||
|
||||
s->target.type = TARG_TYPE_NONE;
|
||||
s->target.ptr.v = NULL;
|
||||
while (srv) {
|
||||
if (memcmp(&addr, &(srv->addr), sizeof(addr)) == 0) {
|
||||
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;
|
||||
s->target.type = TARG_TYPE_SERVER;
|
||||
s->target.ptr.s = s->srv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -349,6 +349,8 @@ static int check_for_pending(struct server *s)
|
||||
if (!p)
|
||||
break;
|
||||
p->sess->srv = s;
|
||||
p->sess->target.ptr.s = s;
|
||||
p->sess->target.type = TARG_TYPE_SERVER;
|
||||
sess = p->sess;
|
||||
pendconn_free(p);
|
||||
task_wakeup(sess->task, TASK_WOKEN_RES);
|
||||
|
@ -1187,6 +1187,8 @@ struct session *peer_session_create(struct peer *peer, struct peer_session *ps)
|
||||
s->si[1].release = NULL;
|
||||
|
||||
s->srv = s->prev_srv = s->srv_conn = NULL;
|
||||
s->target.type = TARG_TYPE_NONE;
|
||||
s->target.ptr.v = NULL;
|
||||
s->pend_pos = NULL;
|
||||
|
||||
/* init store persistence */
|
||||
|
@ -3949,6 +3949,8 @@ void http_end_txn_clean_session(struct session *s)
|
||||
if (unlikely(s->srv_conn))
|
||||
sess_change_server(s, NULL);
|
||||
s->srv = NULL;
|
||||
s->target.type = TARG_TYPE_NONE;
|
||||
s->target.ptr.v = NULL;
|
||||
|
||||
s->req->cons->state = s->req->cons->prev_state = SI_ST_INI;
|
||||
s->req->cons->fd = -1; /* just to help with debugging */
|
||||
@ -5962,6 +5964,9 @@ void manage_client_side_appsession(struct session *t, const char *buf, int len)
|
||||
txn->flags |= (srv->state & SRV_RUNNING) ? TX_CK_VALID : TX_CK_DOWN;
|
||||
t->flags |= SN_DIRECT | SN_ASSIGNED;
|
||||
t->srv = srv;
|
||||
t->target.type = TARG_TYPE_SERVER;
|
||||
t->target.ptr.s = srv;
|
||||
|
||||
break;
|
||||
} else {
|
||||
txn->flags &= ~TX_CK_MASK;
|
||||
@ -6371,6 +6376,8 @@ void manage_client_side_cookies(struct session *t, struct buffer *req)
|
||||
txn->flags |= (srv->state & SRV_RUNNING) ? TX_CK_VALID : TX_CK_DOWN;
|
||||
t->flags |= SN_DIRECT | SN_ASSIGNED;
|
||||
t->srv = srv;
|
||||
t->target.type = TARG_TYPE_SERVER;
|
||||
t->target.ptr.s = srv;
|
||||
break;
|
||||
} else {
|
||||
/* we found a server, but it's down,
|
||||
@ -7535,6 +7542,8 @@ void http_reset_txn(struct session *s)
|
||||
s->be = s->fe;
|
||||
s->logs.logwait = s->fe->to_log;
|
||||
s->srv = s->prev_srv = s->srv_conn = NULL;
|
||||
s->target.type = TARG_TYPE_NONE;
|
||||
s->target.ptr.v = NULL;
|
||||
/* re-init store persistence */
|
||||
s->store_count = 0;
|
||||
|
||||
|
@ -122,6 +122,8 @@ struct session *pendconn_get_next_sess(struct server *srv, struct proxy *px)
|
||||
|
||||
/* we want to note that the session has now been assigned a server */
|
||||
sess->flags |= SN_ASSIGNED;
|
||||
sess->target.type = TARG_TYPE_SERVER;
|
||||
sess->target.ptr.s = srv;
|
||||
sess->srv = srv;
|
||||
sess->srv_conn = srv;
|
||||
srv->served++;
|
||||
|
@ -203,6 +203,8 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
||||
s->si[1].flags |= SI_FL_INDEP_STR;
|
||||
|
||||
s->srv = s->prev_srv = s->srv_conn = NULL;
|
||||
s->target.type = TARG_TYPE_NONE;
|
||||
s->target.ptr.v = NULL;
|
||||
s->pend_pos = NULL;
|
||||
|
||||
/* init store persistence */
|
||||
@ -1066,6 +1068,8 @@ int process_sticking_rules(struct session *s, struct buffer *req, int an_bit)
|
||||
(s->flags & SN_FORCE_PRST)) {
|
||||
s->flags |= SN_DIRECT | SN_ASSIGNED;
|
||||
s->srv = srv;
|
||||
s->target.type = TARG_TYPE_SERVER;
|
||||
s->target.ptr.s = srv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user