]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stream: move all the session-specific stuff of stream_accept() earlier
authorWilly Tarreau <w@1wt.eu>
Sat, 4 Apr 2015 14:55:53 +0000 (16:55 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 6 Apr 2015 09:37:31 +0000 (11:37 +0200)
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.

src/stream.c

index 47310f5d70d95d0701e4f6afa6368b2ab2af16ff..651f0119a6bf799dbc67c55f1dc27d9c1ddb8fdb 100644 (file)
@@ -98,60 +98,31 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
        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 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
                /* 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 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
                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 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
  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;