quic_lb (quic v1.3.0)

View Source

QUIC 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

decode_server_id(CID, Lb_config)

-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.

expected_cid_len(Lb_config)

-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.

generate_cid(Cid_config)

-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.

generate_cid(Cid_config, 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.

get_config_rotation(_)

-spec get_config_rotation(binary()) -> 0..7.

Get the config rotation bits from a CID's first byte.

is_lb_routable(CID)

-spec is_lb_routable(binary()) -> boolean().

Check if a CID is LB-routable (CR != 0b111).

new_cid_config(Opts)

-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

new_config(Opts)

-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)

validate_config(Lb_config)

-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.