VirtualBox

source: vbox/trunk/src/libs/openssl-3.3.2/include/internal/quic_lcidm.h@ 108403

最後變更 在這個檔案從108403是 108206,由 vboxsync 提交於 5 週 前

openssl-3.3.2: Exported all files to OSE and removed .scm-settings ​bugref:10757

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 10.7 KB
 
1/*
2* Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
3*
4* Licensed under the Apache License 2.0 (the "License"). You may not use
5* this file except in compliance with the License. You can obtain a copy
6* in the file LICENSE in the source distribution or at
7* https://www.openssl.org/source/license.html
8*/
9
10#ifndef OSSL_INTERNAL_QUIC_LCIDM_H
11# define OSSL_INTERNAL_QUIC_LCIDM_H
12# pragma once
13
14# include "internal/e_os.h"
15# include "internal/time.h"
16# include "internal/quic_types.h"
17# include "internal/quic_wire.h"
18# include "internal/quic_predef.h"
19
20# ifndef OPENSSL_NO_QUIC
21
22/*
23 * QUIC Local Connection ID Manager
24 * ================================
25 *
26 * This manages connection IDs for the RX side, which is to say that it issues
27 * local CIDs (LCIDs) to a peer which that peer can then use to address us via a
28 * packet DCID. This is as opposed to CID management for the TX side, which
29 * determines which CIDs we use to transmit based on remote CIDs (RCIDs) the
30 * peer sent to us.
31 *
32 * An opaque pointer can be associated with each LCID. Pointer identity
33 * (equality) is used to distinguish distinct connections.
34 *
35 * LCIDs fall into three categories:
36 *
37 * 1. A client's Initial ODCID (1)
38 * 2. Our local Initial SCID (1)
39 * 3. A CID issued via a NEW_CONNECTION_ID frame (n)
40 * 4. A server's Retry SCID (0..1)
41 *
42 * (1) is enrolled using ossl_quic_lcidm_enrol_odcid() and retired by the time
43 * of handshake completion at the latest. It is needed in case the first
44 * response packet from a server is lost and the client keeps using its Initial
45 * ODCID. There is never more than one of these, and no sequence number is
46 * associated with this temporary LCID.
47 *
48 * (2) is created by a client when it begins connecting, or by a server when it
49 * responds to a new connection request. In the latter case, it is generated by
50 * the server as the preferred DCID for traffic directed towards it. A client
51 * should switch to using this as a RCID as soon as it receives a valid packet
52 * from the server. This LCID has a sequence number of 0.
53 *
54 * (3) is created when we issue a NEW_CONNECTION_ID frame. Arbitrarily many of
55 * these can exist.
56 *
57 * (4) is a special case. When a server issues a retry it generates a new SCID
58 * much as it does for (2). However since retries are supposed to be stateless,
59 * we don't actually register it as an LCID. When the client subsequently
60 * replies with an Initial packet with token in response to the Retry, the
61 * server will handle this as a new connection attempt due to not recognising
62 * the DCID, which is what we want anyway. (The Retry SCID is subsequently
63 * validated as matching the new Initial ODCID via attestation in the encrypted
64 * contents of the opaque retry token.) Thus, the LCIDM is not actually involved
65 * at all here.
66 *
67 * Retirement is as follows:
68 *
69 * (1) is retired automatically when we know it won't be needed anymore. This is
70 * when the handshake is completed at the latest, and could potentially be
71 * earlier.
72 *
73 * Both (2) and (3) are retired normally via RETIRE_CONNECTION_ID frames, as it
74 * has a sequence number of 0.
75 *
76 *
77 * ODCID Peculiarities
78 * -------------------
79 *
80 * Almost all LCIDs are issued by the receiver responsible for routing them,
81 * which means that almost all LCIDs will have the same length (specified in
82 * lcid_len below). The only exception to this is (1); the ODCID is the only
83 * case where we recognise an LCID we didn't ourselves generate. Since an ODCID
84 * is chosen by the peer, it can be any length and doesn't necessarily match the
85 * length we use for LCIDs we generate ourselves.
86 *
87 * Since DCID decoding for short-header packets requires an implicitly known
88 * DCID length, it logically follows that an ODCID can never be used in a 1-RTT
89 * packet. This is fine as by the time the 1-RTT EL is reached the peer should
90 * already have switched away from the ODCID to a CID we generated ourselves,
91 * and if this has not happened we can consider that a protocol violation.
92 *
93 * In any case, this means that the LCIDM must necessarily support LCIDs of
94 * different lengths, even if it always generates LCIDs of a given length.
95 *
96 * An ODCID has no sequence number associated with it. It is the only CID to
97 * lack one.
98 */
99
100/*
101 * Creates a new LCIDM. lcid_len is the length to use for LCIDs in bytes, which
102 * may be zero.
103 *
104 * Returns NULL on failure.
105 */
106QUIC_LCIDM *ossl_quic_lcidm_new(OSSL_LIB_CTX *libctx, size_t lcid_len);
107
108/* Frees a LCIDM. */
109void ossl_quic_lcidm_free(QUIC_LCIDM *lcidm);
110
111/* Gets the local CID length this LCIDM was configured to use. */
112size_t ossl_quic_lcidm_get_lcid_len(const QUIC_LCIDM *lcidm);
113
114/*
115 * Determines the number of active LCIDs (i.e,. LCIDs which can be used for
116 * reception) currently associated with the given opaque pointer.
117 */
118size_t ossl_quic_lcidm_get_num_active_lcid(const QUIC_LCIDM *lcidm,
119 void *opaque);
120
121/*
122 * Enrol an Initial ODCID sent by the peer. This is the DCID in the first
123 * Initial packet sent by a client. When we receive a client's first Initial
124 * packet, we immediately respond with our own SCID (generated using
125 * ossl_quic_lcidm_generate_initial) to tell the client to switch to using that,
126 * so ideally the ODCID will only be used for a single packet. However since
127 * that response might be lost, we also need to accept additional packets using
128 * the ODCID and need to make sure they get routed to the same connection and
129 * not interpreted as another new connection attempt. Thus before the CID
130 * switchover is confirmed, we also have to handle incoming packets addressed to
131 * the ODCID. This function is used to temporarily enroll the ODCID for a
132 * connection. Such a LCID is considered to have a sequence number of
133 * LCIDM_ODCID_SEQ_NUM internally for our purposes.
134 *
135 * Note that this is the *only* circumstance where we recognise an LCID we did
136 * not generate ourselves, or allow an LCID with a different length to lcid_len.
137 *
138 * An ODCID MUST be at least 8 bytes in length (RFC 9000 s. 7.2).
139 *
140 * This function may only be called once for a given connection.
141 * Returns 1 on success or 0 on failure.
142 */
143int ossl_quic_lcidm_enrol_odcid(QUIC_LCIDM *lcidm, void *opaque,
144 const QUIC_CONN_ID *initial_odcid);
145
146/*
147 * Retire a previously enrolled ODCID for a connection. This is generally done
148 * when we know the peer won't be using it any more (when the handshake is
149 * completed at the absolute latest, possibly earlier).
150 *
151 * Returns 1 if there was an enrolled ODCID which was retired and 0 if there was
152 * not or on other failure.
153 */
154int ossl_quic_lcidm_retire_odcid(QUIC_LCIDM *lcidm, void *opaque);
155
156/*
157 * Create the first LCID for a given opaque pointer. The generated LCID is
158 * written to *initial_lcid and associated with the given opaque pointer.
159 *
160 * After this function returns successfully, the caller can for example
161 * register the new LCID with a DEMUX.
162 *
163 * May not be called more than once for a given opaque pointer value.
164 */
165int ossl_quic_lcidm_generate_initial(QUIC_LCIDM *lcidm,
166 void *opaque,
167 QUIC_CONN_ID *initial_lcid);
168
169/*
170 * Create a subsequent LCID for a given opaque pointer. The information needed
171 * for a NEW_CONN_ID frame informing the peer of the new LCID, including the
172 * LCID itself, is written to *ncid_frame.
173 *
174 * ncid_frame->stateless_reset is not initialised and the caller is responsible
175 * for setting it.
176 *
177 * After this function returns successfully, the caller can for example
178 * register the new LCID with a DEMUX and queue the NEW_CONN_ID frame.
179 */
180int ossl_quic_lcidm_generate(QUIC_LCIDM *lcidm,
181 void *opaque,
182 OSSL_QUIC_FRAME_NEW_CONN_ID *ncid_frame);
183
184/*
185 * Retire up to one LCID for a given opaque pointer value. Called repeatedly to
186 * handle a RETIRE_CONN_ID frame.
187 *
188 * If containing_pkt_dcid is non-NULL, this function enforces the requirement
189 * that a CID not be retired by a packet using that CID as the DCID. If
190 * containing_pkt_dcid is NULL, this check is skipped.
191 *
192 * If a LCID is retired as a result of a call to this function, the LCID which
193 * was retired is written to *retired_lcid, the sequence number of the LCID is
194 * written to *retired_seq_num and *did_retire is set to 1. Otherwise,
195 * *did_retire is set to 0. This enables a caller to e.g. unregister the LCID
196 * from a DEMUX. A caller should call this function repeatedly until the
197 * function returns with *did_retire set to 0.
198 *
199 * This call is likely to cause the value returned by
200 * ossl_quic_lcidm_get_num_active_lcid() to go down. A caller may wish to call
201 * ossl_quic_lcidm_generate() repeatedly to bring the number of active LCIDs
202 * back up to some threshold in response after calling this function.
203 *
204 * Returns 1 on success and 0 on failure. If arguments are valid but zero LCIDs
205 * are retired, this is considered a success condition.
206 */
207int ossl_quic_lcidm_retire(QUIC_LCIDM *lcidm,
208 void *opaque,
209 uint64_t retire_prior_to,
210 const QUIC_CONN_ID *containing_pkt_dcid,
211 QUIC_CONN_ID *retired_lcid,
212 uint64_t *retired_seq_num,
213 int *did_retire);
214
215/*
216 * Cull all LCIDM state relating to a given opaque pointer value. This is useful
217 * if connection state is spontaneously freed. The caller is responsible for
218 * e.g. DEMUX state updates.
219 */
220int ossl_quic_lcidm_cull(QUIC_LCIDM *lcidm, void *opaque);
221
222/*
223 * Lookup a LCID. If the LCID is found, writes the associated opaque pointer to
224 * *opaque and the associated sequence number to *seq_num. Returns 1 on success
225 * and 0 if an entry is not found. An output argument may be set to NULL if its
226 * value is not required.
227 *
228 * If the LCID is for an Initial ODCID, *seq_num is set to
229 * LCIDM_ODCID_SEQ_NUM.
230 */
231#define LCIDM_ODCID_SEQ_NUM UINT64_MAX
232
233int ossl_quic_lcidm_lookup(QUIC_LCIDM *lcidm,
234 const QUIC_CONN_ID *lcid,
235 uint64_t *seq_num,
236 void **opaque);
237
238/*
239 * Debug call to manually remove a specific LCID. Should not be needed in normal
240 * usage. Returns 1 if the LCID was successfully found and removed and 0
241 * otherwise.
242 */
243int ossl_quic_lcidm_debug_remove(QUIC_LCIDM *lcidm,
244 const QUIC_CONN_ID *lcid);
245
246/*
247 * Debug call to manually add a numbered LCID with a specific CID value and
248 * sequence number. Should not be needed in normal usage. Returns 1 on success
249 * and 0 on failure.
250 */
251int ossl_quic_lcidm_debug_add(QUIC_LCIDM *lcidm, void *opaque,
252 const QUIC_CONN_ID *lcid,
253 uint64_t seq_num);
254
255# endif
256
257#endif
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette