Skip to documentation
SLOP

tiny.quic.connection.parameters

Reference tiny.quic connection parameters

Defined in connection.

API (7)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callsconnectionparameters
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallstest sourcelib.quic.src.connection.params.test_RFC_9000_...2 stream parameters cap at the receiv...test sourcelib.quic.src.connection.params.test_RFC_9000_...3 transport parameters authenticate c...connection.parameterslocalStreamsBidiconnection.parametersencode
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callsconnection.parametersencodeconnection.parameterslocalStreamsBidi
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.quic.src.connection.params.test_RFC_9000_...2 stream parameters cap at the receiv...connection.parametersstreamReceiveWindow
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.quic.src.connection.params.test_RFC_9000_...2 stream parameters cap at the receiv...connection.parametersstreamSendLimit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.quic.src.connection.params.test_RFC_9000_...2 client preferred address is rejectedtest sourcelib.quic.src.connection.params.test_RFC_9000_...2 client stateless reset token is rej...test sourcelib.quic.src.connection.params.test_RFC_9000_...3 transport parameters authenticate c...private sourcelib.quic.src.connection.paramsequalCidconnection.parametersvalidatePeer
Static calls · unresolved targets: 1 · external targets: 0.

Source: lib/quic/src/connection/params.zig

zig
const std = @import("std");const quic = @import("../root.zig");pub const Error = quic.transport.EncodeError || quic.transport.DecodeError ||    error{ InvalidConnectionId, InvalidRole, NoSpace };pub fn encode(    config: quic.connection.Config,    limits: quic.connection.Limits,    local: quic.packet.ConnectionId,    original: ?quic.packet.ConnectionId,    bytes: []u8,) Error![]const u8 {    var output = quic.cursor.Write.init(bytes);    const receive_bytes: u62 = limits.stream_receive_bytes;    const stream_local = @min(config.initial_max_stream_data_bidi_local, receive_bytes);    const stream_remote = @min(config.initial_max_stream_data_bidi_remote, receive_bytes);    try quic.transport.encode(.{        .original_destination_connection_id = original,        .max_idle_timeout = config.max_idle_timeout,        .max_udp_payload_size = limits.datagram_bytes,        .initial_max_data = config.initial_max_data,        .initial_max_stream_data_bidi_local = stream_local,        .initial_max_stream_data_bidi_remote = stream_remote,        .initial_max_streams_bidi = localStreamsBidi(config.role),        .ack_delay_exponent = config.ack_delay_exponent,        .max_ack_delay = config.max_ack_delay,        .active_connection_id_limit = 2,        .initial_source_connection_id = local,    }, &output);    return output.written();}pub fn validatePeer(    role: quic.tls.Role,    bytes: []const u8,    peer_source: quic.packet.ConnectionId,    original: ?quic.packet.ConnectionId,) Error!quic.transport.Parameters {    const parameters = try quic.transport.decode(bytes);    const initial_source = parameters.initial_source_connection_id orelse        return error.InvalidConnectionId;    if (!equalCid(initial_source, peer_source)) return error.InvalidConnectionId;    if (parameters.retry_source_connection_id != null) return error.InvalidRole;    switch (role) {        .client => {            const expected = original orelse return error.InvalidConnectionId;            const received = parameters.original_destination_connection_id orelse                return error.InvalidConnectionId;            if (!equalCid(expected, received)) return error.InvalidConnectionId;        },        .server => if (parameters.original_destination_connection_id != null) {            return error.InvalidRole;        } else if (parameters.stateless_reset_token != null) {            return error.InvalidRole;        } else if (parameters.preferred_address != null) return error.InvalidRole,    }    return parameters;}/// Says how many bidirectional streams this endpoint lets the peer open, as the limit this endpoint/// advertises and the same limit that arriving frames are held to. A server answers 1, which is/// room for the client's stream 0, and a client answers 0. The figure travels to the peer among the/// transport parameters, and `admitStream` closes with STREAM_LIMIT_ERROR for anything past it.pub fn localStreamsBidi(role: quic.tls.Role) u62 {    return switch (role) {        .client => 0,        .server => 1,    };}/// Takes the lesser of the reassembly buffer and the limit configured for stream 0, sizing the/// receiving half of stream 0 so the advertised window stays within the buffer behind it. Which/// configured limit that is depends on the role, because the client is the side that opens/// stream 0. `Connection.init` hands the result to the receiving half as its window.pub fn streamReceiveWindow(config: quic.connection.Config, limits: quic.connection.Limits) u62 {    const advertised = switch (config.role) {        .client => config.initial_max_stream_data_bidi_local,        .server => config.initial_max_stream_data_bidi_remote,    };    return @min(advertised, @as(u62, limits.stream_receive_bytes));}/// Reads out of the peer's parameters how many stream 0 bytes this endpoint may send before the/// peer grants more. A client reads the peer's remote-initiated figure and a server the peer's/// local-initiated one, because the two name the same stream from opposite sides./// `authenticatePeer` lifts the sending half's credit to it as soon as the connection has checked/// the peer's parameters.pub fn streamSendLimit(role: quic.tls.Role, peer: quic.transport.Parameters) u62 {    return switch (role) {        .client => peer.initial_max_stream_data_bidi_remote,        .server => peer.initial_max_stream_data_bidi_local,    };}pub fn effectiveIdle(local: u62, peer: u62) u62 {    if (local == 0) return peer;    if (peer == 0) return local;    return @min(local, peer);}fn equalCid(left: quic.packet.ConnectionId, right: quic.packet.ConnectionId) bool {    return std.mem.eql(u8, left.slice(), right.slice());}test "RFC 9000 section 7.3 transport parameters authenticate connection IDs" {    const local = try quic.packet.ConnectionId.init("local-id");    const original = try quic.packet.ConnectionId.init("original");    const config = testConfig();    const limits = testLimits();    var bytes: [256]u8 = undefined;    const encoded = try encode(config, limits, local, original, &bytes);    const decoded = try validatePeer(.client, encoded, local, original);    try std.testing.expectEqual(@as(u62, 0), decoded.initial_max_streams_bidi);}test "RFC 9000 section 4.6 and section 18.2 stream parameters cap at the receive buffer" {    var config = testConfig();    config.role = .server;    config.initial_max_stream_data_bidi_remote = 5_000;    const limits = testLimits();    const local = try quic.packet.ConnectionId.init("server-id");    var bytes: [256]u8 = undefined;    const decoded = try quic.transport.decode(try encode(config, limits, local, null, &bytes));    try std.testing.expectEqual(@as(u62, 1), decoded.initial_max_streams_bidi);    try std.testing.expectEqual(@as(u62, 50), decoded.initial_max_stream_data_bidi_local);    try std.testing.expectEqual(@as(u62, 64), decoded.initial_max_stream_data_bidi_remote);    try std.testing.expectEqual(@as(u62, 64), streamReceiveWindow(config, limits));    try std.testing.expectEqual(@as(u62, 50), streamSendLimit(.server, decoded));    try std.testing.expectEqual(@as(u62, 64), streamSendLimit(.client, decoded));}test "RFC 9000 section 18.2 client stateless reset token is rejected" {    const peer = try quic.packet.ConnectionId.init("client-id");    var bytes: [256]u8 = undefined;    var output = quic.cursor.Write.init(&bytes);    try quic.transport.encode(.{        .stateless_reset_token = @splat(0x55),        .initial_source_connection_id = peer,    }, &output);    try std.testing.expectError(        error.InvalidRole,        validatePeer(.server, output.written(), peer, null),    );}test "RFC 9000 section 18.2 client preferred address is rejected" {    const peer = try quic.packet.ConnectionId.init("client-id");    const preferred = try quic.packet.ConnectionId.init("preferred");    var bytes: [256]u8 = undefined;    var output = quic.cursor.Write.init(&bytes);    try quic.transport.encode(.{        .preferred_address = .{            .ipv4 = @splat(0),            .ipv4_port = 0,            .ipv6 = @splat(0),            .ipv6_port = 0,            .connection_id = preferred,            .reset_token = @splat(0x66),        },        .initial_source_connection_id = peer,    }, &output);    try std.testing.expectError(        error.InvalidRole,        validatePeer(.server, output.written(), peer, null),    );}fn testLimits() quic.connection.Limits {    return .{        .tls_message_max = 256,        .crypto_buffer_bytes = 512,        .sent_records = 4,        .received_ranges = 4,        .datagram_bytes = 1200,        .stream_send_bytes = 64,        .stream_receive_bytes = 64,        .stream_receive_ranges = 4,        .stream_sent_ranges = 4,    };}fn testConfig() quic.connection.Config {    const identity = quic.tls.Identity.fromSeed(@splat(1)) catch unreachable;    return .{        .role = .client,        .identity = identity,        .expected_peer = null,        .alpn = "tiny/1",        .server_name = null,        .random = quic.tls.Random.testing(.{ .hello = @splat(2), .key_exchange = @splat(3) }),        .local_cid = "local-id",        .max_idle_timeout = 10,        .ack_delay_exponent = 3,        .max_ack_delay = 25,        .initial_max_data = 100,        .initial_max_stream_data_bidi_local = 50,        .initial_max_stream_data_bidi_remote = 50,    };}

Source: lib/quic/src/connection/root.zig:24

zig
pub const parameters = params;

Audit

Definitions8
Public names8
Members0
Version26.7.0
Revisiondaab053ee433