Improve gVisor UDP

This commit is contained in:
世界 2023-07-23 14:01:36 +08:00
parent fd850d00e5
commit bbf542f01a
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 28 additions and 10 deletions

View file

@ -23,6 +23,11 @@ type UDPForwarder struct {
ctx context.Context ctx context.Context
stack *stack.Stack stack *stack.Stack
udpNat *udpnat.Service[netip.AddrPort] udpNat *udpnat.Service[netip.AddrPort]
// cache
cacheProto tcpip.NetworkProtocolNumber
cacheID stack.TransportEndpointID
cachePacket stack.PacketBufferPtr
} }
func NewUDPForwarder(ctx context.Context, stack *stack.Stack, handler Handler, udpTimeout int64) *UDPForwarder { func NewUDPForwarder(ctx context.Context, stack *stack.Stack, handler Handler, udpTimeout int64) *UDPForwarder {
@ -37,24 +42,37 @@ func (f *UDPForwarder) HandlePacket(id stack.TransportEndpointID, pkt stack.Pack
var upstreamMetadata M.Metadata var upstreamMetadata M.Metadata
upstreamMetadata.Source = M.SocksaddrFrom(AddrFromAddress(id.RemoteAddress), id.RemotePort) upstreamMetadata.Source = M.SocksaddrFrom(AddrFromAddress(id.RemoteAddress), id.RemotePort)
upstreamMetadata.Destination = M.SocksaddrFrom(AddrFromAddress(id.LocalAddress), id.LocalPort) upstreamMetadata.Destination = M.SocksaddrFrom(AddrFromAddress(id.LocalAddress), id.LocalPort)
var netProto tcpip.NetworkProtocolNumber
if upstreamMetadata.Source.IsIPv4() { if upstreamMetadata.Source.IsIPv4() {
netProto = header.IPv4ProtocolNumber f.cacheProto = header.IPv4ProtocolNumber
} else { } else {
netProto = header.IPv6ProtocolNumber f.cacheProto = header.IPv6ProtocolNumber
} }
gBuffer := pkt.ToBuffer()
sBuffer := buf.NewSize(int(gBuffer.Size()))
gBuffer.Apply(func(view *buffer.View) {
sBuffer.Write(view.AsSlice())
})
f.cacheID = id
f.cachePacket = pkt
f.udpNat.NewPacket( f.udpNat.NewPacket(
f.ctx, f.ctx,
upstreamMetadata.Source.AddrPort(), upstreamMetadata.Source.AddrPort(),
buf.As(pkt.Data().AsRange().ToSlice()), sBuffer,
upstreamMetadata, upstreamMetadata,
func(natConn N.PacketConn) N.PacketWriter { f.newUDPConn,
return &UDPBackWriter{f.stack, id.RemoteAddress, id.RemotePort, netProto}
},
) )
return true return true
} }
func (f *UDPForwarder) newUDPConn(natConn N.PacketConn) N.PacketWriter {
return &UDPBackWriter{
stack: f.stack,
source: f.cacheID.RemoteAddress,
sourcePort: f.cacheID.RemotePort,
sourceNetwork: f.cacheProto,
}
}
type UDPBackWriter struct { type UDPBackWriter struct {
stack *stack.Stack stack *stack.Stack
source tcpip.Address source tcpip.Address