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.
diff --git a/src/stream.c b/src/stream.c
index 47310f5..651f011 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -98,60 +98,31 @@
cli_conn->target = &l->obj_type;
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);
if (!sess)
goto out_free_conn;
- sess->listener = l;
- sess->fe = p;
- sess->origin = &cli_conn->obj_type;
- sess->accept_date = date; /* user-visible date for logging */
- sess->tv_accept = now; /* corrected date for internal use */
- memset(sess->stkctr, 0, sizeof(sess->stkctr));
-
- if (unlikely((s = pool_alloc2(pool2_stream)) == NULL))
- goto out_free_sess;
-
- /* minimum stream initialization required for an embryonic stream is
- * fairly low. We need very little to execute L4 ACLs, then we need a
- * task to make the client-side connection live on its own.
- * - flags
- * - stick-entry tracking
- */
- s->flags = 0;
- s->logs.logwait = p->to_log;
- s->logs.level = 0;
-
- /* Initialise the current rule list pointer to NULL. We are sure that
- * any rulelist match the NULL pointer.
- */
- s->current_rule_list = NULL;
-
- memset(s->stkctr, 0, sizeof(s->stkctr));
-
- s->sess = sess;
- s->si[0].flags = SI_FL_NONE;
- s->si[1].flags = SI_FL_ISBACK;
-
- 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->uniq_id = global.req_count++;
p->feconn++;
- /* This stream was accepted, count it now */
+ /* 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);
- /* 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);
+ sess->listener = l;
+ sess->fe = p;
+ sess->origin = &cli_conn->obj_type;
+ sess->accept_date = date; /* user-visible date for logging */
+ sess->tv_accept = now; /* corrected date for internal use */
+ 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
@@ -161,7 +132,7 @@
/* 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;
+ goto out_free_sess;
}
/* monitor-net and health mode are processed immediately after TCP
@@ -189,14 +160,45 @@
else if (p->mode == PR_MODE_HEALTH)
send(cfd, "OK\n", 3, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
ret = 0;
- goto out_free_strm;
+ goto out_free_sess;
}
- /* 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((s = pool_alloc2(pool2_stream)) == NULL))
+ goto out_free_sess;
+
+ /* minimum stream initialization required for an embryonic stream is
+ * fairly low. We need very little to execute L4 ACLs, then we need a
+ * task to make the client-side connection live on its own.
+ * - flags
+ * - stick-entry tracking
+ */
+ s->flags = 0;
+ s->logs.logwait = p->to_log;
+ s->logs.level = 0;
+
+ /* Initialise the current rule list pointer to NULL. We are sure that
+ * any rulelist match the NULL pointer.
+ */
+ s->current_rule_list = NULL;
+
+ memset(s->stkctr, 0, sizeof(s->stkctr));
+
+ s->sess = sess;
+ s->si[0].flags = SI_FL_NONE;
+ s->si[1].flags = SI_FL_ISBACK;
+
+ 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->uniq_id = global.req_count++;
+
+ /* 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);
if (unlikely((t = task_new()) == NULL))
goto out_free_strm;
@@ -237,9 +239,9 @@
out_free_task:
task_free(t);
out_free_strm:
- p->feconn--;
pool_free2(pool2_stream, s);
out_free_sess:
+ p->feconn--;
session_free(sess);
out_free_conn:
cli_conn->flags &= ~CO_FL_XPRT_TRACKED;