github.com/chwjbn/xclash@v0.2.0/transport/ssr/protocol/auth_chain_b.go (about)

     1  package protocol
     2  
     3  import (
     4  	"net"
     5  	"sort"
     6  
     7  	"github.com/chwjbn/xclash/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  }