Package io.github.mahmoudimus.quic.connection
package io.github.mahmoudimus.quic.connection
The sans-I/O QUIC connection and endpoint, ported from quinn-proto: the
Connection state machine (handshake, packet assembly and
processing, key updates, closing and draining), the Endpoint that routes datagrams and answers with Version
Negotiation, Retry and stateless resets, their configurations (TransportConfig, ServerConfig, ClientConfig, EndpointConfig), and the building blocks they are made of:
range sets (RangeSet), reassembly of received data
(Assembler), buffering of sent data (SendBuffer), streams and flow control (StreamsState), packet number spaces and ACK generation
(PacketSpace), loss detection (Recovery), pacing (Pacer), path MTU discovery (MtuDiscovery) and timers (TimerTable).
Nothing here performs I/O, reads a clock or starts a thread: every method that depends on time
takes the current time as a long in nanoseconds from one monotonic clock (see NanoClock), so tests drive them with a fake clock.
Threads. None of these classes is thread-safe and none takes a lock. Each connection is owned by one driver that serializes all access to it, and the endpoint likewise; configurations are immutable.
-
ClassDescriptionState of the QUIC ACK frequency extension, as quinn implements it: the
max_ack_delaythe peer uses (its transport parameter, or what we last asked for in an ACK_FREQUENCY frame once it is acknowledged) and the one we use (ours, or what the peer asked for).Reassembles STREAM or CRYPTO frame data that arrives out of order, duplicated or overlapping, into the stream's bytes (RFC 9000 section 2.2).A run of received stream or CRYPTO data and its offset in the stream.A read in progress on one stream, fromStreamsState.read(io.github.mahmoudimus.quic.connection.StreamId, boolean, io.github.mahmoudimus.quic.connection.Retransmits).How a client connects: its TLS configuration (trust, server name, ALPN, 0-RTT), the transport settings, the QUIC version and theSessionCachethat keeps session tickets and NEW_TOKEN tokens between connections.Builds aClientConfig.One QUIC connection (RFC 9000, 9001, 9002) as a sans-I/O state machine, after quinn-proto'sConnection.Why a connection ended.What ended a connection.What aConnectiontells its application, throughConnection.pollEvent().The handshake completed: streams and datagrams can flow.The connection ended; this is the last event.One or more DATAGRAM frames arrived; read them withConnection.receiveDatagram().The handshake is confirmed (RFC 9001 section 4.1.2).The handshake has progressed far enough that the ALPN protocol and, on a server, the client's server name are known.A client's probe of a new path got no PATH_RESPONSE in time: the connection stays on its path.The path packets are sent on changed: the server followed the client to a new address (and validates it), went back to the previous path after a failed validation, or the client switched to a path it probed (Connection.probePath(long, java.net.InetSocketAddress), or the server's preferred address).Something happened on a stream.Generates the connection IDs an endpoint issues.A sliding-window detector of duplicate packet numbers, in the style of RFC 4303: a 128-bit field, one bit per packet number below the highest authenticated one.Delivery rate estimation as draft-cheng-iccrg-delivery-rate-estimation describes it, the sampler BBR is built on.Whether a stream carries data in both directions or only from its initiator (RFC 9000 section 2.1).The connections of one UDP socket, as a sans-I/O state machine after quinn-proto'sEndpoint: it routes incoming datagrams to connections by Destination Connection ID, whatever address they come from, so that a connection follows a peer that migrates (or by the peer's address when local IDs are zero-length, which rules migration out), creates server connections from Initial packets, and answers what no connection should see: Version Negotiation for unknown versions, Retry for address validation, stateless resets for unknown connection IDs, and CONNECTION_CLOSE for refused attempts.What to do with a datagram.The datagram belongs to a connection: pass it toConnection.handleDatagram(long, java.net.InetSocketAddress, int, java.nio.ByteBuffer).A client's first Initial created a server connection: start driving it, then pass it the datagram.Send this datagram back to the datagram's sender (Version Negotiation, Retry, stateless reset or CONNECTION_CLOSE).Settings shared by every connection of an endpoint: how local connection IDs are made, the key stateless reset tokens derive from, the QUIC versions accepted, and the stateless reset rate limit.Builds anEndpointConfig.The connection issued a local connection ID; packets for it must reach the connection.The peer retired a local connection ID; it no longer routes to the connection.The connection is gone and holds no state the endpoint must keep; this is the last event.The peer's current stateless reset token, which lets a reset with a random connection ID reach the connection.A local connection ID issued to the peer, to be sent in a NEW_CONNECTION_ID frame.Receives TLS traffic secrets in the NSS key log format (SSLKEYLOGFILE), which Wireshark reads to decrypt QUIC packets.The connection IDs this endpoint issued to its peer (RFC 9000 section 5.1.1): sequence numbers, stateless reset tokens derived from a static key, retirement by the peer, and periodic rotation throughretire_prior_towhen IDs have a lifetime.The outcome of a RETIRE_CONNECTION_ID.Datagram packetization layer path MTU discovery (DPLPMTUD, RFC 8899): probes larger packets in the application data space by binary search, and detects MTU black holes from the pattern of lost packets.Configuration of DPLPMTUD, packetization layer path MTU discovery (RFC 8899, RFC 9000 section 14.3).A monotonic clock in nanoseconds, injected into the connection layer so that timers can be driven deterministically in tests.A token-bucket pacer (RFC 9002 section 7.7).Mitigates optimistic ACK attacks (RFC 9000 section 21.4) by occasionally skipping a packet number in the application data space: an ACK of a skipped number proves the peer acknowledges packets it never received.One packet number space (RFC 9000 section 12.3, RFC 9002 appendix A): its keys, the packets received and to acknowledge, the next packet number, the packets sent and not yet acknowledged or lost, the frames waiting to be sent, the CRYPTO stream, and the loss detection state thatRecoverykeeps per space.What a space has to send.One network path of a connection (RFC 9000 section 9): the peer's address, the local address the connection uses on it, and what is measured per path: the RTT, the congestion controller, the pacer, MTU discovery, the delivery rate, the bytes in flight, and the anti-amplification counts until the path is validated (RFC 9000 section 8).The packets of one space waiting to be acknowledged, and when an ACK must go out (RFC 9000 section 13.2): after more thanack_eliciting_thresholdack-eliciting packets (one, by default, so every second one is acknowledged at once), on reordering, or oncemax_ack_delayhas passed since the first unacknowledged ack-eliciting packet.Receives qlog-style connection events, for debugging: packets sent, received and lost, recovery metrics, key updates and state changes.Generates random connection IDs of a fixed length, 8 bytes by default.A set of non-negativelongvalues stored as disjoint, non-adjacent half-open ranges, for long runs with random insertion and removal: received packet numbers, ACK ranges, received and acknowledged stream offsets.A half-open range[start, end).Loss detection and congestion control of one connection (RFC 9002): the three packet number spaces, the in-flight counts, the RTT estimator, the congestion controller, the pacer, MTU discovery and the probe timeout.Receives acknowledged and lost packets.Configuration of loss detection, congestion control, pacing and MTU discovery.Builds aRecoveryConfig.The states of the receiving part of a stream (RFC 9000 section 3.2, figure 3).The connection IDs the peer issued to this endpoint (RFC 9000 section 5.1.2): a window of at mostlimitIDs, ouractive_connection_id_limit, starting with the one in use.Signals that an ID could not be stored; seeRemoteCidQueue.InsertError.Sequence numbers to retire, and the reset token of the ID now in use.Control frames waiting to be sent in one packet number space, and, attached to aSentPacket, the control frames that packet carried, to queue again if it is lost.A RESET_STREAM to send.The outgoing data of one stream that is not yet acknowledged: what the application wrote, what has been sent, what was deemed lost and must be sent again, and which ranges the peer has acknowledged.The rangeSendBuffer.pollTransmit(int)chose to send next.The states of the sending part of a stream (RFC 9000 section 3.1, figure 2).What loss recovery remembers about a sent packet until it is acknowledged or deemed lost (RFC 9002 appendix A.1.1).The sent packets of one packet number space that are neither acknowledged nor lost, by packet number.How a server accepts connections: its TLS configuration (certificates, possibly selected per SNI, ALPN, session tickets and 0-RTT), the transport settings, Retry-based address validation, the NEW_TOKEN tokens that let returning clients skip the Retry, the connection cap, whether clients may migrate, and a preferred address.Builds aServerConfig.What a client remembers about servers between connections: TLS session tickets, for resumption and 0-RTT (each ticket also carries the server's transport parameters, which 0-RTT data must keep within), and NEW_TOKEN tokens, which let a server skip its Retry round trip.The role of an endpoint in a connection.The three packet number spaces (RFC 9000 section 12.3).Application events about streams, polled fromStreamsState.poll().The peer raised the stream limit, so at least one more stream of this directionality may be opened.A finished stream's data, FIN included, has all been acknowledged.The peer opened one or more streams, whichStreamsState.accept(Dir)now returns.A stream probably has data, its end or a reset waiting to be read.The peer sent STOP_SENDING: it no longer wants the stream's data.A stream that could not take more data might take some now, or was stopped.An application-level stream operation that cannot proceed.Why the operation failed.A stream ID (RFC 9000 section 2.1): the two low bits give the initiator and direction, the rest the stream's index among the streams of that type.What a sent STREAM frame carried, without its data, which stays in the stream'sSendBuffer: kept with the sent packet to acknowledge or retransmit the range.The streams of one connection (RFC 9000 sections 2 to 4): opening and accepting streams, stream and connection flow control, the send and receive state machines, RESET_STREAM and STOP_SENDING, priorities, and the control and STREAM frames they produce.The timers of a connection, kept in aTimerTable.A datagram aConnectionwants sent: usually to the peer's address on the current path, but a PATH_CHALLENGE or PATH_RESPONSE may go to another address, or (on a client probing a new path,Connection.probePath(long, java.net.InetSocketAddress)) from another local address.The transport settings of a connection, the same for both sides: flow-control windows, stream limits, timeouts, loss detection, congestion control, MTU discovery, DATAGRAM support and the debugging aids.Builds aTransportConfig.The congestion controllers this module provides.