server_udp.go 2.3 KB

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