mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-24 23:31:40 +02:00
MINOR: quic: extract connection retrieval
Simplify qc_lstnr_pkt_rcv() by extracting code responsible to retrieve the quic-conn instance. This code is put in a dedicated function named quic_rx_pkt_retrieve_conn(). This new function could be skipped if a FD-owned quic-conn socket is used. The first traces of qc_lstnr_pkt_rcv() have been clean up as qc instance is always NULL here : thus qc parameter can be removed without any change. This change has no functional impact. It is a part of a refactoring series on qc_lstnr_pkt_rcv(). The objective is facilitate integration of FD-owned socket patches. This should be backported up to 2.6.
This commit is contained in:
parent
deb7c87f55
commit
449b1a8f55
220
src/quic_conn.c
220
src/quic_conn.c
@ -5926,6 +5926,119 @@ static inline int quic_padding_check(const unsigned char *buf,
|
||||
return buf == end;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* <l> is the listener instance on which it was received.
|
||||
*
|
||||
* Returns the quic-conn instance or NULL.
|
||||
*/
|
||||
static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
|
||||
struct quic_dgram *dgram,
|
||||
struct listener *l)
|
||||
{
|
||||
struct quic_cid odcid;
|
||||
const struct quic_cid *token_odcid = NULL; // ODCID received from client token
|
||||
struct quic_conn *qc = NULL;
|
||||
struct proxy *prx;
|
||||
struct quic_counters *prx_counters;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_LPKT);
|
||||
|
||||
prx = l->bind_conf->frontend;
|
||||
prx_counters = EXTRA_COUNTERS_GET(prx->extra_counters_fe, &quic_stats_module);
|
||||
|
||||
qc = retrieve_qc_conn_from_cid(pkt, l, &dgram->saddr);
|
||||
|
||||
if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
|
||||
BUG_ON(!pkt->version); /* This must not happen. */
|
||||
|
||||
if (global.cluster_secret && pkt->token_len) {
|
||||
if (*pkt->token == QUIC_TOKEN_FMT_RETRY) {
|
||||
const struct quic_version *ver = qc ? qc->original_version : pkt->version;
|
||||
if (!quic_retry_token_check(pkt->token, pkt->token_len, ver, &odcid,
|
||||
&pkt->scid, qc, &dgram->saddr)) {
|
||||
HA_ATOMIC_INC(&prx_counters->retry_error);
|
||||
TRACE_PROTO("Wrong retry token",
|
||||
QUIC_EV_CONN_LPKT, qc, NULL, NULL, pkt->version);
|
||||
/* TODO: RFC 9000 8.1.2 A server SHOULD immediately close the connection
|
||||
* with an INVALID_TOKEN error.
|
||||
*/
|
||||
goto out;
|
||||
}
|
||||
|
||||
token_odcid = &odcid;
|
||||
HA_ATOMIC_INC(&prx_counters->retry_validated);
|
||||
}
|
||||
else {
|
||||
/* TODO: New token check */
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc, NULL, NULL, pkt->version);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!qc) {
|
||||
int ipv4;
|
||||
|
||||
if (global.cluster_secret && !pkt->token_len && !(l->bind_conf->options & BC_O_QUIC_FORCE_RETRY) &&
|
||||
HA_ATOMIC_LOAD(&prx_counters->half_open_conn) >= global.tune.quic_retry_threshold) {
|
||||
TRACE_PROTO("Initial without token, sending retry",
|
||||
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
|
||||
if (send_retry(l->rx.fd, &dgram->saddr, pkt, pkt->version)) {
|
||||
TRACE_ERROR("Error during Retry generation",
|
||||
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
|
||||
goto out;
|
||||
}
|
||||
|
||||
HA_ATOMIC_INC(&prx_counters->retry_sent);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* RFC 9000 7.2. Negotiating Connection IDs:
|
||||
* When an Initial packet is sent by a client that has not previously
|
||||
* received an Initial or Retry packet from the server, the client
|
||||
* populates the Destination Connection ID field with an unpredictable
|
||||
* value. This Destination Connection ID MUST be at least 8 bytes in length.
|
||||
*/
|
||||
if (pkt->dcid.len < QUIC_ODCID_MINLEN) {
|
||||
TRACE_PROTO("dropped packet",
|
||||
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
|
||||
goto err;
|
||||
}
|
||||
|
||||
pkt->saddr = dgram->saddr;
|
||||
ipv4 = dgram->saddr.ss_family == AF_INET;
|
||||
|
||||
qc = qc_new_conn(pkt->version, ipv4, &pkt->dcid, &pkt->scid, token_odcid,
|
||||
&dgram->daddr, &pkt->saddr, 1,
|
||||
!!pkt->token_len, l);
|
||||
if (qc == NULL)
|
||||
goto err;
|
||||
|
||||
HA_ATOMIC_INC(&prx_counters->half_open_conn);
|
||||
/* Insert the DCID the QUIC client has chosen (only for listeners) */
|
||||
ebmb_insert(&quic_dghdlrs[tid].odcids, &qc->odcid_node,
|
||||
qc->odcid.len + qc->odcid.addrlen);
|
||||
}
|
||||
}
|
||||
else if (!qc) {
|
||||
TRACE_PROTO("No connection on a non Initial packet", QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
|
||||
if (global.cluster_secret && !send_stateless_reset(l, &dgram->saddr, pkt))
|
||||
TRACE_ERROR("stateless reset not sent", QUIC_EV_CONN_LPKT, qc);
|
||||
goto err;
|
||||
}
|
||||
|
||||
pkt->qc = qc;
|
||||
|
||||
out:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_LPKT, qc);
|
||||
return qc;
|
||||
|
||||
err:
|
||||
HA_ATOMIC_INC(&prx_counters->dropped_pkt);
|
||||
TRACE_LEAVE(QUIC_EV_CONN_LPKT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse a QUIC packet from UDP datagram found in <buf> buffer with <end> the
|
||||
* end of this buffer past one byte and populate <pkt> RX packet structure
|
||||
* with the information collected from the packet.
|
||||
@ -5994,22 +6107,20 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
|
||||
|
||||
if (long_header) {
|
||||
uint64_t len;
|
||||
struct quic_cid odcid;
|
||||
const struct quic_cid *token_odcid = NULL; // ODCID received from client token
|
||||
|
||||
TRACE_PROTO("long header packet received", QUIC_EV_CONN_LPKT, qc);
|
||||
TRACE_PROTO("long header packet received", QUIC_EV_CONN_LPKT);
|
||||
if (!quic_packet_read_long_header(&buf, end, pkt)) {
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (pkt->type == QUIC_PACKET_TYPE_0RTT && !l->bind_conf->ssl_conf.early_data) {
|
||||
TRACE_PROTO("0-RTT packet not supported", QUIC_EV_CONN_LPKT, qc);
|
||||
TRACE_PROTO("0-RTT packet not supported", QUIC_EV_CONN_LPKT);
|
||||
drop_no_conn = 1;
|
||||
}
|
||||
else if (pkt->type == QUIC_PACKET_TYPE_INITIAL &&
|
||||
dgram->len < QUIC_INITIAL_PACKET_MINLEN) {
|
||||
TRACE_PROTO("Too short datagram with an Initial packet", QUIC_EV_CONN_LPKT, qc);
|
||||
TRACE_PROTO("Too short datagram with an Initial packet", QUIC_EV_CONN_LPKT);
|
||||
HA_ATOMIC_INC(&prx_counters->too_short_initial_dgram);
|
||||
goto drop;
|
||||
}
|
||||
@ -6020,7 +6131,7 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
|
||||
if (!(pkt->flags & QUIC_FL_RX_PACKET_DGRAM_FIRST) &&
|
||||
(pkt->dcid.len != dgram->dcid_len ||
|
||||
memcmp(dgram->dcid, pkt->dcid.data, pkt->dcid.len))) {
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc);
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
@ -6109,84 +6220,9 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
|
||||
pkt->len = pkt->pn_offset + len;
|
||||
if (drop_no_conn)
|
||||
goto drop_no_conn;
|
||||
|
||||
qc = retrieve_qc_conn_from_cid(pkt, l, &dgram->saddr);
|
||||
if (global.cluster_secret && pkt->token_len) {
|
||||
if (*pkt->token == QUIC_TOKEN_FMT_RETRY) {
|
||||
const struct quic_version *ver = qc ? qc->original_version : qv;
|
||||
if (!quic_retry_token_check(pkt->token, pkt->token_len, ver, &odcid,
|
||||
&pkt->scid, qc, &dgram->saddr)) {
|
||||
HA_ATOMIC_INC(&prx_counters->retry_error);
|
||||
TRACE_PROTO("Wrong retry token",
|
||||
QUIC_EV_CONN_LPKT, qc, NULL, NULL, qv);
|
||||
/* TODO: RFC 9000 8.1.2 A server SHOULD immediately close the connection
|
||||
* with an INVALID_TOKEN error.
|
||||
*/
|
||||
goto drop;
|
||||
}
|
||||
|
||||
token_odcid = &odcid;
|
||||
HA_ATOMIC_INC(&prx_counters->retry_validated);
|
||||
}
|
||||
else {
|
||||
/* TODO: New token check */
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc, NULL, NULL, qv);
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
if (!qc) {
|
||||
int ipv4;
|
||||
|
||||
if (pkt->type != QUIC_PACKET_TYPE_INITIAL) {
|
||||
TRACE_PROTO("Non Initial packet", QUIC_EV_CONN_LPKT, NULL, NULL, NULL, qv);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (global.cluster_secret && !pkt->token_len && !(l->bind_conf->options & BC_O_QUIC_FORCE_RETRY) &&
|
||||
HA_ATOMIC_LOAD(&prx_counters->half_open_conn) >= global.tune.quic_retry_threshold) {
|
||||
TRACE_PROTO("Initial without token, sending retry",
|
||||
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, qv);
|
||||
if (send_retry(l->rx.fd, &dgram->saddr, pkt, qv)) {
|
||||
TRACE_ERROR("Error during Retry generation",
|
||||
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, qv);
|
||||
goto err;
|
||||
}
|
||||
|
||||
HA_ATOMIC_INC(&prx_counters->retry_sent);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* RFC 9000 7.2. Negotiating Connection IDs:
|
||||
* When an Initial packet is sent by a client that has not previously
|
||||
* received an Initial or Retry packet from the server, the client
|
||||
* populates the Destination Connection ID field with an unpredictable
|
||||
* value. This Destination Connection ID MUST be at least 8 bytes in length.
|
||||
*/
|
||||
if (pkt->dcid.len < QUIC_ODCID_MINLEN) {
|
||||
TRACE_PROTO("dropped packet",
|
||||
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, qv);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
pkt->saddr = dgram->saddr;
|
||||
ipv4 = dgram->saddr.ss_family == AF_INET;
|
||||
|
||||
qc = qc_new_conn(qv, ipv4, &pkt->dcid, &pkt->scid, token_odcid,
|
||||
&dgram->daddr, &pkt->saddr, 1,
|
||||
!!pkt->token_len, l);
|
||||
if (qc == NULL)
|
||||
goto drop;
|
||||
|
||||
HA_ATOMIC_INC(&prx_counters->half_open_conn);
|
||||
/* Insert the DCID the QUIC client has chosen (only for listeners) */
|
||||
ebmb_insert(&quic_dghdlrs[tid].odcids, &qc->odcid_node,
|
||||
qc->odcid.len + qc->odcid.addrlen);
|
||||
}
|
||||
|
||||
pkt->qc = qc;
|
||||
}
|
||||
else {
|
||||
TRACE_PROTO("short header packet received", QUIC_EV_CONN_LPKT, qc);
|
||||
TRACE_PROTO("short header packet received", QUIC_EV_CONN_LPKT);
|
||||
if (end - buf < QUIC_HAP_CID_LEN) {
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
|
||||
goto drop;
|
||||
@ -6201,7 +6237,7 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
|
||||
if (!(pkt->flags & QUIC_FL_RX_PACKET_DGRAM_FIRST) &&
|
||||
(pkt->dcid.len != dgram->dcid_len ||
|
||||
memcmp(dgram->dcid, pkt->dcid.data, pkt->dcid.len))) {
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc);
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
@ -6210,17 +6246,15 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
|
||||
pkt->pn_offset = buf - beg;
|
||||
/* A short packet is the last one of a UDP datagram. */
|
||||
pkt->len = end - beg;
|
||||
}
|
||||
|
||||
qc = retrieve_qc_conn_from_cid(pkt, l, &dgram->saddr);
|
||||
if (!qc) {
|
||||
size_t pktlen = end - buf;
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, NULL, pkt, &pktlen);
|
||||
if (global.cluster_secret && !send_stateless_reset(l, &dgram->saddr, pkt))
|
||||
TRACE_ERROR("stateless reset not sent", QUIC_EV_CONN_LPKT, qc);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
pkt->qc = qc;
|
||||
qc = quic_rx_pkt_retrieve_conn(pkt, dgram, dgram->owner);
|
||||
if (!qc) {
|
||||
size_t pktlen = end - buf;
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, NULL, pkt, &pktlen);
|
||||
if (global.cluster_secret && !send_stateless_reset(l, &dgram->saddr, pkt))
|
||||
TRACE_ERROR("stateless reset not sent", QUIC_EV_CONN_LPKT, qc);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (qc->flags & QUIC_FL_CONN_CLOSING) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user