HTTP/3 upstream transport
Dwara can connect to an upstream over HTTP/3 (h3 over QUIC) -- the same protocol it can serve on the ingress side, but used here for the gateway-to-upstream hop. An h3 upstream uses QUIC's multiplexed streams without head-of-line blocking and benefits from QUIC's faster connection establishment and connection migration, while the gateway's listener side can still serve clients over HTTP/1.1, HTTP/2, or HTTP/3 independently.
When to use this
Use an h3 upstream when the upstream itself speaks HTTP/3 and you want the gateway-to-upstream hop to gain QUIC's properties:
- Multiplexed concurrent requests without head-of-line blocking, so a slow response on one stream does not stall the others sharing the connection.
- Lower connection-establishment latency (1-RTT, or 0-RTT on resumption), useful when the gateway opens short-lived connections to the upstream.
- Connection migration -- the QUIC connection survives a NAT rebinding or a gateway failover that changes the source IP, avoiding a reconnect.
If the upstream only speaks HTTP/1.1 or HTTP/2, use protocol: http1 or protocol: http2 instead. h3 is not a faster choice for a single request/response; it pays off when the gateway reuses one QUIC connection for many concurrent streams to the same upstream.
Enabling
The h3 upstream transport is compiled into the default build alongside HTTP/3 ingress (default OFF), because both pull in the quinn (QUIC) and h3 crates:
cargo build -p dwara-binIn a default build the feature is absent and upstream.protocol: h3 is accepted but inert -- the upstream connects over HTTP/1.1 instead.
Configuration
Set the upstream's protocol to h3:
upstreams:
- name: h3-backend
endpoints:
- address: 10.0.0.7
port: 8443
protocol: h3
tls:
cert_file: /etc/dwara/upstream-ca.pemQUIC mandates TLS 1.3, so the upstream connection is always encrypted -- there is no cleartext h3 equivalent of h2c. The tls block supplies the CA used to validate the upstream's certificate. The same certificate trust model as an https/http2 upstream applies; only the transport differs.
How it differs from HTTP/3 ingress
HTTP/3 ingress (a listener with protocol: h3) and an h3 upstream are independent:
- Ingress h3 is about how clients connect to the gateway. Clients negotiate it via
Alt-Svcadvertised by an h1/h2 listener or connect directly to the h3 port. See HTTP/3 ingress. - Upstream h3 is about how the gateway connects to backends. The gateway can serve HTTP/1.1 clients on the front and proxy to an h3 backend on the rear, or serve h3 on the front and proxy to an h2 backend on the rear -- the two sides are decoupled.
A request flows: client -> (ingress protocol) -> gateway -> (upstream protocol) -> backend. The ingress and upstream protocols are chosen separately per listener and per upstream.
Notes
- The
h3feature pulls in thequinnandh3crates, increasing the binary size. That is why the feature is default OFF -- enable it only in builds that serve or proxy h3 traffic. - An h3 upstream cannot fall back to cleartext; QUIC is always encrypted, so the
tlsblock is required. - Connection pooling for h3 upstreams reuses a single QUIC connection across many concurrent request streams. The pool settings (
max_connections_per_host, idle timeout) apply to QUIC connections the same way they apply to TCP connections for h1/h2 upstreams.
Runnable demo
Run this feature against a live gateway: demos/10-tls-transport/ (test script: test-07-http3.sh) in the repository. The demo documents the current limitations alongside what runs today; see its README.