Skip to main content

QuicServer

QuicServer decrypts upstream carrier datagrams into a raw application byte stream and encrypts downstream application bytes into QUIC datagrams. Google QUICHE performs QUIC v1/TLS 1.3. Existing adapters accept peers and own their normal WaterWall lines; this node creates no listener or socket.

UdpListener -> QuicServer -> TcpConnector
UdpListener -> QuicServer -> VlessServer -> SpeedTestServer

Example​

{
"name": "quic-server",
"type": "QuicServer",
"next": "application-out",
"settings": {
"cert-file": "server.crt",
"key-file": "server.key",
"protocol": "h3",
"carrier-mode": "datagram"
}
}

name, type, next and an object settings are required. type must be exactly QuicServer. Full UDP and framed TCP client/server configurations and local certificate instructions are in tunnels/QuicClient/examples.

Server settings​

SettingDefaultBehavior
cert-fileRequiredReadable PEM certificate chain, leaf first.
key-fileRequiredReadable matching PEM private key.

Unreadable or malformed credentials and mismatched certificate/private-key pairs fail startup. The server retains its signing configuration until every session has retired. Certificate hot reload and client-certificate authentication are outside this node's interface. QUICHE parses the first valid Initial and preserves QUIC anti-amplification before peer address validation; an existing WaterWall line does not by itself validate that address.

Shared settings​

SettingDefaultAccepted values and behavior
protocol"h3"One exact, printable ASCII ALPN identifier, 1–255 bytes. Both peers must agree.
carrier-mode"datagram"Exactly datagram or stream. Select explicitly for a stream carrier.
handshake-timeout-ms10000Integer 1–86,400,000. Total deadline through authenticated handshake and application-stream opening; partial input does not restart it.
idle-timeout-ms60000Integer 1–86,400,000. QUIC idle lifetime, subject to peer negotiation and the carrier's own lifetime.
max-packet-size1350Integer 1200–1452. Maximum emitted QUIC datagram, excluding the stream envelope.
max-buffered-bytes2097152Integer 65,536–67,108,864. Per-line bound for each independent retained application/output backlog, including accepted unacknowledged plaintext.
max-buffered-buffers1024Integer 1–65,536. Per-backlog entry bound, including active retention.
receive-window-bytes1048576Integer 16,384–16,777,216 and no greater than max-buffered-bytes; initial stream receive credit.
verbosefalseBoolean extra diagnostics; does not log plaintext, private keys or session secrets.

Integers must be JSON integer tokens. Strings, booleans and fractional numbers do not satisfy integer fields. Invalid values fail startup with a setting-specific diagnostic. Set receive-window-bytes as well when reducing the byte budget below its default.

Each configured entry reserves descriptor storage: require (max-buffered-buffers + 1) * 24 <= max-buffered-bytes. A send ledger reserves 16 bytes per configured entry, and each wire/plaintext backlog reserves 24 bytes per configured entry plus one READY/CLOSED event slot before payload allocation. These backing charges count toward their allocation budgets even while the rings are empty; closing releases them.

Carrier and application semantics​

The application interface is a reliable byte stream. Application Payload buffer boundaries are not preserved. There is one QUIC connection and one client-initiated bidirectional stream per existing normal WaterWall line. QUIC nodes borrow that line; adapters or application sources own sockets and line creation/destruction.

In datagram mode, one carrier Payload is exactly one complete QUIC datagram, with no private outer prefix. In stream mode every datagram has a four-byte unsigned big-endian length followed by that many bytes. Both peers must select stream over a byte-stream carrier. Its incremental parser accepts fragmented prefixes/bodies and coalesced frames; zero lengths or lengths above 1,472 close the association. There is no automatic carrier detection, fallback or adapter insertion.

The client sends one encrypted opening byte 0x00 before application data. The server consumes it internally, allowing a server-first application to send even when the client has no application bytes. A real leading NUL in application data remains intact. Extra application streams and the QUIC DATAGRAM application extension are not exposed.

protocol="h3" announces ALPN only. The stream mapping is private raw QUIC, with no HTTP/3 requests, responses, QPACK or HTTP control streams. Ordinary HTTP/3 peers cannot use it. This setting makes no Chrome/Cloudflare impersonation or classifier claim and does not change HttpClient/HttpServer.

Flow, storage and close​

Every supported transport Est is relayed promptly, including repeats; authenticated handshake and stream readiness are independent internal barriers. Before readiness, admitted application data waits in FIFO order under hard budgets. Pause/Resume are advisory and relayed, including duplicates. QUIC loss alarms, ACK processing and ordered ready output continue through advisory Pause. Local send pressure asks only the application producer to pause when any retained byte count, entry count or allocation charge exceeds three quarters of its limit. It resumes only when all three fall below one half; equality preserves the hold. The allocation limit is twice the byte budget. ACK-only input can release accepted send storage and clear this pressure.

Configured byte and entry limits apply independently to the documented backlogs. WaterWall-owned retained allocation charge is also bounded to twice the associated byte budget. Accepted send chunks remain charged while unacknowledged; a later ACK cannot bypass an earlier outstanding ledger entry. These limits do not claim a hard cap on every QUICHE heap allocation.

An adjacent UDP adapter may stop reads during an external Pause, including ACK ingress. A finite pause can recover; a sufficiently long pause may expire QUIC deadlines. Both nodes block splice and do not implement connection pooling, migration across carrier lines, NAT-rebinding reassociation, resumption or 0-RTT.

Receiving Finish retires local protocol state and cancels timers before forwarding only away from the sender. Application-side Finish makes one bounded synchronous attempt to hand already queued ready packets to the still-open carrier, respecting congestion control and pacing. A borrowed line cannot remain alive while waiting asynchronously for final QUIC acknowledgments. Final delivery after local teardown is not guaranteed; lost final packets resolve through the peer's finite timeout. QUIC stream FIN/reset closes the whole association after already-decoded bytes; application half-close is not provided.

Node Metadata​

Both nodes are ordinary Layer 4 middle transforms: they allow previous and next nodes, advertise kNodeFlagBlocksSplice, and require zero additional left padding. They do not inspect or reject neighboring adapter types. Google QUICHE and its runtime dependencies are linked statically through the shared prefixed BoringSSL provider.

Source-backed metadata:

PropertyValue
node flagskNodeFlagBlocksSplice
can_have_prevtrue
can_have_nexttrue
layer_groupkNodeLayer4
layer_group_prev_nodekNodeLayer4
layer_group_next_nodekNodeLayer4
required_padding_left0 bytes