Skip to content

Commit

Permalink
CLEANUP: quic: Add a new module to handle QUIC connection IDs
Browse files Browse the repository at this point in the history
Move quic_cid and quic_connnection_id from quic_conn-t.h to new quic_cid-t.h header.
Move defintions of quic_stateless_reset_token_init(), quic_derive_cid(),
new_quic_cid(), quic_get_cid_tid() and retrieve_qc_conn_from_cid() to quic_cid.c
new C file.
  • Loading branch information
haproxyFred committed Nov 23, 2023
1 parent 4a51dee commit c0daeb4
Show file tree
Hide file tree
Showing 10 changed files with 391 additions and 343 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ OPTIONS_OBJS += src/quic_conn.o src/mux_quic.o src/h3.o src/xprt_quic.o \
src/h3_stats.o src/qmux_http.o src/cfgparse-quic.o \
src/cbuf.o src/quic_cc.o src/quic_cc_nocc.o src/quic_ack.o \
src/quic_trace.o src/quic_cli.o src/quic_ssl.o \
src/quic_rx.o src/quic_tx.o
src/quic_rx.o src/quic_tx.o src/quic_cid.o
endif
ifneq ($(USE_QUIC_OPENSSL_COMPAT),)
Expand Down
37 changes: 37 additions & 0 deletions include/haproxy/quic_cid-t.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef _HAPROXY_QUIC_CID_T_H
#define _HAPROXY_QUIC_CID_T_H

#include <haproxy/quic_tp-t.h>

/* QUIC connection ID maximum length for version 1. */
#define QUIC_CID_MAXLEN 20 /* bytes */

/* QUIC connection id data.
*
* This struct is used by ebmb_node structs as last member of flexible arrays.
* So do not change the order of the member of quic_cid struct.
* <data> member must be the first one.
*/
struct quic_cid {
unsigned char data[QUIC_CID_MAXLEN];
unsigned char len; /* size of QUIC CID */
};

/* QUIC connection id attached to a QUIC connection.
*
* This structure is used to match received packets DCIDs with the
* corresponding QUIC connection.
*/
struct quic_connection_id {
struct eb64_node seq_num;
uint64_t retire_prior_to;
unsigned char stateless_reset_token[QUIC_STATELESS_RESET_TOKEN_LEN];

struct ebmb_node node; /* node for receiver tree, cid.data as key */
struct quic_cid cid; /* CID data */

struct quic_conn *qc; /* QUIC connection using this CID */
uint tid; /* Attached Thread ID for the connection. */
};

#endif /* _HAPROXY_QUIC_CID_T_H */
87 changes: 87 additions & 0 deletions include/haproxy/quic_cid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#ifndef _HAPROXY_QUIC_CID_H
#define _HAPROXY_QUIC_CID_H

#include <import/ebmbtree.h>

#include <haproxy/buf-t.h>
#include <haproxy/chunk.h>
#include <haproxy/quic_conn-t.h>
#include <haproxy/proto_quic.h>

struct quic_connection_id *new_quic_cid(struct eb_root *root,
struct quic_conn *qc,
const struct quic_cid *orig,
const struct sockaddr_storage *addr);
int quic_get_cid_tid(const unsigned char *cid, size_t cid_len,
const struct sockaddr_storage *cli_addr,
unsigned char *pos, size_t len);
struct quic_cid quic_derive_cid(const struct quic_cid *orig,
const struct sockaddr_storage *addr);
struct quic_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
struct listener *l,
struct sockaddr_storage *saddr,
int *new_tid);

/* Copy <src> QUIC CID to <dst>.
* This is the responsibility of the caller to check there is enough room in
* <dst> to copy <src>.
* Always succeeds.
*/
static inline void quic_cid_cpy(struct quic_cid *dst, const struct quic_cid *src)
{
memcpy(dst->data, src->data, src->len);
dst->len = src->len;
}

/* Dump the QUIC connection ID value if present (non null length). Used only for
* debugging purposes.
* Always succeeds.
*/
static inline void quic_cid_dump(struct buffer *buf,
const struct quic_cid *cid)
{
int i;

chunk_appendf(buf, "(%d", cid->len);
if (cid->len)
chunk_appendf(buf, ",");
for (i = 0; i < cid->len; i++)
chunk_appendf(buf, "%02x", cid->data[i]);
chunk_appendf(buf, ")");
}

/* Return tree index where <cid> is stored. */
static inline uchar _quic_cid_tree_idx(const unsigned char *cid)
{
return cid[0];
}

/* Return tree index where <cid> is stored. */
static inline uchar quic_cid_tree_idx(const struct quic_cid *cid)
{
return _quic_cid_tree_idx(cid->data);
}

/* Insert <conn_id> into global CID tree as a thread-safe operation. */
static inline void quic_cid_insert(struct quic_connection_id *conn_id)
{
const uchar idx = quic_cid_tree_idx(&conn_id->cid);
struct quic_cid_tree *tree = &quic_cid_trees[idx];

HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
ebmb_insert(&tree->root, &conn_id->node, conn_id->cid.len);
HA_RWLOCK_WRUNLOCK(QC_CID_LOCK, &tree->lock);
}

/* Remove <conn_id> from global CID tree as a thread-safe operation. */
static inline void quic_cid_delete(struct quic_connection_id *conn_id)
{
const uchar idx = quic_cid_tree_idx(&conn_id->cid);
struct quic_cid_tree __maybe_unused *tree = &quic_cid_trees[idx];

HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
ebmb_delete(&conn_id->node);
HA_RWLOCK_WRUNLOCK(QC_CID_LOCK, &tree->lock);
}

