← 返回日报
精读 预计 6 分钟

savearoundtrip: publish an HTTPS DNS record, skip a round trip

摘要

文章对比了通过 Alt-Svc 响应头和 HTTPS DNS 记录(RFC 9460)发现 HTTP/3 的差异。前者需先建立 TCP 连接才能获知 H3 支持,而后者在 DNS 解析阶段即可完成,使浏览器能在首次请求时直接使用 QUIC。此外,HTTPS 记录还支持加密客户端问候(ECH)、提供 IP 提示以加速连接,并拥有更可靠的缓存机制。目前主流浏览器均已支持,且该配置对旧客户端具有良好的向下兼容性。

荐读理由

通过在 DNS 中配置文中给出的一行 HTTPS 记录(RFC 9460),你可以让自己的产品在用户首次访问时直接启用 HTTP/3 并支持 ECH 加密,省掉传统 Alt-Svc 握手带来的 5-150ms 延迟。

原文

savearoundtrip

Advertise HTTP/3 support in an HTTPS DNS record, not just an Alt-Svc header, and browsers use HTTP/3 (QUIC) on the first connection.

A browser can discover a site's HTTP/3 support two ways: either by first connecting over HTTP/1 or HTTP/2 and reading its Alt-Svc HTTP header, or right away from an HTTPS DNS record lookup. Only with the HTTPS DNS record can the browser use HTTP/3 on the first connection, saving a round trip using QUIC.

of connections in Firefox Nightly reach HTTP/3 only on a later connection: the site advertised HTTP/3 only in an Alt-Svc HTTP header, not in DNS, though it could have published both. A published HTTPS record would have saved each one a round trip on the first connection.

loading from GLAM...

check a domain

try: savearoundtrip.com cloudflare.com blog.mozilla.org github.com example.com

This site eats its own dog food: savearoundtrip.com publishes an HTTPS record with h3, IP hints, and ECH.

