handler_udp.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. udpDispatcherConstructor := udp.NewSplitDispatcher
  60. dest := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.LocalAddress), net.Port(id.LocalPort))
  61. src := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.RemoteAddress), net.Port(id.RemotePort))
  62. udpServer := udpDispatcherConstructor(h.dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {
  63. if _, err := conn.WriteTo(packet.Payload.Bytes(), &net.UDPAddr{
  64. IP: src.Address.IP(),
  65. Port: int(src.Port),
  66. }); err != nil {
  67. newError("failed to write UDP packet").Base(err).WriteToLog()
  68. }
  69. })
  70. for {
  71. select {
  72. case <-ctx.Done():
  73. return nil
  74. default:
  75. var buffer [2048]byte
  76. n, _, err := conn.ReadFrom(buffer[:])
  77. if err != nil {
  78. return newError("failed to read UDP packet").Base(err)
  79. }
  80. currentPacketCtx := ctx
  81. udpServer.Dispatch(currentPacketCtx, dest, buf.FromBytes(buffer[:n]))
  82. }
  83. }
  84. }