mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 13:51:26 +02:00
MINOR: quic: get rid of ->target quic_conn struct member
The ->li (struct listener *) member of quic_conn struct was replaced by a ->target (struct obj_type *) member by this commit: MINOR: quic-be: get rid of ->li quic_conn member to abstract the connection type (front or back) when implementing QUIC for the backends. In these cases, ->target was a pointer to the ojb_type of a server struct. This could not work with the dynamic servers contrary to the listeners which are not dynamic. This patch almost reverts the one mentioned above. ->target pointer to obj_type member is replaced by ->li pointer to listener struct member. As the listener are not dynamic, this is easy to do this. All one has to do is to replace the objt_listener(qc->target) statement by qc->li where applicable. For the backend connection, when needed, this is always qc->conn->target which is used only when qc->conn is initialized. The only "problematic" case is for quic_dgram_parse() which takes a pointer to an obj_type as third argument. But this obj_type is only used to call quic_rx_pkt_parse(). Inside this function it is used to access the proxy counters of the connection thanks to qc_counters(). So, this obj_type argument may be null for now on with this patch. This is the reason why qc_counters() is modified to take this into consideration.
This commit is contained in:
parent
5354c24c76
commit
47bb15ca84
@ -322,7 +322,7 @@ struct qcc_app_ops;
|
|||||||
* with a connection \
|
* with a connection \
|
||||||
*/ \
|
*/ \
|
||||||
struct eb_root *cids; \
|
struct eb_root *cids; \
|
||||||
enum obj_type *target; \
|
struct listener *li; \
|
||||||
/* Idle timer task */ \
|
/* Idle timer task */ \
|
||||||
struct task *idle_timer_task; \
|
struct task *idle_timer_task; \
|
||||||
unsigned int idle_expire; \
|
unsigned int idle_expire; \
|
||||||
|
@ -173,9 +173,14 @@ static inline void quic_free_ncbuf(struct ncbuf *ncbuf)
|
|||||||
static inline void *qc_counters(enum obj_type *o, const struct stats_module *m)
|
static inline void *qc_counters(enum obj_type *o, const struct stats_module *m)
|
||||||
{
|
{
|
||||||
struct proxy *p;
|
struct proxy *p;
|
||||||
struct listener *l = objt_listener(o);
|
struct listener *l;
|
||||||
struct server *s = objt_server(o);
|
struct server *s;
|
||||||
|
|
||||||
|
if (!o)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
l = objt_listener(o);
|
||||||
|
s = objt_server(o);
|
||||||
p = l ? l->bind_conf->frontend :
|
p = l ? l->bind_conf->frontend :
|
||||||
s ? s->proxy : NULL;
|
s ? s->proxy : NULL;
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ static inline char qc_test_fd(struct quic_conn *qc)
|
|||||||
*/
|
*/
|
||||||
static inline int qc_fd(struct quic_conn *qc)
|
static inline int qc_fd(struct quic_conn *qc)
|
||||||
{
|
{
|
||||||
/* TODO: check this: For backends, qc->fd is always initialized */
|
/* For backends, qc->fd is always initialized */
|
||||||
return qc_test_fd(qc) ? qc->fd : __objt_listener(qc->target)->rx.fd;
|
return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to increment <l> handshake current counter. If listener limit is
|
/* Try to increment <l> handshake current counter. If listener limit is
|
||||||
|
@ -1425,8 +1425,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
|
|||||||
#if defined(USE_QUIC)
|
#if defined(USE_QUIC)
|
||||||
else if (fdt.iocb == quic_conn_sock_fd_iocb) {
|
else if (fdt.iocb == quic_conn_sock_fd_iocb) {
|
||||||
qc = fdtab[fd].owner;
|
qc = fdtab[fd].owner;
|
||||||
li = qc ? objt_listener(qc->target) : NULL;
|
li = qc ? qc->li : NULL;
|
||||||
sv = qc ? objt_server(qc->target) : NULL;
|
sv = qc ? (qc->conn ? objt_server(qc->conn->target) : NULL) : NULL;
|
||||||
xprt_ctx = qc ? qc->xprt_ctx : NULL;
|
xprt_ctx = qc ? qc->xprt_ctx : NULL;
|
||||||
conn = qc ? qc->conn : NULL;
|
conn = qc ? qc->conn : NULL;
|
||||||
xprt = conn ? conn->xprt : NULL; // in fact it's &ssl_quic
|
xprt = conn ? conn->xprt : NULL; // in fact it's &ssl_quic
|
||||||
|
@ -181,10 +181,11 @@ static void dump_quic_oneline(struct show_quic_ctx *ctx, struct quic_conn *qc)
|
|||||||
char bufaddr[INET6_ADDRSTRLEN], bufport[6];
|
char bufaddr[INET6_ADDRSTRLEN], bufport[6];
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char cid_len;
|
unsigned char cid_len;
|
||||||
struct listener *l = objt_listener(qc->target);
|
struct listener *l = qc->li;
|
||||||
|
|
||||||
ret = chunk_appendf(&trash, "%p[%02u]/%-.12s ", qc, ctx->thr,
|
ret = chunk_appendf(&trash, "%p[%02u]/%-.12s ", qc, ctx->thr,
|
||||||
l ? l->bind_conf->frontend->id : __objt_server(qc->target)->id);
|
l ? l->bind_conf->frontend->id :
|
||||||
|
qc->conn ? __objt_server(qc->conn->target)->id : "UNKNOWN");
|
||||||
|
|
||||||
chunk_appendf(&trash, "%*s", 36 - ret, " "); /* align output */
|
chunk_appendf(&trash, "%*s", 36 - ret, " "); /* align output */
|
||||||
|
|
||||||
|
@ -749,7 +749,7 @@ static struct quic_conn_closed *qc_new_cc_conn(struct quic_conn *qc)
|
|||||||
cc_qc->dcid = qc->dcid;
|
cc_qc->dcid = qc->dcid;
|
||||||
cc_qc->scid = qc->scid;
|
cc_qc->scid = qc->scid;
|
||||||
|
|
||||||
cc_qc->target = qc->target;
|
cc_qc->li = qc->li;
|
||||||
cc_qc->cids = qc->cids;
|
cc_qc->cids = qc->cids;
|
||||||
|
|
||||||
cc_qc->idle_timer_task = qc->idle_timer_task;
|
cc_qc->idle_timer_task = qc->idle_timer_task;
|
||||||
@ -1113,7 +1113,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
qc->target = target;
|
qc->li = l;
|
||||||
/* Now that quic_conn instance is allocated, quic_conn_release() will
|
/* Now that quic_conn instance is allocated, quic_conn_release() will
|
||||||
* ensure global accounting is decremented.
|
* ensure global accounting is decremented.
|
||||||
*/
|
*/
|
||||||
@ -1418,7 +1418,7 @@ int qc_handle_conn_migration(struct quic_conn *qc,
|
|||||||
* used during the handshake, unless the endpoint has acted on a
|
* used during the handshake, unless the endpoint has acted on a
|
||||||
* preferred_address transport parameter from the peer.
|
* preferred_address transport parameter from the peer.
|
||||||
*/
|
*/
|
||||||
if (__objt_listener(qc->target)->bind_conf->quic_params.disable_active_migration) {
|
if (qc->li->bind_conf->quic_params.disable_active_migration) {
|
||||||
TRACE_ERROR("Active migration was disabled, datagram dropped", QUIC_EV_CONN_LPKT, qc);
|
TRACE_ERROR("Active migration was disabled, datagram dropped", QUIC_EV_CONN_LPKT, qc);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -1548,8 +1548,8 @@ int quic_conn_release(struct quic_conn *qc)
|
|||||||
*/
|
*/
|
||||||
if (MT_LIST_INLIST(&qc->accept_list)) {
|
if (MT_LIST_INLIST(&qc->accept_list)) {
|
||||||
MT_LIST_DELETE(&qc->accept_list);
|
MT_LIST_DELETE(&qc->accept_list);
|
||||||
BUG_ON(__objt_listener(qc->target)->rx.quic_curr_accept == 0);
|
BUG_ON(qc->li->rx.quic_curr_accept == 0);
|
||||||
HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_accept);
|
HA_ATOMIC_DEC(&qc->li->rx.quic_curr_accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subtract last congestion window from global memory counter. */
|
/* Subtract last congestion window from global memory counter. */
|
||||||
@ -1622,8 +1622,8 @@ int quic_conn_release(struct quic_conn *qc)
|
|||||||
/* Connection released before handshake completion. */
|
/* Connection released before handshake completion. */
|
||||||
if (unlikely(qc->state < QUIC_HS_ST_COMPLETE)) {
|
if (unlikely(qc->state < QUIC_HS_ST_COMPLETE)) {
|
||||||
if (!qc_is_back(qc)) {
|
if (!qc_is_back(qc)) {
|
||||||
BUG_ON(__objt_listener(qc->target)->rx.quic_curr_handshake == 0);
|
BUG_ON(qc->li->rx.quic_curr_handshake == 0);
|
||||||
HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_handshake);
|
HA_ATOMIC_DEC(&qc->li->rx.quic_curr_handshake);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2031,8 +2031,8 @@ void qc_bind_tid_commit(struct quic_conn *qc, struct listener *new_li)
|
|||||||
/* At this point no connection was accounted for yet on this
|
/* At this point no connection was accounted for yet on this
|
||||||
* listener so it's OK to just swap the pointer.
|
* listener so it's OK to just swap the pointer.
|
||||||
*/
|
*/
|
||||||
if (new_li && new_li != __objt_listener(qc->target)) {
|
if (new_li && new_li != qc->li) {
|
||||||
qc->target = &new_li->obj_type;
|
qc->li = new_li;
|
||||||
|
|
||||||
/* Update GSO conn support based on new listener status. */
|
/* Update GSO conn support based on new listener status. */
|
||||||
if (HA_ATOMIC_LOAD(&new_li->flags) & LI_F_UDP_GSO_NOTSUPP)
|
if (HA_ATOMIC_LOAD(&new_li->flags) & LI_F_UDP_GSO_NOTSUPP)
|
||||||
|
@ -1674,7 +1674,9 @@ static inline int quic_token_validate(struct quic_rx_packet *pkt,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the associated connection to the packet <pkt> or create a new one if
|
/* Listener only function.
|
||||||
|
*
|
||||||
|
* Find the associated connection to the packet <pkt> or create a new one if
|
||||||
* this is an Initial packet. <dgram> is the datagram containing the packet and
|
* this is an Initial packet. <dgram> is the datagram containing the packet and
|
||||||
* <l> is the listener instance on which it was received.
|
* <l> is the listener instance on which it was received.
|
||||||
*
|
*
|
||||||
@ -2112,6 +2114,7 @@ static int quic_rx_pkt_parse(struct quic_conn *qc, struct quic_rx_packet *pkt,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
drop:
|
drop:
|
||||||
|
if (prx_counters)
|
||||||
HA_ATOMIC_INC(&prx_counters->dropped_pkt);
|
HA_ATOMIC_INC(&prx_counters->dropped_pkt);
|
||||||
drop_silent:
|
drop_silent:
|
||||||
if (!pkt->len)
|
if (!pkt->len)
|
||||||
@ -2308,6 +2311,9 @@ static void qc_rx_pkt_handle(struct quic_conn *qc, struct quic_rx_packet *pkt,
|
|||||||
* function will thus retrieve the connection from the CID tree or allocate a
|
* function will thus retrieve the connection from the CID tree or allocate a
|
||||||
* new one if possible. <li> is the listener attached to the receiver.
|
* new one if possible. <li> is the listener attached to the receiver.
|
||||||
*
|
*
|
||||||
|
* Note that for a QUIC backend, <from_qc> is never NULL. <o> is never NULL
|
||||||
|
* for a QUIC frontend.
|
||||||
|
*
|
||||||
* Returns 0 on success else non-zero. If an error happens, some packets from
|
* Returns 0 on success else non-zero. If an error happens, some packets from
|
||||||
* the datagram may not have been parsed.
|
* the datagram may not have been parsed.
|
||||||
*/
|
*/
|
||||||
|
@ -87,7 +87,7 @@ int quic_sock_get_dst(struct connection *conn, struct sockaddr *addr, socklen_t
|
|||||||
memcpy(addr, &qc->peer_addr, len);
|
memcpy(addr, &qc->peer_addr, len);
|
||||||
} else {
|
} else {
|
||||||
struct sockaddr_storage *from;
|
struct sockaddr_storage *from;
|
||||||
struct listener *l = objt_listener(qc->target);
|
struct listener *l = qc->li;
|
||||||
|
|
||||||
/* Return listener address if IP_PKTINFO or friends are not
|
/* Return listener address if IP_PKTINFO or friends are not
|
||||||
* supported by the socket.
|
* supported by the socket.
|
||||||
@ -701,7 +701,7 @@ static int qc_may_use_saddr(struct quic_conn *qc)
|
|||||||
* possible. This is not useful if the listening socket is bound to
|
* possible. This is not useful if the listening socket is bound to
|
||||||
* a specific address. It is even prohibited on FreeBSD.
|
* a specific address. It is even prohibited on FreeBSD.
|
||||||
*/
|
*/
|
||||||
return (!is_addr(&__objt_listener(qc->target)->rx.addr) &&
|
return (!is_addr(&qc->li->rx.addr) &&
|
||||||
is_addr(&qc->local_addr));
|
is_addr(&qc->local_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,7 +839,7 @@ int qc_rcv_buf(struct quic_conn *qc)
|
|||||||
struct buffer buf = BUF_NULL;
|
struct buffer buf = BUF_NULL;
|
||||||
unsigned char *dgram_buf;
|
unsigned char *dgram_buf;
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
struct listener *l = objt_listener(qc->target);
|
struct listener *l = qc->li;
|
||||||
|
|
||||||
/* Do not call this if quic-conn FD is uninitialized. */
|
/* Do not call this if quic-conn FD is uninitialized. */
|
||||||
BUG_ON(qc->fd < 0);
|
BUG_ON(qc->fd < 0);
|
||||||
@ -948,7 +948,8 @@ int qc_rcv_buf(struct quic_conn *qc)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
quic_dgram_parse(new_dgram, qc, qc->target);
|
quic_dgram_parse(new_dgram, qc, l ? &l->obj_type :
|
||||||
|
(qc->conn ? &__objt_server(qc->conn->target)->obj_type : NULL));
|
||||||
/* A datagram must always be consumed after quic_parse_dgram(). */
|
/* A datagram must always be consumed after quic_parse_dgram(). */
|
||||||
BUG_ON(new_dgram->buf);
|
BUG_ON(new_dgram->buf);
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
@ -975,7 +976,7 @@ int qc_rcv_buf(struct quic_conn *qc)
|
|||||||
void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
|
void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
|
||||||
const struct sockaddr_storage *dst)
|
const struct sockaddr_storage *dst)
|
||||||
{
|
{
|
||||||
struct listener *l = __objt_listener(qc->target);
|
struct listener *l = qc->li;
|
||||||
struct bind_conf *bc = l->bind_conf;
|
struct bind_conf *bc = l->bind_conf;
|
||||||
struct proxy *p = bc->frontend;
|
struct proxy *p = bc->frontend;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
@ -1083,7 +1084,7 @@ struct quic_accept_queue *quic_accept_queues;
|
|||||||
void quic_accept_push_qc(struct quic_conn *qc)
|
void quic_accept_push_qc(struct quic_conn *qc)
|
||||||
{
|
{
|
||||||
struct quic_accept_queue *queue = &quic_accept_queues[tid];
|
struct quic_accept_queue *queue = &quic_accept_queues[tid];
|
||||||
struct listener *l = __objt_listener(qc->target);
|
struct listener *l = qc->li;
|
||||||
struct li_per_thread *lthr = &l->per_thr[ti->ltid];
|
struct li_per_thread *lthr = &l->per_thr[ti->ltid];
|
||||||
|
|
||||||
/* A connection must only be accepted once per instance. */
|
/* A connection must only be accepted once per instance. */
|
||||||
|
@ -938,7 +938,7 @@ int qc_ssl_do_hanshake(struct quic_conn *qc, struct ssl_sock_ctx *ctx)
|
|||||||
* handshake level CRYPTO data which are validated by the TLS stack.
|
* handshake level CRYPTO data which are validated by the TLS stack.
|
||||||
*/
|
*/
|
||||||
if (!qc_is_back(qc)) {
|
if (!qc_is_back(qc)) {
|
||||||
if (__objt_listener(qc->target)->bind_conf->ssl_conf.early_data &&
|
if (qc->li->bind_conf->ssl_conf.early_data &&
|
||||||
(!qc->ael || !qc->ael->tls_ctx.rx.secret)) {
|
(!qc->ael || !qc->ael->tls_ctx.rx.secret)) {
|
||||||
TRACE_PROTO("SSL handshake in progress",
|
TRACE_PROTO("SSL handshake in progress",
|
||||||
QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
|
QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
|
||||||
@ -982,7 +982,7 @@ int qc_ssl_do_hanshake(struct quic_conn *qc, struct ssl_sock_ctx *ctx)
|
|||||||
|
|
||||||
qc->flags |= QUIC_FL_CONN_NEED_POST_HANDSHAKE_FRMS;
|
qc->flags |= QUIC_FL_CONN_NEED_POST_HANDSHAKE_FRMS;
|
||||||
if (!qc_is_back(qc)) {
|
if (!qc_is_back(qc)) {
|
||||||
struct listener *l = __objt_listener(qc->target);
|
struct listener *l = qc->li;
|
||||||
/* I/O callback switch */
|
/* I/O callback switch */
|
||||||
qc->wait_event.tasklet->process = quic_conn_app_io_cb;
|
qc->wait_event.tasklet->process = quic_conn_app_io_cb;
|
||||||
qc->state = QUIC_HS_ST_CONFIRMED;
|
qc->state = QUIC_HS_ST_CONFIRMED;
|
||||||
@ -1268,7 +1268,7 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn)
|
|||||||
ctx->qc = qc;
|
ctx->qc = qc;
|
||||||
|
|
||||||
if (!qc_is_back(qc)) {
|
if (!qc_is_back(qc)) {
|
||||||
struct bind_conf *bc = __objt_listener(qc->target)->bind_conf;
|
struct bind_conf *bc = qc->li->bind_conf;
|
||||||
|
|
||||||
if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl, NULL, 1) == -1)
|
if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl, NULL, 1) == -1)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -333,7 +333,7 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
|||||||
|
|
||||||
/* Permanently disable UDP GSO for future conns which use current listener/server instance. */
|
/* Permanently disable UDP GSO for future conns which use current listener/server instance. */
|
||||||
if (!qc_is_back(qc)) {
|
if (!qc_is_back(qc)) {
|
||||||
struct listener *l = __objt_listener(qc->target);
|
struct listener *l = qc->li;
|
||||||
TRACE_ERROR("mark listener UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
|
TRACE_ERROR("mark listener UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
|
||||||
HA_ATOMIC_OR(&l->flags, LI_F_UDP_GSO_NOTSUPP);
|
HA_ATOMIC_OR(&l->flags, LI_F_UDP_GSO_NOTSUPP);
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
|
|||||||
s = __objt_listener(conn->target)->bind_conf;
|
s = __objt_listener(conn->target)->bind_conf;
|
||||||
#ifdef USE_QUIC
|
#ifdef USE_QUIC
|
||||||
else if (qc)
|
else if (qc)
|
||||||
s = __objt_listener(qc->target)->bind_conf;
|
s = qc->li->bind_conf;
|
||||||
#endif /* USE_QUIC */
|
#endif /* USE_QUIC */
|
||||||
|
|
||||||
if (!s) {
|
if (!s) {
|
||||||
|
@ -132,7 +132,7 @@ int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
|
|||||||
struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
|
struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
|
||||||
|
|
||||||
/* null if not a listener */
|
/* null if not a listener */
|
||||||
li = objt_listener(qc->target);
|
li = qc->li;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1135,7 +1135,7 @@ static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned
|
|||||||
ref = __objt_listener(conn->target)->bind_conf->keys_ref;
|
ref = __objt_listener(conn->target)->bind_conf->keys_ref;
|
||||||
#ifdef USE_QUIC
|
#ifdef USE_QUIC
|
||||||
else if (qc)
|
else if (qc)
|
||||||
ref = __objt_listener(qc->target)->bind_conf->keys_ref;
|
ref = qc->li->bind_conf->keys_ref;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
@ -1691,7 +1691,7 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
|
|||||||
else {
|
else {
|
||||||
qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
|
qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
|
||||||
BUG_ON(!qc); /* Must never happen */
|
BUG_ON(!qc); /* Must never happen */
|
||||||
bind_conf = __objt_listener(qc->target)->bind_conf;
|
bind_conf = qc->li->bind_conf;
|
||||||
ctx = qc->xprt_ctx;
|
ctx = qc->xprt_ctx;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user