Skip to content

Commit b5468f5

Browse files
committed
Pad certificate queries enough to retrieve PQ certs over UDP
An anonymized relay forwards certificate queries to the upstream resolver over UDP only, and both the resolver and the relay refuse to return a UDP response larger than the request that triggered it. A post-quantum certificate is about 1.3 KB, so a small certificate probe came back truncated to the classical certificate alone, and the proxy never learned that the resolver supported X-Wing when it was reached through a relay. Pad the large certificate probe well past the response size to fix this.
1 parent d164a54 commit b5468f5

1 file changed

Lines changed: 16 additions & 2 deletions

File tree

dnscrypt-proxy/dnsutils.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,20 @@ type DNSExchangeResponse struct {
348348
err error
349349
}
350350

351+
// A resolver and an Anonymized DNSCrypt relay both refuse to return a UDP
352+
// response larger than the request that triggered it, so a post-quantum
353+
// certificate only comes back over UDP when the certificate probe is padded past
354+
// the response. A PQ certificate is ~1.3 KB, ~1.5 KB once paired with the classical
355+
// certificate; during a key rotation the set doubles to two classical plus two PQ
356+
// certificates, roughly 3 KB. The large probe is padded past that rollover size so
357+
// PQ discovery keeps working through relays even mid-rotation. The fragments-blocked
358+
// probe stays small on purpose, so a PQ resolver truncates it and we still learn of
359+
// PQ support through the TC bit and fall back to TCP.
360+
const (
361+
certProbePaddedLen = 3200
362+
certProbeFragmentsBlockedLen = 480
363+
)
364+
351365
func DNSExchange(
352366
proxy *Proxy,
353367
proto string,
@@ -374,7 +388,7 @@ func DNSExchange(
374388
select {
375389
case <-cancelChannel:
376390
default:
377-
option = _dnsExchange(proxy, proto, query, serverAddress, relay, 1500)
391+
option = _dnsExchange(proxy, proto, query, serverAddress, relay, certProbePaddedLen)
378392
}
379393
option.fragmentsBlocked = false
380394
option.priority = 0
@@ -390,7 +404,7 @@ func DNSExchange(
390404
select {
391405
case <-cancelChannel:
392406
default:
393-
option = _dnsExchange(proxy, proto, query, serverAddress, relay, 480)
407+
option = _dnsExchange(proxy, proto, query, serverAddress, relay, certProbeFragmentsBlockedLen)
394408
}
395409
option.fragmentsBlocked = true
396410
option.priority = 1

0 commit comments

Comments
 (0)