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