mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-17 19:16:56 +00:00
MEDIUM: rhttp: create session for active preconnect
Modify rhttp preconnect by instantiating a new session for each connection attempt. Connection is thus linked to a session directly on its instantiation contrary to previously where no session existed until listener_accept(). This patch will allow to extend rhttp usage. Most notably, it will be useful to use various sample fetches on the server line and extend logging capabilities. Changes are minimal, yet consequences are considered not trivial as for the first time a FE connection session is instantiated before listener_accept(). This requires an extra explicit check in session_accept_fd() to not overwrite an existing session. Also, flag SESS_FL_RELEASE_LI is not set immediately as listener counters must note be decremented if connection and its session are freed before reversal is completed, or else listener counters will be invalid. conn_session_free() is used as connection destroy callback to ensure the session will be freed automatically on connection release.
This commit is contained in:
parent
45b80aed70
commit
12c40c25a9
@ -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);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <haproxy/proxy.h>
|
||||
#include <haproxy/sample.h>
|
||||
#include <haproxy/server.h>
|
||||
#include <haproxy/session.h>
|
||||
#include <haproxy/sock.h>
|
||||
#include <haproxy/ssl_sock.h>
|
||||
#include <haproxy/task.h>
|
||||
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user