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