Fix gvisor icmp destination

This commit is contained in:
世界
2025-08-23 16:21:48 +08:00
parent 8dbb51cfb7
commit f46791bc0d
6 changed files with 24 additions and 27 deletions

View File

@@ -1,6 +1,7 @@
package ping package ping
import ( import (
"context"
"errors" "errors"
"net/netip" "net/netip"
"os" "os"
@@ -16,12 +17,13 @@ import (
var _ tun.DirectRouteDestination = (*Destination)(nil) var _ tun.DirectRouteDestination = (*Destination)(nil)
type Destination struct { type Destination struct {
logger logger.Logger ctx context.Context
logger logger.ContextLogger
routeContext tun.DirectRouteContext routeContext tun.DirectRouteContext
conn *Conn conn *Conn
} }
func ConnectDestination(logger logger.Logger, controlFunc control.Func, address netip.Addr, routeContext tun.DirectRouteContext) (tun.DirectRouteDestination, error) { func ConnectDestination(ctx context.Context, logger logger.ContextLogger, controlFunc control.Func, address netip.Addr, routeContext tun.DirectRouteContext) (tun.DirectRouteDestination, error) {
var ( var (
conn *Conn conn *Conn
err error err error
@@ -39,6 +41,7 @@ func ConnectDestination(logger logger.Logger, controlFunc control.Func, address
return nil, err return nil, err
} }
d := &Destination{ d := &Destination{
ctx: ctx,
logger: logger, logger: logger,
routeContext: routeContext, routeContext: routeContext,
conn: conn, conn: conn,
@@ -54,13 +57,13 @@ func (d *Destination) loopRead() {
if err != nil { if err != nil {
buffer.Release() buffer.Release()
if !E.IsClosed(err) { if !E.IsClosed(err) {
d.logger.Error(E.Cause(err, "receive ICMP echo reply")) d.logger.ErrorContext(d.ctx, E.Cause(err, "receive ICMP echo reply"))
} }
return return
} }
err = d.routeContext.WritePacket(buffer.Bytes()) err = d.routeContext.WritePacket(buffer.Bytes())
if err != nil { if err != nil {
d.logger.Error(E.Cause(err, "write ICMP echo reply")) d.logger.Error(d.ctx, E.Cause(err, "write ICMP echo reply"))
} }
buffer.Release() buffer.Release()
} }

View File

@@ -12,6 +12,7 @@ import (
"github.com/sagernet/sing/common/control" "github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )

View File

@@ -6,8 +6,14 @@ import (
"github.com/sagernet/sing-tun/internal/gtcpip/checksum" "github.com/sagernet/sing-tun/internal/gtcpip/checksum"
"github.com/sagernet/sing-tun/internal/gtcpip/header" "github.com/sagernet/sing-tun/internal/gtcpip/header"
"github.com/sagernet/sing/common/buf"
) )
type DirectRouteDestination interface {
WritePacket(packet *buf.Buffer) error
Close() error
}
type NatMapping struct { type NatMapping struct {
access sync.RWMutex access sync.RWMutex
sessions map[DirectRouteSession]DirectRouteContext sessions map[DirectRouteSession]DirectRouteContext

View File

@@ -5,16 +5,9 @@ package tun
import ( import (
"github.com/sagernet/gvisor/pkg/tcpip" "github.com/sagernet/gvisor/pkg/tcpip"
"github.com/sagernet/gvisor/pkg/tcpip/header" "github.com/sagernet/gvisor/pkg/tcpip/header"
stack "github.com/sagernet/gvisor/pkg/tcpip/stack" "github.com/sagernet/gvisor/pkg/tcpip/stack"
"github.com/sagernet/sing/common/buf"
) )
type DirectRouteDestination interface {
WritePacket(packet *buf.Buffer) error
WritePacketBuffer(packetBuffer *stack.PacketBuffer) error
Close() error
}
func (w *NatWriter) RewritePacketBuffer(packetBuffer *stack.PacketBuffer) { func (w *NatWriter) RewritePacketBuffer(packetBuffer *stack.PacketBuffer) {
var bindAddr tcpip.Address var bindAddr tcpip.Address
if packetBuffer.NetworkProtocolNumber == header.IPv4ProtocolNumber { if packetBuffer.NetworkProtocolNumber == header.IPv4ProtocolNumber {

View File

@@ -1,12 +0,0 @@
//go:build !with_gvisor
package tun
import (
"github.com/sagernet/sing/common/buf"
)
type DirectRouteDestination interface {
WritePacket(packet *buf.Buffer) error
Close() error
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/sagernet/gvisor/pkg/tcpip/network/ipv4" "github.com/sagernet/gvisor/pkg/tcpip/network/ipv4"
"github.com/sagernet/gvisor/pkg/tcpip/network/ipv6" "github.com/sagernet/gvisor/pkg/tcpip/network/ipv6"
"github.com/sagernet/gvisor/pkg/tcpip/stack" "github.com/sagernet/gvisor/pkg/tcpip/stack"
"github.com/sagernet/sing/common/buf"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
) )
@@ -62,8 +63,7 @@ func (f *ICMPForwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.Pa
} }
if action != nil { if action != nil {
// TODO: handle error // TODO: handle error
pkt.IncRef() _ = icmpWritePacketBuffer(action, pkt)
_ = action.WritePacketBuffer(pkt)
return true return true
} }
icmpHdr.SetType(header.ICMPv4EchoReply) icmpHdr.SetType(header.ICMPv4EchoReply)
@@ -120,7 +120,7 @@ func (f *ICMPForwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.Pa
if action != nil { if action != nil {
// TODO: handle error // TODO: handle error
pkt.IncRef() pkt.IncRef()
_ = action.WritePacketBuffer(pkt) _ = icmpWritePacketBuffer(action, pkt)
return true return true
} }
icmpHdr.SetType(header.ICMPv6EchoReply) icmpHdr.SetType(header.ICMPv6EchoReply)
@@ -207,3 +207,9 @@ func (w *ICMPBackWriter) WritePacket(p []byte) error {
} }
return nil return nil
} }
func icmpWritePacketBuffer(action DirectRouteDestination, packetBuffer *stack.PacketBuffer) error {
packetSlice := packetBuffer.TransportHeader().Slice()
packetSlice = append(packetSlice, packetBuffer.Data().AsRange().ToSlice()...)
return action.WritePacket(buf.As(packetSlice).ToOwned())
}