protocol.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package shadowsocks
  2. import (
  3. "io"
  4. "github.com/v2ray/v2ray-core/common/alloc"
  5. "github.com/v2ray/v2ray-core/common/log"
  6. v2net "github.com/v2ray/v2ray-core/common/net"
  7. "github.com/v2ray/v2ray-core/common/serial"
  8. "github.com/v2ray/v2ray-core/transport"
  9. )
  10. const (
  11. AddrTypeIPv4 = 1
  12. AddrTypeIPv6 = 4
  13. AddrTypeDomain = 3
  14. )
  15. type Request struct {
  16. Address v2net.Address
  17. Port v2net.Port
  18. OTA bool
  19. UDPPayload *alloc.Buffer
  20. }
  21. func ReadRequest(reader io.Reader, auth *Authenticator, udp bool) (*Request, error) {
  22. buffer := alloc.NewSmallBuffer()
  23. defer buffer.Release()
  24. _, err := io.ReadFull(reader, buffer.Value[:1])
  25. if err != nil {
  26. log.Error("Shadowsocks: Failed to read address type: ", err)
  27. return nil, transport.ErrorCorruptedPacket
  28. }
  29. lenBuffer := 1
  30. request := new(Request)
  31. addrType := (buffer.Value[0] & 0x0F)
  32. if (buffer.Value[0] & 0x10) == 0x10 {
  33. request.OTA = true
  34. }
  35. switch addrType {
  36. case AddrTypeIPv4:
  37. _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+4])
  38. if err != nil {
  39. log.Error("Shadowsocks: Failed to read IPv4 address: ", err)
  40. return nil, transport.ErrorCorruptedPacket
  41. }
  42. request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+4])
  43. lenBuffer += 4
  44. case AddrTypeIPv6:
  45. _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+16])
  46. if err != nil {
  47. log.Error("Shadowsocks: Failed to read IPv6 address: ", err)
  48. return nil, transport.ErrorCorruptedPacket
  49. }
  50. request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+16])
  51. lenBuffer += 16
  52. case AddrTypeDomain:
  53. _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+1])
  54. if err != nil {
  55. log.Error("Shadowsocks: Failed to read domain lenth: ", err)
  56. return nil, transport.ErrorCorruptedPacket
  57. }
  58. domainLength := int(buffer.Value[lenBuffer])
  59. lenBuffer++
  60. _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+domainLength])
  61. if err != nil {
  62. log.Error("Shadowsocks: Failed to read domain: ", err)
  63. return nil, transport.ErrorCorruptedPacket
  64. }
  65. request.Address = v2net.DomainAddress(string(buffer.Value[lenBuffer : lenBuffer+domainLength]))
  66. lenBuffer += domainLength
  67. default:
  68. log.Error("Shadowsocks: Unknown address type: ", addrType)
  69. return nil, transport.ErrorCorruptedPacket
  70. }
  71. _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+2])
  72. if err != nil {
  73. log.Error("Shadowsocks: Failed to read port: ", err)
  74. return nil, transport.ErrorCorruptedPacket
  75. }
  76. request.Port = v2net.PortFromBytes(buffer.Value[lenBuffer : lenBuffer+2])
  77. lenBuffer += 2
  78. var authBytes []byte
  79. if udp {
  80. nBytes, err := reader.Read(buffer.Value[lenBuffer:])
  81. if err != nil {
  82. log.Error("Shadowsocks: Failed to read UDP payload: ", err)
  83. return nil, transport.ErrorCorruptedPacket
  84. }
  85. buffer.Slice(0, lenBuffer+nBytes)
  86. if request.OTA {
  87. authBytes = buffer.Value[lenBuffer+nBytes-AuthSize:]
  88. request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer : lenBuffer+nBytes-AuthSize])
  89. lenBuffer = lenBuffer + nBytes - AuthSize
  90. } else {
  91. request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer:])
  92. }
  93. } else {
  94. if request.OTA {
  95. authBytes = buffer.Value[lenBuffer : lenBuffer+AuthSize]
  96. _, err = io.ReadFull(reader, authBytes)
  97. if err != nil {
  98. log.Error("Shadowsocks: Failed to read OTA: ", err)
  99. return nil, transport.ErrorCorruptedPacket
  100. }
  101. }
  102. }
  103. if request.OTA {
  104. actualAuth := auth.Authenticate(nil, buffer.Value[0:lenBuffer])
  105. if !serial.BytesLiteral(actualAuth).Equals(serial.BytesLiteral(authBytes)) {
  106. log.Error("Shadowsocks: Invalid OTA: ", actualAuth)
  107. return nil, transport.ErrorCorruptedPacket
  108. }
  109. }
  110. return request, nil
  111. }