udp.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package protocol
  2. import (
  3. "v2ray.com/core/common/buf"
  4. "v2ray.com/core/common/errors"
  5. v2net "v2ray.com/core/common/net"
  6. "v2ray.com/core/common/serial"
  7. )
  8. var (
  9. ErrorUnknownAddressType = errors.New("Unknown Address Type.")
  10. )
  11. type Socks5UDPRequest struct {
  12. Fragment byte
  13. Address v2net.Address
  14. Port v2net.Port
  15. Data *buf.Buffer
  16. }
  17. func (request *Socks5UDPRequest) Destination() v2net.Destination {
  18. return v2net.UDPDestination(request.Address, request.Port)
  19. }
  20. func (request *Socks5UDPRequest) Write(buffer *buf.Buffer) {
  21. buffer.AppendBytes(0, 0, request.Fragment)
  22. switch request.Address.Family() {
  23. case v2net.AddressFamilyIPv4:
  24. buffer.AppendBytes(AddrTypeIPv4)
  25. buffer.Append(request.Address.IP())
  26. case v2net.AddressFamilyIPv6:
  27. buffer.AppendBytes(AddrTypeIPv6)
  28. buffer.Append(request.Address.IP())
  29. case v2net.AddressFamilyDomain:
  30. buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
  31. buffer.Append([]byte(request.Address.Domain()))
  32. }
  33. buffer.AppendSupplier(serial.WriteUint16(request.Port.Value()))
  34. buffer.Append(request.Data.Bytes())
  35. }
  36. func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) {
  37. if len(packet) < 5 {
  38. return nil, errors.New("Socks|UDP: Insufficient length of packet.")
  39. }
  40. request := new(Socks5UDPRequest)
  41. // packet[0] and packet[1] are reserved
  42. request.Fragment = packet[2]
  43. addrType := packet[3]
  44. var dataBegin int
  45. switch addrType {
  46. case AddrTypeIPv4:
  47. if len(packet) < 10 {
  48. return nil, errors.New("Socks|UDP: Insufficient length of packet.")
  49. }
  50. ip := packet[4:8]
  51. request.Port = v2net.PortFromBytes(packet[8:10])
  52. request.Address = v2net.IPAddress(ip)
  53. dataBegin = 10
  54. case AddrTypeIPv6:
  55. if len(packet) < 22 {
  56. return nil, errors.New("Socks|UDP: Insufficient length of packet.")
  57. }
  58. ip := packet[4:20]
  59. request.Port = v2net.PortFromBytes(packet[20:22])
  60. request.Address = v2net.IPAddress(ip)
  61. dataBegin = 22
  62. case AddrTypeDomain:
  63. domainLength := int(packet[4])
  64. if len(packet) < 5+domainLength+2 {
  65. return nil, errors.New("Socks|UDP: Insufficient length of packet.")
  66. }
  67. domain := string(packet[5 : 5+domainLength])
  68. request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
  69. request.Address = v2net.ParseAddress(domain)
  70. dataBegin = 5 + domainLength + 2
  71. default:
  72. return nil, errors.Format("Socks|UDP: Unknown address type %d", addrType)
  73. }
  74. if len(packet) > dataBegin {
  75. b := buf.NewSmall()
  76. b.Append(packet[dataBegin:])
  77. request.Data = b
  78. }
  79. return request, nil
  80. }