quic_lb (quic v1.3.0)
View SourceQUIC Load Balancer Connection ID encoding and decoding.
This module implements RFC 9312 Connection ID encoding schemes that allow load balancers to route QUIC packets to the correct server based on server identity encoded in the Connection ID.
CID Format
The first byte contains: - CR (Config Rotation): 3 bits identifying the configuration - Length: 5 bits (CID length - 1, so 0-19 maps to 1-20 bytes)
+--------+----------------+--------+
| CR:3 | Server ID | Nonce |
| Len:5 | (1-15 bytes) | (4-18) |
+--------+----------------+--------+
Algorithms
1. Plaintext: No encryption, server_id visible in CID 2. Stream Cipher: AES-128-CTR encrypts first octet + server_id 3. Block Cipher: AES-128-ECB with Feistel network for non-16-byte
Summary
Functions
Extract the server ID from a CID.
Calculate the expected CID length from configuration.
Generate a CID using the configuration. Uses a random nonce.
Generate a CID with an explicit nonce.
Get the config rotation bits from a CID's first byte.
Check if a CID is LB-routable (CR != 0b111).
Create a CID generation configuration from options map.
Create a new LB configuration from options map.
Validate an LB configuration.
Functions
-spec decode_server_id(binary(), #lb_config{config_rotation :: 0..6, algorithm :: plaintext | stream_cipher | block_cipher, server_id :: binary(), server_id_len :: 1..15, nonce_len :: 4..18, key :: binary() | undefined}) -> {ok, binary()} | {error, term()}.
Extract the server ID from a CID.
-spec expected_cid_len(#lb_config{config_rotation :: 0..6, algorithm :: plaintext | stream_cipher | block_cipher, server_id :: binary(), server_id_len :: 1..15, nonce_len :: 4..18, key :: binary() | undefined}) -> pos_integer().
Calculate the expected CID length from configuration.
-spec generate_cid(#cid_config{lb_config :: #lb_config{config_rotation :: 0..6, algorithm :: plaintext | stream_cipher | block_cipher, server_id :: binary(), server_id_len :: 1..15, nonce_len :: 4..18, key :: binary() | undefined} | undefined, cid_len :: 1..20, reset_secret :: binary() | undefined}) -> binary().
Generate a CID using the configuration. Uses a random nonce.
-spec generate_cid(#cid_config{lb_config :: #lb_config{config_rotation :: 0..6, algorithm :: plaintext | stream_cipher | block_cipher, server_id :: binary(), server_id_len :: 1..15, nonce_len :: 4..18, key :: binary() | undefined} | undefined, cid_len :: 1..20, reset_secret :: binary() | undefined}, binary()) -> binary().
Generate a CID with an explicit nonce.
-spec get_config_rotation(binary()) -> 0..7.
Get the config rotation bits from a CID's first byte.
Check if a CID is LB-routable (CR != 0b111).
-spec new_cid_config(map()) -> {ok, #cid_config{lb_config :: #lb_config{config_rotation :: 0..6, algorithm :: plaintext | stream_cipher | block_cipher, server_id :: binary(), server_id_len :: 1..15, nonce_len :: 4..18, key :: binary() | undefined} | undefined, cid_len :: 1..20, reset_secret :: binary() | undefined}} | {error, term()}.
Create a CID generation configuration from options map.
Options: - lb_config: #lb_config{} | undefined - LB configuration - cid_len: 1..20 (default: 8) - Target CID length - reset_secret: binary() - Secret for reset token generation
-spec new_config(map()) -> {ok, #lb_config{config_rotation :: 0..6, algorithm :: plaintext | stream_cipher | block_cipher, server_id :: binary(), server_id_len :: 1..15, nonce_len :: 4..18, key :: binary() | undefined}} | {error, term()}.
Create a new LB configuration from options map.
Options: - server_id: binary() (required) - Server identifier (1-15 bytes) - algorithm: plaintext | stream_cipher | block_cipher (default: plaintext) - config_rotation: 0..6 (default: 0) - nonce_len: 4..18 (default: 4) - key: binary() - 16-byte AES key (required for cipher algorithms)
-spec validate_config(#lb_config{config_rotation :: 0..6, algorithm :: plaintext | stream_cipher | block_cipher, server_id :: binary(), server_id_len :: 1..15, nonce_len :: 4..18, key :: binary() | undefined}) -> ok | {error, term()}.
Validate an LB configuration.