handler_udp.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package tun
  2. import (
  3. "context"
  4. "github.com/v2fly/v2ray-core/v5/common/buf"
  5. "github.com/v2fly/v2ray-core/v5/common/net"
  6. "github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
  7. udp_proto "github.com/v2fly/v2ray-core/v5/common/protocol/udp"
  8. "github.com/v2fly/v2ray-core/v5/features/policy"
  9. "github.com/v2fly/v2ray-core/v5/features/routing"
  10. "github.com/v2fly/v2ray-core/v5/transport/internet/udp"
  11. "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
  12. "gvisor.dev/gvisor/pkg/tcpip/stack"
  13. gvisor_udp "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
  14. "gvisor.dev/gvisor/pkg/waiter"
  15. )
  16. type UDPHandler struct {
  17. ctx context.Context
  18. dispatcher routing.Dispatcher
  19. policyManager policy.Manager
  20. config *Config
  21. stack *stack.Stack
  22. }
  23. func SetUDPHandler(ctx context.Context, dispatcher routing.Dispatcher, policyManager policy.Manager, config *Config) StackOption {
  24. return func(s *stack.Stack) error {
  25. udpForwarder := gvisor_udp.NewForwarder(s, func(r *gvisor_udp.ForwarderRequest) {
  26. wg := new(waiter.Queue)
  27. linkedEndpoint, err := r.CreateEndpoint(wg)
  28. if err != nil {
  29. // TODO: log
  30. return
  31. }
  32. udpConn := gonet.NewUDPConn(s, wg, linkedEndpoint)
  33. udpHandler := &UDPHandler{
  34. ctx: ctx,
  35. dispatcher: dispatcher,
  36. policyManager: policyManager,
  37. config: config,
  38. stack: s,
  39. }
  40. udpHandler.Handle(udpConn)
  41. })
  42. s.SetTransportProtocolHandler(gvisor_udp.ProtocolNumber, udpForwarder.HandlePacket)
  43. return nil
  44. }
  45. }
  46. func (h *UDPHandler) Handle(conn net.Conn) error {
  47. ctx := h.ctx
  48. packetConn := conn.(net.PacketConn)
  49. udpDispatcherConstructor := udp.NewSplitDispatcher
  50. switch h.config.PacketEncoding {
  51. case packetaddr.PacketAddrType_None:
  52. break
  53. case packetaddr.PacketAddrType_Packet:
  54. packetAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx)
  55. udpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher
  56. }
  57. udpServer := udpDispatcherConstructor(h.dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {
  58. if _, err := packetConn.WriteTo(packet.Payload.Bytes(), &net.UDPAddr{
  59. IP: packet.Source.Address.IP(),
  60. Port: int(packet.Source.Port),
  61. }); err != nil {
  62. newError("failed to write UDP packet").Base(err).WriteToLog()
  63. }
  64. })
  65. for {
  66. select {
  67. case <-ctx.Done():
  68. return nil
  69. default:
  70. var buffer [2048]byte
  71. n, addr, err := packetConn.ReadFrom(buffer[:])
  72. if err != nil {
  73. return newError("failed to read UDP packet").Base(err)
  74. }
  75. currentPacketCtx := ctx
  76. udpServer.Dispatch(currentPacketCtx, net.DestinationFromAddr(addr), buf.FromBytes(buffer[:n]))
  77. }
  78. }
  79. }