]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: session: factor out duplicated code for conn_complete_session
authorWilly Tarreau <w@1wt.eu>
Fri, 15 Sep 2017 08:06:28 +0000 (10:06 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 15 Sep 2017 09:49:52 +0000 (11:49 +0200)
session_accept_fd() may either successfully complete a session creation,
or defer it to conn_complete_session() depending of whether a handshake
remains to be performed or not. The problem is that all the code after
the handshake was duplicated between the two functions.

This patch make session_accept_fd() synchronously call
conn_complete_session() to finish the session creation. It is only needed
to check if the session's task has to be released or not at the end, which
is fairly minimal. This way there is now a single place where the sessions
are created.

src/session.c

index c4c929450baeaedb84345c8e3b336af5f5b47c0c..98d7e2c4628135735b7340a9556f4ae0a80cc10d 100644 (file)
@@ -260,20 +260,10 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr
        /* OK let's complete stream initialization since there is no handshake */
        cli_conn->flags |= CO_FL_CONNECTED;
 
-       /* if logs require transport layer information, note it on the connection */
-       if (sess->fe->to_log & LW_XPRT)
-               cli_conn->flags |= CO_FL_XPRT_TRACKED;
-
-       /* we may have some tcp-request-session rules */
-       if ((l->options & LI_O_TCP_L5_RULES) && !tcp_exec_l5_rules(sess))
-               goto out_free_sess;
-
-       session_count_new(sess);
-       if (stream_create_from_conn(cli_conn) < 0)
-               goto out_free_sess;
-
-       return 1;
+       if (conn_complete_session(cli_conn) >= 0)
+               return 1;
 
+       /* error unrolling */
  out_free_sess:
        p->feconn--;
        session_free(sess);
@@ -398,13 +388,15 @@ static struct task *session_expire_embryonic(struct task *t)
 }
 
 /* Finish initializing a session from a connection, or kills it if the
- * connection shows and error. Returns <0 if the connection was killed.
+ * connection shows and error. Returns <0 if the connection was killed. It may
+ * be called either asynchronously as an xprt_done callback with an embryonic
+ * session, or synchronously to finalize the session. The distinction is made
+ * on sess->task which is only set in the embryonic session case.
  */
 static int conn_complete_session(struct connection *conn)
 {
        struct session *sess = conn->owner;
 
-       /* the embryonic session's task is not needed anymore */
        conn_clear_xprt_done_cb(conn);
 
        if (conn->flags & CO_FL_ERROR)
@@ -423,13 +415,16 @@ static int conn_complete_session(struct connection *conn)
                goto fail;
 
        /* the embryonic session's task is not needed anymore */
-       task_delete(sess->task);
-       task_free(sess->task);
-       sess->task = NULL;
+       if (sess->task) {
+               task_delete(sess->task);
+               task_free(sess->task);
+               sess->task = NULL;
+       }
        return 0;
 
  fail:
-       session_kill_embryonic(sess);
+       if (sess->task)
+               session_kill_embryonic(sess);
        return -1;
 }