#endif /* _HAPROXY_QUIC_CID_H */
31 changes: 1 addition & 30 deletions include/haproxy/quic_conn-t.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#include <haproxy/openssl-compat.h>
#include <haproxy/mux_quic-t.h>
#include <haproxy/quic_cid-t.h>
#include <haproxy/quic_cc-t.h>
#include <haproxy/quic_loss-t.h>
#include <haproxy/quic_openssl_compat-t.h>
Expand Down Expand Up @@ -61,8 +62,6 @@ typedef unsigned long long ull;
#define QUIC_HAP_CID_LEN 8

/* Common definitions for short and long QUIC packet headers. */
/* QUIC connection ID maximum length for version 1. */
#define QUIC_CID_MAXLEN 20 /* bytes */
/* QUIC original destination connection ID minial length */
#define QUIC_ODCID_MINLEN 8 /* bytes */
/*
Expand Down Expand Up @@ -219,34 +218,6 @@ extern const struct quic_version quic_versions[];
extern const size_t quic_versions_nb;
extern const struct quic_version *preferred_version;

/* QUIC connection id data.
*
* This struct is used by ebmb_node structs as last member of flexible arrays.
* So do not change the order of the member of quic_cid struct.
* <data> member must be the first one.
*/
struct quic_cid {
unsigned char data[QUIC_CID_MAXLEN];
unsigned char len; /* size of QUIC CID */
};

/* QUIC connection id attached to a QUIC connection.
*
* This structure is used to match received packets DCIDs with the
* corresponding QUIC connection.
*/
struct quic_connection_id {
struct eb64_node seq_num;
uint64_t retire_prior_to;
unsigned char stateless_reset_token[QUIC_STATELESS_RESET_TOKEN_LEN];

struct ebmb_node node; /* node for receiver tree, cid.data as key */
struct quic_cid cid; /* CID data */

struct quic_conn *qc; /* QUIC connection using this CID */
uint tid; /* Attached Thread ID for the connection. */
};

/* unused: 0x01 */
/* Flag the packet number space as requiring an ACK frame to be sent. */
#define QUIC_FL_PKTNS_ACK_REQUIRED (1UL << 1)
Expand Down
63 changes: 1 addition & 62 deletions include/haproxy/quic_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <haproxy/listener.h>
#include <haproxy/proto_quic.h>
#include <haproxy/quic_cc.h>
#include <haproxy/quic_cid.h>
#include <haproxy/quic_conn-t.h>
#include <haproxy/quic_enc.h>
#include <haproxy/quic_frame.h>
Expand Down Expand Up @@ -109,17 +110,6 @@ static inline int qc_is_listener(struct quic_conn *qc)
return qc->flags & QUIC_FL_CONN_LISTENER;
}

/* Copy <src> QUIC CID to <dst>.
* This is the responsibility of the caller to check there is enough room in
* <dst> to copy <src>.
* Always succeeds.
*/
static inline void quic_cid_cpy(struct quic_cid *dst, const struct quic_cid *src)
{
memcpy(dst->data, src->data, src->len);
dst->len = src->len;
}

/* Copy <saddr> socket address data into <buf> buffer.
* This is the responsibility of the caller to check the output buffer is big
* enough to contain these socket address data.
Expand Down Expand Up @@ -153,57 +143,6 @@ static inline size_t quic_saddr_cpy(unsigned char *buf,
return p - buf;
}

/* Dump the QUIC connection ID value if present (non null length). Used only for
* debugging purposes.
* Always succeeds.
*/
static inline void quic_cid_dump(struct buffer *buf,
const struct quic_cid *cid)
{
int i;

chunk_appendf(buf, "(%d", cid->len);
if (cid->len)
chunk_appendf(buf, ",");
for (i = 0; i < cid->len; i++)
chunk_appendf(buf, "%02x", cid->data[i]);
chunk_appendf(buf, ")");
}

/* Return tree index where <cid> is stored. */
static inline uchar _quic_cid_tree_idx(const unsigned char *cid)
{
return cid[0];
}

/* Return tree index where <cid> is stored. */
static inline uchar quic_cid_tree_idx(const struct quic_cid *cid)
{
return _quic_cid_tree_idx(cid->data);
}

/* Insert <conn_id> into global CID tree as a thread-safe operation. */
static inline void quic_cid_insert(struct quic_connection_id *conn_id)
{
const uchar idx = quic_cid_tree_idx(&conn_id->cid);
struct quic_cid_tree *tree = &quic_cid_trees[idx];

HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
ebmb_insert(&tree->root, &conn_id->node, conn_id->cid.len);
HA_RWLOCK_WRUNLOCK(QC_CID_LOCK, &tree->lock);
}

/* Remove <conn_id> from global CID tree as a thread-safe operation. */
static inline void quic_cid_delete(struct quic_connection_id *conn_id)
{
const uchar idx = quic_cid_tree_idx(&conn_id->cid);
struct quic_cid_tree __maybe_unused *tree = &quic_cid_trees[idx];

HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
ebmb_delete(&conn_id->node);
HA_RWLOCK_WRUNLOCK(QC_CID_LOCK, &tree->lock);
}

/* Free the CIDs attached to <conn> QUIC connection. */
static inline void free_quic_conn_cids(struct quic_conn *conn)
{
Expand Down
Loading

0 comments on commit c0daeb4

Please sign in to comment.