#include <import/eb64tree.h>
#include <haproxy/api-t.h>
#include <haproxy/quic_cid-t.h>
+#include <haproxy/quic_sock-t.h>
#include <inttypes.h>
#include <sys/socket.h>
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;
};
#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;
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 */
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)) {
*/
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) {
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);
/* 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);
}
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;
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);
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);
* 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;
}
*/
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;
}
}
/* 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;
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;
}
{
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.
}
/* 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)) {
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) {
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 */