17void append_varint(std::vector<uint8_t>& buffer, uint64_t value)
20 buffer.insert(buffer.end(), encoded.begin(), encoded.end());
23void append_bytes(std::vector<uint8_t>& buffer, std::span<const uint8_t> data)
25 buffer.insert(buffer.end(),
data.begin(),
data.end());
28void append_parameter(std::vector<uint8_t>& buffer, uint64_t param_id,
29 std::span<const uint8_t> value)
31 append_varint(buffer, param_id);
32 append_varint(buffer, value.size());
33 append_bytes(buffer, value);
36void append_varint_parameter(std::vector<uint8_t>& buffer, uint64_t param_id,
40 append_parameter(buffer, param_id,
41 std::span<const uint8_t>(encoded_value.data(), encoded_value.size()));
44void append_empty_parameter(std::vector<uint8_t>& buffer, uint64_t param_id)
46 append_varint(buffer, param_id);
47 append_varint(buffer, 0);
50auto read_varint_from_span(std::span<const uint8_t>& data)
57 "Failed to decode varint",
60 auto [value, consumed] = result.value();
62 return ok(std::move(value));
69 std::vector<uint8_t> buffer;
135 append_varint_parameter(buffer,
142 append_varint_parameter(buffer,
181 std::vector<uint8_t> addr_data;
182 addr_data.reserve(64);
185 append_bytes(addr_data,
191 append_bytes(addr_data,
197 addr_data.push_back(
static_cast<uint8_t
>(
preferred_address->connection_id.length()));
201 append_bytes(addr_data,
206 std::span<const uint8_t>(addr_data.data(), addr_data.size()));
216 std::set<uint64_t> seen_params;
218 while (!data.empty())
221 auto id_result = read_varint_from_span(data);
222 if (id_result.is_err())
225 "Failed to decode parameter ID",
228 uint64_t param_id = id_result.value();
231 if (seen_params.contains(param_id))
234 "Duplicate transport parameter",
237 seen_params.insert(param_id);
240 auto len_result = read_varint_from_span(data);
241 if (len_result.is_err())
244 "Failed to decode parameter length",
247 uint64_t param_len = len_result.value();
249 if (param_len > data.size())
252 "Parameter length exceeds buffer",
256 std::span<const uint8_t> param_data = data.subspan(0, param_len);
257 data = data.subspan(param_len);
266 "Connection ID too long",
277 "Connection ID too long",
288 "Connection ID too long",
299 "Stateless reset token must be 16 bytes",
303 std::array<uint8_t, 16> token{};
304 std::copy_n(param_data.data(), 16, token.data());
315 "Failed to decode max_idle_timeout",
328 "Failed to decode ack_delay_exponent",
331 if (result.value().first > 20)
334 "ack_delay_exponent exceeds maximum (20)",
347 "Failed to decode max_ack_delay",
350 if (result.value().first > 16383)
353 "max_ack_delay exceeds maximum (16383)",
366 "Failed to decode max_udp_payload_size",
369 if (result.value().first < 1200)
372 "max_udp_payload_size below minimum (1200)",
385 "Failed to decode initial_max_data",
399 "Failed to decode initial_max_stream_data_bidi_local",
413 "Failed to decode initial_max_stream_data_bidi_remote",
427 "Failed to decode initial_max_stream_data_uni",
441 "Failed to decode initial_max_streams_bidi",
455 "Failed to decode initial_max_streams_uni",
467 "disable_active_migration must have zero-length value",
480 "Failed to decode active_connection_id_limit",
483 if (result.value().first < 2)
487 "active_connection_id_limit must be at least 2",
500 "Preferred address too short",
507 std::copy_n(param_data.data() + offset, 4, addr.
ipv4_address.data());
512 (param_data[offset] << 8) | param_data[offset + 1]);
516 std::copy_n(param_data.data() + offset, 16, addr.
ipv6_address.data());
521 (param_data[offset] << 8) | param_data[offset + 1]);
525 uint8_t cid_len = param_data[offset++];
526 if (cid_len > 20 || offset + cid_len + 16 > param_len)
529 "Invalid preferred address connection ID",
533 std::span<const uint8_t>(param_data.data() + offset, cid_len));
549 return ok(std::move(params));
555 if (ack_delay_exponent > 20)
558 "ack_delay_exponent must not exceed 20",
563 if (max_ack_delay > 16383)
566 "max_ack_delay must not exceed 16383",
571 if (max_udp_payload_size < 1200)
574 "max_udp_payload_size must be at least 1200",
579 if (active_connection_id_limit < 2)
582 "active_connection_id_limit must be at least 2",
589 if (original_destination_connection_id)
592 "Client must not send original_destination_connection_id",
595 if (retry_source_connection_id)
598 "Client must not send retry_source_connection_id",
601 if (stateless_reset_token)
604 "Client must not send stateless_reset_token",
607 if (preferred_address)
610 "Client must not send preferred_address",
QUIC Connection ID (RFC 9000 Section 5.1)
static auto encode(uint64_t value) -> std::vector< uint8_t >
Encode a value to variable-length format.
static auto decode(std::span< const uint8_t > data) -> Result< std::pair< uint64_t, size_t > >
Decode variable-length integer from buffer.
constexpr int decode_error
constexpr int invalid_parameter
constexpr int invalid_value
constexpr int duplicate_parameter
constexpr uint64_t active_connection_id_limit
constexpr uint64_t initial_max_data
constexpr uint64_t ack_delay_exponent
constexpr uint64_t initial_max_streams_uni
constexpr uint64_t initial_source_connection_id
constexpr uint64_t initial_max_streams_bidi
constexpr uint64_t initial_max_stream_data_bidi_local
constexpr uint64_t max_udp_payload_size
constexpr uint64_t disable_active_migration
constexpr uint64_t initial_max_stream_data_bidi_remote
constexpr uint64_t retry_source_connection_id
constexpr uint64_t stateless_reset_token
constexpr uint64_t initial_max_stream_data_uni
constexpr uint64_t preferred_address
constexpr uint64_t max_ack_delay
constexpr uint64_t max_idle_timeout
constexpr uint64_t original_destination_connection_id
@ error
Black hole detected, reset to base.
auto make_default_client_params() -> transport_parameters
Create default client transport parameters.
auto make_default_server_params() -> transport_parameters
Create default server transport parameters.
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
QUIC preferred address transport parameter (RFC 9000 Section 18.2)
std::array< uint8_t, 4 > ipv4_address
class connection_id connection_id
std::array< uint8_t, 16 > ipv6_address
std::array< uint8_t, 16 > stateless_reset_token
QUIC transport parameters (RFC 9000 Section 18)
std::optional< connection_id > retry_source_connection_id
Retry Source Connection ID (server only, after Retry)
uint64_t max_idle_timeout
Maximum idle timeout in milliseconds (0 = disabled)
uint64_t initial_max_data
Initial maximum data for connection (default: 0)
uint64_t ack_delay_exponent
ACK delay exponent (default: 3, meaning 8 microseconds)
uint64_t initial_max_streams_uni
Initial maximum unidirectional streams.
std::optional< std::array< uint8_t, 16 > > stateless_reset_token
Stateless reset token (server only, 16 bytes)
void apply_defaults()
Apply default values for unset parameters.
auto encode() const -> std::vector< uint8_t >
Encode transport parameters to binary format.
bool disable_active_migration
Whether active connection migration is disabled.
auto validate(bool is_server) const -> VoidResult
Validate transport parameters.
uint64_t initial_max_streams_bidi
Initial maximum bidirectional streams.
uint64_t max_udp_payload_size
Maximum UDP payload size (default: 65527)
uint64_t initial_max_stream_data_bidi_remote
Initial maximum data for remotely-initiated bidirectional streams.
std::optional< preferred_address_info > preferred_address
Preferred address for migration (server only)
static auto decode(std::span< const uint8_t > data) -> Result< transport_parameters >
Decode transport parameters from binary format.
std::optional< connection_id > initial_source_connection_id
Initial Source Connection ID.
uint64_t max_ack_delay
Maximum ACK delay in milliseconds (default: 25)
uint64_t active_connection_id_limit
Maximum number of connection IDs from the peer.
std::optional< connection_id > original_destination_connection_id
Original Destination Connection ID (server only)
uint64_t initial_max_stream_data_bidi_local
Initial maximum data for locally-initiated bidirectional streams.
uint64_t initial_max_stream_data_uni
Initial maximum data for unidirectional streams.