diff --git a/include/haproxy/session.h b/include/haproxy/session.h index a9cea62ed..48d2fa088 100644 --- a/include/haproxy/session.h +++ b/include/haproxy/session.h @@ -36,6 +36,7 @@ extern struct pool_head *pool_head_sess_priv_conns; struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type *origin); void session_free(struct session *sess); +void conn_session_free(struct connection *conn); int session_accept_fd(struct connection *cli_conn); int conn_complete_session(struct connection *conn); struct task *session_expire_embryonic(struct task *t, void *context, unsigned int state); diff --git a/src/proto_rhttp.c b/src/proto_rhttp.c index 736351375..f0f26f2b5 100644 --- a/src/proto_rhttp.c +++ b/src/proto_rhttp.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -55,11 +56,17 @@ static struct connection *new_reverse_conn(struct listener *l, struct server *sr { struct connection *conn = conn_new(srv); struct sockaddr_storage *bind_addr = NULL; + struct session *sess = NULL; if (!conn) goto err; HA_ATOMIC_INC(&th_ctx->nb_rhttp_conns); + sess = session_new(l->bind_conf->frontend, l, NULL); + if (!sess) + goto err; + + conn_set_owner(conn, sess, conn_session_free); conn_set_reverse(conn, &l->obj_type); if (alloc_bind_address(&bind_addr, srv, srv->proxy, NULL) != SRV_STATUS_OK) @@ -82,7 +89,7 @@ static struct connection *new_reverse_conn(struct listener *l, struct server *sr if (srv->ssl_ctx.sni) { struct sample *sni_smp = NULL; /* TODO remove NULL session which can cause crash depending on the SNI sample expr used. */ - sni_smp = sample_fetch_as_type(srv->proxy, NULL, NULL, + sni_smp = sample_fetch_as_type(srv->proxy, sess, NULL, SMP_OPT_DIR_REQ | SMP_OPT_FINAL, srv->ssl_ctx.sni, SMP_T_STR); if (smp_make_safe(sni_smp)) @@ -96,7 +103,7 @@ static struct connection *new_reverse_conn(struct listener *l, struct server *sr if (!srv->use_ssl || (!srv->ssl_ctx.alpn_str && !srv->ssl_ctx.npn_str) || srv->mux_proto) { - if (conn_install_mux_be(conn, NULL, NULL, NULL) < 0) + if (conn_install_mux_be(conn, NULL, sess, NULL) < 0) goto err; } @@ -112,6 +119,7 @@ static struct connection *new_reverse_conn(struct listener *l, struct server *sr l->rx.rhttp.state = LI_PRECONN_ST_ERR; } + /* No need to free session as conn.destroy_cb will take care of it. */ if (conn) { conn_stop_tracking(conn); conn_xprt_shutw(conn); @@ -297,6 +305,7 @@ int rhttp_bind_listener(struct listener *listener, char *errmsg, int errlen) snprintf(errmsg, errlen, "Out of memory."); goto err; } + task->process = rhttp_process; task->context = listener; listener->rx.rhttp.task = task; diff --git a/src/session.c b/src/session.c index d9cfa8819..f8953df77 100644 --- a/src/session.c +++ b/src/session.c @@ -186,11 +186,17 @@ int session_accept_fd(struct connection *cli_conn) } } - sess = session_new(p, l, &cli_conn->obj_type); - if (!sess) - goto out_free_conn; + /* Reversed conns already have an assigned session, do not recreate it. */ + if (!(cli_conn->flags & CO_FL_REVERSED)) { + sess = session_new(p, l, &cli_conn->obj_type); + if (!sess) + goto out_free_conn; - conn_set_owner(cli_conn, sess, NULL); + conn_set_owner(cli_conn, sess, NULL); + } + else { + sess = cli_conn->owner; + } /* now evaluate the tcp-request layer4 rules. We only need a session * and no stream for these rules.