The HTTPS record is looked up in your browser via Cloudflare's DNS-over-HTTPS endpoint. The Alt-Svc header and a live HTTP/3 handshake can't be checked from a browser (CORS hides cross-origin headers, and a browser can't force a cold QUIC connection), so the domain you enter is sent to a small open-source backend that runs only those two checks. Nothing is stored.

The live HTTP/3 handshake is performed with quic-go.

what a round trip costs

A round trip is one message to the server and back, bounded by the speed of light: roughly 5 to 20 ms within a city, 40 to 80 ms across a country, and 150 ms or more across an ocean or a mobile network (Cloudflare Radar has live numbers). It is paid where people notice: under about 100 ms an interaction feels instantaneous; past that it feels like waiting (Nielsen Norman Group).

the wasted round trip

Alt-Svc (RFC 7838) is an HTTP response header. To read it, the client must finish a request, which means it has already opened a TCP connection, done a TLS handshake, and spoken HTTP/1.1 or HTTP/2. Only then does it learn "by the way, I also speak HTTP/3". The HTTP/3 upgrade lands on the next connection.

HTTP/3 advertised only via the Alt-Svc HTTP header

sequenceDiagram
    participant C as Client
    participant D as DNS
    participant S as Your server
    Note over C,S: First connection
    C->>D: look up A / AAAA
    D-->>C: IP address
    C->>S: TCP SYN
    S-->>C: SYN-ACK
    C->>S: TLS ClientHello
    S-->>C: TLS ServerHello, Finished
    C->>S: HTTP/2 request
    S-->>C: response + Alt-Svc: h3
    Note over C,S: only now does the client learn you speak HTTP/3
    Note over C,S: Second connection
    C->>S: QUIC + HTTP/3 handshake
    S-->>C: connected (HTTP/3)

HTTP/3 only on the second connection.

An HTTPS record (RFC 9460) carries the same "I speak HTTP/3" signal, but in the DNS. The client reads it during the name resolution it was going to do anyway, before it opens any connection. So it can make its very first connection over QUIC/HTTP/3, with no earlier HTTP/1 or HTTP/2 connection spent just to find out.

HTTP/3 advertised in an HTTPS DNS record

sequenceDiagram
    participant C as Client
    participant D as DNS
    participant S as Your server
    Note over C,S: First connection
    C->>D: look up HTTPS record
    D-->>C: alpn=h3 + IP hints (+ ECH)
    C->>S: QUIC + HTTP/3 handshake
    S-->>C: connected (HTTP/3)
    C->>S: HTTP/3 request
    S-->>C: response

HTTP/3 right away, on the first connection.

why the HTTPS record is strictly better

The HTTPS resource record (RFC 9460, Nov 2023) folds everything a client needs to open the optimal connection into the DNS answer it was already fetching. Concretely:

1 · HTTP/3 discovery before the first byte

The alpn SvcParam lists the ALPN protocol IDs the endpoint speaks, e.g. h3 (HTTP/3) and h2. Because it arrives during name resolution, the client can pick QUIC for its very first connection instead of discovering h3 only after a previous HTTP/1 or HTTP/2 connection.

2 · ECH: Encrypted Client Hello (only the DNS can deliver it)

The ech SvcParam carries the endpoint's ECHConfigList public keys (RFC 9849). ECH encrypts the TLS ClientHello, including the SNI server name, so a network observer can't see which site you're visiting. This is a chicken-and-egg problem an HTTP header can't solve: you need the public key before you send the first ClientHello, which is exactly when no connection exists yet. Only an out-of-band channel, the DNS (the HTTPS record), can bootstrap ECH. No HTTPS RR, no ECH.

3 · IP hints: start connecting sooner

Happy Eyeballs v3 already issues the A, AAAA, and HTTPS queries in parallel. The ipv4hint and ipv6hint inside that HTTPS answer give it candidate addresses to start connecting from when the answer arrives before the A/AAAA records, instead of waiting on them. The A/AAAA records still come and supersede the hints; the hints just keep the first connection attempt from stalling on a lookup that has not returned yet. Alt-Svc has no equivalent.

4 · One authoritative source, sane caching

Reachability lives in the DNS with a normal TTL, instead of being smeared across per-origin HTTP-header caches with their max-age dilemma: too long and clients use stale alternatives, too short and they fall back to older protocols more often than they should. The browser was going to do a DNS lookup anyway; this just makes that lookup carry the answer.

capability Alt-Svc HTTP header (RFC 7838) HTTPS RR (RFC 9460)
learned when? after a full connection during DNS resolution
h3 on first connection no yes
IP hints n/a ipv4hint / ipv6hint
ECH keys impossible ech param
source of truth HTTP header + fragile cache the DNS, with a TTL

from a real browser

Firefox Nightly Measured by Firefox itself, via Mozilla's public GLAM telemetry.

A browser can learn that a server speaks HTTP/3 in two ways: from the Alt-Svc HTTP response header (seen only after it has already connected), or from an HTTPS DNS record (seen before connecting). So every connection falls into one of four groups:

  • Neither: HTTP/3 was not advertised at all.

  • Alt-Svc only: advertised, but only in the header, so the first connection could not use it.

  • HTTPS record only: advertised in DNS, so the first connection could go straight to HTTP/3.

  • Both: advertised in DNS and the header.

HTTP/3 discovery, by the numbers

Share of measured connections, Firefox Nightly. The four groups cover every connection, so they add up to 100%. The two right-hand groups had a usable HTTPS record; Alt-Svc only is the gap a record would close.

How it is developing over time

Each bar is one Nightly build, split into the four groups (100%). Firefox Nightly only.

publish one (it's one line)

A ServiceMode HTTPS record advertising h3, with address hints:

; zone file (BIND-style)
example.com.  3600  IN  HTTPS 1 . alpn="h3,h2" ipv4hint=203.0.113.10 ipv6hint=2001:db8::10

Reading it left to right:

  • example.com. the name you publish it under; the trailing dot makes it fully qualified.

  • 3600 the TTL: how many seconds a resolver may cache the record.

  • IN the DNS class (Internet), as on every web record.

  • HTTPS the record type (RFC 9460).

  • 1 the priority. 1 or higher is ServiceMode (this record carries the parameters); 0 is AliasMode, which just points at another target.

  • . the target host. . means the owner name itself, here example.com.

  • alpn="h3,h2" the protocols the server speaks, best first: h3 is HTTP/3, h2 is HTTP/2.

  • ipv4hint / ipv6hint addresses the client can start connecting to right away, alongside its A/AAAA lookups.

Most managed DNS providers (Cloudflare, Route 53, and others) expose an HTTPS record type directly. Verify yours with the checker.

what HTTPS records carry in the wild

Firefox Nightly Of the connections where Firefox saw an HTTPS record, the share whose record carried each feature.

Source: Firefox Nightly, via GLAM. Per-connection estimate reconstructed from GLAM's histograms, so approximate.

faq

Does my CDN publish this automatically?

Some do. Cloudflare, for one, serves an HTTPS record with alpn="h3" automatically for proxied zones. Others leave it to you. The quickest way to find out is to check your domain above.

Will an HTTPS record break older clients?

No. A client that doesn't understand HTTPS records just ignores them and falls back to ordinary A/AAAA lookups (and your Alt-Svc header, if you still send it). Publishing one is strictly additive.

What about repeat visits?

Even better: once a client has spoken HTTP/3 with you, a return visit can resume the QUIC connection in 0-RTT, putting the first request on the wire with no handshake round trip at all. And the HTTPS record itself is cached for its TTL like any DNS answer, so repeat visits usually skip the lookup too.

Which browsers use the HTTPS record to reach HTTP/3?

All the major engines support it and ship it on by default: Chrome, Firefox, and Safari.

Should I drop the Alt-Svc header?

No. Keep sending it as a fallback for anything that did not get the HTTPS record: older clients, and resolvers or networks that do not deliver it. With the record in place, browsers that do read it learn about HTTP/3 from DNS instead, and no longer spend a round trip discovering it.

Lobsters · 9 赞 · 3 评 讨论 → 阅读原文 →

这条对你有帮助吗?