lib/quic/src/connection/model.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 const quic = @import("../root.zig");
  2 
  3 /// Fixes, field by field, how much the connection may retain, so that a caller fills this structure
  4 /// once and hands the same value to the capacity, the storage, and the connection. The connection
  5 /// asks for nothing more once it is running. `Capacity.derive`, `Storage.init`, and
  6 /// `Connection.init` all take the same value, and the connection compares its storage against a
  7 /// capacity derived afresh, answering `StorageMismatch` when the two disagree. Derivation turns
  8 /// away a zero in any field, a datagram size under 1200 bytes, and a received range count past what
  9 /// one ACK frame can hold.
 10 pub const Limits = struct {
 11     tls_message_max: u16,
 12     crypto_buffer_bytes: u20,
 13     sent_records: u16,
 14     received_ranges: u16,
 15     datagram_bytes: u16,
 16     /// Decides how much an application can hand over before waiting for the peer by sizing the
 17     /// buffer that keeps stream 0 bytes while the peer has yet to acknowledge them. `write` takes
 18     /// only what fits the room left there, so this figure bounds one handover. Room returns when
 19     /// every earlier byte has been acknowledged, or when a reset abandons what is left.
 20     stream_send_bytes: u32,
 21     /// Decides both how much arriving data the connection can hold and how much it invites the peer
 22     /// to send by sizing the buffer that holds arriving stream 0 bytes until an application reads
 23     /// them. The window advertised for stream 0 is the lesser of that buffer and the configured
 24     /// stream data limit, so the peer is invited to send only what there is room for.
 25     stream_receive_bytes: u32,
 26     /// Decides how much reordering the receiving half absorbs before a packet costs the connection
 27     /// a round trip by sizing the table that tracks separate stretches of arrived data while the
 28     /// holes between them stay unfilled. One packet past that count goes unacknowledged and lifts
 29     /// the `drops.stream_ranges` counter, so the peer sends it a second time.
 30     stream_receive_ranges: u16,
 31     /// Decides how many STREAM frames can be outstanding at one time by sizing the table that keeps
 32     /// one entry per STREAM frame until an acknowledgment or a loss resolves it. With every entry
 33     /// taken, `nextChunk` offers nothing, so the connection packs no further STREAM frame until one
 34     /// entry comes free.
 35     stream_sent_ranges: u16,
 36 };
 37 
 38 /// Carries the identity, the parameter values, the connection ID, and the random source that one
 39 /// handshake draws on. A caller passes this structure as the second argument to `Connection.init`
 40 /// so that the handshake receives everything it needs. Its `role` field decides which side of the
 41 /// protocol this connection plays, and the whole state machine branches on it. `Connection.init`
 42 /// turns away an empty connection ID, one past 20 bytes, and an acknowledgment delay exponent
 43 /// above 20. The parameter fields travel to the peer inside the TLS handshake.
 44 pub const Config = struct {
 45     role: quic.tls.Role,
 46     identity: quic.tls.Identity,
 47     expected_peer: ?quic.tls.PublicKey,
 48     alpn: []const u8,
 49     server_name: ?[]const u8,
 50     random: quic.tls.Random,
 51     local_cid: []const u8,
 52     preferred_suite: quic.crypto.Suite = .aes_128_gcm_sha256,
 53     max_idle_timeout: u62,
 54     ack_delay_exponent: u5,
 55     max_ack_delay: u14,
 56     initial_max_data: u62,
 57     initial_max_stream_data_bidi_local: u62,
 58     initial_max_stream_data_bidi_remote: u62,
 59 };
 60 
 61 /// Names the five conditions a caller can observe from outside as handshaking, established,
 62 /// closing, draining, and closed. `Connection.state` hands this status back so that a caller knows
 63 /// whether to keep driving the connection. While a connection is closing or draining, `nextTimeout`
 64 /// offers only its close deadline, and a closed one offers nothing. A closing connection works
 65 /// through CONNECTION_CLOSE frames and passes over the rest.
 66 pub const Status = enum {
 67     handshaking,
 68     established,
 69     closing,
 70     draining,
 71     closed,
 72 };
 73 
 74 /// `Connection.closeReason` hands this structure back to report what ended the connection, and
 75 /// whether this endpoint or the peer decided it. The structure carries the numeric code, whether
 76 /// that code came from the application, the frame type if one applies, and the reason text. The
 77 /// reason text points into the connection's own storage, so it lives as long as that storage does.
 78 pub const CloseReason = struct {
 79     error_code: u62,
 80     application: bool,
 81     frame_type: ?u62,
 82     reason: []const u8,
 83     remote: bool,
 84 };
 85 
 86 pub const DropStats = struct {
 87     malformed: u64 = 0,
 88     unauthenticated: u64 = 0,
 89     unsupported: u64 = 0,
 90     unavailable_keys: u64 = 0,
 91     wrong_connection: u64 = 0,
 92     duplicate: u64 = 0,
 93     undersized_initial: u64 = 0,
 94     oversized: u64 = 0,
 95     /// Counts the packets that went unacknowledged because the reassembly table had no room left,
 96     /// so a caller learns that the table and the network cost a packet.
 97     stream_ranges: u64 = 0,
 98 };
 99 
