mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-25 07:41:36 +02:00
MEDIUM: stream: move all the session-specific stuff of stream_accept() earlier
Since the tcp-request connection rules don't need the stream anymore, we can safely move the session-specific stuff earlier and prepare for a split of session and stream initialization. Some work remains to be done.
This commit is contained in:
parent
1df0cc6466
commit
5ecb069c58
108
src/stream.c
108
src/stream.c
@ -98,10 +98,25 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
|||||||
cli_conn->target = &l->obj_type;
|
cli_conn->target = &l->obj_type;
|
||||||
cli_conn->proxy_netns = l->netns;
|
cli_conn->proxy_netns = l->netns;
|
||||||
|
|
||||||
|
conn_ctrl_init(cli_conn);
|
||||||
|
|
||||||
|
/* wait for a PROXY protocol header */
|
||||||
|
if (l->options & LI_O_ACC_PROXY) {
|
||||||
|
cli_conn->flags |= CO_FL_ACCEPT_PROXY;
|
||||||
|
conn_sock_want_recv(cli_conn);
|
||||||
|
}
|
||||||
|
|
||||||
sess = pool_alloc2(pool2_session);
|
sess = pool_alloc2(pool2_session);
|
||||||
if (!sess)
|
if (!sess)
|
||||||
goto out_free_conn;
|
goto out_free_conn;
|
||||||
|
|
||||||
|
p->feconn++;
|
||||||
|
/* This session was accepted, count it now */
|
||||||
|
if (p->feconn > p->fe_counters.conn_max)
|
||||||
|
p->fe_counters.conn_max = p->feconn;
|
||||||
|
|
||||||
|
proxy_inc_fe_conn_ctr(l, p);
|
||||||
|
|
||||||
sess->listener = l;
|
sess->listener = l;
|
||||||
sess->fe = p;
|
sess->fe = p;
|
||||||
sess->origin = &cli_conn->obj_type;
|
sess->origin = &cli_conn->obj_type;
|
||||||
@ -109,6 +124,45 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
|||||||
sess->tv_accept = now; /* corrected date for internal use */
|
sess->tv_accept = now; /* corrected date for internal use */
|
||||||
memset(sess->stkctr, 0, sizeof(sess->stkctr));
|
memset(sess->stkctr, 0, sizeof(sess->stkctr));
|
||||||
|
|
||||||
|
/* now evaluate the tcp-request layer4 rules. Since we expect to be able
|
||||||
|
* to abort right here as soon as possible, we check the rules before
|
||||||
|
* even initializing the stream interfaces.
|
||||||
|
*/
|
||||||
|
if ((l->options & LI_O_TCP_RULES) && !tcp_exec_req_rules(sess)) {
|
||||||
|
/* let's do a no-linger now to close with a single RST. */
|
||||||
|
setsockopt(cfd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger));
|
||||||
|
ret = 0; /* successful termination */
|
||||||
|
goto out_free_sess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* monitor-net and health mode are processed immediately after TCP
|
||||||
|
* connection rules. This way it's possible to block them, but they
|
||||||
|
* never use the lower data layers, they send directly over the socket,
|
||||||
|
* as they were designed for. We first flush the socket receive buffer
|
||||||
|
* in order to avoid emission of an RST by the system. We ignore any
|
||||||
|
* error.
|
||||||
|
*/
|
||||||
|
if (unlikely((p->mode == PR_MODE_HEALTH) ||
|
||||||
|
((l->options & LI_O_CHK_MONNET) &&
|
||||||
|
addr->ss_family == AF_INET &&
|
||||||
|
(((struct sockaddr_in *)addr)->sin_addr.s_addr & p->mon_mask.s_addr) == p->mon_net.s_addr))) {
|
||||||
|
/* we have 4 possibilities here :
|
||||||
|
* - HTTP mode, from monitoring address => send "HTTP/1.0 200 OK"
|
||||||
|
* - HEALTH mode with HTTP check => send "HTTP/1.0 200 OK"
|
||||||
|
* - HEALTH mode without HTTP check => just send "OK"
|
||||||
|
* - TCP mode from monitoring address => just close
|
||||||
|
*/
|
||||||
|
if (l->proto->drain)
|
||||||
|
l->proto->drain(cfd);
|
||||||
|
if (p->mode == PR_MODE_HTTP ||
|
||||||
|
(p->mode == PR_MODE_HEALTH && (p->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK))
|
||||||
|
send(cfd, "HTTP/1.0 200 OK\r\n\r\n", 19, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
|
||||||
|
else if (p->mode == PR_MODE_HEALTH)
|
||||||
|
send(cfd, "OK\n", 3, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
|
||||||
|
ret = 0;
|
||||||
|
goto out_free_sess;
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely((s = pool_alloc2(pool2_stream)) == NULL))
|
if (unlikely((s = pool_alloc2(pool2_stream)) == NULL))
|
||||||
goto out_free_sess;
|
goto out_free_sess;
|
||||||
|
|
||||||
@ -136,12 +190,6 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
|||||||
s->logs.accept_date = sess->accept_date; /* user-visible date for logging */
|
s->logs.accept_date = sess->accept_date; /* user-visible date for logging */
|
||||||
s->logs.tv_accept = sess->tv_accept; /* corrected date for internal use */
|
s->logs.tv_accept = sess->tv_accept; /* corrected date for internal use */
|
||||||
s->uniq_id = global.req_count++;
|
s->uniq_id = global.req_count++;
|
||||||
p->feconn++;
|
|
||||||
/* This stream was accepted, count it now */
|
|
||||||
if (p->feconn > p->fe_counters.conn_max)
|
|
||||||
p->fe_counters.conn_max = p->feconn;
|
|
||||||
|
|
||||||
proxy_inc_fe_conn_ctr(l, p);
|
|
||||||
|
|
||||||
/* Add the minimum callbacks to prepare the connection's control layer.
|
/* Add the minimum callbacks to prepare the connection's control layer.
|
||||||
* We need this so that we can safely execute the ACLs used by the
|
* We need this so that we can safely execute the ACLs used by the
|
||||||
@ -151,52 +199,6 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
|||||||
*/
|
*/
|
||||||
si_attach_conn(&s->si[0], cli_conn);
|
si_attach_conn(&s->si[0], cli_conn);
|
||||||
conn_attach(cli_conn, s, &sess_conn_cb);
|
conn_attach(cli_conn, s, &sess_conn_cb);
|
||||||
conn_ctrl_init(cli_conn);
|
|
||||||
|
|
||||||
/* now evaluate the tcp-request layer4 rules. Since we expect to be able
|
|
||||||
* to abort right here as soon as possible, we check the rules before
|
|
||||||
* even initializing the stream interfaces.
|
|
||||||
*/
|
|
||||||
if ((l->options & LI_O_TCP_RULES) && !tcp_exec_req_rules(sess)) {
|
|
||||||
/* let's do a no-linger now to close with a single RST. */
|
|
||||||
setsockopt(cfd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger));
|
|
||||||
ret = 0; /* successful termination */
|
|
||||||
goto out_free_strm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* monitor-net and health mode are processed immediately after TCP
|
|
||||||
* connection rules. This way it's possible to block them, but they
|
|
||||||
* never use the lower data layers, they send directly over the socket,
|
|
||||||
* as they were designed for. We first flush the socket receive buffer
|
|
||||||
* in order to avoid emission of an RST by the system. We ignore any
|
|
||||||
* error.
|
|
||||||
*/
|
|
||||||
if (unlikely((p->mode == PR_MODE_HEALTH) ||
|
|
||||||
((l->options & LI_O_CHK_MONNET) &&
|
|
||||||
addr->ss_family == AF_INET &&
|
|
||||||
(((struct sockaddr_in *)addr)->sin_addr.s_addr & p->mon_mask.s_addr) == p->mon_net.s_addr))) {
|
|
||||||
/* we have 4 possibilities here :
|
|
||||||
* - HTTP mode, from monitoring address => send "HTTP/1.0 200 OK"
|
|
||||||
* - HEALTH mode with HTTP check => send "HTTP/1.0 200 OK"
|
|
||||||
* - HEALTH mode without HTTP check => just send "OK"
|
|
||||||
* - TCP mode from monitoring address => just close
|
|
||||||
*/
|
|
||||||
if (l->proto->drain)
|
|
||||||
l->proto->drain(cfd);
|
|
||||||
if (p->mode == PR_MODE_HTTP ||
|
|
||||||
(p->mode == PR_MODE_HEALTH && (p->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK))
|
|
||||||
send(cfd, "HTTP/1.0 200 OK\r\n\r\n", 19, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
|
|
||||||
else if (p->mode == PR_MODE_HEALTH)
|
|
||||||
send(cfd, "OK\n", 3, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
|
|
||||||
ret = 0;
|
|
||||||
goto out_free_strm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* wait for a PROXY protocol header */
|
|
||||||
if (l->options & LI_O_ACC_PROXY) {
|
|
||||||
cli_conn->flags |= CO_FL_ACCEPT_PROXY;
|
|
||||||
conn_sock_want_recv(cli_conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely((t = task_new()) == NULL))
|
if (unlikely((t = task_new()) == NULL))
|
||||||
goto out_free_strm;
|
goto out_free_strm;
|
||||||
@ -237,9 +239,9 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
|||||||
out_free_task:
|
out_free_task:
|
||||||
task_free(t);
|
task_free(t);
|
||||||
out_free_strm:
|
out_free_strm:
|
||||||
p->feconn--;
|
|
||||||
pool_free2(pool2_stream, s);
|
pool_free2(pool2_stream, s);
|
||||||
out_free_sess:
|
out_free_sess:
|
||||||
|
p->feconn--;
|
||||||
session_free(sess);
|
session_free(sess);
|
||||||
out_free_conn:
|
out_free_conn:
|
||||||
cli_conn->flags &= ~CO_FL_XPRT_TRACKED;
|
cli_conn->flags &= ~CO_FL_XPRT_TRACKED;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user