udp.go 2.5 KB

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