@@ -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+
338377func filterIPHintsFromHTTPS (response * mDNS.Msg ) {
339378 if response == nil {
340379 return
0 commit comments