1QUIC Connection ID Cache
2========================
3
4The connection ID cache is responsible for managing connection IDs, both local
5and remote.
6
7Remote Connection IDs
8---------------------
9
10For remote connection IDs, we need to be able to:
11
12* add new IDs per connection;
13* pick a non-retired ID associated from those available for a connection and
14* select a connection ID by sequence number and retire that and all older IDs.
15
16The cache will be implemented as a double ended queue as part of the
17QUIC_CONNECTION object.  The queue will be sorted by sequence number
18and must maintain a count of the number of connection IDs present.
19There is no requirement to maintain a global mapping since remote IDs
20are only used when sending packets, not receiving them.
21
22In MVP, a many-to-1 matching of Connection IDs per Connection object
23is required.  Refer third paragraph in [5.1].
24
25When picking a non-retired connection ID for MVP, the youngest available will
26be chosen.
27
28Local Connection IDs
29--------------------
30
31For local connection IDs, we need to be able to:
32
33* generate a new connection ID and associate it with a connection;
34* query if a connection ID is present;
35* for a server, map a connection ID to a QUIC_CONNECTION;
36* drop all connection IDs associated with a QUIC_CONNECTION;
37* select a connection ID by sequence number and retire that and all older IDs
38  and
39* select a connection ID by sequence number and drop that and all older IDs.
40
41All connection IDs issued by our stack must be the same length because
42short form packets include the connection ID but no length byte.  Random
43connection IDs of this length will be allocated.  Note that no additional
44information will be contained in the connection ID.
45
46There will be one global set of local connection IDs, `QUIC_ROUTE_TABLE`,
47which is shared by all connections over all SSL_CTX objects.  This is
48used to dispatch incoming datagrams to their correct destination and
49will be implemented as a dictionary.
50
51### Notes
52
53* For MVP, it would be sufficient to only use a zero length connection ID.
54* For MVP, a connection ID to QUIC_CONNECTION mapping need not be implemented.
55* Post MVP, funnelling all received packets through a single socket is
56  likely to be bottleneck.
57  An alternative would be receiving from <host address, source port> pairs.
58* For MVP, the local connection ID cache need only have one element.
59  I.e. there is no requirement to implement any form of lookup.
60
61Routes
62------
63
64A pair of connection IDs identify a route between the two ends of the
65communication.  This contains the connection IDs of both ends of the
66connection and the common sequence number.  We need to be able to:
67
68* select a connection ID by sequence number and retire that and all older IDs
69  and
70* select a connection ID by sequence number and drop that and all older IDs.
71
72It is likely that operations on local and remote connection IDs can be
73subsumed by the route functionality.
74
75ID Retirement
76-------------
77
78Connection IDs are retired by either a [NEW_CONNECTION_ID] or
79a [RETIRE_CONNECTION_ID] frame and this is acknowledged by a
80RETIRE_CONNECTION_ID or a NEW_CONNECTION_ID frame respectively.
81
82When a retirement frame is received, we can immediately _remove_ the
83IDs covered from our cache and then send back an acknowledgement of
84the retirement.
85
86If we want to retire a frame, we send a retirement frame and mark the
87IDs covered in our cache as _retired_.  This means that we cannot send
88using any of these IDs but can still receive using them.  Once our peer
89acknowledges the retirement, we can _remove_ the IDs.
90
91It is possible to receive out of order packets **after** receiving a
92retirement notification.  It's unclear what to do with these, however
93dropping them seems reasonable.  The alternative would be to maintain
94the route in a _deletable_ state until all packets in flight at the time
95of retirement have been acked.
96
97API
98---
99
100QUIC connection IDs are defined in #18949 but some extra functions
101are available:
102
103```c
104/* QUIC connection ID representation. */
105#define QUIC_MAX_CONN_ID_LEN   20
106
107typedef struct quic_conn_id_st {
108    unsigned char id_len;
109    unsigned char id[QUIC_MAX_CONN_ID_LEN];
110#if 0
111    /* likely required later, although this might not be the ideal location */
112    unsigned char reset_token[16];  /* stateless reset token is per conn ID */
113#endif
114} QUIC_CONN_ID;
115
116static ossl_unused ossl_inline int ossl_quic_conn_id_eq(const QUIC_CONN_ID *a,
117                                                        const QUIC_CONN_ID *b);
118
119/* New functions */
120int ossl_quic_conn_id_set(QUIC_CONN_ID *cid, unsigned char *id,
121                          unsigned int id_len);
122
123int ossl_quic_conn_id_generate(QUIC_CONN_ID *cid);
124```
125
126### Remote Connection ID APIs
127
128```c
129typedef struct quic_remote_conn_id_cache_st QUIC_REMOTE_CONN_ID_CACHE;
130
131/*
132 * Allocate and free a remote connection ID cache
133 */
134QUIC_REMOTE_CONN_ID_CACHE *ossl_quic_remote_conn_id_cache_new(
135        size_t id_limit   /* [active_connection_id_limit] */
136    );
137void ossl_quic_remote_conn_id_cache_free(QUIC_REMOTE_CONN_ID_CACHE *cache);
138
139/*
140 * Add a remote connection ID to the cache
141 */
142int ossl_quic_remote_conn_id_cache_add(QUIC_REMOTE_CONN_ID_CACHE *cache,
143                                       const QUIC_CONNECTION *conn,
144                                       const unsigned char *conn_id,
145                                       size_t conn_id_len,
146                                       uint64_t seq_no);
147
148/*
149 * Query a remote connection for a connection ID.
150 * Each connection can have multiple connection IDs associated with different
151 * routes.  This function returns one of these in a non-specified manner.
152 */
153int ossl_quic_remote_conn_id_cache_get0_conn_id(
154        const QUIC_REMOTE_CONN_ID_CACHE *cache,
155        const QUIC_CONNECTION *conn, QUIC_CONN_ID **cid);
156
157/*
158 * Retire remote connection IDs up to and including the one determined by the
159 * sequence number.
160 */
161int ossl_quic_remote_conn_id_cache_retire(
162        QUIC_REMOTE_CONN_ID_CACHE *cache, uint64_t seq_no);
163
164/*
165 * Remove remote connection IDs up to and including the one determined by the
166 * sequence number.
167 */
168int ossl_quic_remote_conn_id_cache_remove(
169        QUIC_REMOTE_CONN_ID_CACHE *cache, uint64_t seq_no);
170```
171
172### Local Connection ID APIs
173
174```c
175typedef struct quic_local_conn_id_cache_st QUIC_LOCAL_CONN_ID_CACHE;
176
177/*
178 * Allocate and free a local connection ID cache
179 */
180QUIC_LOCAL_CONN_ID_CACHE *ossl_quic_local_conn_id_cache_new(void);
181void ossl_quic_local_conn_id_cache_free(QUIC_LOCAL_CONN_ID_CACHE *cache);
182
183/*
184 * Generate a new random local connection ID and associate it with a connection.
185 * For MVP this could just be a zero length ID.
186 */
187int ossl_quic_local_conn_id_cache_new_conn_id(QUIC_LOCAL_CONN_ID_CACHE *cache,
188                                              QUIC_CONNECTION *conn,
189                                              QUIC_CONN_ID **cid);
190
191/*
192 * Remove a local connection and all associated cached IDs
193 */
194int ossl_quic_local_conn_id_cache_remove_conn(QUIC_LOCAL_CONN_ID_CACHE *cache,
195                                              const QUIC_CONNECTION *conn);
196
197/*
198 * Lookup a local connection by ID.
199 * Returns the connection or NULL if absent.
200 */
201QUIC_CONNECTION *ossl_quic_local_conn_id_cache_get0_conn(
202        const QUIC_LOCAL_CONN_ID_CACHE *cache,
203        const unsigned char *conn_id, size_t conn_id_len);
204
205/*
206 * Retire local connection IDs up to and including the one specified by the
207 * sequence number.
208 */
209int ossl_quic_local_conn_id_cache_retire(
210        QUIC_LOCAL_CONN_ID_CACHE *cache, uint64_t from_seq_no);
211
212/*
213 * Remove local connection IDs up to and including the one specified by the
214 * sequence number.
215 */
216int ossl_quic_local_conn_id_cache_remove(
217        QUIC_LOCAL_CONN_ID_CACHE *cache, uint64_t from_seq_no);
218```
219
220### Routes
221
222Additional status and source information is also included.
223
224```c
225typedef struct quic_route_st QUIC_ROUTE;
226typedef struct quic_route_table QUIC_ROUTE_TABLE;
227
228struct quic_route_st {
229    QUIC_CONNECTION *conn;
230    QUIC_CONN_ID     local;
231    QUIC_CONN_ID     remote;
232    uint64_t         seq_no;        /* Sequence number for both ends */
233    unsigned int     retired : 1;   /* Connection ID has been retired */
234#if 0
235    /* Later will require */
236    BIO_ADDR         remote_address;/* remote source address */
237#endif
238};
239
240QUIC_ROUTE_TABLE *ossl_quic_route_table_new(void);
241void ossl_quic_route_table_free(QUIC_ROUTE_TABLE *routes);
242```
243
244### Add route to route table
245
246```c
247int ossl_route_table_add_route(QUIC_ROUTE_TABLE *cache,
248                               QUIC_ROUTE_TABLE *route);
249```
250
251### Route query
252
253```c
254/*
255 * Query a route table entry by either local or remote ID
256 */
257QUIC_ROUTE *ossl_route_table_get0_route_from_local(
258        const QUIC_ROUTE_TABLE *cache,
259        const unsigned char *conn_id, size_t conn_id_len);
260QUIC_ROUTE *ossl_route_table_get0_route_from_remote(
261        const QUIC_ROUTE_TABLE *cache,
262        const unsigned char *conn_id, size_t conn_id_len);
263```
264
265### Route retirement
266
267```c
268/*
269 * Retire by sequence number up to and including the one specified.
270 */
271int ossl_quic_route_table_retire(QUIC_ROUTE_TABLE *routes,
272                                 QUIC_CONNECTION *conn,
273                                 uint64_t seq_no);
274
275/*
276 * Delete by sequence number up to and including the one specified.
277 */
278int ossl_quic_route_table_remove(QUIC_ROUTE_TABLE *routes,
279                                 QUIC_CONNECTION *conn,
280                                 uint64_t seq_no);
281```
282
283[5.1]: (https://datatracker.ietf.org/doc/html/rfc9000#section-5.1)
284[active_connection_id_limit]: (https://datatracker.ietf.org/doc/html/rfc9000#section-18.2)
285[NEW_CONNECTION_ID]: (https://datatracker.ietf.org/doc/html/rfc9000#section-19.15)
286[RETIRE_CONNECTION_ID]: (https://datatracker.ietf.org/doc/html/rfc9000#section-19.16)
287[retired]: (https://datatracker.ietf.org/doc/html/rfc9000#section-5.1.2)
288