github.com/metacubex/mihomo@v1.18.5/transport/ssr/protocol/auth_chain_b.go (about) 1 package protocol 2 3 import ( 4 "net" 5 "sort" 6 7 "github.com/metacubex/mihomo/transport/ssr/tools" 8 ) 9 10 func init() { 11 register("auth_chain_b", newAuthChainB, 4) 12 } 13 14 type authChainB struct { 15 *authChainA 16 dataSizeList []int 17 dataSizeList2 []int 18 } 19 20 func newAuthChainB(b *Base) Protocol { 21 a := &authChainB{ 22 authChainA: &authChainA{ 23 Base: b, 24 authData: &authData{}, 25 userData: &userData{}, 26 salt: "auth_chain_b", 27 }, 28 } 29 a.initUserData() 30 return a 31 } 32 33 func (a *authChainB) StreamConn(c net.Conn, iv []byte) net.Conn { 34 p := &authChainB{ 35 authChainA: &authChainA{ 36 Base: a.Base, 37 authData: a.next(), 38 userData: a.userData, 39 salt: a.salt, 40 packID: 1, 41 recvID: 1, 42 }, 43 } 44 p.iv = iv 45 p.randDataLength = p.getRandLength 46 p.initDataSize() 47 return &Conn{Conn: c, Protocol: p} 48 } 49 50 func (a *authChainB) initDataSize() { 51 a.dataSizeList = a.dataSizeList[:0] 52 a.dataSizeList2 = a.dataSizeList2[:0] 53 54 a.randomServer.InitFromBin(a.Key) 55 length := a.randomServer.Next()%8 + 4 56 for ; length > 0; length-- { 57 a.dataSizeList = append(a.dataSizeList, int(a.randomServer.Next()%2340%2040%1440)) 58 } 59 sort.Ints(a.dataSizeList) 60 61 length = a.randomServer.Next()%16 + 8 62 for ; length > 0; length-- { 63 a.dataSizeList2 = append(a.dataSizeList2, int(a.randomServer.Next()%2340%2040%1440)) 64 } 65 sort.Ints(a.dataSizeList2) 66 } 67 68 func (a *authChainB) getRandLength(length int, lashHash []byte, random *tools.XorShift128Plus) int { 69 if length >= 1440 { 70 return 0 71 } 72 random.InitFromBinAndLength(lashHash, length) 73 pos := sort.Search(len(a.dataSizeList), func(i int) bool { return a.dataSizeList[i] >= length+a.Overhead }) 74 finalPos := pos + int(random.Next()%uint64(len(a.dataSizeList))) 75 if finalPos < len(a.dataSizeList) { 76 return a.dataSizeList[finalPos] - length - a.Overhead 77 } 78 79 pos = sort.Search(len(a.dataSizeList2), func(i int) bool { return a.dataSizeList2[i] >= length+a.Overhead }) 80 finalPos = pos + int(random.Next()%uint64(len(a.dataSizeList2))) 81 if finalPos < len(a.dataSizeList2) { 82 return a.dataSizeList2[finalPos] - length - a.Overhead 83 } 84 if finalPos < pos+len(a.dataSizeList2)-1 { 85 return 0 86 } 87 if length > 1300 { 88 return int(random.Next() % 31) 89 } 90 if length > 900 { 91 return int(random.Next() % 127) 92 } 93 if length > 400 { 94 return int(random.Next() % 521) 95 } 96 return int(random.Next() % 1021) 97 }