From 43589ee243b8e541e7c812fdc62f8f3ae15bfdb1 Mon Sep 17 00:00:00 2001 From: mzz2017 <2017@duck.com> Date: Sat, 18 Feb 2023 01:48:56 +0800 Subject: [PATCH] fix(tls sniff): may be multiple types SNI in an extension --- component/sniffing/tls.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/component/sniffing/tls.go b/component/sniffing/tls.go index 22c6b20..b7e9991 100644 --- a/component/sniffing/tls.go +++ b/component/sniffing/tls.go @@ -9,6 +9,7 @@ import ( "bytes" "encoding/binary" "github.com/v2rayA/dae/component/sniffing/internal/quicutils" + "strings" ) const ( @@ -114,22 +115,27 @@ func findSniExtension(search quicutils.Locator) (string, error) { return "", NotApplicableError } if typ == TlsExtension_ServerName { - b = search.Range(i+4, i+9) + b = search.Range(i+4, i+6) sniLen := int(binary.BigEndian.Uint16(b)) - if extLength != sniLen+2 { + if extLength < sniLen+2 { return "", NotApplicableError } - // There may be multiple server names, we only pick the first. - if b[2] != TlsExtension_ServerNameType_HostName { - return "", NotApplicableError + // Search HostName type SNI. + for j, indicatorLen := i+6, 0; j+3 <= iNextField; j += indicatorLen { + b = search.Range(j, j+3) + indicatorLen = int(binary.BigEndian.Uint16(b[1:])) + if b[0] != TlsExtension_ServerNameType_HostName { + continue + } + if j+3+indicatorLen > iNextField { + return "", NotApplicableError + } + b = search.Range(j+3, j+3+indicatorLen) + // An SNI value may not include a trailing dot. + // https://tools.ietf.org/html/rfc6066#section-3 + // But we accept it here. + return strings.TrimSuffix(string(b), "."), nil } - snLen := int(binary.BigEndian.Uint16(b[3:])) - if i+9+snLen > iNextField { - return "", NotApplicableError - } - b = search.Range(i+9, i+9+snLen) - sni := string(b) - return sni, nil } i = iNextField }