relay-server/ingress/sni.go
2025-12-23 16:38:32 +03:00

74 lines
1.3 KiB
Go

package ingress
import (
"bufio"
"encoding/binary"
"errors"
"io"
"strings"
)
func peekClientHello(r io.Reader) (sni string, hello []byte, err error) {
br := bufio.NewReader(r)
hdr, err := br.Peek(5)
if err != nil {
return "", nil, err
}
if hdr[0] != 0x16 {
return "", nil, errors.New("not TLS handshake")
}
recLen := int(binary.BigEndian.Uint16(hdr[3:5]))
total := 5 + recLen
hello, err = br.Peek(total)
if err != nil {
return "", nil, err
}
data := hello[5:]
if data[0] != 0x01 {
return "", hello, errors.New("not ClientHello")
}
i := 4
i += 2 + 32
sidLen := int(data[i])
i += 1 + sidLen
csLen := int(binary.BigEndian.Uint16(data[i:]))
i += 2 + csLen
compLen := int(data[i])
i += 1 + compLen
extLen := int(binary.BigEndian.Uint16(data[i:]))
i += 2
end := i + extLen
for i+4 <= end {
typ := binary.BigEndian.Uint16(data[i:])
sz := int(binary.BigEndian.Uint16(data[i+2:]))
i += 4
if typ == 0x00 {
l := int(binary.BigEndian.Uint16(data[i:]))
j := i + 2
for j+3 < i+l {
nameType := data[j]
nameLen := int(binary.BigEndian.Uint16(data[j+1:]))
if nameType == 0 {
sni = strings.ToLower(string(data[j+3 : j+3+nameLen]))
return sni, hello, nil
}
j += 3 + nameLen
}
}
i += sz
}
return "", hello, nil
}