From: Olivier Houchard Date: Thu, 21 Mar 2019 17:27:17 +0000 (+0100) Subject: MEDIUM: connections: Provide a xprt_ctx for each xprt method. X-Git-Tag: v2.0-dev3~222 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e179d0e88f2ae189558e42e4954ac00dc1ff9958;p=thirdparty%2Fhaproxy.git MEDIUM: connections: Provide a xprt_ctx for each xprt method. For most of the xprt methods, provide a xprt_ctx. This will be useful later when we'll want to be able to stack xprts. The init() method now has to create and provide the said xprt_ctx if needed. --- diff --git a/include/proto/connection.h b/include/proto/connection.h index 3a88f58a23..f0a4841526 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -48,8 +48,8 @@ int make_proxy_line(char *buf, int buf_len, struct server *srv, struct connectio int make_proxy_line_v1(char *buf, int buf_len, struct sockaddr_storage *src, struct sockaddr_storage *dst); int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connection *remote); -int conn_subscribe(struct connection *conn, int event_type, void *param); -int conn_unsubscribe(struct connection *conn, int event_type, void *param); +int conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param); +int conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param); /* receive a NetScaler Client IP insertion header over a connection */ int conn_recv_netscaler_cip(struct connection *conn, int flag); @@ -81,7 +81,7 @@ static inline int conn_xprt_init(struct connection *conn) int ret = 0; if (!conn_xprt_ready(conn) && conn->xprt && conn->xprt->init) - ret = conn->xprt->init(conn); + ret = conn->xprt->init(conn, &conn->xprt_ctx); if (ret >= 0) conn->flags |= CO_FL_XPRT_READY; @@ -98,7 +98,7 @@ static inline void conn_xprt_close(struct connection *conn) { if ((conn->flags & (CO_FL_XPRT_READY|CO_FL_XPRT_TRACKED)) == CO_FL_XPRT_READY) { if (conn->xprt->close) - conn->xprt->close(conn); + conn->xprt->close(conn, conn->xprt_ctx); conn->flags &= ~CO_FL_XPRT_READY; } } @@ -462,7 +462,7 @@ static inline void conn_xprt_shutw(struct connection *c) /* clean data-layer shutdown */ if (c->xprt && c->xprt->shutw) - c->xprt->shutw(c, 1); + c->xprt->shutw(c, c->xprt_ctx, 1); } static inline void conn_xprt_shutw_hard(struct connection *c) @@ -471,7 +471,7 @@ static inline void conn_xprt_shutw_hard(struct connection *c) /* unclean data-layer shutdown */ if (c->xprt && c->xprt->shutw) - c->xprt->shutw(c, 0); + c->xprt->shutw(c, c->xprt_ctx, 0); } /* shut read */ @@ -940,7 +940,7 @@ static inline int conn_get_alpn(const struct connection *conn, const char **str, { if (!conn_xprt_ready(conn) || !conn->xprt->get_alpn) return 0; - return conn->xprt->get_alpn(conn, str, len); + return conn->xprt->get_alpn(conn, conn->xprt_ctx, str, len); } /* registers proto mux list . Modifies the list element! */ diff --git a/include/types/connection.h b/include/types/connection.h index dd4935df57..308be7d7f7 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -302,22 +302,22 @@ enum { * and the other ones are used to setup and release the transport layer. */ struct xprt_ops { - size_t (*rcv_buf)(struct connection *conn, struct buffer *buf, size_t count, int flags); /* recv callback */ - size_t (*snd_buf)(struct connection *conn, const struct buffer *buf, size_t count, int flags); /* send callback */ - int (*rcv_pipe)(struct connection *conn, struct pipe *pipe, unsigned int count); /* recv-to-pipe callback */ - int (*snd_pipe)(struct connection *conn, struct pipe *pipe); /* send-to-pipe callback */ - void (*shutr)(struct connection *, int); /* shutr function */ - void (*shutw)(struct connection *, int); /* shutw function */ - void (*close)(struct connection *); /* close the transport layer */ - int (*init)(struct connection *conn); /* initialize the transport layer */ + size_t (*rcv_buf)(struct connection *conn, void *xprt_ctx, struct buffer *buf, size_t count, int flags); /* recv callback */ + size_t (*snd_buf)(struct connection *conn, void *xprt_ctx, const struct buffer *buf, size_t count, int flags); /* send callback */ + int (*rcv_pipe)(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count); /* recv-to-pipe callback */ + int (*snd_pipe)(struct connection *conn, void *xprt_ctx, struct pipe *pipe); /* send-to-pipe callback */ + void (*shutr)(struct connection *conn, void *xprt_ctx, int); /* shutr function */ + void (*shutw)(struct connection *conn, void *xprt_ctx, int); /* shutw function */ + void (*close)(struct connection *conn, void *xprt_ctx); /* close the transport layer */ + int (*init)(struct connection *conn, void **ctx); /* initialize the transport layer */ int (*prepare_bind_conf)(struct bind_conf *conf); /* prepare a whole bind_conf */ void (*destroy_bind_conf)(struct bind_conf *conf); /* destroy a whole bind_conf */ int (*prepare_srv)(struct server *srv); /* prepare a server context */ void (*destroy_srv)(struct server *srv); /* destroy a server context */ - int (*get_alpn)(const struct connection *conn, const char **str, int *len); /* get application layer name */ + int (*get_alpn)(const struct connection *conn, void *xprt_ctx, const char **str, int *len); /* get application layer name */ char name[8]; /* transport layer name, zero-terminated */ - int (*subscribe)(struct connection *conn, int event_type, void *param); /* Subscribe to events, such as "being able to send" */ - int (*unsubscribe)(struct connection *conn, int event_type, void *param); /* Unsubscribe to events */ + int (*subscribe)(struct connection *conn, void *xprt_ctx, int event_type, void *param); /* Subscribe to events, such as "being able to send" */ + int (*unsubscribe)(struct connection *conn, void *xprt_ctx, int event_type, void *param); /* Unsubscribe to events */ }; /* mux_ops describes the mux operations, which are to be performed at the diff --git a/src/connection.c b/src/connection.c index 303f6df42e..2a66996b26 100644 --- a/src/connection.c +++ b/src/connection.c @@ -316,7 +316,7 @@ int conn_sock_send(struct connection *conn, const void *buf, int len, int flags) return ret; } -int conn_unsubscribe(struct connection *conn, int event_type, void *param) +int conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) { struct wait_event *sw; @@ -340,7 +340,7 @@ int conn_unsubscribe(struct connection *conn, int event_type, void *param) return 0; } -int conn_subscribe(struct connection *conn, int event_type, void *param) +int conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) { struct wait_event *sw; diff --git a/src/mux_h1.c b/src/mux_h1.c index 2fb2803bbb..46bc33c908 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -484,7 +484,7 @@ static void h1_release(struct h1c *h1c) h1s_destroy(h1c->h1s); if (conn && h1c->wait_event.events != 0) - conn->xprt->unsubscribe(conn, h1c->wait_event.events, + conn->xprt->unsubscribe(conn, conn->xprt_ctx, h1c->wait_event.events, &h1c->wait_event); pool_free(pool_head_h1c, h1c); } @@ -1753,7 +1753,7 @@ static int h1_recv(struct h1c *h1c) */ h1c->ibuf.head = sizeof(struct htx); } - ret = conn->xprt->rcv_buf(conn, &h1c->ibuf, max, 0); + ret = conn->xprt->rcv_buf(conn, conn->xprt_ctx, &h1c->ibuf, max, 0); } if (ret > 0) { rcvd = 1; @@ -1769,7 +1769,7 @@ static int h1_recv(struct h1c *h1c) goto end; } - conn->xprt->subscribe(conn, SUB_RETRY_RECV, &h1c->wait_event); + conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event); end: if (ret > 0 || (conn->flags & CO_FL_ERROR) || conn_xprt_read0_pending(conn)) @@ -1800,7 +1800,7 @@ static int h1_send(struct h1c *h1c) if (h1c->flags & H1C_F_CS_WAIT_CONN) { if (!(h1c->wait_event.events & SUB_RETRY_SEND)) - conn->xprt->subscribe(conn, SUB_RETRY_SEND, &h1c->wait_event); + conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_SEND, &h1c->wait_event); return 0; } @@ -1810,7 +1810,7 @@ static int h1_send(struct h1c *h1c) if (h1c->flags & H1C_F_OUT_FULL) flags |= CO_SFL_MSG_MORE; - ret = conn->xprt->snd_buf(conn, &h1c->obuf, b_data(&h1c->obuf), flags); + ret = conn->xprt->snd_buf(conn, conn->xprt_ctx, &h1c->obuf, b_data(&h1c->obuf), flags); if (ret > 0) { h1c->flags &= ~H1C_F_OUT_FULL; b_del(&h1c->obuf, ret); @@ -1833,7 +1833,7 @@ static int h1_send(struct h1c *h1c) h1_shutw_conn(conn, CS_SHW_NORMAL); } else if (!(h1c->wait_event.events & SUB_RETRY_SEND)) - conn->xprt->subscribe(conn, SUB_RETRY_SEND, &h1c->wait_event); + conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_SEND, &h1c->wait_event); return sent; } @@ -2134,7 +2134,8 @@ static void h1_shutr(struct conn_stream *cs, enum cs_shr_mode mode) if (cs->flags & CS_FL_SHR) return; if (conn_xprt_ready(cs->conn) && cs->conn->xprt->shutr) - cs->conn->xprt->shutr(cs->conn, (mode == CS_SHR_DRAIN)); + cs->conn->xprt->shutr(cs->conn, cs->conn->xprt_ctx, + (mode == CS_SHR_DRAIN)); if ((cs->conn->flags & (CO_FL_SOCK_RD_SH|CO_FL_SOCK_WR_SH)) == (CO_FL_SOCK_RD_SH|CO_FL_SOCK_WR_SH)) h1c->flags = (h1c->flags & ~H1C_F_CS_SHUTW_NOW) | H1C_F_CS_SHUTDOWN; } @@ -2296,7 +2297,7 @@ static int h1_rcv_pipe(struct conn_stream *cs, struct pipe *pipe, unsigned int c if ((h1m->state != H1_MSG_DATA && h1m->state != H1_MSG_TUNNEL) || (h1m->state == H1_MSG_DATA && !h1m->curr_len)) { h1s->flags &= ~(H1S_F_BUF_FLUSH|H1S_F_SPLICED_DATA); - cs->conn->xprt->subscribe(cs->conn, SUB_RETRY_RECV, &h1s->h1c->wait_event); + cs->conn->xprt->subscribe(cs->conn, cs->conn->xprt_ctx, SUB_RETRY_RECV, &h1s->h1c->wait_event); goto end; } @@ -2309,7 +2310,7 @@ static int h1_rcv_pipe(struct conn_stream *cs, struct pipe *pipe, unsigned int c h1s->flags |= H1S_F_SPLICED_DATA; if (h1m->state == H1_MSG_DATA && count > h1m->curr_len) count = h1m->curr_len; - ret = cs->conn->xprt->rcv_pipe(cs->conn, pipe, count); + ret = cs->conn->xprt->rcv_pipe(cs->conn, cs->conn->xprt_ctx, pipe, count); if (h1m->state == H1_MSG_DATA && ret > 0) { h1m->curr_len -= ret; if (!h1m->curr_len) @@ -2333,11 +2334,11 @@ static int h1_snd_pipe(struct conn_stream *cs, struct pipe *pipe) if (b_data(&h1s->h1c->obuf)) goto end; - ret = cs->conn->xprt->snd_pipe(cs->conn, pipe); + ret = cs->conn->xprt->snd_pipe(cs->conn, cs->conn->xprt_ctx, pipe); end: if (pipe->data) { if (!(h1s->h1c->wait_event.events & SUB_RETRY_SEND)) - cs->conn->xprt->subscribe(cs->conn, SUB_RETRY_SEND, &h1s->h1c->wait_event); + cs->conn->xprt->subscribe(cs->conn, cs->conn->xprt_ctx, SUB_RETRY_SEND, &h1s->h1c->wait_event); } return ret; } diff --git a/src/mux_h2.c b/src/mux_h2.c index 5d084728c0..a6d89b92d4 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -643,7 +643,7 @@ static void h2_release(struct h2c *h2c) if (h2c->wait_event.task) tasklet_free(h2c->wait_event.task); if (h2c->wait_event.events != 0) - conn->xprt->unsubscribe(conn, h2c->wait_event.events, + conn->xprt->unsubscribe(conn, conn->xprt_ctx, h2c->wait_event.events, &h2c->wait_event); pool_free(pool_head_h2c, h2c); @@ -2676,13 +2676,13 @@ static int h2_recv(struct h2c *h2c) max = b_room(buf); if (max) - ret = conn->xprt->rcv_buf(conn, buf, max, 0); + ret = conn->xprt->rcv_buf(conn, conn->xprt_ctx, buf, max, 0); else ret = 0; } while (ret > 0); if (h2_recv_allowed(h2c) && (b_data(buf) < buf->size)) - conn->xprt->subscribe(conn, SUB_RETRY_RECV, &h2c->wait_event); + conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_RECV, &h2c->wait_event); if (!b_data(buf)) { h2_release_buf(h2c, &h2c->dbuf); @@ -2749,7 +2749,7 @@ static int h2_send(struct h2c *h2c) flags |= CO_SFL_MSG_MORE; if (b_data(&h2c->mbuf)) { - int ret = conn->xprt->snd_buf(conn, &h2c->mbuf, b_data(&h2c->mbuf), flags); + int ret = conn->xprt->snd_buf(conn, conn->xprt_ctx, &h2c->mbuf, b_data(&h2c->mbuf), flags); if (!ret) break; sent = 1; @@ -2796,7 +2796,7 @@ static int h2_send(struct h2c *h2c) return sent; schedule: if (!(h2c->wait_event.events & SUB_RETRY_SEND)) - conn->xprt->subscribe(conn, SUB_RETRY_SEND, &h2c->wait_event); + conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_SEND, &h2c->wait_event); return sent; } @@ -2947,7 +2947,7 @@ static struct task *h2_timeout_task(struct task *t, void *context, unsigned shor h2c->flags |= H2_CF_GOAWAY_FAILED; if (b_data(&h2c->mbuf) && !(h2c->flags & H2_CF_GOAWAY_FAILED) && conn_xprt_ready(h2c->conn)) { - int ret = h2c->conn->xprt->snd_buf(h2c->conn, &h2c->mbuf, b_data(&h2c->mbuf), 0); + int ret = h2c->conn->xprt->snd_buf(h2c->conn, h2c->conn->xprt_ctx, &h2c->mbuf, b_data(&h2c->mbuf), 0); if (ret > 0) { b_del(&h2c->mbuf, ret); b_realign_if_empty(&h2c->mbuf); diff --git a/src/mux_pt.c b/src/mux_pt.c index 278a8f55da..18bc96ee83 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -54,7 +54,7 @@ static struct task *mux_pt_io_cb(struct task *t, void *tctx, unsigned short stat if (ctx->conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH)) mux_pt_destroy(ctx); else - ctx->conn->xprt->subscribe(ctx->conn, SUB_RETRY_RECV, + ctx->conn->xprt->subscribe(ctx->conn, ctx->conn->xprt_ctx, SUB_RETRY_RECV, &ctx->wait_event); return NULL; @@ -146,7 +146,7 @@ static struct conn_stream *mux_pt_attach(struct connection *conn, struct session struct conn_stream *cs; struct mux_pt_ctx *ctx = conn->ctx; - conn->xprt->unsubscribe(conn, SUB_RETRY_RECV, &ctx->wait_event); + conn->xprt->unsubscribe(ctx->conn, conn->xprt_ctx, SUB_RETRY_RECV, &ctx->wait_event); cs = cs_new(conn); if (!cs) goto fail; @@ -191,7 +191,7 @@ static void mux_pt_detach(struct conn_stream *cs) if (conn->owner != NULL && !(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) { ctx->cs = NULL; - conn->xprt->subscribe(conn, SUB_RETRY_RECV, &ctx->wait_event); + conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_RECV, &ctx->wait_event); } else /* There's no session attached to that connection, destroy it */ mux_pt_destroy(ctx); @@ -217,7 +217,8 @@ static void mux_pt_shutr(struct conn_stream *cs, enum cs_shr_mode mode) return; cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM); if (conn_xprt_ready(cs->conn) && cs->conn->xprt->shutr) - cs->conn->xprt->shutr(cs->conn, (mode == CS_SHR_DRAIN)); + cs->conn->xprt->shutr(cs->conn, cs->conn->xprt_ctx, + (mode == CS_SHR_DRAIN)); if (cs->flags & CS_FL_SHW) conn_full_close(cs->conn); /* Maybe we've been put in the list of available idle connections, @@ -232,7 +233,8 @@ static void mux_pt_shutw(struct conn_stream *cs, enum cs_shw_mode mode) if (cs->flags & CS_FL_SHW) return; if (conn_xprt_ready(cs->conn) && cs->conn->xprt->shutw) - cs->conn->xprt->shutw(cs->conn, (mode == CS_SHW_NORMAL)); + cs->conn->xprt->shutw(cs->conn, cs->conn->xprt_ctx, + (mode == CS_SHW_NORMAL)); if (!(cs->flags & CS_FL_SHR)) conn_sock_shutw(cs->conn, (mode == CS_SHW_NORMAL)); else @@ -256,7 +258,7 @@ static size_t mux_pt_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t return 0; } b_realign_if_empty(buf); - ret = cs->conn->xprt->rcv_buf(cs->conn, buf, count, flags); + ret = cs->conn->xprt->rcv_buf(cs->conn, cs->conn->xprt_ctx, buf, count, flags); if (conn_xprt_read0_pending(cs->conn)) { if (ret == 0) cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM); @@ -277,7 +279,7 @@ static size_t mux_pt_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t if (cs->conn->flags & CO_FL_HANDSHAKE) return 0; - ret = cs->conn->xprt->snd_buf(cs->conn, buf, count, flags); + ret = cs->conn->xprt->snd_buf(cs->conn, cs->conn->xprt_ctx, buf, count, flags); if (ret > 0) b_del(buf, ret); @@ -287,12 +289,12 @@ static size_t mux_pt_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t /* Called from the upper layer, to subscribe to events */ static int mux_pt_subscribe(struct conn_stream *cs, int event_type, void *param) { - return (cs->conn->xprt->subscribe(cs->conn, event_type, param)); + return (cs->conn->xprt->subscribe(cs->conn, cs->conn->xprt_ctx, event_type, param)); } static int mux_pt_unsubscribe(struct conn_stream *cs, int event_type, void *param) { - return (cs->conn->xprt->unsubscribe(cs->conn, event_type, param)); + return (cs->conn->xprt->unsubscribe(cs->conn, cs->conn->xprt_ctx, event_type, param)); } #if defined(CONFIG_HAP_LINUX_SPLICE) @@ -301,7 +303,7 @@ static int mux_pt_rcv_pipe(struct conn_stream *cs, struct pipe *pipe, unsigned i { int ret; - ret = cs->conn->xprt->rcv_pipe(cs->conn, pipe, count); + ret = cs->conn->xprt->rcv_pipe(cs->conn, cs->conn->xprt_ctx, pipe, count); if (conn_xprt_read0_pending(cs->conn)) cs->flags |= CS_FL_EOS; if (cs->conn->flags & CO_FL_ERROR) @@ -311,7 +313,7 @@ static int mux_pt_rcv_pipe(struct conn_stream *cs, struct pipe *pipe, unsigned i static int mux_pt_snd_pipe(struct conn_stream *cs, struct pipe *pipe) { - return (cs->conn->xprt->snd_pipe(cs->conn, pipe)); + return (cs->conn->xprt->snd_pipe(cs->conn, cs->conn->xprt_ctx, pipe)); } #endif diff --git a/src/raw_sock.c b/src/raw_sock.c index 40b1bbc3dc..6c5a634a9b 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -66,7 +66,7 @@ * connection flags are updated (error, read0, wait_room, wait_data). * The caller must have previously allocated the pipe. */ -int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int count) +int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count) { #ifndef ASSUME_SPLICE_WORKS static THREAD_LOCAL int splice_detects_close; @@ -198,7 +198,7 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co /* Send as many bytes as possible from the pipe to the connection's socket. */ -int raw_sock_from_pipe(struct connection *conn, struct pipe *pipe) +int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe) { int ret, done; @@ -250,7 +250,7 @@ int raw_sock_from_pipe(struct connection *conn, struct pipe *pipe) * errno is cleared before starting so that the caller knows that if it spots an * error without errno, it's pending and can be retrieved via getsockopt(SO_ERROR). */ -static size_t raw_sock_to_buf(struct connection *conn, struct buffer *buf, size_t count, int flags) +static size_t raw_sock_to_buf(struct connection *conn, void *xprt_ctx, struct buffer *buf, size_t count, int flags) { ssize_t ret; size_t try, done = 0; @@ -363,7 +363,7 @@ static size_t raw_sock_to_buf(struct connection *conn, struct buffer *buf, size_ * is responsible for this. It's up to the caller to update the buffer's contents * based on the return value. */ -static size_t raw_sock_from_buf(struct connection *conn, const struct buffer *buf, size_t count, int flags) +static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const struct buffer *buf, size_t count, int flags) { ssize_t ret; size_t try, done; @@ -419,13 +419,22 @@ static size_t raw_sock_from_buf(struct connection *conn, const struct buffer *bu return done; } +static int raw_sock_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +{ + return conn_subscribe(conn, xprt_ctx, event_type, param); +} + +static int raw_sock_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +{ + return conn_unsubscribe(conn, xprt_ctx, event_type, param); +} /* transport-layer operations for RAW sockets */ static struct xprt_ops raw_sock = { .snd_buf = raw_sock_from_buf, .rcv_buf = raw_sock_to_buf, - .subscribe = conn_subscribe, - .unsubscribe = conn_unsubscribe, + .subscribe = raw_sock_subscribe, + .unsubscribe = raw_sock_unsubscribe, #if defined(CONFIG_HAP_LINUX_SPLICE) .rcv_pipe = raw_sock_to_pipe, .snd_pipe = raw_sock_from_pipe, diff --git a/src/ssl_sock.c b/src/ssl_sock.c index b4aa94ab9a..119eafb7fc 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -5094,11 +5094,11 @@ ssl_sock_free_ca(struct bind_conf *bind_conf) * handshake flag on the connection. It is safe to call it multiple times. * It returns 0 on success and -1 in error case. */ -static int ssl_sock_init(struct connection *conn) +static int ssl_sock_init(struct connection *conn, void **xprt_ctx) { struct ssl_sock_ctx *ctx; /* already initialized */ - if (conn->xprt_ctx) + if (*xprt_ctx) return 0; if (!conn_ctrl_ready(conn)) @@ -5174,10 +5174,10 @@ static int ssl_sock_init(struct connection *conn) /* leave init state and start handshake */ conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN; - conn->xprt_ctx = ctx; _HA_ATOMIC_ADD(&sslconns, 1); _HA_ATOMIC_ADD(&totalsslconns, 1); + *xprt_ctx = ctx; return 0; } else if (objt_listener(conn->target)) { @@ -5229,7 +5229,7 @@ static int ssl_sock_init(struct connection *conn) _HA_ATOMIC_ADD(&sslconns, 1); _HA_ATOMIC_ADD(&totalsslconns, 1); - conn->xprt_ctx = ctx; + *xprt_ctx = ctx; return 0; } /* don't know how to handle such a target */ @@ -5524,14 +5524,16 @@ reneg_ok: return 0; } -static int ssl_subscribe(struct connection *conn, int event_type, void *param) +static int ssl_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) { - return conn_subscribe(conn, event_type, param); + + return conn_subscribe(conn, NULL, event_type, param); } -static int ssl_unsubscribe(struct connection *conn, int event_type, void *param) +static int ssl_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) { - return conn_unsubscribe(conn, event_type, param); + + return conn_unsubscribe(conn, NULL, event_type, param); } /* Receive up to bytes from connection 's socket and store them @@ -5542,15 +5544,15 @@ static int ssl_unsubscribe(struct connection *conn, int event_type, void *param) * avoiding the call if inappropriate. The function does not call the * connection's polling update function, so the caller is responsible for this. */ -static size_t ssl_sock_to_buf(struct connection *conn, struct buffer *buf, size_t count, int flags) +static size_t ssl_sock_to_buf(struct connection *conn, void *xprt_ctx, struct buffer *buf, size_t count, int flags) { - struct ssl_sock_ctx *ctx = conn->xprt_ctx; + struct ssl_sock_ctx *ctx = xprt_ctx; ssize_t ret; size_t try, done = 0; conn_refresh_polling_flags(conn); - if (!conn->xprt_ctx) + if (!ctx) goto out_error; if (conn->flags & CO_FL_HANDSHAKE) @@ -5703,16 +5705,16 @@ static size_t ssl_sock_to_buf(struct connection *conn, struct buffer *buf, size_ * caller to take care of this. It's up to the caller to update the buffer's * contents based on the return value. */ -static size_t ssl_sock_from_buf(struct connection *conn, const struct buffer *buf, size_t count, int flags) +static size_t ssl_sock_from_buf(struct connection *conn, void *xprt_ctx, const struct buffer *buf, size_t count, int flags) { - struct ssl_sock_ctx *ctx = conn->xprt_ctx; + struct ssl_sock_ctx *ctx = xprt_ctx; ssize_t ret; size_t try, done; done = 0; conn_refresh_polling_flags(conn); - if (!conn->xprt_ctx) + if (!ctx) goto out_error; if (conn->flags & CO_FL_HANDSHAKE) @@ -5838,11 +5840,11 @@ static size_t ssl_sock_from_buf(struct connection *conn, const struct buffer *bu goto leave; } -static void ssl_sock_close(struct connection *conn) { +static void ssl_sock_close(struct connection *conn, void *xprt_ctx) { - struct ssl_sock_ctx *ctx = conn->xprt_ctx; + struct ssl_sock_ctx *ctx = xprt_ctx; - if (conn->xprt_ctx) { + if (ctx) { #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC) if (global_ssl.async) { OSSL_ASYNC_FD all_fd[32], afd; @@ -5875,7 +5877,6 @@ static void ssl_sock_close(struct connection *conn) { fd_cant_recv(afd); } pool_free(ssl_sock_ctx_pool, ctx); - conn->xprt_ctx = NULL; _HA_ATOMIC_ADD(&jobs, 1); return; } @@ -5891,7 +5892,6 @@ static void ssl_sock_close(struct connection *conn) { #endif SSL_free(ctx->ssl); pool_free(ssl_sock_ctx_pool, ctx); - conn->xprt_ctx = NULL; _HA_ATOMIC_SUB(&sslconns, 1); } } @@ -5899,9 +5899,9 @@ static void ssl_sock_close(struct connection *conn) { /* This function tries to perform a clean shutdown on an SSL connection, and in * any case, flags the connection as reusable if no handshake was in progress. */ -static void ssl_sock_shutw(struct connection *conn, int clean) +static void ssl_sock_shutw(struct connection *conn, void *xprt_ctx, int clean) { - struct ssl_sock_ctx *ctx = conn->xprt_ctx; + struct ssl_sock_ctx *ctx = xprt_ctx; if (conn->flags & CO_FL_HANDSHAKE) return; @@ -6348,14 +6348,12 @@ unsigned int ssl_sock_get_verify_result(struct connection *conn) * freed by the caller. NPN is also checked if available since older versions * of openssl (1.0.1) which are more common in field only support this one. */ -static int ssl_sock_get_alpn(const struct connection *conn, const char **str, int *len) +static int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx, const char **str, int *len) { #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation) || \ defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG) -struct ssl_sock_ctx *ctx = conn->xprt_ctx; -#endif - - if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock) + struct ssl_sock_ctx *ctx = xprt_ctx; + if (!ctx) return 0; *str = NULL; @@ -6369,6 +6367,7 @@ struct ssl_sock_ctx *ctx = conn->xprt_ctx; SSL_get0_next_proto_negotiated(ctx->ssl, (const unsigned char **)str, (unsigned *)len); if (*str) return 1; +#endif #endif return 0; }