mirror of
https://github.com/SagerNet/sing-tun.git
synced 2025-04-04 20:37:43 +03:00
Remove use of Write Unreachable as SendRejectionError panics when passing invalid packet
This commit is contained in:
parent
e212724bac
commit
b6d323004e
3 changed files with 5 additions and 51 deletions
|
@ -6,7 +6,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
|
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
|
@ -129,7 +128,7 @@ func (t *GVisor) Start() error {
|
||||||
endpoint.Abort()
|
endpoint.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gConn := &gUDPConn{UDPConn: udpConn, stack: ipStack, packet: (*gRequest)(unsafe.Pointer(request)).pkt.IncRef()}
|
gConn := &gUDPConn{UDPConn: udpConn}
|
||||||
go func() {
|
go func() {
|
||||||
var metadata M.Metadata
|
var metadata M.Metadata
|
||||||
metadata.Source = M.SocksaddrFromNet(lAddr)
|
metadata.Source = M.SocksaddrFromNet(lAddr)
|
||||||
|
|
|
@ -30,9 +30,8 @@ type UDPForwarder struct {
|
||||||
udpNat *udpnat.Service[netip.AddrPort]
|
udpNat *udpnat.Service[netip.AddrPort]
|
||||||
|
|
||||||
// cache
|
// cache
|
||||||
cacheProto tcpip.NetworkProtocolNumber
|
cacheProto tcpip.NetworkProtocolNumber
|
||||||
cacheID stack.TransportEndpointID
|
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 {
|
||||||
|
@ -58,7 +57,6 @@ func (f *UDPForwarder) HandlePacket(id stack.TransportEndpointID, pkt stack.Pack
|
||||||
sBuffer.Write(view.AsSlice())
|
sBuffer.Write(view.AsSlice())
|
||||||
})
|
})
|
||||||
f.cacheID = id
|
f.cacheID = id
|
||||||
f.cachePacket = pkt
|
|
||||||
f.udpNat.NewPacket(
|
f.udpNat.NewPacket(
|
||||||
f.ctx,
|
f.ctx,
|
||||||
upstreamMetadata.Source.AddrPort(),
|
upstreamMetadata.Source.AddrPort(),
|
||||||
|
@ -75,7 +73,6 @@ func (f *UDPForwarder) newUDPConn(natConn N.PacketConn) N.PacketWriter {
|
||||||
source: f.cacheID.RemoteAddress,
|
source: f.cacheID.RemoteAddress,
|
||||||
sourcePort: f.cacheID.RemotePort,
|
sourcePort: f.cacheID.RemotePort,
|
||||||
sourceNetwork: f.cacheProto,
|
sourceNetwork: f.cacheProto,
|
||||||
packet: f.cachePacket.IncRef(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,17 +85,6 @@ type UDPBackWriter struct {
|
||||||
packet stack.PacketBufferPtr
|
packet stack.PacketBufferPtr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *UDPBackWriter) Close() error {
|
|
||||||
w.access.Lock()
|
|
||||||
defer w.access.Unlock()
|
|
||||||
if w.packet == nil {
|
|
||||||
return os.ErrClosed
|
|
||||||
}
|
|
||||||
w.packet.DecRef()
|
|
||||||
w.packet = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *UDPBackWriter) WritePacket(packetBuffer *buf.Buffer, destination M.Socksaddr) error {
|
func (w *UDPBackWriter) WritePacket(packetBuffer *buf.Buffer, destination M.Socksaddr) error {
|
||||||
if !destination.IsIP() {
|
if !destination.IsIP() {
|
||||||
return E.Cause(os.ErrInvalid, "invalid destination")
|
return E.Cause(os.ErrInvalid, "invalid destination")
|
||||||
|
@ -163,16 +149,6 @@ func (w *UDPBackWriter) WritePacket(packetBuffer *buf.Buffer, destination M.Sock
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *UDPBackWriter) HandshakeFailure(err error) error {
|
|
||||||
if w.packet == nil {
|
|
||||||
return os.ErrClosed
|
|
||||||
}
|
|
||||||
err = gWriteUnreachable(w.stack, w.packet, err)
|
|
||||||
w.packet.DecRef()
|
|
||||||
w.packet = nil
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type gRequest struct {
|
type gRequest struct {
|
||||||
stack *stack.Stack
|
stack *stack.Stack
|
||||||
id stack.TransportEndpointID
|
id stack.TransportEndpointID
|
||||||
|
@ -181,9 +157,6 @@ type gRequest struct {
|
||||||
|
|
||||||
type gUDPConn struct {
|
type gUDPConn struct {
|
||||||
*gonet.UDPConn
|
*gonet.UDPConn
|
||||||
access sync.Mutex
|
|
||||||
stack *stack.Stack
|
|
||||||
packet stack.PacketBufferPtr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gUDPConn) Read(b []byte) (n int, err error) {
|
func (c *gUDPConn) Read(b []byte) (n int, err error) {
|
||||||
|
@ -205,27 +178,10 @@ func (c *gUDPConn) Write(b []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gUDPConn) Close() error {
|
func (c *gUDPConn) Close() error {
|
||||||
c.access.Lock()
|
|
||||||
defer c.access.Unlock()
|
|
||||||
if c.packet == nil {
|
|
||||||
return os.ErrClosed
|
|
||||||
}
|
|
||||||
c.packet.DecRef()
|
|
||||||
c.packet = nil
|
|
||||||
return c.UDPConn.Close()
|
return c.UDPConn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gUDPConn) HandshakeFailure(err error) error {
|
func gWriteUnreachable(gStack *stack.Stack, packet stack.PacketBufferPtr, err error) (retErr error) {
|
||||||
if c.packet == nil {
|
|
||||||
return os.ErrClosed
|
|
||||||
}
|
|
||||||
err = gWriteUnreachable(c.stack, c.packet, err)
|
|
||||||
c.packet.DecRef()
|
|
||||||
c.packet = nil
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func gWriteUnreachable(gStack *stack.Stack, packet stack.PacketBufferPtr, err error) error {
|
|
||||||
if errors.Is(err, syscall.ENETUNREACH) {
|
if errors.Is(err, syscall.ENETUNREACH) {
|
||||||
if packet.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
if packet.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
||||||
return gWriteUnreachable4(gStack, packet, stack.RejectIPv4WithICMPNetUnreachable)
|
return gWriteUnreachable4(gStack, packet, stack.RejectIPv4WithICMPNetUnreachable)
|
||||||
|
|
|
@ -4,7 +4,6 @@ package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/sagernet/gvisor/pkg/buffer"
|
"github.com/sagernet/gvisor/pkg/buffer"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
|
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
|
@ -68,7 +67,7 @@ func (m *Mixed) Start() error {
|
||||||
endpoint.Abort()
|
endpoint.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gConn := &gUDPConn{UDPConn: udpConn, stack: ipStack, packet: (*gRequest)(unsafe.Pointer(request)).pkt.IncRef()}
|
gConn := &gUDPConn{UDPConn: udpConn}
|
||||||
go func() {
|
go func() {
|
||||||
var metadata M.Metadata
|
var metadata M.Metadata
|
||||||
metadata.Source = M.SocksaddrFromNet(lAddr)
|
metadata.Source = M.SocksaddrFromNet(lAddr)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue