auth_chain_b.go 2.3 KB

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