salamander.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package hysteria2
  2. import (
  3. "net"
  4. "github.com/sagernet/sing/common"
  5. "github.com/sagernet/sing/common/buf"
  6. "github.com/sagernet/sing/common/bufio"
  7. E "github.com/sagernet/sing/common/exceptions"
  8. M "github.com/sagernet/sing/common/metadata"
  9. N "github.com/sagernet/sing/common/network"
  10. "golang.org/x/crypto/blake2b"
  11. )
  12. const salamanderSaltLen = 8
  13. const ObfsTypeSalamander = "salamander"
  14. type Salamander struct {
  15. net.PacketConn
  16. password []byte
  17. }
  18. func NewSalamanderConn(conn net.PacketConn, password []byte) net.PacketConn {
  19. writer, isVectorised := bufio.CreateVectorisedPacketWriter(conn)
  20. if isVectorised {
  21. return &VectorisedSalamander{
  22. Salamander: Salamander{
  23. PacketConn: conn,
  24. password: password,
  25. },
  26. writer: writer,
  27. }
  28. } else {
  29. return &Salamander{
  30. PacketConn: conn,
  31. password: password,
  32. }
  33. }
  34. }
  35. func (s *Salamander) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
  36. n, addr, err = s.PacketConn.ReadFrom(p)
  37. if err != nil {
  38. return
  39. }
  40. if n <= salamanderSaltLen {
  41. return 0, nil, E.New("salamander: packet too short")
  42. }
  43. key := blake2b.Sum256(append(s.password, p[:salamanderSaltLen]...))
  44. for index, c := range p[salamanderSaltLen:n] {
  45. p[index] = c ^ key[index%blake2b.Size256]
  46. }
  47. return n - salamanderSaltLen, addr, nil
  48. }
  49. func (s *Salamander) WriteTo(p []byte, addr net.Addr) (n int, err error) {
  50. buffer := buf.NewSize(len(p) + salamanderSaltLen)
  51. defer buffer.Release()
  52. buffer.WriteRandom(salamanderSaltLen)
  53. key := blake2b.Sum256(append(s.password, buffer.Bytes()...))
  54. for index, c := range p {
  55. common.Must(buffer.WriteByte(c ^ key[index%blake2b.Size256]))
  56. }
  57. _, err = s.PacketConn.WriteTo(buffer.Bytes(), addr)
  58. if err != nil {
  59. return
  60. }
  61. return len(p), nil
  62. }
  63. type VectorisedSalamander struct {
  64. Salamander
  65. writer N.VectorisedPacketWriter
  66. }
  67. func (s *VectorisedSalamander) WriteTo(p []byte, addr net.Addr) (n int, err error) {
  68. buffer := buf.NewSize(salamanderSaltLen)
  69. buffer.WriteRandom(salamanderSaltLen)
  70. key := blake2b.Sum256(append(s.password, buffer.Bytes()...))
  71. for i := range p {
  72. p[i] ^= key[i%blake2b.Size256]
  73. }
  74. err = s.writer.WriteVectorisedPacket([]*buf.Buffer{buffer, buf.As(p)}, M.SocksaddrFromNet(addr))
  75. if err != nil {
  76. return
  77. }
  78. return len(p), nil
  79. }
  80. func (s *VectorisedSalamander) WriteVectorisedPacket(buffers []*buf.Buffer, destination M.Socksaddr) error {
  81. header := buf.NewSize(salamanderSaltLen)
  82. defer header.Release()
  83. header.WriteRandom(salamanderSaltLen)
  84. key := blake2b.Sum256(append(s.password, header.Bytes()...))
  85. var bufferIndex int
  86. for _, buffer := range buffers {
  87. content := buffer.Bytes()
  88. for index, c := range content {
  89. content[bufferIndex+index] = c ^ key[bufferIndex+index%blake2b.Size256]
  90. }
  91. bufferIndex += len(content)
  92. }
  93. return s.writer.WriteVectorisedPacket(append([]*buf.Buffer{header}, buffers...), destination)
  94. }