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  }