udp.go 2.4 KB

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