mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 16:41:30 +00:00
Fix loopback detector
This commit is contained in:
parent
76f20482f7
commit
7b0f5061dc
|
@ -148,7 +148,7 @@ func (h *Direct) ListenPacket(ctx context.Context, destination M.Socksaddr) (net
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conn = h.loopBack.NewPacketConn(bufio.NewPacketConn(conn))
|
conn = h.loopBack.NewPacketConn(bufio.NewPacketConn(conn), destination)
|
||||||
if originDestination != destination {
|
if originDestination != destination {
|
||||||
conn = bufio.NewNATPacketConn(bufio.NewPacketConn(conn), destination, originDestination)
|
conn = bufio.NewNATPacketConn(bufio.NewPacketConn(conn), destination, originDestination)
|
||||||
}
|
}
|
||||||
|
@ -156,14 +156,14 @@ func (h *Direct) ListenPacket(ctx context.Context, destination M.Socksaddr) (net
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Direct) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
func (h *Direct) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||||
if h.loopBack.CheckConn(metadata.Source.AddrPort()) {
|
if h.loopBack.CheckConn(metadata.Source.AddrPort(), M.AddrPortFromNet(conn.LocalAddr())) {
|
||||||
return E.New("reject loopback connection to ", metadata.Destination)
|
return E.New("reject loopback connection to ", metadata.Destination)
|
||||||
}
|
}
|
||||||
return NewConnection(ctx, h, conn, metadata)
|
return NewConnection(ctx, h, conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Direct) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
func (h *Direct) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||||
if h.loopBack.CheckPacketConn(metadata.Source.AddrPort()) {
|
if h.loopBack.CheckPacketConn(metadata.Source.AddrPort(), M.AddrPortFromNet(conn.LocalAddr())) {
|
||||||
return E.New("reject loopback packet connection to ", metadata.Destination)
|
return E.New("reject loopback packet connection to ", metadata.Destination)
|
||||||
}
|
}
|
||||||
return NewPacketConnection(ctx, h, conn, metadata)
|
return NewPacketConnection(ctx, h, conn, metadata)
|
||||||
|
|
|
@ -10,58 +10,83 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type loopBackDetector struct {
|
type loopBackDetector struct {
|
||||||
|
// router adapter.Router
|
||||||
connAccess sync.RWMutex
|
connAccess sync.RWMutex
|
||||||
packetConnAccess sync.RWMutex
|
packetConnAccess sync.RWMutex
|
||||||
connMap map[netip.AddrPort]bool
|
connMap map[netip.AddrPort]netip.AddrPort
|
||||||
packetConnMap map[netip.AddrPort]bool
|
packetConnMap map[uint16]uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLoopBackDetector() *loopBackDetector {
|
func newLoopBackDetector( /*router adapter.Router*/ ) *loopBackDetector {
|
||||||
return &loopBackDetector{
|
return &loopBackDetector{
|
||||||
connMap: make(map[netip.AddrPort]bool),
|
// router: router,
|
||||||
packetConnMap: make(map[netip.AddrPort]bool),
|
connMap: make(map[netip.AddrPort]netip.AddrPort),
|
||||||
|
packetConnMap: make(map[uint16]uint16),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopBackDetector) NewConn(conn net.Conn) net.Conn {
|
func (l *loopBackDetector) NewConn(conn net.Conn) net.Conn {
|
||||||
connAddr := M.AddrPortFromNet(conn.LocalAddr())
|
source := M.AddrPortFromNet(conn.LocalAddr())
|
||||||
if !connAddr.IsValid() {
|
if !source.IsValid() {
|
||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
if udpConn, isUDPConn := conn.(abstractUDPConn); isUDPConn {
|
if udpConn, isUDPConn := conn.(abstractUDPConn); isUDPConn {
|
||||||
l.packetConnAccess.Lock()
|
/*if !source.Addr().IsLoopback() {
|
||||||
l.packetConnMap[connAddr] = true
|
_, err := l.router.InterfaceFinder().InterfaceByAddr(source.Addr())
|
||||||
l.packetConnAccess.Unlock()
|
if err != nil {
|
||||||
return &loopBackDetectUDPWrapper{abstractUDPConn: udpConn, detector: l, connAddr: connAddr}
|
return conn
|
||||||
} else {
|
|
||||||
l.connAccess.Lock()
|
|
||||||
l.connMap[connAddr] = true
|
|
||||||
l.connAccess.Unlock()
|
|
||||||
return &loopBackDetectWrapper{Conn: conn, detector: l, connAddr: connAddr}
|
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
if !N.IsPublicAddr(source.Addr()) {
|
||||||
func (l *loopBackDetector) NewPacketConn(conn N.NetPacketConn) N.NetPacketConn {
|
|
||||||
connAddr := M.AddrPortFromNet(conn.LocalAddr())
|
|
||||||
if !connAddr.IsValid() {
|
|
||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
l.packetConnAccess.Lock()
|
l.packetConnAccess.Lock()
|
||||||
l.packetConnMap[connAddr] = true
|
l.packetConnMap[source.Port()] = M.AddrPortFromNet(conn.RemoteAddr()).Port()
|
||||||
l.packetConnAccess.Unlock()
|
l.packetConnAccess.Unlock()
|
||||||
return &loopBackDetectPacketWrapper{NetPacketConn: conn, detector: l, connAddr: connAddr}
|
return &loopBackDetectUDPWrapper{abstractUDPConn: udpConn, detector: l, connPort: source.Port()}
|
||||||
|
} else {
|
||||||
|
l.connAccess.Lock()
|
||||||
|
l.connMap[source] = M.AddrPortFromNet(conn.RemoteAddr())
|
||||||
|
l.connAccess.Unlock()
|
||||||
|
return &loopBackDetectWrapper{Conn: conn, detector: l, connAddr: source}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopBackDetector) CheckConn(connAddr netip.AddrPort) bool {
|
func (l *loopBackDetector) NewPacketConn(conn N.NetPacketConn, destination M.Socksaddr) N.NetPacketConn {
|
||||||
|
source := M.AddrPortFromNet(conn.LocalAddr())
|
||||||
|
if !source.IsValid() {
|
||||||
|
return conn
|
||||||
|
}
|
||||||
|
l.packetConnAccess.Lock()
|
||||||
|
l.packetConnMap[source.Port()] = destination.AddrPort().Port()
|
||||||
|
l.packetConnAccess.Unlock()
|
||||||
|
return &loopBackDetectPacketWrapper{NetPacketConn: conn, detector: l, connPort: source.Port()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *loopBackDetector) CheckConn(source netip.AddrPort, local netip.AddrPort) bool {
|
||||||
l.connAccess.RLock()
|
l.connAccess.RLock()
|
||||||
defer l.connAccess.RUnlock()
|
defer l.connAccess.RUnlock()
|
||||||
return l.connMap[connAddr]
|
destination, loaded := l.connMap[source]
|
||||||
|
return loaded && destination != local
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopBackDetector) CheckPacketConn(connAddr netip.AddrPort) bool {
|
func (l *loopBackDetector) CheckPacketConn(source netip.AddrPort, local netip.AddrPort) bool {
|
||||||
|
if !source.IsValid() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/*if !source.Addr().IsLoopback() {
|
||||||
|
_, err := l.router.InterfaceFinder().InterfaceByAddr(source.Addr())
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
if N.IsPublicAddr(source.Addr()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
l.packetConnAccess.RLock()
|
l.packetConnAccess.RLock()
|
||||||
defer l.packetConnAccess.RUnlock()
|
defer l.packetConnAccess.RUnlock()
|
||||||
return l.packetConnMap[connAddr]
|
destinationPort, loaded := l.packetConnMap[source.Port()]
|
||||||
|
return loaded && destinationPort != local.Port()
|
||||||
}
|
}
|
||||||
|
|
||||||
type loopBackDetectWrapper struct {
|
type loopBackDetectWrapper struct {
|
||||||
|
@ -95,14 +120,14 @@ func (w *loopBackDetectWrapper) Upstream() any {
|
||||||
type loopBackDetectPacketWrapper struct {
|
type loopBackDetectPacketWrapper struct {
|
||||||
N.NetPacketConn
|
N.NetPacketConn
|
||||||
detector *loopBackDetector
|
detector *loopBackDetector
|
||||||
connAddr netip.AddrPort
|
connPort uint16
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *loopBackDetectPacketWrapper) Close() error {
|
func (w *loopBackDetectPacketWrapper) Close() error {
|
||||||
w.closeOnce.Do(func() {
|
w.closeOnce.Do(func() {
|
||||||
w.detector.packetConnAccess.Lock()
|
w.detector.packetConnAccess.Lock()
|
||||||
delete(w.detector.packetConnMap, w.connAddr)
|
delete(w.detector.packetConnMap, w.connPort)
|
||||||
w.detector.packetConnAccess.Unlock()
|
w.detector.packetConnAccess.Unlock()
|
||||||
})
|
})
|
||||||
return w.NetPacketConn.Close()
|
return w.NetPacketConn.Close()
|
||||||
|
@ -128,14 +153,14 @@ type abstractUDPConn interface {
|
||||||
type loopBackDetectUDPWrapper struct {
|
type loopBackDetectUDPWrapper struct {
|
||||||
abstractUDPConn
|
abstractUDPConn
|
||||||
detector *loopBackDetector
|
detector *loopBackDetector
|
||||||
connAddr netip.AddrPort
|
connPort uint16
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *loopBackDetectUDPWrapper) Close() error {
|
func (w *loopBackDetectUDPWrapper) Close() error {
|
||||||
w.closeOnce.Do(func() {
|
w.closeOnce.Do(func() {
|
||||||
w.detector.packetConnAccess.Lock()
|
w.detector.packetConnAccess.Lock()
|
||||||
delete(w.detector.packetConnMap, w.connAddr)
|
delete(w.detector.packetConnMap, w.connPort)
|
||||||
w.detector.packetConnAccess.Unlock()
|
w.detector.packetConnAccess.Unlock()
|
||||||
})
|
})
|
||||||
return w.abstractUDPConn.Close()
|
return w.abstractUDPConn.Close()
|
||||||
|
|
Loading…
Reference in a new issue