tiny.quic.connection.parameters
Defined in connection.
API (7)
Actions
Public operations.
effectiveIdleencodelocalStreamsBidi: 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.streamReceiveWindow: 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.streamSendLimit: Reads out of the peer's parameters how many stream 0 bytes this endpoint may send before the peer grants more.validatePeer
Types and contracts
Public types and contracts.
Source
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
| Definitions | 8 |
|---|---|
| Public names | 8 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |