From: Willy Tarreau Date: Fri, 15 Sep 2017 08:06:28 +0000 (+0200) Subject: MEDIUM: session: factor out duplicated code for conn_complete_session X-Git-Tag: v1.8-dev3~90 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c4ed35225080118466e574ff310c8b37a308496;p=thirdparty%2Fhaproxy.git MEDIUM: session: factor out duplicated code for conn_complete_session 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. --- diff --git a/src/session.c b/src/session.c index c4c929450b..98d7e2c462 100644 --- a/src/session.c +++ b/src/session.c @@ -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; }