udp.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package socks
  2. import (
  3. "net"
  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/proxy/socks/protocol"
  8. "github.com/v2ray/v2ray-core/transport/hub"
  9. )
  10. func (this *SocksServer) ListenUDP(port v2net.Port) error {
  11. addr := &net.UDPAddr{
  12. IP: net.IP{0, 0, 0, 0},
  13. Port: int(port),
  14. Zone: "",
  15. }
  16. conn, err := net.ListenUDP("udp", addr)
  17. if err != nil {
  18. log.Error("Socks: failed to listen UDP on port ", port, ": ", err)
  19. return err
  20. }
  21. this.udpMutex.Lock()
  22. this.udpAddress = v2net.UDPDestination(this.config.Address, port)
  23. this.udpConn = conn
  24. this.udpServer = hub.NewUDPServer(this.packetDispatcher)
  25. this.udpMutex.Unlock()
  26. go this.AcceptPackets()
  27. return nil
  28. }
  29. func (this *SocksServer) AcceptPackets() error {
  30. for this.accepting {
  31. buffer := alloc.NewBuffer()
  32. this.udpMutex.RLock()
  33. if !this.accepting {
  34. this.udpMutex.RUnlock()
  35. return nil
  36. }
  37. nBytes, addr, err := this.udpConn.ReadFromUDP(buffer.Value)
  38. this.udpMutex.RUnlock()
  39. if err != nil {
  40. log.Error("Socks: failed to read UDP packets: ", err)
  41. buffer.Release()
  42. continue
  43. }
  44. log.Info("Socks: Client UDP connection from ", addr)
  45. request, err := protocol.ReadUDPRequest(buffer.Value[:nBytes])
  46. buffer.Release()
  47. if err != nil {
  48. log.Error("Socks: failed to parse UDP request: ", err)
  49. continue
  50. }
  51. if request.Data == nil || request.Data.Len() == 0 {
  52. continue
  53. }
  54. if request.Fragment != 0 {
  55. log.Warning("Socks: Dropping fragmented UDP packets.")
  56. // TODO handle fragments
  57. request.Data.Release()
  58. continue
  59. }
  60. udpPacket := v2net.NewPacket(request.Destination(), request.Data, false)
  61. log.Info("Socks: Send packet to ", udpPacket.Destination(), " with ", request.Data.Len(), " bytes")
  62. this.udpServer.Dispatch(
  63. v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port)), udpPacket,
  64. func(packet v2net.Packet) {
  65. response := &protocol.Socks5UDPRequest{
  66. Fragment: 0,
  67. Address: udpPacket.Destination().Address(),
  68. Port: udpPacket.Destination().Port(),
  69. Data: packet.Chunk(),
  70. }
  71. log.Info("Socks: Writing back UDP response with ", response.Data.Len(), " bytes to ", packet.Destination())
  72. udpMessage := alloc.NewSmallBuffer().Clear()
  73. response.Write(udpMessage)
  74. this.udpMutex.RLock()
  75. if !this.accepting {
  76. this.udpMutex.RUnlock()
  77. return
  78. }
  79. nBytes, err := this.udpConn.WriteToUDP(udpMessage.Value, &net.UDPAddr{
  80. IP: packet.Destination().Address().IP(),
  81. Port: int(packet.Destination().Port()),
  82. })
  83. this.udpMutex.RUnlock()
  84. udpMessage.Release()
  85. response.Data.Release()
  86. if err != nil {
  87. log.Error("Socks: failed to write UDP message (", nBytes, " bytes) to ", packet.Destination(), ": ", err)
  88. }
  89. })
  90. }
  91. return nil
  92. }