1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-18 02:16:10 -05:00
v2fly/app/tun/handler_udp.go

107 lines
3.1 KiB
Go
Raw Normal View History

2023-05-28 03:16:37 -04:00
package tun
import (
"context"
2023-10-22 20:44:36 -04:00
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
"gvisor.dev/gvisor/pkg/tcpip/stack"
gvisor_udp "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
"gvisor.dev/gvisor/pkg/waiter"
2023-05-28 10:22:59 -04:00
tun_net "github.com/v2fly/v2ray-core/v5/app/tun/net"
2023-05-28 03:16:37 -04:00
"github.com/v2fly/v2ray-core/v5/common/buf"
"github.com/v2fly/v2ray-core/v5/common/net"
udp_proto "github.com/v2fly/v2ray-core/v5/common/protocol/udp"
2023-05-28 05:00:50 -04:00
"github.com/v2fly/v2ray-core/v5/common/session"
2023-05-28 03:16:37 -04:00
"github.com/v2fly/v2ray-core/v5/features/policy"
"github.com/v2fly/v2ray-core/v5/features/routing"
"github.com/v2fly/v2ray-core/v5/transport/internet/udp"
)
type UDPHandler struct {
ctx context.Context
dispatcher routing.Dispatcher
policyManager policy.Manager
config *Config
}
2023-05-28 09:08:36 -04:00
type udpConn struct {
*gonet.UDPConn
id stack.TransportEndpointID
}
func (c *udpConn) ID() *stack.TransportEndpointID {
return &c.id
}
2023-05-30 01:28:22 -04:00
func SetUDPHandler(ctx context.Context, dispatcher routing.Dispatcher, policyManager policy.Manager, config *Config) StackOption {
2023-05-28 03:16:37 -04:00
return func(s *stack.Stack) error {
udpForwarder := gvisor_udp.NewForwarder(s, func(r *gvisor_udp.ForwarderRequest) {
wg := new(waiter.Queue)
linkedEndpoint, err := r.CreateEndpoint(wg)
if err != nil {
newError("failed to create endpoint: ", err).WriteToLog(session.ExportIDToError(ctx))
2023-05-28 03:16:37 -04:00
return
}
2023-05-28 10:43:08 -04:00
conn := &udpConn{
2023-05-28 09:08:36 -04:00
UDPConn: gonet.NewUDPConn(s, wg, linkedEndpoint),
id: r.ID(),
2023-05-28 03:16:37 -04:00
}
2023-05-28 09:08:36 -04:00
2023-05-30 01:28:22 -04:00
handler := &UDPHandler{
ctx: ctx,
dispatcher: dispatcher,
policyManager: policyManager,
config: config,
}
go handler.Handle(conn)
2023-05-28 03:16:37 -04:00
})
s.SetTransportProtocolHandler(gvisor_udp.ProtocolNumber, udpForwarder.HandlePacket)
return nil
}
}
2023-05-28 09:08:36 -04:00
2023-05-28 10:22:59 -04:00
func (h *UDPHandler) Handle(conn tun_net.UDPConn) error {
defer conn.Close()
id := conn.ID()
2023-05-28 05:00:50 -04:00
ctx := session.ContextWithInbound(h.ctx, &session.Inbound{Tag: h.config.Tag})
2023-10-28 22:47:23 -04:00
content := new(session.Content)
if h.config.SniffingSettings != nil {
content.SniffingRequest.Enabled = h.config.SniffingSettings.Enabled
content.SniffingRequest.OverrideDestinationForProtocol = h.config.SniffingSettings.DestinationOverride
content.SniffingRequest.MetadataOnly = h.config.SniffingSettings.MetadataOnly
}
ctx = session.ContextWithContent(ctx, content)
2023-05-28 03:16:37 -04:00
udpDispatcherConstructor := udp.NewSplitDispatcher
2023-05-28 10:22:59 -04:00
dest := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.LocalAddress), net.Port(id.LocalPort))
src := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.RemoteAddress), net.Port(id.RemotePort))
2023-05-28 03:16:37 -04:00
udpServer := udpDispatcherConstructor(h.dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {
2023-05-28 10:32:01 -04:00
if _, err := conn.WriteTo(packet.Payload.Bytes(), &net.UDPAddr{
2023-05-28 10:22:59 -04:00
IP: src.Address.IP(),
Port: int(src.Port),
2023-05-28 03:16:37 -04:00
}); err != nil {
newError("failed to write UDP packet").Base(err).WriteToLog()
}
})
for {
select {
case <-ctx.Done():
return nil
default:
var buffer [2048]byte
2023-05-28 10:32:01 -04:00
n, _, err := conn.ReadFrom(buffer[:])
2023-05-28 03:16:37 -04:00
if err != nil {
return newError("failed to read UDP packet").Base(err)
}
currentPacketCtx := ctx
2023-05-28 10:22:59 -04:00
udpServer.Dispatch(currentPacketCtx, dest, buf.FromBytes(buffer[:n]))
2023-05-28 03:16:37 -04:00
}
}
}