diff --git a/include/haproxy/quic_rx-t.h b/include/haproxy/quic_rx-t.h index 686e6fff1..9bfe6fbb1 100644 --- a/include/haproxy/quic_rx-t.h +++ b/include/haproxy/quic_rx-t.h @@ -7,6 +7,7 @@ extern struct pool_head *pool_head_quic_rx_packet; #include #include #include +#include #include #include @@ -52,7 +53,7 @@ struct quic_rx_packet { struct eb64_node pn_node; volatile unsigned int refcnt; /* Source address of this packet. */ - struct sockaddr_storage saddr; + union sockaddr_in46 saddr; unsigned int flags; unsigned int time_received; }; diff --git a/include/haproxy/quic_sock-t.h b/include/haproxy/quic_sock-t.h index 735801757..19bf8d51e 100644 --- a/include/haproxy/quic_sock-t.h +++ b/include/haproxy/quic_sock-t.h @@ -21,6 +21,11 @@ struct quic_accept_queue { #define QUIC_DGRAM_FL_REJECT 0x00000001 #define QUIC_DGRAM_FL_SEND_RETRY 0x00000002 +union sockaddr_in46 { + struct sockaddr_in in4; + struct sockaddr_in6 in6; +}; + /* QUIC datagram */ struct quic_dgram { enum obj_type obj_type; @@ -29,8 +34,8 @@ struct quic_dgram { size_t len; size_t dcid_off; size_t dcid_len; - struct sockaddr_storage saddr; - struct sockaddr_storage daddr; + union sockaddr_in46 saddr; + union sockaddr_in46 daddr; struct quic_conn *qc; int flags; /* QUIC_DGRAM_FL_* values */ diff --git a/src/quic_retry.c b/src/quic_retry.c index 2ac981034..23b74d8fc 100644 --- a/src/quic_retry.c +++ b/src/quic_retry.c @@ -283,7 +283,8 @@ int quic_retry_token_check(struct quic_rx_packet *pkt, goto err; } - aadlen = quic_generate_retry_token_aad(aad, qv->num, &pkt->scid, &dgram->saddr); + aadlen = quic_generate_retry_token_aad(aad, qv->num, &pkt->scid, + (struct sockaddr_storage *)&dgram->saddr); salt = token + tokenlen - QUIC_RETRY_TOKEN_SALTLEN; if (!quic_tls_derive_retry_token_secret(EVP_sha256(), key, sizeof key, iv, sizeof iv, salt, QUIC_RETRY_TOKEN_SALTLEN, sec, seclen)) { diff --git a/src/quic_rules.c b/src/quic_rules.c index d73a4a7e4..55ccb899c 100644 --- a/src/quic_rules.c +++ b/src/quic_rules.c @@ -28,8 +28,8 @@ int quic_init_exec_rules(struct listener *li, struct quic_dgram *dgram) */ rule_sess.fe = px; rule_sess.listener = li; - rule_sess.src = &dgram->saddr; - rule_sess.dst = &dgram->daddr; + rule_sess.src = (struct sockaddr_storage *)&dgram->saddr; + rule_sess.dst = (struct sockaddr_storage *)&dgram->daddr; rule_sess.origin = &dgram->obj_type; list_for_each_entry(rule, &px->quic_init_rules, list) { diff --git a/src/quic_rx.c b/src/quic_rx.c index 4f2cb14a9..6c1c2733b 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -1753,7 +1753,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt, prx = l->bind_conf->frontend; prx_counters = EXTRA_COUNTERS_GET(prx->extra_counters_fe, &quic_stats_module); - qc = retrieve_qc_conn_from_cid(pkt, &dgram->saddr, new_tid); + qc = retrieve_qc_conn_from_cid(pkt, (struct sockaddr_storage *)&dgram->saddr, new_tid); /* quic_conn must be set to NULL if bind on another thread. */ BUG_ON_HOT(qc && *new_tid != -1); @@ -1788,7 +1788,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt, /* Validate the token, retry or not only when connection is unknown. */ if (!quic_token_validate(pkt, dgram, l, qc, &token_odcid)) { if (dgram->flags & QUIC_DGRAM_FL_SEND_RETRY) { - if (send_retry(l->rx.fd, &dgram->saddr, pkt, pkt->version)) { + if (send_retry(l->rx.fd, (struct sockaddr_storage *)&dgram->saddr, pkt, pkt->version)) { TRACE_ERROR("Error during Retry generation", QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version); } @@ -1818,7 +1818,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt, 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)) { + if (send_retry(l->rx.fd, (struct sockaddr_storage *)&dgram->saddr, pkt, pkt->version)) { TRACE_ERROR("Error during Retry generation", QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version); goto out; @@ -1850,7 +1850,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt, goto err; } - if (quic_cid_derive_from_odcid(conn_id, &pkt->dcid, &pkt->saddr)) { + if (quic_cid_derive_from_odcid(conn_id, &pkt->dcid, (struct sockaddr_storage *)&pkt->saddr)) { TRACE_ERROR("error on CID generation", QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version); pool_free(pool_head_quic_connection_id, conn_id); @@ -1868,8 +1868,9 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt, pool_free(pool_head_quic_connection_id, conn_id); } else { - qc = qc_new_conn(l, pkt, &token_odcid, - NULL, conn_id, &dgram->daddr, &pkt->saddr); + qc = qc_new_conn(l, pkt, &token_odcid, NULL, conn_id, + (struct sockaddr_storage *)&dgram->daddr, + (struct sockaddr_storage *)&pkt->saddr); if (qc == NULL) { quic_cid_delete(conn_id); /* Removes CID from global tree as it points to a NULL qc. */ pool_free(pool_head_quic_connection_id, conn_id); @@ -1896,7 +1897,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt, * emits stateless_reset_token in its TPs. */ TRACE_PROTO("RX non Initial pkt without connection", QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version); - if (!send_stateless_reset(l, &dgram->saddr, pkt)) + if (!send_stateless_reset(l, (struct sockaddr_storage *)&dgram->saddr, pkt)) TRACE_ERROR("stateless reset not sent", QUIC_EV_CONN_LPKT, qc); goto err; } @@ -1993,7 +1994,7 @@ static int quic_rx_pkt_parse(struct quic_conn *qc, struct quic_rx_packet *pkt, */ if (l && !pkt->version) { /* unsupported version, send Negotiation packet */ - if (send_version_negotiation(l->rx.fd, &dgram->saddr, pkt)) { + if (send_version_negotiation(l->rx.fd, (struct sockaddr_storage *)&dgram->saddr, pkt)) { TRACE_ERROR("VN packet not sent", QUIC_EV_CONN_LPKT); goto drop_silent; } @@ -2489,8 +2490,10 @@ int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *from_qc, } /* Detect QUIC connection migration. */ - if (li && ipcmp(&qc->peer_addr, &dgram->saddr, 1)) { - if (qc_handle_conn_migration(qc, &dgram->saddr, &dgram->daddr)) { + if (li && ipcmp(&qc->peer_addr, (struct sockaddr_storage *)&dgram->saddr, 1)) { + if (qc_handle_conn_migration(qc, + (struct sockaddr_storage *)&dgram->saddr, + (struct sockaddr_storage *)&dgram->daddr)) { /* Skip the entire datagram. */ TRACE_ERROR("error during connection migration, datagram dropped", QUIC_EV_CONN_LPKT, qc); pkt->len = end - pos; diff --git a/src/quic_sock.c b/src/quic_sock.c index ea9a8e0e3..4620e612f 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -267,14 +267,16 @@ static void quic_dgram_init(struct quic_dgram *dgram, struct sockaddr_storage *saddr, struct sockaddr_storage *daddr) { + BUG_ON_HOT(!is_inet_addr(saddr) || !is_inet_addr(daddr)); + dgram->obj_type = OBJ_TYPE_DGRAM; dgram->owner = owner; dgram->buf = pos; dgram->len = len; dgram->dcid_off = dcid_off; dgram->dcid_len = dcid_len; - dgram->saddr = *saddr; - dgram->daddr = *daddr; + memcpy(&dgram->saddr, saddr, sizeof(dgram->saddr)); + memcpy(&dgram->daddr, daddr, sizeof(dgram->daddr)); dgram->qc = NULL; dgram->flags = 0; } @@ -432,7 +434,8 @@ int quic_dgram_requeue(struct quic_dgram *dgram, int cid_tid) { return quic_dgram_write(dgram->buf, dgram->len, dgram->owner, dgram->dcid_off, dgram->dcid_len, - &dgram->saddr, &dgram->daddr, cid_tid); + (struct sockaddr_storage *)&dgram->saddr, + (struct sockaddr_storage *)&dgram->daddr, cid_tid); } /* Attempt to push a datagram to its handler thread. diff --git a/src/quic_token.c b/src/quic_token.c index 9c1d69cd1..5200225ef 100644 --- a/src/quic_token.c +++ b/src/quic_token.c @@ -135,7 +135,7 @@ int quic_token_check(struct quic_rx_packet *pkt, } /* Generate the AAD. */ - aadlen = ipaddrcpy(aad, &dgram->saddr); + aadlen = ipaddrcpy(aad, (struct sockaddr_storage *)&dgram->saddr); rand = token + tokenlen - QUIC_TOKEN_RAND_DLEN; if (!quic_tls_derive_token_secret(EVP_sha256(), key, sizeof key, iv, sizeof iv, rand, QUIC_TOKEN_RAND_DLEN, sec, seclen)) { diff --git a/src/quic_trace.c b/src/quic_trace.c index 2dd12b805..21d8bc72c 100644 --- a/src/quic_trace.c +++ b/src/quic_trace.c @@ -606,6 +606,7 @@ static void quic_trace(enum trace_level level, uint64_t mask, const struct trace if (mask & QUIC_EV_CONN_RCV) { int i; const struct quic_dgram *dgram = a2; + const struct sockaddr_storage *saddr, *daddr; char bufaddr[INET6_ADDRSTRLEN], bufport[6]; if (qc) { @@ -617,14 +618,15 @@ static void quic_trace(enum trace_level level, uint64_t mask, const struct trace if (dgram) { chunk_appendf(&trace_buf, " dgram.len=%zu", dgram->len); /* Socket */ - if (dgram->saddr.ss_family == AF_INET || - dgram->saddr.ss_family == AF_INET6) { - addr_to_str(&dgram->saddr, bufaddr, sizeof(bufaddr)); - port_to_str(&dgram->saddr, bufport, sizeof(bufport)); + saddr = (struct sockaddr_storage *)&dgram->saddr; + daddr = (struct sockaddr_storage *)&dgram->daddr; + if (saddr->ss_family == AF_INET || saddr->ss_family == AF_INET6) { + addr_to_str(saddr, bufaddr, sizeof(bufaddr)); + port_to_str(saddr, bufport, sizeof(bufport)); chunk_appendf(&trace_buf, "saddr=%s:%s ", bufaddr, bufport); - addr_to_str(&dgram->daddr, bufaddr, sizeof(bufaddr)); - port_to_str(&dgram->daddr, bufport, sizeof(bufport)); + addr_to_str(daddr, bufaddr, sizeof(bufaddr)); + port_to_str(daddr, bufport, sizeof(bufport)); chunk_appendf(&trace_buf, "daddr=%s:%s ", bufaddr, bufport); } /* DCID */