quic_cid (quic v1.10.0)
View SourceSummary
Functions
Take a NEW_CONNECTION_ID from the peer.
Take the CID carried in the server's preferred_address transport parameter, which has an implicit sequence number of 1 and arrives outside any NEW_CONNECTION_ID (RFC 9000 Section 9.6).
Take a CID for a new path and bind it there in one step.
Match a packet's trailing bytes against the reset tokens the peer gave us. Compared in constant time: the tokens are secret (RFC 9000 Section 10.3.1), so avoid a byte-position timing oracle.
An active, unbound peer CID other than the one in use.
The token advertised for a CID. With a listener-wide secret it is derived, so a restarted listener holding the same secret can recompute it for a connection whose state it has lost. Without one it is random, which no listener can reproduce.
Issue N new CIDs, returning them in issue order for the caller to register and advertise.
The limit we advertise, which bounds how many of the peer's CIDs we retain.
A pool holding our handshake CID as sequence 0, and the limit we advertise, which bounds how many of the peer's CIDs we will retain.
Drop retired peer CIDs. RETIRE_CONNECTION_ID has been sent for them and we will not use them again (RFC 9000 Section 5.1.2).
Fill in the reset token the peer sent in its transport parameters. Sequence 0 exists already, installed when its Initial was adopted; a token alone never creates the entry.
A replacement when the CID we send with has just been retired.
How many more CIDs the peer's limit leaves room for.
Retire a CID we issued, returning it so the caller can drop it from the listener's routing table. A sequence we never issued is a protocol violation the caller reports (RFC 9000 Section 19.16).
Retire one peer CID by value, reporting its sequence number so the caller can announce it. Used when a path stops using a CID, which RFC 9000 Section 5.1.2 says to retire rather than leave outstanding.
Record the peer's handshake CID as its sequence 0, when its Initial is adopted. It counts against the limit we advertised, so it has to be in the pool before any NEW_CONNECTION_ID is counted against that limit.
Adopt the peer's advertised active_connection_id_limit, which bounds how many CIDs we may issue.
Types
Functions
-spec add_peer_cid(pool(), non_neg_integer(), non_neg_integer(), binary(), binary() | undefined) -> {ok, pool(), [non_neg_integer()]} | {duplicate, pool()} | {error, limit_exceeded} | {error, {reuse, non_neg_integer()}}.
Take a NEW_CONNECTION_ID from the peer.
Returns the sequence numbers this frame retires, for the caller to announce. They are captured before the entries are marked, so the announcement does not depend on a status the marking clears. The entries stay in the pool as retired until prune_retired_peer/1, so a retired current DCID can still be replaced first.
-spec add_preferred_address_cid(pool(), binary(), binary() | undefined) -> {ok, pool()} | {error, {collision, non_neg_integer()}} | {error, limit_exceeded}.
Take the CID carried in the server's preferred_address transport parameter, which has an implicit sequence number of 1 and arrives outside any NEW_CONNECTION_ID (RFC 9000 Section 9.6).
Take a CID for a new path and bind it there in one step.
RFC 9000 Section 9.5 forbids the same CID appearing on two paths, so selection and reservation cannot be separate calls: two paths probing at once would otherwise pick the same entry. A bound CID is never offered again, and none is what stops a path being probed at all.
Match a packet's trailing bytes against the reset tokens the peer gave us. Compared in constant time: the tokens are secret (RFC 9000 Section 10.3.1), so avoid a byte-position timing oracle.
An active, unbound peer CID other than the one in use.
The token advertised for a CID. With a listener-wide secret it is derived, so a restarted listener holding the same secret can recompute it for a connection whose state it has lost. Without one it is random, which no listener can reproduce.
Effectful in the no-secret case.
-spec issue(pool(), non_neg_integer(), binary() | undefined) -> {pool(), [{non_neg_integer(), binary(), binary()}]}.
Issue N new CIDs, returning them in issue order for the caller to register and advertise.
Effectful: the CID is random, and so is the reset token when no secret is configured.
-spec local_active_count(pool()) -> non_neg_integer().
-spec local_active_limit(pool()) -> non_neg_integer().
The limit we advertise, which bounds how many of the peer's CIDs we retain.
-spec local_entries(pool()) -> [#cid_entry{seq_num :: non_neg_integer(), cid :: binary(), stateless_reset_token :: binary() | undefined, status :: active | retired, bound_to :: term() | undefined}].
-spec new(binary(), non_neg_integer()) -> pool().
A pool holding our handshake CID as sequence 0, and the limit we advertise, which bounds how many of the peer's CIDs we will retain.
-spec peer_active_count(pool()) -> non_neg_integer().
-spec peer_entries(pool()) -> [#cid_entry{seq_num :: non_neg_integer(), cid :: binary(), stateless_reset_token :: binary() | undefined, status :: active | retired, bound_to :: term() | undefined}].
Drop retired peer CIDs. RETIRE_CONNECTION_ID has been sent for them and we will not use them again (RFC 9000 Section 5.1.2).
Fill in the reset token the peer sent in its transport parameters. Sequence 0 exists already, installed when its Initial was adopted; a token alone never creates the entry.
A replacement when the CID we send with has just been retired.
RFC 9000 Section 5.1.2: keeping a retired DCID makes the peer treat our packets as unroutable, so the switch happens before the retirements are announced. keep means the current DCID is still usable, or the peer retired everything without providing a replacement.
-spec replenish_needed(pool()) -> non_neg_integer().
How many more CIDs the peer's limit leaves room for.
-spec retire_local(pool(), non_neg_integer()) -> {ok, pool(), binary()} | {ok, pool(), undefined} | {error, unissued}.
Retire a CID we issued, returning it so the caller can drop it from the listener's routing table. A sequence we never issued is a protocol violation the caller reports (RFC 9000 Section 19.16).
-spec retire_peer(pool(), binary()) -> {ok, pool(), non_neg_integer()} | not_found.
Retire one peer CID by value, reporting its sequence number so the caller can announce it. Used when a path stops using a CID, which RFC 9000 Section 5.1.2 says to retire rather than leave outstanding.
Total by design: an unknown CID and an already-retired one both answer not_found, so a caller abandoning a CID never has to guard first.
Record the peer's handshake CID as its sequence 0, when its Initial is adopted. It counts against the limit we advertised, so it has to be in the pool before any NEW_CONNECTION_ID is counted against that limit.
-spec set_peer_active_limit(pool(), non_neg_integer()) -> pool().
Adopt the peer's advertised active_connection_id_limit, which bounds how many CIDs we may issue.