server_udp.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package socks
  2. import (
  3. "github.com/v2ray/v2ray-core/common/alloc"
  4. "github.com/v2ray/v2ray-core/common/log"
  5. v2net "github.com/v2ray/v2ray-core/common/net"
  6. "github.com/v2ray/v2ray-core/proxy"
  7. "github.com/v2ray/v2ray-core/proxy/socks/protocol"
  8. "github.com/v2ray/v2ray-core/transport/internet/udp"
  9. )
  10. func (this *Server) listenUDP() error {
  11. this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher)
  12. udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPayload)
  13. if err != nil {
  14. log.Error("Socks: Failed to listen on udp ", this.meta.Address, ":", this.meta.Port)
  15. return err
  16. }
  17. this.udpMutex.Lock()
  18. this.udpAddress = v2net.UDPDestination(this.config.Address, this.meta.Port)
  19. this.udpHub = udpHub
  20. this.udpMutex.Unlock()
  21. return nil
  22. }
  23. func (this *Server) handleUDPPayload(payload *alloc.Buffer, source v2net.Destination) {
  24. log.Info("Socks: Client UDP connection from ", source)
  25. request, err := protocol.ReadUDPRequest(payload.Value)
  26. payload.Release()
  27. if err != nil {
  28. log.Error("Socks: Failed to parse UDP request: ", err)
  29. return
  30. }
  31. if request.Data.Len() == 0 {
  32. request.Data.Release()
  33. return
  34. }
  35. if request.Fragment != 0 {
  36. log.Warning("Socks: Dropping fragmented UDP packets.")
  37. // TODO handle fragments
  38. request.Data.Release()
  39. return
  40. }
  41. log.Info("Socks: Send packet to ", request.Destination(), " with ", request.Data.Len(), " bytes")
  42. log.Access(source, request.Destination, log.AccessAccepted, "")
  43. this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: request.Destination()}, request.Data, func(destination v2net.Destination, payload *alloc.Buffer) {
  44. response := &protocol.Socks5UDPRequest{
  45. Fragment: 0,
  46. Address: request.Destination().Address(),
  47. Port: request.Destination().Port(),
  48. Data: payload,
  49. }
  50. log.Info("Socks: Writing back UDP response with ", payload.Len(), " bytes to ", destination)
  51. udpMessage := alloc.NewLocalBuffer(2048).Clear()
  52. response.Write(udpMessage)
  53. this.udpMutex.RLock()
  54. if !this.accepting {
  55. this.udpMutex.RUnlock()
  56. return
  57. }
  58. nBytes, err := this.udpHub.WriteTo(udpMessage.Value, destination)
  59. this.udpMutex.RUnlock()
  60. udpMessage.Release()
  61. response.Data.Release()
  62. if err != nil {
  63. log.Error("Socks: failed to write UDP message (", nBytes, " bytes) to ", destination, ": ", err)
  64. }
  65. })
  66. }