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.

  • Class
    Description
    State of the QUIC ACK frequency extension, as quinn implements it: the max_ack_delay the 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.
    How a client connects: its TLS configuration (trust, server name, ALPN, 0-RTT), the transport settings, the QUIC version and the SessionCache that keeps session tickets and NEW_TOKEN tokens between connections.
    Builds a ClientConfig.
    One QUIC connection (RFC 9000, 9001, 9002) as a sans-I/O state machine, after quinn-proto's Connection.
    Why a connection ended.
    What ended a connection.
    What a Connection tells its application, through Connection.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 with Connection.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's Endpoint: 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.
    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 an EndpointConfig.
    What a Connection tells its Endpoint, through Connection.pollEndpointEvent(): routing changes.
    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 through retire_prior_to when 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 that Recovery keeps 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 than ack_eliciting_threshold ack-eliciting packets (one, by default, so every second one is acknowledged at once), on reordering, or once max_ack_delay has 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-negative long values 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 a RecoveryConfig.
    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 most limit IDs, our active_connection_id_limit, starting with the one in use.
    Signals that an ID could not be stored; see RemoteCidQueue.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 a SentPacket, 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 range SendBuffer.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 a ServerConfig.
    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 from StreamsState.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, which StreamsState.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's SendBuffer: 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 a TimerTable.
    The deadline of each Timer, in nanoseconds from the connection's NanoClock.
    A datagram a Connection wants 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 a TransportConfig.
    The congestion controllers this module provides.