github.com/kelleygo/clashcore@v1.0.2/transport/ssr/protocol/protocol.go (about) 1 package protocol 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "net" 8 9 N "github.com/kelleygo/clashcore/common/net" 10 11 "github.com/zhangyunhao116/fastrand" 12 ) 13 14 var ( 15 errAuthSHA1V4CRC32Error = errors.New("auth_sha1_v4 decode data wrong crc32") 16 errAuthSHA1V4LengthError = errors.New("auth_sha1_v4 decode data wrong length") 17 errAuthSHA1V4Adler32Error = errors.New("auth_sha1_v4 decode data wrong adler32") 18 errAuthAES128MACError = errors.New("auth_aes128 decode data wrong mac") 19 errAuthAES128LengthError = errors.New("auth_aes128 decode data wrong length") 20 errAuthAES128ChksumError = errors.New("auth_aes128 decode data wrong checksum") 21 errAuthChainLengthError = errors.New("auth_chain decode data wrong length") 22 errAuthChainChksumError = errors.New("auth_chain decode data wrong checksum") 23 ) 24 25 type Protocol interface { 26 StreamConn(net.Conn, []byte) net.Conn 27 PacketConn(N.EnhancePacketConn) N.EnhancePacketConn 28 Decode(dst, src *bytes.Buffer) error 29 Encode(buf *bytes.Buffer, b []byte) error 30 DecodePacket([]byte) ([]byte, error) 31 EncodePacket(buf *bytes.Buffer, b []byte) error 32 } 33 34 type protocolCreator func(b *Base) Protocol 35 36 var protocolList = make(map[string]struct { 37 overhead int 38 new protocolCreator 39 }) 40 41 func register(name string, c protocolCreator, o int) { 42 protocolList[name] = struct { 43 overhead int 44 new protocolCreator 45 }{overhead: o, new: c} 46 } 47 48 func PickProtocol(name string, b *Base) (Protocol, error) { 49 if choice, ok := protocolList[name]; ok { 50 b.Overhead += choice.overhead 51 return choice.new(b), nil 52 } 53 return nil, fmt.Errorf("protocol %s not supported", name) 54 } 55 56 func getHeadSize(b []byte, defaultValue int) int { 57 if len(b) < 2 { 58 return defaultValue 59 } 60 headType := b[0] & 7 61 switch headType { 62 case 1: 63 return 7 64 case 4: 65 return 19 66 case 3: 67 return 4 + int(b[1]) 68 } 69 return defaultValue 70 } 71 72 func getDataLength(b []byte) int { 73 bLength := len(b) 74 dataLength := getHeadSize(b, 30) + fastrand.Intn(32) 75 if bLength < dataLength { 76 return bLength 77 } 78 return dataLength 79 }