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