MINOR: quic-be: get rid of ->li quic_conn member
Replace ->li quic_conn pointer to struct listener member by ->target which is an object type enum and adapt the code. Use __objt_(listener|server)() where the object type is known. Typically this is were the code which is specific to one connection type (frontend/backend). Remove <server> parameter passed to qc_new_conn(). It is redundant with the <target> parameter. GSO is not supported at this time for QUIC backend. qc_prep_pkts() is modified to prevent it from building more than an MTU. This has as consequence to prevent qc_send_ppkts() to use GSO. ssl_clienthello.c code is run only by listeners. This is why __objt_listener() is used in place of ->li.
This commit is contained in:
parent
f6ef3bbc8a
commit
b9703cf711
@ -319,7 +319,7 @@ struct qcc_app_ops;
|
||||
* with a connection \
|
||||
*/ \
|
||||
struct eb_root *cids; \
|
||||
struct listener *li; /* only valid for frontend connections */ \
|
||||
enum obj_type *target; \
|
||||
/* Idle timer task */ \
|
||||
struct task *idle_timer_task; \
|
||||
unsigned int idle_expire; \
|
||||
|
@ -69,7 +69,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
struct quic_connection_id *conn_id,
|
||||
struct sockaddr_storage *local_addr,
|
||||
struct sockaddr_storage *peer_addr,
|
||||
int server, int token, void *owner,
|
||||
int token, void *owner,
|
||||
struct connection *conn);
|
||||
int quic_build_post_handshake_frames(struct quic_conn *qc);
|
||||
const struct quic_version *qc_supported_version(uint32_t version);
|
||||
@ -164,13 +164,6 @@ static inline void quic_free_ncbuf(struct ncbuf *ncbuf)
|
||||
*ncbuf = NCBUF_NULL;
|
||||
}
|
||||
|
||||
/* Return the address of the connection owner object type. */
|
||||
static inline enum obj_type *qc_owner_obj_type(struct quic_conn *qc)
|
||||
{
|
||||
return qc_is_listener(qc) ? &qc->li->obj_type :
|
||||
&objt_server(qc->conn->target)->obj_type;
|
||||
}
|
||||
|
||||
/* Return the address of the QUIC counters attached to the proxy of
|
||||
* the owner of the connection whose object type address is <o> for
|
||||
* listener and servers, or NULL for others object type.
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <haproxy/connection-t.h>
|
||||
#include <haproxy/fd-t.h>
|
||||
#include <haproxy/listener-t.h>
|
||||
#include <haproxy/obj_type.h>
|
||||
#include <haproxy/quic_conn-t.h>
|
||||
#include <haproxy/quic_sock-t.h>
|
||||
|
||||
@ -78,7 +79,8 @@ static inline char qc_test_fd(struct quic_conn *qc)
|
||||
*/
|
||||
static inline int qc_fd(struct quic_conn *qc)
|
||||
{
|
||||
return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
|
||||
/* TODO: check this: For backends, qc->fd is always initialized */
|
||||
return qc_test_fd(qc) ? qc->fd : __objt_listener(qc->target)->rx.fd;
|
||||
}
|
||||
|
||||
/* Try to increment <l> handshake current counter. If listener limit is
|
||||
|
@ -1423,7 +1423,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
|
||||
#if defined(USE_QUIC)
|
||||
else if (fdt.iocb == quic_conn_sock_fd_iocb) {
|
||||
qc = fdtab[fd].owner;
|
||||
li = qc ? qc->li : NULL;
|
||||
li = qc ? objt_listener(qc->target) : NULL;
|
||||
sv = qc ? objt_server(qc->target) : NULL;
|
||||
xprt_ctx = qc ? qc->xprt_ctx : NULL;
|
||||
conn = qc ? qc->conn : NULL;
|
||||
xprt = conn ? conn->xprt : NULL; // in fact it's &ssl_quic
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <haproxy/cli.h>
|
||||
#include <haproxy/list.h>
|
||||
#include <haproxy/mux_quic.h>
|
||||
#include <haproxy/quic_conn-t.h>
|
||||
#include <haproxy/quic_conn.h>
|
||||
#include <haproxy/quic_tp.h>
|
||||
#include <haproxy/quic_utils.h>
|
||||
#include <haproxy/tools.h>
|
||||
@ -181,9 +181,11 @@ static void dump_quic_oneline(struct show_quic_ctx *ctx, struct quic_conn *qc)
|
||||
char bufaddr[INET6_ADDRSTRLEN], bufport[6];
|
||||
int ret;
|
||||
unsigned char cid_len;
|
||||
struct listener *l = objt_listener(qc->target);
|
||||
|
||||
ret = chunk_appendf(&trash, "%p[%02u]/%-.12s ", qc, ctx->thr,
|
||||
qc->li->bind_conf->frontend->id);
|
||||
l ? l->bind_conf->frontend->id : __objt_server(qc->target)->id);
|
||||
|
||||
chunk_appendf(&trash, "%*s", 36 - ret, " "); /* align output */
|
||||
|
||||
/* State */
|
||||
|
@ -749,7 +749,7 @@ static struct quic_conn_closed *qc_new_cc_conn(struct quic_conn *qc)
|
||||
cc_qc->dcid = qc->dcid;
|
||||
cc_qc->scid = qc->scid;
|
||||
|
||||
cc_qc->li = qc->li;
|
||||
cc_qc->target = qc->target;
|
||||
cc_qc->cids = qc->cids;
|
||||
|
||||
cc_qc->idle_timer_task = qc->idle_timer_task;
|
||||
@ -1067,27 +1067,18 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
struct quic_connection_id *conn_id,
|
||||
struct sockaddr_storage *local_addr,
|
||||
struct sockaddr_storage *peer_addr,
|
||||
int server, int token, void *owner,
|
||||
int token, void *target,
|
||||
struct connection *conn)
|
||||
{
|
||||
struct quic_conn *qc = NULL;
|
||||
struct listener *l = NULL;
|
||||
struct server *srv = NULL;
|
||||
struct proxy *prx = NULL;
|
||||
struct listener *l = objt_listener(target);
|
||||
struct server *srv = objt_server(target);
|
||||
struct proxy *prx = l ? l->bind_conf->frontend : __objt_server(target)->proxy;
|
||||
struct quic_cc_algo *cc_algo = NULL;
|
||||
unsigned int next_actconn = 0, next_sslconn = 0, next_handshake = 0;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_INIT);
|
||||
|
||||
if (server) {
|
||||
l = owner;
|
||||
prx = l->bind_conf->frontend;
|
||||
}
|
||||
else {
|
||||
srv = owner;
|
||||
prx = srv->proxy;
|
||||
}
|
||||
|
||||
next_actconn = increment_actconn();
|
||||
if (!next_actconn) {
|
||||
_HA_ATOMIC_INC(&maxconn_reached);
|
||||
@ -1101,7 +1092,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (server) {
|
||||
if (l) {
|
||||
next_handshake = quic_increment_curr_handshake(l);
|
||||
if (!next_handshake) {
|
||||
TRACE_STATE("max handshake reached", QUIC_EV_CONN_INIT);
|
||||
@ -1121,6 +1112,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
goto err;
|
||||
}
|
||||
|
||||
qc->target = target;
|
||||
*qc->cids = EB_ROOT;
|
||||
/* Now that quic_conn instance is allocated, quic_conn_release() will
|
||||
* ensure global accounting is decremented.
|
||||
@ -1176,7 +1168,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
qc->prx_counters = EXTRA_COUNTERS_GET(prx->extra_counters_fe, &quic_stats_module);
|
||||
|
||||
/* QUIC Server (or listener). */
|
||||
if (server) {
|
||||
if (l) {
|
||||
cc_algo = l->bind_conf->quic_cc_algo;
|
||||
|
||||
qc->flags = QUIC_FL_CONN_LISTENER;
|
||||
@ -1189,7 +1181,6 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
/* Copy the packet SCID to reuse it as DCID for sending */
|
||||
qc->dcid = *scid;
|
||||
qc->tx.buf = BUF_NULL;
|
||||
qc->li = l;
|
||||
conn_id->qc = qc;
|
||||
}
|
||||
/* QUIC Client (outgoing connection to servers) */
|
||||
@ -1218,7 +1209,6 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
conn_id = conn_cid;
|
||||
|
||||
qc->tx.buf = BUF_NULL;
|
||||
qc->li = NULL;
|
||||
qc->next_cid_seq_num = 1;
|
||||
conn->handle.qc = qc;
|
||||
}
|
||||
@ -1228,7 +1218,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
/* Listener only: if connection is instantiated due to an INITIAL packet with an
|
||||
* already checked token, consider the peer address as validated.
|
||||
*/
|
||||
if (server) {
|
||||
if (l) {
|
||||
if (token_odcid->len) {
|
||||
TRACE_STATE("validate peer address due to initial token",
|
||||
QUIC_EV_CONN_INIT, qc);
|
||||
@ -1301,7 +1291,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
qc->max_ack_delay = 0;
|
||||
/* Only one path at this time (multipath not supported) */
|
||||
qc->path = &qc->paths[0];
|
||||
quic_cc_path_init(qc->path, ipv4, server ? l->bind_conf->max_cwnd : 0,
|
||||
quic_cc_path_init(qc->path, ipv4, l ? l->bind_conf->max_cwnd : 0,
|
||||
cc_algo ? cc_algo : default_quic_cc_algo, qc);
|
||||
|
||||
if (local_addr)
|
||||
@ -1310,7 +1300,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
memset(&qc->local_addr, 0, sizeof(qc->local_addr));
|
||||
memcpy(&qc->peer_addr, peer_addr, sizeof qc->peer_addr);
|
||||
|
||||
if (server) {
|
||||
if (l) {
|
||||
qc_lstnr_params_init(qc, &l->bind_conf->quic_params,
|
||||
conn_id->stateless_reset_token,
|
||||
qc->dcid.data, qc->dcid.len,
|
||||
@ -1344,7 +1334,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
!quic_conn_init_idle_timer_task(qc, prx))
|
||||
goto err;
|
||||
|
||||
if (!qc_new_isecs(qc, &qc->iel->tls_ctx, qc->original_version, dcid->data, dcid->len, server))
|
||||
if (!qc_new_isecs(qc, &qc->iel->tls_ctx, qc->original_version, dcid->data, dcid->len, !!l))
|
||||
goto err;
|
||||
|
||||
/* Counters initialization */
|
||||
@ -1395,7 +1385,7 @@ int qc_handle_conn_migration(struct quic_conn *qc,
|
||||
* used during the handshake, unless the endpoint has acted on a
|
||||
* preferred_address transport parameter from the peer.
|
||||
*/
|
||||
if (qc->li->bind_conf->quic_params.disable_active_migration) {
|
||||
if (__objt_listener(qc->target)->bind_conf->quic_params.disable_active_migration) {
|
||||
TRACE_ERROR("Active migration was disabled, datagram dropped", QUIC_EV_CONN_LPKT, qc);
|
||||
goto err;
|
||||
}
|
||||
@ -1525,8 +1515,8 @@ int quic_conn_release(struct quic_conn *qc)
|
||||
*/
|
||||
if (MT_LIST_INLIST(&qc->accept_list)) {
|
||||
MT_LIST_DELETE(&qc->accept_list);
|
||||
BUG_ON(qc->li->rx.quic_curr_accept == 0);
|
||||
HA_ATOMIC_DEC(&qc->li->rx.quic_curr_accept);
|
||||
BUG_ON(__objt_listener(qc->target)->rx.quic_curr_accept == 0);
|
||||
HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_accept);
|
||||
}
|
||||
|
||||
/* Substract last congestion window from global memory counter. */
|
||||
@ -1596,8 +1586,8 @@ int quic_conn_release(struct quic_conn *qc)
|
||||
/* Connection released before handshake completion. */
|
||||
if (unlikely(qc->state < QUIC_HS_ST_COMPLETE)) {
|
||||
if (qc_is_listener(qc)) {
|
||||
BUG_ON(qc->li->rx.quic_curr_handshake == 0);
|
||||
HA_ATOMIC_DEC(&qc->li->rx.quic_curr_handshake);
|
||||
BUG_ON(__objt_listener(qc->target)->rx.quic_curr_handshake == 0);
|
||||
HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_handshake);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2005,8 +1995,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
|
||||
* listener so it's OK to just swap the pointer.
|
||||
*/
|
||||
if (new_li && new_li != qc->li)
|
||||
qc->li = new_li;
|
||||
if (new_li && new_li != __objt_listener(qc->target))
|
||||
qc->target = &new_li->obj_type;
|
||||
|
||||
/* Rebind the connection FD. */
|
||||
if (qc_test_fd(qc)) {
|
||||
|
@ -1819,7 +1819,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
|
||||
goto err;
|
||||
|
||||
qc = qc_new_conn(pkt->version, ipv4, &pkt->dcid, &pkt->scid, &token_odcid,
|
||||
conn_id, &dgram->daddr, &pkt->saddr, 1,
|
||||
conn_id, &dgram->daddr, &pkt->saddr,
|
||||
!!pkt->token_len, l, NULL);
|
||||
if (qc == NULL) {
|
||||
pool_free(pool_head_quic_connection_id, conn_id);
|
||||
|
@ -87,13 +87,13 @@ int quic_sock_get_dst(struct connection *conn, struct sockaddr *addr, socklen_t
|
||||
memcpy(addr, &qc->peer_addr, len);
|
||||
} else {
|
||||
struct sockaddr_storage *from;
|
||||
struct listener *l = objt_listener(qc->target);
|
||||
|
||||
/* Return listener address if IP_PKTINFO or friends are not
|
||||
* supported by the socket.
|
||||
*/
|
||||
BUG_ON(!qc->li);
|
||||
from = is_addr(&qc->local_addr) ? &qc->local_addr :
|
||||
&qc->li->rx.addr;
|
||||
BUG_ON(!l);
|
||||
from = is_addr(&qc->local_addr) ? &qc->local_addr : &l->rx.addr;
|
||||
if (len > sizeof(*from))
|
||||
len = sizeof(*from);
|
||||
memcpy(addr, from, len);
|
||||
@ -819,6 +819,7 @@ int qc_rcv_buf(struct quic_conn *qc)
|
||||
struct buffer buf = BUF_NULL;
|
||||
unsigned char *dgram_buf;
|
||||
ssize_t ret = 0;
|
||||
struct listener *l = objt_listener(qc->target);
|
||||
|
||||
/* Do not call this if quic-conn FD is uninitialized. */
|
||||
BUG_ON(qc->fd < 0);
|
||||
@ -869,7 +870,7 @@ int qc_rcv_buf(struct quic_conn *qc)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qc_is_listener(qc) && !qc_check_dcid(qc, new_dgram->dcid, new_dgram->dcid_len)) {
|
||||
if (l && !qc_check_dcid(qc, new_dgram->dcid, new_dgram->dcid_len)) {
|
||||
/* Datagram received by error on the connection FD, dispatch it
|
||||
* to its associated quic-conn.
|
||||
*
|
||||
@ -879,7 +880,6 @@ int qc_rcv_buf(struct quic_conn *qc)
|
||||
struct quic_dgram *tmp_dgram;
|
||||
unsigned char *rxbuf_tail;
|
||||
size_t cspace;
|
||||
struct listener *l = qc->li;
|
||||
|
||||
TRACE_STATE("datagram for other connection on quic-conn socket, requeue it", QUIC_EV_CONN_RCV, qc);
|
||||
|
||||
@ -928,7 +928,7 @@ int qc_rcv_buf(struct quic_conn *qc)
|
||||
continue;
|
||||
}
|
||||
|
||||
quic_dgram_parse(new_dgram, qc, qc_owner_obj_type(qc));
|
||||
quic_dgram_parse(new_dgram, qc, qc->target);
|
||||
/* A datagram must always be consumed after quic_parse_dgram(). */
|
||||
BUG_ON(new_dgram->buf);
|
||||
} while (ret > 0);
|
||||
@ -950,11 +950,13 @@ int qc_rcv_buf(struct quic_conn *qc)
|
||||
*
|
||||
* Return the socket FD or a negative error code. On error, socket is marked as
|
||||
* uninitialized.
|
||||
* Note: This function must not be run for backends connection.
|
||||
*/
|
||||
void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
|
||||
const struct sockaddr_storage *dst)
|
||||
{
|
||||
struct bind_conf *bc = qc->li->bind_conf;
|
||||
struct listener *l = __objt_listener(qc->target);
|
||||
struct bind_conf *bc = l->bind_conf;
|
||||
struct proxy *p = bc->frontend;
|
||||
int fd = -1;
|
||||
int ret;
|
||||
@ -1007,7 +1009,7 @@ void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
|
||||
}
|
||||
|
||||
/* Fallback to listener socket for this receiver instance. */
|
||||
HA_ATOMIC_STORE(&qc->li->rx.quic_mode, QUIC_SOCK_MODE_LSTNR);
|
||||
HA_ATOMIC_STORE(&l->rx.quic_mode, QUIC_SOCK_MODE_LSTNR);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
@ -1061,13 +1063,14 @@ struct quic_accept_queue *quic_accept_queues;
|
||||
void quic_accept_push_qc(struct quic_conn *qc)
|
||||
{
|
||||
struct quic_accept_queue *queue = &quic_accept_queues[tid];
|
||||
struct li_per_thread *lthr = &qc->li->per_thr[ti->ltid];
|
||||
struct listener *l = __objt_listener(qc->target);
|
||||
struct li_per_thread *lthr = &l->per_thr[ti->ltid];
|
||||
|
||||
/* A connection must only be accepted once per instance. */
|
||||
BUG_ON(qc->flags & QUIC_FL_CONN_ACCEPT_REGISTERED);
|
||||
|
||||
BUG_ON(MT_LIST_INLIST(&qc->accept_list));
|
||||
HA_ATOMIC_INC(&qc->li->rx.quic_curr_accept);
|
||||
HA_ATOMIC_INC(&l->rx.quic_curr_accept);
|
||||
|
||||
qc->flags |= QUIC_FL_CONN_ACCEPT_REGISTERED;
|
||||
/* 1. insert the listener in the accept queue
|
||||
|
@ -937,14 +937,16 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf,
|
||||
* provided by the stack. This happens after having received the peer
|
||||
* handshake level CRYPTO data which are validated by the TLS stack.
|
||||
*/
|
||||
if (qc->li->bind_conf->ssl_conf.early_data &&
|
||||
(!qc->ael || !qc->ael->tls_ctx.rx.secret)) {
|
||||
TRACE_PROTO("SSL handshake in progress",
|
||||
QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
TRACE_PROTO("SSL handshake OK", QUIC_EV_CONN_IO_CB, qc, &state);
|
||||
if (qc_is_listener(qc)) {
|
||||
if (__objt_listener(qc->target)->bind_conf->ssl_conf.early_data &&
|
||||
(!qc->ael || !qc->ael->tls_ctx.rx.secret)) {
|
||||
TRACE_PROTO("SSL handshake in progress",
|
||||
QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
TRACE_PROTO("SSL handshake OK", QUIC_EV_CONN_IO_CB, qc, &state);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -957,6 +959,7 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf,
|
||||
|
||||
qc->flags |= QUIC_FL_CONN_NEED_POST_HANDSHAKE_FRMS;
|
||||
if (qc_is_listener(ctx->qc)) {
|
||||
struct listener *l = __objt_listener(qc->target);
|
||||
/* I/O callback switch */
|
||||
qc->wait_event.tasklet->process = quic_conn_app_io_cb;
|
||||
qc->state = QUIC_HS_ST_CONFIRMED;
|
||||
@ -972,8 +975,8 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf,
|
||||
tasklet_wakeup(qc->wait_event.tasklet);
|
||||
}
|
||||
|
||||
BUG_ON(qc->li->rx.quic_curr_handshake == 0);
|
||||
HA_ATOMIC_DEC(&qc->li->rx.quic_curr_handshake);
|
||||
BUG_ON(l->rx.quic_curr_handshake == 0);
|
||||
HA_ATOMIC_DEC(&l->rx.quic_curr_handshake);
|
||||
}
|
||||
else {
|
||||
qc->state = QUIC_HS_ST_COMPLETE;
|
||||
@ -1201,7 +1204,7 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn)
|
||||
ctx->qc = qc;
|
||||
|
||||
if (qc_is_listener(qc)) {
|
||||
struct bind_conf *bc = qc->li->bind_conf;
|
||||
struct bind_conf *bc = __objt_listener(qc->target)->bind_conf;
|
||||
|
||||
if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl, NULL, 1) == -1)
|
||||
goto err;
|
||||
|
@ -288,8 +288,10 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
int ret = 0;
|
||||
struct quic_conn *qc;
|
||||
char skip_sendto = 0;
|
||||
struct listener *l;
|
||||
|
||||
qc = ctx->qc;
|
||||
l = objt_listener(qc->target);
|
||||
TRACE_ENTER(QUIC_EV_CONN_SPPKTS, qc);
|
||||
while (b_contig_data(buf, 0)) {
|
||||
unsigned char *pos;
|
||||
@ -305,7 +307,11 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
|
||||
/* If datagram bigger than MTU, several ones were encoded for GSO usage. */
|
||||
if (dglen > qc->path->mtu) {
|
||||
if (likely(!(HA_ATOMIC_LOAD(&qc->li->flags) & LI_F_UDP_GSO_NOTSUPP))) {
|
||||
/* TODO: note that at this time for connection to backends this
|
||||
* part is not run because no more than an MTU has been prepared for
|
||||
* such connections (dglen <= qc->path->mtu). So, here l is not NULL.
|
||||
*/
|
||||
if (likely(!(HA_ATOMIC_LOAD(&l->flags) & LI_F_UDP_GSO_NOTSUPP))) {
|
||||
TRACE_PROTO("send multiple datagrams with GSO", QUIC_EV_CONN_SPPKTS, qc);
|
||||
gso = qc->path->mtu;
|
||||
}
|
||||
@ -327,11 +333,15 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
int ret = qc_snd_buf(qc, &tmpbuf, tmpbuf.data, 0, gso);
|
||||
if (ret < 0) {
|
||||
if (gso && ret == -EIO) {
|
||||
/* TODO: note that at this time for connection to backends this
|
||||
* part is not run because no more than an MTU has been
|
||||
* prepared for such connections (l is not NULL).
|
||||
*/
|
||||
/* Disable permanently UDP GSO for this listener.
|
||||
* Retry standard emission.
|
||||
*/
|
||||
TRACE_ERROR("mark listener UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
|
||||
HA_ATOMIC_OR(&qc->li->flags, LI_F_UDP_GSO_NOTSUPP);
|
||||
HA_ATOMIC_OR(&l->flags, LI_F_UDP_GSO_NOTSUPP);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -576,6 +586,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
|
||||
int dgram_cnt = 0;
|
||||
/* Restrict GSO emission to comply with sendmsg limitation. See QUIC_MAX_GSO_DGRAMS for more details. */
|
||||
uchar gso_dgram_cnt = 0;
|
||||
struct listener *l = objt_listener(qc->target);
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_IO_CB, qc);
|
||||
/* Currently qc_prep_pkts() does not handle buffer wrapping so the
|
||||
@ -765,11 +776,13 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
|
||||
prv_pkt = cur_pkt;
|
||||
}
|
||||
else if (!(quic_tune.options & QUIC_TUNE_NO_UDP_GSO) &&
|
||||
!(HA_ATOMIC_LOAD(&qc->li->flags) & LI_F_UDP_GSO_NOTSUPP) &&
|
||||
dglen == qc->path->mtu &&
|
||||
(char *)end < b_wrap(buf) &&
|
||||
++gso_dgram_cnt < QUIC_MAX_GSO_DGRAMS) {
|
||||
|
||||
++gso_dgram_cnt < QUIC_MAX_GSO_DGRAMS &&
|
||||
l && !(HA_ATOMIC_LOAD(&l->flags) & LI_F_UDP_GSO_NOTSUPP)) {
|
||||
/* TODO: note that for backends GSO is not used. No more than
|
||||
* an MTU is prepared.
|
||||
*/
|
||||
/* A datagram covering the full MTU has been
|
||||
* built, use GSO to built next entry. Do not
|
||||
* reserve extra space for datagram header.
|
||||
|
@ -177,7 +177,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
|
||||
s = __objt_listener(conn->target)->bind_conf;
|
||||
#ifdef USE_QUIC
|
||||
else if (qc)
|
||||
s = qc->li->bind_conf;
|
||||
s = __objt_listener(qc->target)->bind_conf;
|
||||
#endif /* USE_QUIC */
|
||||
|
||||
if (!s) {
|
||||
|
@ -127,7 +127,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);
|
||||
|
||||
/* null if not a listener */
|
||||
li = qc->li;
|
||||
li = objt_listener(qc->target);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -926,7 +926,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;
|
||||
#ifdef USE_QUIC
|
||||
else if (qc)
|
||||
ref = qc->li->bind_conf->keys_ref;
|
||||
ref = __objt_listener(qc->target)->bind_conf->keys_ref;
|
||||
#endif
|
||||
|
||||
if (!ref) {
|
||||
@ -1482,7 +1482,7 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
|
||||
else {
|
||||
qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
|
||||
BUG_ON(!qc); /* Must never happen */
|
||||
bind_conf = qc->li->bind_conf;
|
||||
bind_conf = __objt_listener(qc->target)->bind_conf;
|
||||
ctx = qc->xprt_ctx;
|
||||
}
|
||||
#endif
|
||||
|
@ -123,7 +123,7 @@ static int qc_conn_init(struct connection *conn, void **xprt_ctx)
|
||||
int ipv4 = conn->dst->ss_family == AF_INET;
|
||||
struct server *srv = objt_server(conn->target);
|
||||
qc = qc_new_conn(quic_version_1, ipv4, NULL, NULL, NULL,
|
||||
NULL, NULL, &srv->addr, 0, 0, srv, conn);
|
||||
NULL, NULL, &srv->addr, 0, srv, conn);
|
||||
}
|
||||
|
||||
if (!qc)
|
||||
|
Loading…
x
Reference in New Issue
Block a user