handler_udp.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package tun
  2. import (
  3. "context"
  4. "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
  5. "gvisor.dev/gvisor/pkg/tcpip/stack"
  6. gvisor_udp "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
  7. "gvisor.dev/gvisor/pkg/waiter"
  8. tun_net "github.com/v2fly/v2ray-core/v5/app/tun/net"
  9. "github.com/v2fly/v2ray-core/v5/common/buf"
  10. "github.com/v2fly/v2ray-core/v5/common/net"
  11. udp_proto "github.com/v2fly/v2ray-core/v5/common/protocol/udp"
  12. "github.com/v2fly/v2ray-core/v5/common/session"
  13. "github.com/v2fly/v2ray-core/v5/features/policy"
  14. "github.com/v2fly/v2ray-core/v5/features/routing"
  15. "github.com/v2fly/v2ray-core/v5/transport/internet/udp"
  16. )
  17. type UDPHandler struct {
  18. ctx context.Context
  19. dispatcher routing.Dispatcher
  20. policyManager policy.Manager
  21. config *Config
  22. }
  23. type udpConn struct {
  24. *gonet.UDPConn
  25. id stack.TransportEndpointID
  26. }
  27. func (c *udpConn) ID() *stack.TransportEndpointID {
  28. return &c.id
  29. }
  30. func SetUDPHandler(ctx context.Context, dispatcher routing.Dispatcher, policyManager policy.Manager, config *Config) StackOption {
  31. return func(s *stack.Stack) error {
  32. udpForwarder := gvisor_udp.NewForwarder(s, func(r *gvisor_udp.ForwarderRequest) {
  33. wg := new(waiter.Queue)
  34. linkedEndpoint, err := r.CreateEndpoint(wg)
  35. if err != nil {
  36. newError("failed to create endpoint: ", err).WriteToLog(session.ExportIDToError(ctx))
  37. return
  38. }
  39. conn := &udpConn{
  40. UDPConn: gonet.NewUDPConn(s, wg, linkedEndpoint),
  41. id: r.ID(),
  42. }
  43. handler := &UDPHandler{
  44. ctx: ctx,
  45. dispatcher: dispatcher,
  46. policyManager: policyManager,
  47. config: config,
  48. }
  49. go handler.Handle(conn)
  50. })
  51. s.SetTransportProtocolHandler(gvisor_udp.ProtocolNumber, udpForwarder.HandlePacket)
  52. return nil
  53. }
  54. }
  55. func (h *UDPHandler) Handle(conn tun_net.UDPConn) error {
  56. defer conn.Close()
  57. id := conn.ID()
  58. ctx := session.ContextWithInbound(h.ctx, &session.Inbound{Tag: h.config.Tag})
  59. content := new(session.Content)
  60. if h.config.SniffingSettings != nil {
  61. content.SniffingRequest.Enabled = h.config.SniffingSettings.Enabled
  62. content.SniffingRequest.OverrideDestinationForProtocol = h.config.SniffingSettings.DestinationOverride
  63. content.SniffingRequest.MetadataOnly = h.config.SniffingSettings.MetadataOnly
  64. }
  65. ctx = session.ContextWithContent(ctx, content)
  66. udpDispatcherConstructor := udp.NewSplitDispatcher
  67. dest := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.LocalAddress), net.Port(id.LocalPort))
  68. src := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.RemoteAddress), net.Port(id.RemotePort))
  69. udpServer := udpDispatcherConstructor(h.dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {
  70. if _, err := conn.WriteTo(packet.Payload.Bytes(), &net.UDPAddr{
  71. IP: src.Address.IP(),
  72. Port: int(src.Port),
  73. }); err != nil {
  74. newError("failed to write UDP packet").Base(err).WriteToLog()
  75. }
  76. })
  77. for {
  78. select {
  79. case <-ctx.Done():
  80. return nil
  81. default:
  82. var buffer [2048]byte
  83. n, _, err := conn.ReadFrom(buffer[:])
  84. if err != nil {
  85. return newError("failed to read UDP packet").Base(err)
  86. }
  87. currentPacketCtx := ctx
  88. udpServer.Dispatch(currentPacketCtx, dest, buf.FromBytes(buffer[:n]))
  89. }
  90. }
  91. }