100 /// Counts the stream and flow control frames that crossed in one direction, carried by `Stats` for
101 /// each direction so that a caller can see which frames moved. The structure has a field for STREAM
102 /// frames and their bytes, for RESET_STREAM and STOP_SENDING, for the three MAX frames, and for the
103 /// three BLOCKED frames.
104 pub const StreamFrameStats = struct {
105     stream_frames: u64 = 0,
106     stream_bytes: u64 = 0,
107     reset_stream: u64 = 0,
108     stop_sending: u64 = 0,
109     max_data: u64 = 0,
110     max_stream_data: u64 = 0,
111     max_streams: u64 = 0,
112     data_blocked: u64 = 0,
113     stream_data_blocked: u64 = 0,
114     streams_blocked: u64 = 0,
115 };
116 
117 /// Reports what has happened to stream 0 in both directions, returned by `Connection.streamStats`
118 /// for an open stream so that an application can see how far its data has traveled. The structure
119 /// carries the bytes written, sent, released, received, and read, the final size each side settled
120 /// on, and the codes a reset or a stop carried.
121 pub const StreamStats = struct {
122     bytes_written: u62,
123     bytes_sent: u62,
124     /// Counts the bytes the send buffer has given up, whether an acknowledgment or a reset freed
125     /// them, so an application learns how much of the send buffer has come free for the next
126     /// handover.
127     bytes_released: u62,
128     bytes_received: u62,
129     bytes_read: u62,
130     send_final_size: ?u62,
131     receive_final_size: ?u62,
132     reset_sent_code: ?u62,
133     reset_received_code: ?u62,
134     stop_sending_sent_code: ?u62,
135 };
136 
137 /// Counts datagrams, packets, failed authentications, and drops over the life of one connection,
138 /// returned by `Connection.stats` so that a caller sees what the connection did with each datagram.
139 /// Every counter holds at its maximum once it reaches it. The structure nests one frame counter per
140 /// direction and the drop counters.
141 pub const Stats = struct {
142     datagrams_sent: u64 = 0,
143     datagrams_received: u64 = 0,
144     packets_sent: u64 = 0,
145     packets_received: u64 = 0,
146     ack_frames_sent: u64 = 0,
147     handshake_done_sent: u64 = 0,
148     handshake_done_received: u64 = 0,
149     failed_authentications: u64 = 0,
150     /// Counts what loss detection removed, packet by packet and byte by byte, so that a caller
151     /// learns how much loss detection has taken out of the flight.
152     packets_lost: u64 = 0,
153     bytes_lost: u64 = 0,
154     /// Counts the probe deadlines that passed without one, so that a caller learns how often the
155     /// connection had to prod the peer for an acknowledgment.
156     probe_timeouts: u64 = 0,
157     stream_sent: StreamFrameStats = .{},
158     stream_received: StreamFrameStats = .{},
159     drops: DropStats = .{},
160 };
161 
162 pub const TransportError = struct {
163     pub const no_error: u62 = 0x00;
164     pub const internal_error: u62 = 0x01;
165     pub const flow_control_error: u62 = 0x03;
166     pub const stream_limit_error: u62 = 0x04;
167     pub const stream_state_error: u62 = 0x05;
168     pub const final_size_error: u62 = 0x06;
169     pub const frame_encoding_error: u62 = 0x07;
170     pub const transport_parameter_error: u62 = 0x08;
171     pub const protocol_violation: u62 = 0x0a;
172     pub const application_error: u62 = 0x0c;
173     pub const crypto_buffer_exceeded: u62 = 0x0d;
174     pub const key_update_error: u62 = 0x0e;
175     pub const aead_limit_reached: u62 = 0x0f;
176 };