From 59e3ff45496c645b13093a4fa56011a037ee6e26 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 16 Dec 2013 02:16:50 +0100 Subject: [PATCH] BUG/MAJOR: session: repair tcp-request connection rules Since recent commit f79c817 (MAJOR: connection: add two new flags to indicate readiness of control/transport) and the surrounding commits, the session initialization has been slightly delayed and the control layer of the connection is not yet initialized when processing the rules. We need to move that minimal initialization a bit above. The bug was introduced with latest changes, no backport is needed. --- src/session.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/session.c b/src/session.c index 21fea399d..255731a57 100644 --- a/src/session.c +++ b/src/session.c @@ -131,6 +131,18 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) * to abort right here as soon as possible, we check the rules before * even initializing the stream interfaces. */ + memset(&s->si[0], 0x55, sizeof(s->si[0])); + + /* 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 + * "tcp-request connection" ruleset. We also carefully attach the + * connection to the stream interface without initializing the rest, + * so that ACLs can use si[0]->end. + */ + si_attach_conn(&s->si[0], cli_conn); + conn_attach(cli_conn, s, &sess_conn_cb); + conn_ctrl_init(cli_conn); + if ((l->options & LI_O_TCP_RULES) && !tcp_exec_req_rules(s)) { /* 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)); @@ -187,15 +199,10 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) t->nice = l->nice; s->task = t; - /* Add the various callbacks. Right now the transport layer is present + /* Finish setting the callbacks. Right now the transport layer is present * but not initialized. Also note we need to be careful as the stream * int is not initialized yet. */ - conn_attach(cli_conn, s, &sess_conn_cb); - - /* finish initialization of the accepted file descriptor */ - conn_ctrl_init(cli_conn); - conn_data_want_recv(cli_conn); if (conn_xprt_init(cli_conn) < 0) goto out_free_task;