mirror of
https://github.com/haproxy/haproxy.git
synced 2026-03-06 23:31:08 -05:00
QUIC CIDs are stored in a global tree. Prior to this patch, CIDs used on both frontend and backend sides were mixed together. This patch implement CID storage separation between FE and BE sides. The original tre quic_cid_trees is splitted as quic_fe_cid_trees/quic_be_cid_trees. This patch should reduce contention between frontend and backend usages. Also, it should reduce the risk of random CID collision.
119 lines
3.9 KiB
C
119 lines
3.9 KiB
C
#ifndef _HAPROXY_QUIC_CID_H
|
|
#define _HAPROXY_QUIC_CID_H
|
|
|
|
#ifdef USE_QUIC
|
|
#ifndef USE_OPENSSL
|
|
#error "Must define USE_OPENSSL"
|
|
#endif
|
|
|
|
#include <import/ebmbtree.h>
|
|
|
|
#include <haproxy/buf-t.h>
|
|
#include <haproxy/chunk.h>
|
|
#include <haproxy/quic_conn-t.h>
|
|
#include <haproxy/quic_cid-t.h>
|
|
#include <haproxy/quic_rx-t.h>
|
|
#include <haproxy/proto_quic.h>
|
|
|
|
extern struct quic_cid_tree *quic_fe_cid_trees;
|
|
extern struct quic_cid_tree *quic_be_cid_trees;
|
|
|
|
struct quic_connection_id *quic_cid_alloc(enum quic_cid_side side);
|
|
|
|
int quic_cid_generate_random(struct quic_connection_id *conn_id);
|
|
int quic_cid_generate_from_hash(struct quic_connection_id *conn_id, uint64_t hash64);
|
|
int quic_cid_derive_from_odcid(struct quic_connection_id *conn_id,
|
|
const struct quic_cid *orig,
|
|
const struct sockaddr_storage *addr);
|
|
|
|
void quic_cid_register_seq_num(struct quic_connection_id *conn_id,
|
|
struct quic_conn *qc);
|
|
|
|
int quic_cid_insert(struct quic_connection_id *conn_id, int *new_tid);
|
|
int quic_cmp_cid_conn(const unsigned char *cid, size_t cid_len,
|
|
struct quic_conn *qc);
|
|
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_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
|
|
struct sockaddr_storage *saddr,
|
|
int *new_tid);
|
|
int qc_build_new_connection_id_frm(struct quic_conn *qc,
|
|
struct quic_connection_id *conn_id);
|
|
|
|
/* 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);
|
|
}
|
|
|
|
/* Returns the tree instance responsible for <conn_id> storage. */
|
|
static inline struct quic_cid_tree *quic_cid_get_tree(const struct quic_connection_id *conn_id)
|
|
{
|
|
const int tree_idx = quic_cid_tree_idx(&conn_id->cid);
|
|
return conn_id->side == QUIC_CID_SIDE_FE ?
|
|
&quic_fe_cid_trees[tree_idx] : &quic_be_cid_trees[tree_idx];
|
|
}
|
|
|
|
/* Remove <conn_id> from global CID tree as a thread-safe operation. */
|
|
static inline void quic_cid_delete(struct quic_connection_id *conn_id)
|
|
{
|
|
struct quic_cid_tree __maybe_unused *tree = quic_cid_get_tree(conn_id);
|
|
|
|
HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
|
|
ebmb_delete(&conn_id->node);
|
|
HA_RWLOCK_WRUNLOCK(QC_CID_LOCK, &tree->lock);
|
|
}
|
|
|
|
/* Copy <src> new connection ID information to <dst> NEW_CONNECTION_ID frame.
|
|
* Always succeeds.
|
|
*/
|
|
static inline void quic_connection_id_to_frm_cpy(struct quic_frame *dst,
|
|
struct quic_connection_id *src)
|
|
{
|
|
struct qf_new_connection_id *ncid_frm = &dst->new_connection_id;
|
|
|
|
ncid_frm->seq_num = src->seq_num.key;
|
|
ncid_frm->retire_prior_to = src->retire_prior_to;
|
|
ncid_frm->cid.len = src->cid.len;
|
|
ncid_frm->cid.data = src->cid.data;
|
|
ncid_frm->stateless_reset_token = src->stateless_reset_token;
|
|
}
|
|
|
|
#endif /* USE_QUIC */
|
|
#endif /* _HAPROXY_QUIC_CID_H */
|