Fix gvisor udp write back

This commit is contained in:
世界 2022-08-21 11:37:17 +08:00
parent ce3573838b
commit 8b6630a3b0
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 19 additions and 21 deletions

View file

@ -1,7 +0,0 @@
package tun
//go:generate go install -v mvdan.cc/gofumpt@latest
//go:generate go install -v github.com/daixiang0/gci@v0.4.0
//go:generate gofumpt -l -w .
//go:generate gofmt -s -w .
//go:generate gci write -s "standard,prefix(github.com/sagernet/),default" .

View file

@ -39,14 +39,19 @@ func (f *UDPForwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.Pac
var upstreamMetadata M.Metadata
upstreamMetadata.Source = M.SocksaddrFrom(M.AddrFromIP(net.IP(id.RemoteAddress)), id.RemotePort)
upstreamMetadata.Destination = M.SocksaddrFrom(M.AddrFromIP(net.IP(id.LocalAddress)), id.LocalPort)
var netProto tcpip.NetworkProtocolNumber
if upstreamMetadata.Source.IsIPv4() {
netProto = header.IPv4ProtocolNumber
} else {
netProto = header.IPv6ProtocolNumber
}
f.udpNat.NewPacket(
f.ctx,
upstreamMetadata.Source.AddrPort(),
buf.As(pkt.Data().AsRange().ToSlice()),
upstreamMetadata,
func(natConn N.PacketConn) N.PacketWriter {
return &UDPBackWriter{f.stack, id.RemoteAddress, id.RemotePort}
return &UDPBackWriter{f.stack, id.RemoteAddress, id.RemotePort, netProto}
},
)
return true
@ -56,23 +61,23 @@ type UDPBackWriter struct {
stack *stack.Stack
source tcpip.Address
sourcePort uint16
sourceNetwork tcpip.NetworkProtocolNumber
}
func (w *UDPBackWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
defer buffer.Release()
var netProto tcpip.NetworkProtocolNumber
if destination.IsIPv4() {
netProto = header.IPv4ProtocolNumber
} else {
netProto = header.IPv6ProtocolNumber
if w.sourceNetwork == header.IPv4ProtocolNumber && destination.Addr.Is4In6() {
destination = destination.Unwrap()
} else if w.sourceNetwork == header.IPv6ProtocolNumber && destination.Addr.Is4() {
destination = M.SocksaddrFrom(netip.AddrFrom16(destination.Addr.As16()), destination.Port)
}
route, err := w.stack.FindRoute(
defaultNIC,
tcpip.Address(destination.Addr.AsSlice()),
w.source,
netProto,
w.sourceNetwork,
false,
)
if err != nil {
@ -95,7 +100,7 @@ func (w *UDPBackWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr)
Length: pLen,
})
if route.RequiresTXTransportChecksum() && netProto == header.IPv6ProtocolNumber {
if route.RequiresTXTransportChecksum() && w.sourceNetwork == header.IPv6ProtocolNumber {
xsum := udpHdr.CalculateChecksum(header.ChecksumCombine(
route.PseudoHeaderChecksum(header.UDPProtocolNumber, pLen),
packet.Data().AsRange().Checksum(),

View file

@ -5,9 +5,9 @@ package tun
import (
"context"
"sync"
"time"
"github.com/sagernet/sing/common/x/list"
"time"
)
func (m *networkUpdateMonitor) RegisterCallback(callback NetworkUpdateCallback) *list.Element[NetworkUpdateCallback] {

View file

@ -8,11 +8,11 @@ import (
"os"
"strconv"
"github.com/sagernet/abx-go"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/fsnotify/fsnotify"
"github.com/sagernet/abx-go"
)
type packageManager struct {