修复解析https+ip偶发出现sni乱码的BUG

This commit is contained in:
lanrenwo
2022-10-19 11:23:17 +08:00
parent 522f723b51
commit 84286de8a4
3 changed files with 48 additions and 24 deletions

View File

@@ -9,7 +9,7 @@ import (
)
var tcpParsers = []func([]byte) (uint8, string){
sniParser,
sniNewParser,
httpParser,
}
@@ -21,7 +21,7 @@ func onTCP(payload []byte) (uint8, string) {
}
data := payload[ihl:]
for _, parser := range tcpParsers {
if proto, info := parser(data); info != "" {
if proto, info := parser(data); proto != acc_proto_tcp {
return proto, info
}
}
@@ -29,8 +29,7 @@ func onTCP(payload []byte) (uint8, string) {
}
func sniNewParser(b []byte) (uint8, string) {
dataSize := len(b)
if dataSize < 2 || b[0] != 0x16 || b[1] != 0x03 {
if len(b) < 2 || b[0] != 0x16 || b[1] != 0x03 {
return acc_proto_tcp, ""
}
rest := b[5:]
@@ -51,27 +50,27 @@ func sniNewParser(b []byte) (uint8, string) {
// Skip over random number
current += 4 + 28
if current >= restLen {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
// Skip over session ID
sessionIDLength := int(rest[current])
current += 1
current += sessionIDLength
if current >= restLen {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
cipherSuiteLength := (int(rest[current]) << 8) + int(rest[current+1])
current += 2
current += cipherSuiteLength
if current >= restLen {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
compressionMethodLength := int(rest[current])
current += 1
current += compressionMethodLength
if current >= restLen {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
current += 2
hostname := ""
@@ -84,27 +83,30 @@ func sniNewParser(b []byte) (uint8, string) {
// Skip over number of names as we're assuming there's just one
current += 2
if current >= restLen {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
nameType := rest[current]
current += 1
if nameType != 0 {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
if current+1 >= restLen {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
nameLen := (int(rest[current]) << 8) + int(rest[current+1])
current += 2
if current+nameLen >= restLen {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
hostname = string(rest[current : current+nameLen])
}
current += extensionDataLength
}
if hostname == "" {
return acc_proto_tcp, ""
return acc_proto_https, ""
}
if !validDomainChar(hostname) {
return acc_proto_https, ""
}
return acc_proto_https, hostname
}
@@ -150,8 +152,7 @@ func httpNewParser(data []byte) (uint8, string) {
}
func sniParser(data []byte) (uint8, string) {
dataSize := len(data)
if dataSize < 2 || data[0] != 0x16 || data[1] != 0x03 {
if len(data) < 2 || data[0] != 0x16 || data[1] != 0x03 {
return acc_proto_tcp, ""
}
sniRe := regexp.MustCompile("\x00\x00.{4}\x00.{2}([a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,6})\x00")
@@ -169,3 +170,15 @@ func httpParser(data []byte) (uint8, string) {
}
return acc_proto_tcp, ""
}
// 校验域名的合法字符, 处理乱码问题
func validDomainChar(addr string) bool {
// Allow a-z A-Z . - 0-9
for i := 0; i < len(addr); i++ {
c := addr[i]
if !((c >= 97 && c <= 122) || (c >= 65 && c <= 90) || (c >= 45 && c <= 46) || (c >= 48 && c <= 57)) {
return false
}
}
return true
}