summaryrefslogtreecommitdiffstats
path: root/include/haproxy/quic_cid.h
blob: 482a020e18620ac4c9fb85fc50bf83d851009087 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#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_rx-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 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);
}

/* 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);
}

/* 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 */