CLEANUP: session: simplify references to chn_{prod,cons}(&s->{req,res})

These 4 combinations are needlessly complicated since the session already
has direct access to the associated stream interfaces without having to
check an indirect pointer.
This commit is contained in:
Willy Tarreau 2014-11-28 14:42:25 +01:00
parent 81cd90069a
commit 350f487300
5 changed files with 153 additions and 153 deletions

View File

@ -548,7 +548,7 @@ int assign_server(struct session *s)
srv = NULL; srv = NULL;
s->target = NULL; s->target = NULL;
conn = objt_conn(chn_cons(&s->req)->end); conn = objt_conn(s->si[1].end);
if (conn && if (conn &&
(conn->flags & CO_FL_CONNECTED) && (conn->flags & CO_FL_CONNECTED) &&
@ -607,7 +607,7 @@ int assign_server(struct session *s)
switch (s->be->lbprm.algo & BE_LB_PARM) { switch (s->be->lbprm.algo & BE_LB_PARM) {
case BE_LB_HASH_SRC: case BE_LB_HASH_SRC:
conn = objt_conn(chn_prod(&s->req)->end); conn = objt_conn(s->si[0].end);
if (conn && conn->addr.from.ss_family == AF_INET) { if (conn && conn->addr.from.ss_family == AF_INET) {
srv = get_server_sh(s->be, srv = get_server_sh(s->be,
(void *)&((struct sockaddr_in *)&conn->addr.from)->sin_addr, (void *)&((struct sockaddr_in *)&conn->addr.from)->sin_addr,
@ -698,7 +698,7 @@ int assign_server(struct session *s)
s->target = &s->be->obj_type; s->target = &s->be->obj_type;
} }
else if ((s->be->options & PR_O_HTTP_PROXY) && else if ((s->be->options & PR_O_HTTP_PROXY) &&
(conn = objt_conn(chn_cons(&s->req)->end)) && (conn = objt_conn(s->si[1].end)) &&
is_addr(&conn->addr.to)) { is_addr(&conn->addr.to)) {
/* in proxy mode, we need a valid destination address */ /* in proxy mode, we need a valid destination address */
s->target = &s->be->obj_type; s->target = &s->be->obj_type;
@ -746,8 +746,8 @@ int assign_server(struct session *s)
*/ */
int assign_server_address(struct session *s) int assign_server_address(struct session *s)
{ {
struct connection *cli_conn = objt_conn(chn_prod(&s->req)->end); struct connection *cli_conn = objt_conn(s->si[0].end);
struct connection *srv_conn = objt_conn(chn_cons(&s->req)->end); struct connection *srv_conn = objt_conn(s->si[1].end);
#ifdef DEBUG_FULL #ifdef DEBUG_FULL
fprintf(stderr,"assign_server_address : s=%p\n",s); fprintf(stderr,"assign_server_address : s=%p\n",s);
@ -942,7 +942,7 @@ int assign_server_and_queue(struct session *s)
/* If an explicit source binding is specified on the server and/or backend, and /* If an explicit source binding is specified on the server and/or backend, and
* this source makes use of the transparent proxy, then it is extracted now and * this source makes use of the transparent proxy, then it is extracted now and
* assigned to the session's pending connection. This function assumes that an * assigned to the session's pending connection. This function assumes that an
* outgoing connection has already been assigned to chn_cons(&s->req)->end. * outgoing connection has already been assigned to s->si[1].end.
*/ */
static void assign_tproxy_address(struct session *s) static void assign_tproxy_address(struct session *s)
{ {
@ -950,7 +950,7 @@ static void assign_tproxy_address(struct session *s)
struct server *srv = objt_server(s->target); struct server *srv = objt_server(s->target);
struct conn_src *src; struct conn_src *src;
struct connection *cli_conn; struct connection *cli_conn;
struct connection *srv_conn = objt_conn(chn_cons(&s->req)->end); struct connection *srv_conn = objt_conn(s->si[1].end);
if (srv && srv->conn_src.opts & CO_SRC_BIND) if (srv && srv->conn_src.opts & CO_SRC_BIND)
src = &srv->conn_src; src = &srv->conn_src;
@ -966,7 +966,7 @@ static void assign_tproxy_address(struct session *s)
case CO_SRC_TPROXY_CLI: case CO_SRC_TPROXY_CLI:
case CO_SRC_TPROXY_CIP: case CO_SRC_TPROXY_CIP:
/* FIXME: what can we do if the client connects in IPv6 or unix socket ? */ /* FIXME: what can we do if the client connects in IPv6 or unix socket ? */
cli_conn = objt_conn(chn_prod(&s->req)->end); cli_conn = objt_conn(s->si[0].end);
if (cli_conn) if (cli_conn)
srv_conn->addr.from = cli_conn->addr.from; srv_conn->addr.from = cli_conn->addr.from;
else else
@ -1001,7 +1001,7 @@ static void assign_tproxy_address(struct session *s)
/* /*
* This function initiates a connection to the server assigned to this session * This function initiates a connection to the server assigned to this session
* (s->target, chn_cons(&s->req)->addr.to). It will assign a server if none * (s->target, s->si[1].addr.to). It will assign a server if none
* is assigned yet. * is assigned yet.
* It can return one of : * It can return one of :
* - SN_ERR_NONE if everything's OK * - SN_ERR_NONE if everything's OK
@ -1012,7 +1012,7 @@ static void assign_tproxy_address(struct session *s)
* - SN_ERR_INTERNAL for any other purely internal errors * - SN_ERR_INTERNAL for any other purely internal errors
* Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted. * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
* The server-facing stream interface is expected to hold a pre-allocated connection * The server-facing stream interface is expected to hold a pre-allocated connection
* in chn_cons(&s->req)->conn. * in s->si[1].conn.
*/ */
int connect_server(struct session *s) int connect_server(struct session *s)
{ {
@ -1022,7 +1022,7 @@ int connect_server(struct session *s)
int reuse = 0; int reuse = 0;
int err; int err;
srv_conn = objt_conn(chn_cons(&s->req)->end); srv_conn = objt_conn(s->si[1].end);
if (srv_conn) if (srv_conn)
reuse = s->target == srv_conn->target; reuse = s->target == srv_conn->target;
@ -1043,7 +1043,7 @@ int connect_server(struct session *s)
} }
} }
srv_conn = si_alloc_conn(chn_cons(&s->req), reuse); srv_conn = si_alloc_conn(&s->si[1], reuse);
if (!srv_conn) if (!srv_conn)
return SN_ERR_RESOURCE; return SN_ERR_RESOURCE;
@ -1064,7 +1064,7 @@ int connect_server(struct session *s)
else if (obj_type(s->target) == OBJ_TYPE_PROXY) { else if (obj_type(s->target) == OBJ_TYPE_PROXY) {
/* proxies exclusively run on raw_sock right now */ /* proxies exclusively run on raw_sock right now */
conn_prepare(srv_conn, protocol_by_family(srv_conn->addr.to.ss_family), &raw_sock); conn_prepare(srv_conn, protocol_by_family(srv_conn->addr.to.ss_family), &raw_sock);
if (!objt_conn(chn_cons(&s->req)->end) || !objt_conn(chn_cons(&s->req)->end)->ctrl) if (!objt_conn(s->si[1].end) || !objt_conn(s->si[1].end)->ctrl)
return SN_ERR_INTERNAL; return SN_ERR_INTERNAL;
} }
else else
@ -1074,36 +1074,36 @@ int connect_server(struct session *s)
srv_conn->send_proxy_ofs = 0; srv_conn->send_proxy_ofs = 0;
if (objt_server(s->target) && objt_server(s->target)->pp_opts) { if (objt_server(s->target) && objt_server(s->target)->pp_opts) {
srv_conn->send_proxy_ofs = 1; /* must compute size */ srv_conn->send_proxy_ofs = 1; /* must compute size */
cli_conn = objt_conn(chn_prod(&s->req)->end); cli_conn = objt_conn(s->si[0].end);
if (cli_conn) if (cli_conn)
conn_get_to_addr(cli_conn); conn_get_to_addr(cli_conn);
} }
si_attach_conn(chn_cons(&s->req), srv_conn); si_attach_conn(&s->si[1], srv_conn);
assign_tproxy_address(s); assign_tproxy_address(s);
} }
else { else {
/* the connection is being reused, just re-attach it */ /* the connection is being reused, just re-attach it */
si_attach_conn(chn_cons(&s->req), srv_conn); si_attach_conn(&s->si[1], srv_conn);
s->flags |= SN_SRV_REUSED; s->flags |= SN_SRV_REUSED;
} }
/* flag for logging source ip/port */ /* flag for logging source ip/port */
if (s->fe->options2 & PR_O2_SRC_ADDR) if (s->fe->options2 & PR_O2_SRC_ADDR)
chn_cons(&s->req)->flags |= SI_FL_SRC_ADDR; s->si[1].flags |= SI_FL_SRC_ADDR;
/* disable lingering */ /* disable lingering */
if (s->be->options & PR_O_TCP_NOLING) if (s->be->options & PR_O_TCP_NOLING)
chn_cons(&s->req)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
err = si_connect(chn_cons(&s->req)); err = si_connect(&s->si[1]);
if (err != SN_ERR_NONE) if (err != SN_ERR_NONE)
return err; return err;
/* set connect timeout */ /* set connect timeout */
chn_cons(&s->req)->exp = tick_add_ifset(now_ms, s->be->timeout.connect); s->si[1].exp = tick_add_ifset(now_ms, s->be->timeout.connect);
srv = objt_server(s->target); srv = objt_server(s->target);
if (srv) { if (srv) {
@ -1157,8 +1157,8 @@ int srv_redispatch_connect(struct session *s)
goto redispatch; goto redispatch;
} }
if (!chn_cons(&s->req)->err_type) { if (!s->si[1].err_type) {
chn_cons(&s->req)->err_type = SI_ET_QUEUE_ERR; s->si[1].err_type = SI_ET_QUEUE_ERR;
} }
srv->counters.failed_conns++; srv->counters.failed_conns++;
@ -1167,23 +1167,23 @@ int srv_redispatch_connect(struct session *s)
case SRV_STATUS_NOSRV: case SRV_STATUS_NOSRV:
/* note: it is guaranteed that srv == NULL here */ /* note: it is guaranteed that srv == NULL here */
if (!chn_cons(&s->req)->err_type) { if (!s->si[1].err_type) {
chn_cons(&s->req)->err_type = SI_ET_CONN_ERR; s->si[1].err_type = SI_ET_CONN_ERR;
} }
s->be->be_counters.failed_conns++; s->be->be_counters.failed_conns++;
return 1; return 1;
case SRV_STATUS_QUEUED: case SRV_STATUS_QUEUED:
chn_cons(&s->req)->exp = tick_add_ifset(now_ms, s->be->timeout.queue); s->si[1].exp = tick_add_ifset(now_ms, s->be->timeout.queue);
chn_cons(&s->req)->state = SI_ST_QUE; s->si[1].state = SI_ST_QUE;
/* do nothing else and do not wake any other session up */ /* do nothing else and do not wake any other session up */
return 1; return 1;
case SRV_STATUS_INTERNAL: case SRV_STATUS_INTERNAL:
default: default:
if (!chn_cons(&s->req)->err_type) { if (!s->si[1].err_type) {
chn_cons(&s->req)->err_type = SI_ET_CONN_OTHER; s->si[1].err_type = SI_ET_CONN_OTHER;
} }
if (srv) if (srv)

View File

@ -1439,7 +1439,7 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext
*/ */
if (socket->s->req.buf->size == 0) { if (socket->s->req.buf->size == 0) {
if (!session_alloc_recv_buffer(socket->s, &socket->s->req.buf)) { if (!session_alloc_recv_buffer(socket->s, &socket->s->req.buf)) {
chn_prod(&socket->s->req)->flags |= SI_FL_WAIT_ROOM; socket->s->si[0].flags |= SI_FL_WAIT_ROOM;
goto hlua_socket_write_yield_return; goto hlua_socket_write_yield_return;
} }
} }
@ -1734,7 +1734,7 @@ __LJMP static int hlua_socket_connect(struct lua_State *L)
ip = MAY_LJMP(luaL_checkstring(L, 2)); ip = MAY_LJMP(luaL_checkstring(L, 2));
port = MAY_LJMP(luaL_checkinteger(L, 3)); port = MAY_LJMP(luaL_checkinteger(L, 3));
conn = si_alloc_conn(chn_cons(&socket->s->req), 0); conn = si_alloc_conn(&socket->s->si[1], 0);
if (!conn) if (!conn)
WILL_LJMP(luaL_error(L, "connect: internal error")); WILL_LJMP(luaL_error(L, "connect: internal error"));

View File

@ -984,7 +984,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_CLIENTIP: // %ci case LOG_FMT_CLIENTIP: // %ci
conn = objt_conn(chn_prod(&s->req)->end); conn = objt_conn(s->si[0].end);
if (conn) if (conn)
ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp); ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp);
else else
@ -996,7 +996,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_CLIENTPORT: // %cp case LOG_FMT_CLIENTPORT: // %cp
conn = objt_conn(chn_prod(&s->req)->end); conn = objt_conn(s->si[0].end);
if (conn) { if (conn) {
if (conn->addr.from.ss_family == AF_UNIX) { if (conn->addr.from.ss_family == AF_UNIX) {
ret = ltoa_o(s->listener->luid, tmplog, dst + maxsize - tmplog); ret = ltoa_o(s->listener->luid, tmplog, dst + maxsize - tmplog);
@ -1015,7 +1015,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_FRONTENDIP: // %fi case LOG_FMT_FRONTENDIP: // %fi
conn = objt_conn(chn_prod(&s->req)->end); conn = objt_conn(s->si[0].end);
if (conn) { if (conn) {
conn_get_to_addr(conn); conn_get_to_addr(conn);
ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp); ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp);
@ -1030,7 +1030,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_FRONTENDPORT: // %fp case LOG_FMT_FRONTENDPORT: // %fp
conn = objt_conn(chn_prod(&s->req)->end); conn = objt_conn(s->si[0].end);
if (conn) { if (conn) {
conn_get_to_addr(conn); conn_get_to_addr(conn);
if (conn->addr.to.ss_family == AF_UNIX) if (conn->addr.to.ss_family == AF_UNIX)
@ -1048,7 +1048,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_BACKENDIP: // %bi case LOG_FMT_BACKENDIP: // %bi
conn = objt_conn(chn_cons(&s->req)->end); conn = objt_conn(s->si[1].end);
if (conn) if (conn)
ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp); ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp);
else else
@ -1061,7 +1061,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_BACKENDPORT: // %bp case LOG_FMT_BACKENDPORT: // %bp
conn = objt_conn(chn_cons(&s->req)->end); conn = objt_conn(s->si[1].end);
if (conn) if (conn)
ret = lf_port(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp); ret = lf_port(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp);
else else
@ -1074,7 +1074,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_SERVERIP: // %si case LOG_FMT_SERVERIP: // %si
conn = objt_conn(chn_cons(&s->req)->end); conn = objt_conn(s->si[1].end);
if (conn) if (conn)
ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp); ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp);
else else
@ -1087,7 +1087,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break; break;
case LOG_FMT_SERVERPORT: // %sp case LOG_FMT_SERVERPORT: // %sp
conn = objt_conn(chn_cons(&s->req)->end); conn = objt_conn(s->si[1].end);
if (conn) if (conn)
ret = lf_port(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp); ret = lf_port(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp);
else else
@ -1386,8 +1386,8 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
case LOG_FMT_RETRIES: // %rq case LOG_FMT_RETRIES: // %rq
if (s->flags & SN_REDISP) if (s->flags & SN_REDISP)
LOGCHAR('+'); LOGCHAR('+');
ret = ltoa_o((chn_cons(&s->req)->conn_retries>0) ? ret = ltoa_o((s->si[1].conn_retries>0) ?
(be->conn_retries - chn_cons(&s->req)->conn_retries) : (be->conn_retries - s->si[1].conn_retries) :
be->conn_retries, tmplog, dst + maxsize - tmplog); be->conn_retries, tmplog, dst + maxsize - tmplog);
if (ret == NULL) if (ret == NULL)
goto out; goto out;
@ -1611,7 +1611,7 @@ void sess_log(struct session *s)
err = (s->flags & SN_REDISP) || err = (s->flags & SN_REDISP) ||
((s->flags & SN_ERR_MASK) > SN_ERR_LOCAL) || ((s->flags & SN_ERR_MASK) > SN_ERR_LOCAL) ||
(((s->flags & SN_ERR_MASK) == SN_ERR_NONE) && (((s->flags & SN_ERR_MASK) == SN_ERR_NONE) &&
(chn_cons(&s->req)->conn_retries != s->be->conn_retries)) || (s->si[1].conn_retries != s->be->conn_retries)) ||
((s->fe->mode == PR_MODE_HTTP) && s->txn.status >= 500); ((s->fe->mode == PR_MODE_HTTP) && s->txn.status >= 500);
if (!err && (s->fe->options2 & PR_O2_NOLOGNORM)) if (!err && (s->fe->options2 & PR_O2_NOLOGNORM))

View File

@ -2692,7 +2692,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
} }
txn->status = 400; txn->status = 400;
stream_int_retnclose(chn_prod(req), NULL); stream_int_retnclose(&s->si[0], NULL);
msg->msg_state = HTTP_MSG_ERROR; msg->msg_state = HTTP_MSG_ERROR;
req->analysers = 0; req->analysers = 0;
@ -2721,7 +2721,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
session_inc_http_err_ctr(s); session_inc_http_err_ctr(s);
} }
txn->status = 408; txn->status = 408;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_408)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_408));
msg->msg_state = HTTP_MSG_ERROR; msg->msg_state = HTTP_MSG_ERROR;
req->analysers = 0; req->analysers = 0;
@ -2747,7 +2747,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
if (msg->err_pos >= 0) if (msg->err_pos >= 0)
http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe); http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe);
txn->status = 400; txn->status = 400;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_400)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_400));
msg->msg_state = HTTP_MSG_ERROR; msg->msg_state = HTTP_MSG_ERROR;
req->analysers = 0; req->analysers = 0;
@ -2767,12 +2767,12 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */ req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */ s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
#ifdef TCP_QUICKACK #ifdef TCP_QUICKACK
if (s->listener->options & LI_O_NOQUICKACK && req->buf->i && objt_conn(chn_prod(&s->req)->end) && conn_ctrl_ready(__objt_conn(chn_prod(&s->req)->end))) { if (s->listener->options & LI_O_NOQUICKACK && req->buf->i && objt_conn(s->si[0].end) && conn_ctrl_ready(__objt_conn(s->si[0].end))) {
/* We need more data, we have to re-enable quick-ack in case we /* We need more data, we have to re-enable quick-ack in case we
* previously disabled it, otherwise we might cause the client * previously disabled it, otherwise we might cause the client
* to delay next data. * to delay next data.
*/ */
setsockopt(__objt_conn(chn_prod(&s->req)->end)->t.sock.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)); setsockopt(__objt_conn(s->si[0].end)->t.sock.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
} }
#endif #endif
@ -2809,7 +2809,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
s->logs.logwait = 0; s->logs.logwait = 0;
s->logs.level = 0; s->logs.level = 0;
s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */ s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
stream_int_retnclose(chn_prod(req), NULL); stream_int_retnclose(&s->si[0], NULL);
return 0; return 0;
} }
@ -2877,7 +2877,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
if (ret) { if (ret) {
/* we fail this request, let's return 503 service unavail */ /* we fail this request, let's return 503 service unavail */
txn->status = 503; txn->status = 503;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_503)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_503));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_LOCAL; /* we don't want a real error here */ s->flags |= SN_ERR_LOCAL; /* we don't want a real error here */
goto return_prx_cond; goto return_prx_cond;
@ -2886,7 +2886,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
/* nothing to fail, let's reply normaly */ /* nothing to fail, let's reply normaly */
txn->status = 200; txn->status = 200;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_200)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_200));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_LOCAL; /* we don't want a real error here */ s->flags |= SN_ERR_LOCAL; /* we don't want a real error here */
goto return_prx_cond; goto return_prx_cond;
@ -3065,7 +3065,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
txn->req.msg_state = HTTP_MSG_ERROR; txn->req.msg_state = HTTP_MSG_ERROR;
txn->status = 400; txn->status = 400;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_400)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_400));
s->fe->fe_counters.failed_req++; s->fe->fe_counters.failed_req++;
if (s->listener->counters) if (s->listener->counters)
@ -3094,7 +3094,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
int http_handle_stats(struct session *s, struct channel *req) int http_handle_stats(struct session *s, struct channel *req)
{ {
struct stats_admin_rule *stats_admin_rule; struct stats_admin_rule *stats_admin_rule;
struct stream_interface *si = chn_prod(&s->res); struct stream_interface *si = &s->si[1];
struct http_txn *txn = &s->txn; struct http_txn *txn = &s->txn;
struct http_msg *msg = &txn->req; struct http_msg *msg = &txn->req;
struct uri_auth *uri_auth = s->be->uri_auth; struct uri_auth *uri_auth = s->be->uri_auth;
@ -3440,13 +3440,13 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session
break; break;
case HTTP_REQ_ACT_SET_TOS: case HTTP_REQ_ACT_SET_TOS:
if ((cli_conn = objt_conn(chn_prod(&s->req)->end)) && conn_ctrl_ready(cli_conn)) if ((cli_conn = objt_conn(s->si[0].end)) && conn_ctrl_ready(cli_conn))
inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos); inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
break; break;
case HTTP_REQ_ACT_SET_MARK: case HTTP_REQ_ACT_SET_MARK:
#ifdef SO_MARK #ifdef SO_MARK
if ((cli_conn = objt_conn(chn_prod(&s->req)->end)) && conn_ctrl_ready(cli_conn)) if ((cli_conn = objt_conn(s->si[0].end)) && conn_ctrl_ready(cli_conn))
setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark)); setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
#endif #endif
break; break;
@ -3686,13 +3686,13 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct session
break; break;
case HTTP_RES_ACT_SET_TOS: case HTTP_RES_ACT_SET_TOS:
if ((cli_conn = objt_conn(chn_prod(&s->req)->end)) && conn_ctrl_ready(cli_conn)) if ((cli_conn = objt_conn(s->si[0].end)) && conn_ctrl_ready(cli_conn))
inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos); inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
break; break;
case HTTP_RES_ACT_SET_MARK: case HTTP_RES_ACT_SET_MARK:
#ifdef SO_MARK #ifdef SO_MARK
if ((cli_conn = objt_conn(chn_prod(&s->req)->end)) && conn_ctrl_ready(cli_conn)) if ((cli_conn = objt_conn(s->si[0].end)) && conn_ctrl_ready(cli_conn))
setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark)); setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
#endif #endif
break; break;
@ -4084,7 +4084,7 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct session *
memcpy(trash.str + trash.len, "\r\nConnection: close\r\n\r\n", 23); memcpy(trash.str + trash.len, "\r\nConnection: close\r\n\r\n", 23);
trash.len += 23; trash.len += 23;
} }
stream_int_retnclose(chn_prod(txn->req.chn), &trash); stream_int_retnclose(&s->si[0], &trash);
txn->req.chn->analysers = 0; txn->req.chn->analysers = 0;
} }
@ -4162,12 +4162,12 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
* by a possible reqrep, while they are processed *after* so that a * by a possible reqrep, while they are processed *after* so that a
* reqdeny can still block them. This clearly needs to change in 1.6! * reqdeny can still block them. This clearly needs to change in 1.6!
*/ */
if (stats_check_uri(chn_prod(&s->res), txn, px)) { if (stats_check_uri(&s->si[1], txn, px)) {
s->target = &http_stats_applet.obj_type; s->target = &http_stats_applet.obj_type;
if (unlikely(!stream_int_register_handler(chn_prod(&s->res), objt_applet(s->target)))) { if (unlikely(!stream_int_register_handler(&s->si[1], objt_applet(s->target)))) {
txn->status = 500; txn->status = 500;
s->logs.tv_request = now; s->logs.tv_request = now;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_500)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_500));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_RESOURCE; s->flags |= SN_ERR_RESOURCE;
@ -4297,7 +4297,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
txn->flags |= TX_CLDENY; txn->flags |= TX_CLDENY;
txn->status = 403; txn->status = 403;
s->logs.tv_request = now; s->logs.tv_request = now;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_403)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_403));
session_inc_http_err_ctr(s); session_inc_http_err_ctr(s);
s->fe->fe_counters.denied_req++; s->fe->fe_counters.denied_req++;
if (s->fe != s->be) if (s->fe != s->be)
@ -4317,7 +4317,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
txn->req.msg_state = HTTP_MSG_ERROR; txn->req.msg_state = HTTP_MSG_ERROR;
txn->status = 400; txn->status = 400;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_400)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_400));
s->fe->fe_counters.failed_req++; s->fe->fe_counters.failed_req++;
if (s->listener->counters) if (s->listener->counters)
@ -4347,7 +4347,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
{ {
struct http_txn *txn = &s->txn; struct http_txn *txn = &s->txn;
struct http_msg *msg = &txn->req; struct http_msg *msg = &txn->req;
struct connection *cli_conn = objt_conn(chn_prod(req)->end); struct connection *cli_conn = objt_conn(s->si[1].end);
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) { if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
/* we need more data */ /* we need more data */
@ -4384,11 +4384,11 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
char *path; char *path;
/* Note that for now we don't reuse existing proxy connections */ /* Note that for now we don't reuse existing proxy connections */
if (unlikely((conn = si_alloc_conn(chn_cons(req), 0)) == NULL)) { if (unlikely((conn = si_alloc_conn(&s->si[1], 0)) == NULL)) {
txn->req.msg_state = HTTP_MSG_ERROR; txn->req.msg_state = HTTP_MSG_ERROR;
txn->status = 500; txn->status = 500;
req->analysers = 0; req->analysers = 0;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_500)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_500));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_RESOURCE; s->flags |= SN_ERR_RESOURCE;
@ -4656,7 +4656,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
* and close the socket to save packets and syscalls. * and close the socket to save packets and syscalls.
*/ */
if (!(req->analysers & AN_REQ_HTTP_XFER_BODY)) if (!(req->analysers & AN_REQ_HTTP_XFER_BODY))
chn_cons(req)->flags |= SI_FL_NOHALF; s->si[1].flags |= SI_FL_NOHALF;
s->logs.tv_request = now; s->logs.tv_request = now;
/* OK let's go on with the BODY now */ /* OK let's go on with the BODY now */
@ -4673,7 +4673,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
txn->req.msg_state = HTTP_MSG_ERROR; txn->req.msg_state = HTTP_MSG_ERROR;
txn->status = 400; txn->status = 400;
req->analysers = 0; req->analysers = 0;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_400)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_400));
s->fe->fe_counters.failed_req++; s->fe->fe_counters.failed_req++;
if (s->listener->counters) if (s->listener->counters)
@ -4714,7 +4714,7 @@ int http_process_tarpit(struct session *s, struct channel *req, int an_bit)
txn->status = 500; txn->status = 500;
if (!(req->flags & CF_READ_ERROR)) if (!(req->flags & CF_READ_ERROR))
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_500)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_500));
req->analysers = 0; req->analysers = 0;
req->analyse_exp = TICK_ETERNITY; req->analyse_exp = TICK_ETERNITY;
@ -4825,7 +4825,7 @@ int http_wait_for_request_body(struct session *s, struct channel *req, int an_bi
if ((req->flags & CF_READ_TIMEOUT) || tick_is_expired(req->analyse_exp, now_ms)) { if ((req->flags & CF_READ_TIMEOUT) || tick_is_expired(req->analyse_exp, now_ms)) {
txn->status = 408; txn->status = 408;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_408)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_408));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_CLITO; s->flags |= SN_ERR_CLITO;
@ -4858,7 +4858,7 @@ int http_wait_for_request_body(struct session *s, struct channel *req, int an_bi
return_bad_req: /* let's centralize all bad requests */ return_bad_req: /* let's centralize all bad requests */
txn->req.msg_state = HTTP_MSG_ERROR; txn->req.msg_state = HTTP_MSG_ERROR;
txn->status = 400; txn->status = 400;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_400)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_400));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_PRXCOND; s->flags |= SN_ERR_PRXCOND;
@ -4945,10 +4945,10 @@ void http_end_txn_clean_session(struct session *s)
* to the server. * to the server.
*/ */
if (((s->txn.flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) || if (((s->txn.flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) ||
!si_conn_ready(chn_cons(&s->req))) { !si_conn_ready(&s->si[1])) {
chn_cons(&s->req)->flags |= SI_FL_NOLINGER | SI_FL_NOHALF; s->si[1].flags |= SI_FL_NOLINGER | SI_FL_NOHALF;
si_shutr(chn_cons(&s->req)); si_shutr(&s->si[1]);
si_shutw(chn_cons(&s->req)); si_shutw(&s->si[1]);
} }
if (s->flags & SN_BE_ASSIGNED) { if (s->flags & SN_BE_ASSIGNED) {
@ -5027,15 +5027,15 @@ void http_end_txn_clean_session(struct session *s)
* connection. * connection.
*/ */
if (((s->txn.flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) || if (((s->txn.flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) ||
!si_conn_ready(chn_cons(&s->req))) { !si_conn_ready(&s->si[1])) {
si_release_endpoint(chn_cons(&s->req)); si_release_endpoint(&s->si[1]);
} }
chn_cons(&s->req)->state = chn_cons(&s->req)->prev_state = SI_ST_INI; s->si[1].state = s->si[1].prev_state = SI_ST_INI;
chn_cons(&s->req)->err_type = SI_ET_NONE; s->si[1].err_type = SI_ET_NONE;
chn_cons(&s->req)->conn_retries = 0; /* used for logging too */ s->si[1].conn_retries = 0; /* used for logging too */
chn_cons(&s->req)->exp = TICK_ETERNITY; s->si[1].exp = TICK_ETERNITY;
chn_cons(&s->req)->flags &= SI_FL_ISBACK | SI_FL_DONT_WAKE; /* we're in the context of process_session */ s->si[1].flags &= SI_FL_ISBACK | SI_FL_DONT_WAKE; /* we're in the context of process_session */
s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WAKE_CONNECT|CF_WROTE_DATA); s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WAKE_CONNECT|CF_WROTE_DATA);
s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT|CF_WROTE_DATA); s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT|CF_WROTE_DATA);
s->flags &= ~(SN_DIRECT|SN_ASSIGNED|SN_ADDR_SET|SN_BE_ASSIGNED|SN_FORCE_PRST|SN_IGNORE_PRST); s->flags &= ~(SN_DIRECT|SN_ASSIGNED|SN_ADDR_SET|SN_BE_ASSIGNED|SN_FORCE_PRST|SN_IGNORE_PRST);
@ -5058,7 +5058,7 @@ void http_end_txn_clean_session(struct session *s)
} }
if (s->fe->options2 & PR_O2_INDEPSTR) if (s->fe->options2 & PR_O2_INDEPSTR)
chn_cons(&s->req)->flags |= SI_FL_INDEP_STR; s->si[1].flags |= SI_FL_INDEP_STR;
if (s->fe->options2 & PR_O2_NODELAY) { if (s->fe->options2 & PR_O2_NODELAY) {
s->req.flags |= CF_NEVER_WAIT; s->req.flags |= CF_NEVER_WAIT;
@ -5086,7 +5086,7 @@ void http_end_txn_clean_session(struct session *s)
channel_auto_close(&s->res); channel_auto_close(&s->res);
/* we're in keep-alive with an idle connection, monitor it */ /* we're in keep-alive with an idle connection, monitor it */
si_idle_conn(chn_cons(&s->req)); si_idle_conn(&s->si[1]);
s->req.analysers = s->listener->analysers; s->req.analysers = s->listener->analysers;
s->res.analysers = 0; s->res.analysers = 0;
@ -5132,7 +5132,7 @@ int http_sync_req_state(struct session *s)
/* if the server closes the connection, we want to immediately react /* if the server closes the connection, we want to immediately react
* and close the socket to save packets and syscalls. * and close the socket to save packets and syscalls.
*/ */
chn_cons(chn)->flags |= SI_FL_NOHALF; s->si[1].flags |= SI_FL_NOHALF;
if (txn->rsp.msg_state == HTTP_MSG_ERROR) if (txn->rsp.msg_state == HTTP_MSG_ERROR)
goto wait_other_side; goto wait_other_side;
@ -5187,7 +5187,7 @@ int http_sync_req_state(struct session *s)
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) { if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
/* if we've just closed an output, let's switch */ /* if we've just closed an output, let's switch */
chn_cons(chn)->flags |= SI_FL_NOLINGER; /* we want to close ASAP */ s->si[1].flags |= SI_FL_NOLINGER; /* we want to close ASAP */
if (!channel_is_empty(chn)) { if (!channel_is_empty(chn)) {
txn->req.msg_state = HTTP_MSG_CLOSING; txn->req.msg_state = HTTP_MSG_CLOSING;
@ -5694,10 +5694,10 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
txn->req.msg_state = HTTP_MSG_ERROR; txn->req.msg_state = HTTP_MSG_ERROR;
if (txn->status) { if (txn->status) {
/* Note: we don't send any error if some data were already sent */ /* Note: we don't send any error if some data were already sent */
stream_int_retnclose(chn_prod(req), NULL); stream_int_retnclose(&s->si[0], NULL);
} else { } else {
txn->status = 400; txn->status = 400;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_400)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_400));
} }
req->analysers = 0; req->analysers = 0;
s->res.analysers = 0; /* we're in data phase, we want to abort both directions */ s->res.analysers = 0; /* we're in data phase, we want to abort both directions */
@ -5716,10 +5716,10 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
txn->req.msg_state = HTTP_MSG_ERROR; txn->req.msg_state = HTTP_MSG_ERROR;
if (txn->status) { if (txn->status) {
/* Note: we don't send any error if some data were already sent */ /* Note: we don't send any error if some data were already sent */
stream_int_retnclose(chn_prod(req), NULL); stream_int_retnclose(&s->si[0], NULL);
} else { } else {
txn->status = 502; txn->status = 502;
stream_int_retnclose(chn_prod(req), http_error_message(s, HTTP_ERR_502)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_502));
} }
req->analysers = 0; req->analysers = 0;
s->res.analysers = 0; /* we're in data phase, we want to abort both directions */ s->res.analysers = 0; /* we're in data phase, we want to abort both directions */
@ -5859,9 +5859,9 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
channel_auto_close(rep); channel_auto_close(rep);
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
chn_prod(rep)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
channel_truncate(rep); channel_truncate(rep);
stream_int_retnclose(chn_cons(rep), http_error_message(s, HTTP_ERR_502)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_PRXCOND; s->flags |= SN_ERR_PRXCOND;
@ -5894,9 +5894,9 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
channel_auto_close(rep); channel_auto_close(rep);
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
chn_prod(rep)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
channel_truncate(rep); channel_truncate(rep);
stream_int_retnclose(chn_cons(rep), http_error_message(s, HTTP_ERR_502)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_SRVCL; s->flags |= SN_ERR_SRVCL;
@ -5921,9 +5921,9 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
channel_auto_close(rep); channel_auto_close(rep);
rep->analysers = 0; rep->analysers = 0;
txn->status = 504; txn->status = 504;
chn_prod(rep)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
channel_truncate(rep); channel_truncate(rep);
stream_int_retnclose(chn_cons(rep), http_error_message(s, HTTP_ERR_504)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_504));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_SRVTO; s->flags |= SN_ERR_SRVTO;
@ -5944,7 +5944,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
txn->status = 400; txn->status = 400;
channel_truncate(rep); channel_truncate(rep);
stream_int_retnclose(chn_cons(rep), http_error_message(s, HTTP_ERR_400)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_400));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_CLICL; s->flags |= SN_ERR_CLICL;
@ -5971,9 +5971,9 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
channel_auto_close(rep); channel_auto_close(rep);
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
chn_prod(rep)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
channel_truncate(rep); channel_truncate(rep);
stream_int_retnclose(chn_cons(rep), http_error_message(s, HTTP_ERR_502)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_SRVCL; s->flags |= SN_ERR_SRVCL;
@ -6305,7 +6305,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
s->logs.level = 0; s->logs.level = 0;
s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */ s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
channel_truncate(rep); channel_truncate(rep);
stream_int_retnclose(chn_cons(rep), NULL); stream_int_retnclose(&s->si[0], NULL);
return 0; return 0;
} }
@ -6391,9 +6391,9 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
s->logs.t_data = -1; /* was not a valid response */ s->logs.t_data = -1; /* was not a valid response */
chn_prod(rep)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
channel_truncate(rep); channel_truncate(rep);
stream_int_retnclose(chn_cons(rep), http_error_message(s, HTTP_ERR_502)); stream_int_retnclose(&s->si[0], http_error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_PRXCOND; s->flags |= SN_ERR_PRXCOND;
if (!(s->flags & SN_FINST_MASK)) if (!(s->flags & SN_FINST_MASK))
@ -6927,7 +6927,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
txn->rsp.msg_state = HTTP_MSG_ERROR; txn->rsp.msg_state = HTTP_MSG_ERROR;
/* don't send any error message as we're in the body */ /* don't send any error message as we're in the body */
stream_int_retnclose(chn_cons(res), NULL); stream_int_retnclose(&s->si[0], NULL);
res->analysers = 0; res->analysers = 0;
s->req.analysers = 0; /* we're in data phase, we want to abort both directions */ s->req.analysers = 0; /* we're in data phase, we want to abort both directions */
if (objt_server(s->target)) if (objt_server(s->target))
@ -6947,7 +6947,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
txn->rsp.msg_state = HTTP_MSG_ERROR; txn->rsp.msg_state = HTTP_MSG_ERROR;
/* don't send any error message as we're in the body */ /* don't send any error message as we're in the body */
stream_int_retnclose(chn_cons(res), NULL); stream_int_retnclose(&s->si[0], NULL);
res->analysers = 0; res->analysers = 0;
s->req.analysers = 0; /* we're in data phase, we want to abort both directions */ s->req.analysers = 0; /* we're in data phase, we want to abort both directions */
@ -8638,8 +8638,8 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s,
es->sid = s->uniq_id; es->sid = s->uniq_id;
es->srv = objt_server(s->target); es->srv = objt_server(s->target);
es->oe = other_end; es->oe = other_end;
if (objt_conn(chn_prod(&s->req)->end)) if (objt_conn(s->si[0].end))
es->src = __objt_conn(chn_prod(&s->req)->end)->addr.from; es->src = __objt_conn(s->si[0].end)->addr.from;
else else
memset(&es->src, 0, sizeof(es->src)); memset(&es->src, 0, sizeof(es->src));
@ -8796,8 +8796,8 @@ void debug_hdr(const char *dir, struct session *s, const char *start, const char
int max; int max;
chunk_printf(&trash, "%08x:%s.%s[%04x:%04x]: ", s->uniq_id, s->be->id, chunk_printf(&trash, "%08x:%s.%s[%04x:%04x]: ", s->uniq_id, s->be->id,
dir, dir,
objt_conn(chn_prod(&s->req)->end) ? (unsigned short)objt_conn(chn_prod(&s->req)->end)->t.sock.fd : -1, objt_conn(s->si[0].end) ? (unsigned short)objt_conn(s->si[0].end)->t.sock.fd : -1,
objt_conn(chn_cons(&s->req)->end) ? (unsigned short)objt_conn(chn_cons(&s->req)->end)->t.sock.fd : -1); objt_conn(s->si[1].end) ? (unsigned short)objt_conn(s->si[1].end)->t.sock.fd : -1);
for (max = 0; start + max < end; max++) for (max = 0; start + max < end; max++)
if (start[max] == '\r' || start[max] == '\n') if (start[max] == '\r' || start[max] == '\n')

View File

@ -1084,7 +1084,7 @@ static void sess_update_stream_int(struct session *s, struct stream_interface *s
s->req, s->rep, s->req, s->rep,
s->req.rex, s->res.wex, s->req.rex, s->res.wex,
s->req.flags, s->res.flags, s->req.flags, s->res.flags,
s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, chn_cons(&s->res)->state, s->req.cons->state); s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, s->si[0].state, s->req.cons->state);
if (si->state == SI_ST_ASS) { if (si->state == SI_ST_ASS) {
/* Server assigned to connection request, we have to try to connect now */ /* Server assigned to connection request, we have to try to connect now */
@ -1276,7 +1276,7 @@ static void sess_prepare_conn_req(struct session *s, struct stream_interface *si
s->req, s->rep, s->req, s->rep,
s->req.rex, s->res.wex, s->req.rex, s->res.wex,
s->req.flags, s->res.flags, s->req.flags, s->res.flags,
s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, chn_cons(&s->res)->state, s->req.cons->state); s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, s->si[0].state, s->req.cons->state);
if (si->state != SI_ST_REQ) if (si->state != SI_ST_REQ)
return; return;
@ -1766,27 +1766,27 @@ struct task *process_session(struct task *t)
channel_check_timeouts(&s->req); channel_check_timeouts(&s->req);
if (unlikely((s->req.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) { if (unlikely((s->req.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
chn_cons(&s->req)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
si_shutw(chn_cons(&s->req)); si_shutw(&s->si[1]);
} }
if (unlikely((s->req.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) { if (unlikely((s->req.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
if (chn_prod(&s->req)->flags & SI_FL_NOHALF) if (s->si[0].flags & SI_FL_NOHALF)
chn_prod(&s->req)->flags |= SI_FL_NOLINGER; s->si[0].flags |= SI_FL_NOLINGER;
si_shutr(chn_prod(&s->req)); si_shutr(&s->si[0]);
} }
channel_check_timeouts(&s->res); channel_check_timeouts(&s->res);
if (unlikely((s->res.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) { if (unlikely((s->res.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
chn_cons(&s->res)->flags |= SI_FL_NOLINGER; s->si[0].flags |= SI_FL_NOLINGER;
si_shutw(chn_cons(&s->res)); si_shutw(&s->si[0]);
} }
if (unlikely((s->res.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) { if (unlikely((s->res.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
if (chn_prod(&s->res)->flags & SI_FL_NOHALF) if (s->si[1].flags & SI_FL_NOHALF)
chn_prod(&s->res)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
si_shutr(chn_prod(&s->res)); si_shutr(&s->si[1]);
} }
/* Once in a while we're woken up because the task expires. But /* Once in a while we're woken up because the task expires. But
@ -1891,19 +1891,19 @@ struct task *process_session(struct task *t)
s->req, s->rep, s->req, s->rep,
s->req.rex, s->res.wex, s->req.rex, s->res.wex,
s->req.flags, s->res.flags, s->req.flags, s->res.flags,
s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, chn_cons(&s->res)->state, chn_cons(&s->req)->state, s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, s->si[0].state, s->si[1].state,
chn_cons(&s->res)->err_type, chn_cons(&s->req)->err_type, s->si[0].err_type, s->si[1].err_type,
chn_cons(&s->req)->conn_retries); s->si[1].conn_retries);
/* nothing special to be done on client side */ /* nothing special to be done on client side */
if (unlikely(chn_prod(&s->req)->state == SI_ST_DIS)) if (unlikely(s->si[0].state == SI_ST_DIS))
chn_prod(&s->req)->state = SI_ST_CLO; s->si[0].state = SI_ST_CLO;
/* When a server-side connection is released, we have to count it and /* When a server-side connection is released, we have to count it and
* check for pending connections on this server. * check for pending connections on this server.
*/ */
if (unlikely(chn_cons(&s->req)->state == SI_ST_DIS)) { if (unlikely(s->si[1].state == SI_ST_DIS)) {
chn_cons(&s->req)->state = SI_ST_CLO; s->si[1].state = SI_ST_CLO;
srv = objt_server(s->target); srv = objt_server(s->target);
if (srv) { if (srv) {
if (s->flags & SN_CURR_SESS) { if (s->flags & SN_CURR_SESS) {
@ -1930,7 +1930,7 @@ struct task *process_session(struct task *t)
s->task->state & TASK_WOKEN_MSG) { s->task->state & TASK_WOKEN_MSG) {
unsigned int flags = s->req.flags; unsigned int flags = s->req.flags;
if (chn_prod(&s->req)->state >= SI_ST_EST) { if (s->si[0].state >= SI_ST_EST) {
int max_loops = global.tune.maxpollevents; int max_loops = global.tune.maxpollevents;
unsigned int ana_list; unsigned int ana_list;
unsigned int ana_back; unsigned int ana_back;
@ -2101,7 +2101,7 @@ struct task *process_session(struct task *t)
s->req.flags |= CF_WAKE_ONCE; s->req.flags |= CF_WAKE_ONCE;
} }
if (chn_prod(&s->res)->state >= SI_ST_EST) { if (s->si[1].state >= SI_ST_EST) {
int max_loops = global.tune.maxpollevents; int max_loops = global.tune.maxpollevents;
unsigned int ana_list; unsigned int ana_list;
unsigned int ana_back; unsigned int ana_back;
@ -2271,7 +2271,7 @@ struct task *process_session(struct task *t)
*/ */
if (unlikely(!s->req.analysers && if (unlikely(!s->req.analysers &&
!(s->req.flags & (CF_SHUTW|CF_SHUTR_NOW)) && !(s->req.flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
(chn_prod(&s->req)->state >= SI_ST_EST) && (s->si[0].state >= SI_ST_EST) &&
(s->req.to_forward != CHN_INFINITE_FORWARD))) { (s->req.to_forward != CHN_INFINITE_FORWARD))) {
/* This buffer is freewheeling, there's no analyser /* This buffer is freewheeling, there's no analyser
* attached to it. If any data are left in, we'll permit them to * attached to it. If any data are left in, we'll permit them to
@ -2327,8 +2327,8 @@ struct task *process_session(struct task *t)
if (unlikely((s->req.flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW && if (unlikely((s->req.flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
channel_is_empty(&s->req))) { channel_is_empty(&s->req))) {
if (s->req.flags & CF_READ_ERROR) if (s->req.flags & CF_READ_ERROR)
chn_cons(&s->req)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
si_shutw(chn_cons(&s->req)); si_shutw(&s->si[1]);
if (tick_isset(s->be->timeout.serverfin)) { if (tick_isset(s->be->timeout.serverfin)) {
s->res.rto = s->be->timeout.serverfin; s->res.rto = s->be->timeout.serverfin;
s->res.rex = tick_add(now_ms, s->res.rto); s->res.rex = tick_add(now_ms, s->res.rto);
@ -2342,9 +2342,9 @@ struct task *process_session(struct task *t)
/* shutdown(read) pending */ /* shutdown(read) pending */
if (unlikely((s->req.flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) { if (unlikely((s->req.flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
if (chn_prod(&s->req)->flags & SI_FL_NOHALF) if (s->si[0].flags & SI_FL_NOHALF)
chn_prod(&s->req)->flags |= SI_FL_NOLINGER; s->si[0].flags |= SI_FL_NOLINGER;
si_shutr(chn_prod(&s->req)); si_shutr(&s->si[0]);
if (tick_isset(s->fe->timeout.clientfin)) { if (tick_isset(s->fe->timeout.clientfin)) {
s->res.wto = s->fe->timeout.clientfin; s->res.wto = s->fe->timeout.clientfin;
s->res.wex = tick_add(now_ms, s->res.wto); s->res.wex = tick_add(now_ms, s->res.wto);
@ -2356,19 +2356,19 @@ struct task *process_session(struct task *t)
* - there are data scheduled for emission in the buffer * - there are data scheduled for emission in the buffer
* - the CF_AUTO_CONNECT flag is set (active connection) * - the CF_AUTO_CONNECT flag is set (active connection)
*/ */
if (chn_cons(&s->req)->state == SI_ST_INI) { if (s->si[1].state == SI_ST_INI) {
if (!(s->req.flags & CF_SHUTW)) { if (!(s->req.flags & CF_SHUTW)) {
if ((s->req.flags & CF_AUTO_CONNECT) || !channel_is_empty(&s->req)) { if ((s->req.flags & CF_AUTO_CONNECT) || !channel_is_empty(&s->req)) {
/* If we have an appctx, there is no connect method, so we /* If we have an appctx, there is no connect method, so we
* immediately switch to the connected state, otherwise we * immediately switch to the connected state, otherwise we
* perform a connection request. * perform a connection request.
*/ */
chn_cons(&s->req)->state = SI_ST_REQ; /* new connection requested */ s->si[1].state = SI_ST_REQ; /* new connection requested */
chn_cons(&s->req)->conn_retries = s->be->conn_retries; s->si[1].conn_retries = s->be->conn_retries;
} }
} }
else { else {
chn_cons(&s->req)->state = SI_ST_CLO; /* shutw+ini = abort */ s->si[1].state = SI_ST_CLO; /* shutw+ini = abort */
channel_shutw_now(&s->req); /* fix buffer flags upon abort */ channel_shutw_now(&s->req); /* fix buffer flags upon abort */
channel_shutr_now(&s->res); channel_shutr_now(&s->res);
} }
@ -2411,7 +2411,7 @@ struct task *process_session(struct task *t)
} }
/* Benchmarks have shown that it's optimal to do a full resync now */ /* Benchmarks have shown that it's optimal to do a full resync now */
if (chn_prod(&s->req)->state == SI_ST_DIS || chn_cons(&s->req)->state == SI_ST_DIS) if (s->si[0].state == SI_ST_DIS || s->si[1].state == SI_ST_DIS)
goto resync_stream_interface; goto resync_stream_interface;
/* otherwise we want to check if we need to resync the req buffer or not */ /* otherwise we want to check if we need to resync the req buffer or not */
@ -2427,7 +2427,7 @@ struct task *process_session(struct task *t)
*/ */
if (unlikely(!s->res.analysers && if (unlikely(!s->res.analysers &&
!(s->res.flags & (CF_SHUTW|CF_SHUTR_NOW)) && !(s->res.flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
(chn_prod(&s->res)->state >= SI_ST_EST) && (s->si[1].state >= SI_ST_EST) &&
(s->res.to_forward != CHN_INFINITE_FORWARD))) { (s->res.to_forward != CHN_INFINITE_FORWARD))) {
/* This buffer is freewheeling, there's no analyser /* This buffer is freewheeling, there's no analyser
* attached to it. If any data are left in, we'll permit them to * attached to it. If any data are left in, we'll permit them to
@ -2504,7 +2504,7 @@ struct task *process_session(struct task *t)
/* shutdown(write) pending */ /* shutdown(write) pending */
if (unlikely((s->res.flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW && if (unlikely((s->res.flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
channel_is_empty(&s->res))) { channel_is_empty(&s->res))) {
si_shutw(chn_cons(&s->res)); si_shutw(&s->si[0]);
if (tick_isset(s->fe->timeout.clientfin)) { if (tick_isset(s->fe->timeout.clientfin)) {
s->req.rto = s->fe->timeout.clientfin; s->req.rto = s->fe->timeout.clientfin;
s->req.rex = tick_add(now_ms, s->req.rto); s->req.rex = tick_add(now_ms, s->req.rto);
@ -2518,16 +2518,16 @@ struct task *process_session(struct task *t)
/* shutdown(read) pending */ /* shutdown(read) pending */
if (unlikely((s->res.flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) { if (unlikely((s->res.flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
if (chn_prod(&s->res)->flags & SI_FL_NOHALF) if (s->si[1].flags & SI_FL_NOHALF)
chn_prod(&s->res)->flags |= SI_FL_NOLINGER; s->si[1].flags |= SI_FL_NOLINGER;
si_shutr(chn_prod(&s->res)); si_shutr(&s->si[1]);
if (tick_isset(s->be->timeout.serverfin)) { if (tick_isset(s->be->timeout.serverfin)) {
s->req.wto = s->be->timeout.serverfin; s->req.wto = s->be->timeout.serverfin;
s->req.wex = tick_add(now_ms, s->req.wto); s->req.wex = tick_add(now_ms, s->req.wto);
} }
} }
if (chn_prod(&s->req)->state == SI_ST_DIS || chn_cons(&s->req)->state == SI_ST_DIS) if (s->si[0].state == SI_ST_DIS || s->si[1].state == SI_ST_DIS)
goto resync_stream_interface; goto resync_stream_interface;
if (s->req.flags != rqf_last) if (s->req.flags != rqf_last)
@ -2537,8 +2537,8 @@ struct task *process_session(struct task *t)
goto resync_response; goto resync_response;
/* we're interested in getting wakeups again */ /* we're interested in getting wakeups again */
chn_prod(&s->req)->flags &= ~SI_FL_DONT_WAKE; s->si[0].flags &= ~SI_FL_DONT_WAKE;
chn_cons(&s->req)->flags &= ~SI_FL_DONT_WAKE; s->si[1].flags &= ~SI_FL_DONT_WAKE;
/* This is needed only when debugging is enabled, to indicate /* This is needed only when debugging is enabled, to indicate
* client-side or server-side close. Please note that in the unlikely * client-side or server-side close. Please note that in the unlikely
@ -2567,17 +2567,17 @@ struct task *process_session(struct task *t)
} }
} }
if (likely((chn_cons(&s->res)->state != SI_ST_CLO) || if (likely((s->si[0].state != SI_ST_CLO) ||
(chn_cons(&s->req)->state > SI_ST_INI && chn_cons(&s->req)->state < SI_ST_CLO))) { (s->si[1].state > SI_ST_INI && s->si[1].state < SI_ST_CLO))) {
if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED)) if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED))
session_process_counters(s); session_process_counters(s);
if (chn_cons(&s->res)->state == SI_ST_EST && obj_type(chn_cons(&s->res)->end) != OBJ_TYPE_APPCTX) if (s->si[0].state == SI_ST_EST && obj_type(s->si[0].end) != OBJ_TYPE_APPCTX)
si_update(chn_cons(&s->res)); si_update(&s->si[0]);
if (chn_cons(&s->req)->state == SI_ST_EST && obj_type(chn_cons(&s->req)->end) != OBJ_TYPE_APPCTX) if (s->si[1].state == SI_ST_EST && obj_type(s->si[1].end) != OBJ_TYPE_APPCTX)
si_update(chn_cons(&s->req)); si_update(&s->si[1]);
s->req.flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED); s->req.flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
s->res.flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED); s->res.flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
@ -2609,7 +2609,7 @@ struct task *process_session(struct task *t)
* both functions are always called and that we wake up if at * both functions are always called and that we wake up if at
* least one did something. * least one did something.
*/ */
if ((si_applet_call(chn_cons(&s->req)) | si_applet_call(chn_cons(&s->res))) != 0) { if ((si_applet_call(&s->si[1]) | si_applet_call(&s->si[0])) != 0) {
if (task_in_rq(t)) { if (task_in_rq(t)) {
t->expire = TICK_ETERNITY; t->expire = TICK_ETERNITY;
session_release_buffers(s); session_release_buffers(s);