Skip to content

Commit a4f31bc

Browse files
committed
Fix ECH SVCB interception
1 parent c7c2a50 commit a4f31bc

File tree

2 files changed

+382
-0
lines changed

2 files changed

+382
-0
lines changed

naive_dns.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"io"
2020
"net"
2121
"net/netip"
22+
"strconv"
2223
"strings"
2324
"time"
2425

@@ -287,11 +288,20 @@ func injectECHConfig(request *mDNS.Msg, response *mDNS.Msg, echConfig []byte, al
287288
response.SetReply(request)
288289
}
289290

291+
var servicePort uint16
292+
var hasServicePort bool
293+
if len(request.Question) > 0 {
294+
servicePort, hasServicePort = parseHTTPSServicePort(request.Question[0].Name)
295+
}
296+
290297
hasHTTPS := false
291298
for _, rr := range response.Answer {
292299
if https, ok := rr.(*mDNS.HTTPS); ok {
293300
hasHTTPS = true
294301
updateECHInSVCB(&https.SVCB, echConfig)
302+
if hasServicePort {
303+
updatePortInSVCB(&https.SVCB, servicePort)
304+
}
295305
}
296306
}
297307

@@ -317,6 +327,9 @@ func injectECHConfig(request *mDNS.Msg, response *mDNS.Msg, echConfig []byte, al
317327
Target: targetName,
318328
},
319329
}
330+
if hasServicePort {
331+
https.Value = append(https.Value, &mDNS.SVCBPort{Port: servicePort})
332+
}
320333
https.Value = append(https.Value, &mDNS.SVCBAlpn{Alpn: alpn})
321334
https.Value = append(https.Value, &mDNS.SVCBECHConfig{ECH: echConfig})
322335
response.Answer = append(response.Answer, https)
@@ -335,6 +348,32 @@ func updateECHInSVCB(svcb *mDNS.SVCB, echConfig []byte) {
335348
svcb.Value = append(svcb.Value, &mDNS.SVCBECHConfig{ECH: echConfig})
336349
}
337350

351+
func updatePortInSVCB(svcb *mDNS.SVCB, port uint16) {
352+
for i, kv := range svcb.Value {
353+
if _, ok := kv.(*mDNS.SVCBPort); ok {
354+
svcb.Value[i] = &mDNS.SVCBPort{Port: port}
355+
return
356+
}
357+
}
358+
svcb.Value = append(svcb.Value, &mDNS.SVCBPort{Port: port})
359+
}
360+
361+
func parseHTTPSServicePort(queryName string) (uint16, bool) {
362+
trimmedName := strings.TrimSuffix(queryName, ".")
363+
if !strings.HasPrefix(trimmedName, "_") {
364+
return 0, false
365+
}
366+
parts := strings.SplitN(trimmedName, "._https.", 2)
367+
if len(parts) != 2 {
368+
return 0, false
369+
}
370+
portValue, err := strconv.Atoi(strings.TrimPrefix(parts[0], "_"))
371+
if err != nil || portValue <= 0 || portValue > 65535 {
372+
return 0, false
373+
}
374+
return uint16(portValue), true
375+
}
376+
338377
func filterIPHintsFromHTTPS(response *mDNS.Msg) {
339378
if response == nil {
340379
return

0 commit comments

Comments
 (0)