-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
filter.go
90 lines (83 loc) · 2.45 KB
/
filter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package vision
import (
"bytes"
"encoding/binary"
"github.com/metacubex/mihomo/log"
)
var (
tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
tlsClientHandshakeStart = []byte{0x16, 0x03}
tlsServerHandshakeStart = []byte{0x16, 0x03, 0x03}
tlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
tls13CipherSuiteMap = map[uint16]string{
0x1301: "TLS_AES_128_GCM_SHA256",
0x1302: "TLS_AES_256_GCM_SHA384",
0x1303: "TLS_CHACHA20_POLY1305_SHA256",
0x1304: "TLS_AES_128_CCM_SHA256",
0x1305: "TLS_AES_128_CCM_8_SHA256",
}
)
const (
tlsHandshakeTypeClientHello byte = 0x01
tlsHandshakeTypeServerHello byte = 0x02
)
func (vc *Conn) FilterTLS(buffer []byte) (index int) {
if vc.packetsToFilter <= 0 {
return 0
}
lenP := len(buffer)
vc.packetsToFilter--
if index = bytes.Index(buffer, tlsServerHandshakeStart); index != -1 {
if lenP > index+5 {
if buffer[0] == 22 && buffer[1] == 3 && buffer[2] == 3 {
vc.isTLS = true
if buffer[5] == tlsHandshakeTypeServerHello {
//log.Debugln("isTLS12orAbove")
vc.remainingServerHello = binary.BigEndian.Uint16(buffer[index+3:]) + 5
vc.isTLS12orAbove = true
if lenP-index >= 79 && vc.remainingServerHello >= 79 {
sessionIDLen := int(buffer[index+43])
vc.cipher = binary.BigEndian.Uint16(buffer[index+43+sessionIDLen+1:])
}
}
}
}
} else if index = bytes.Index(buffer, tlsClientHandshakeStart); index != -1 {
if lenP > index+5 && buffer[index+5] == tlsHandshakeTypeClientHello {
vc.isTLS = true
}
}
if vc.remainingServerHello > 0 {
end := int(vc.remainingServerHello)
i := index
if i < 0 {
i = 0
}
if i+end > lenP {
end = lenP
vc.remainingServerHello -= uint16(end - i)
} else {
vc.remainingServerHello -= uint16(end)
end += i
}
if bytes.Contains(buffer[i:end], tls13SupportedVersions) {
// TLS 1.3 Client Hello
cs, ok := tls13CipherSuiteMap[vc.cipher]
if ok && cs != "TLS_AES_128_CCM_8_SHA256" {
vc.enableXTLS = true
}
log.Debugln("XTLS Vision found TLS 1.3, packetLength=%d, CipherSuite=%s", lenP, cs)
vc.packetsToFilter = 0
return
} else if vc.remainingServerHello <= 0 {
log.Debugln("XTLS Vision found TLS 1.2, packetLength=%d", lenP)
vc.packetsToFilter = 0
return
}
log.Debugln("XTLS Vision found inconclusive server hello, packetLength=%d, remainingServerHelloBytes=%d", lenP, vc.remainingServerHello)
}
if vc.packetsToFilter <= 0 {
log.Debugln("XTLS Vision stop filtering")
}
return
}