| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 | 
							- package listener
 
- import (
 
- 	"net"
 
- 	"net/netip"
 
- 	"strings"
 
- 	"syscall"
 
- 	"time"
 
- 	"github.com/sagernet/sing-box/adapter"
 
- 	"github.com/sagernet/sing-box/common/redir"
 
- 	C "github.com/sagernet/sing-box/constant"
 
- 	"github.com/sagernet/sing-box/log"
 
- 	"github.com/sagernet/sing/common/control"
 
- 	E "github.com/sagernet/sing/common/exceptions"
 
- 	M "github.com/sagernet/sing/common/metadata"
 
- 	N "github.com/sagernet/sing/common/network"
 
- 	"github.com/sagernet/sing/service"
 
- 	"github.com/database64128/tfo-go/v2"
 
- )
 
- func (l *Listener) ListenTCP() (net.Listener, error) {
 
- 	//nolint:staticcheck
 
- 	if l.listenOptions.ProxyProtocol || l.listenOptions.ProxyProtocolAcceptNoHeader {
 
- 		return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
 
- 	}
 
- 	var err error
 
- 	bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort)
 
- 	var listenConfig net.ListenConfig
 
- 	if l.listenOptions.BindInterface != "" {
 
- 		listenConfig.Control = control.Append(listenConfig.Control, control.BindToInterface(service.FromContext[adapter.NetworkManager](l.ctx).InterfaceFinder(), l.listenOptions.BindInterface, -1))
 
- 	}
 
- 	if l.listenOptions.RoutingMark != 0 {
 
- 		listenConfig.Control = control.Append(listenConfig.Control, control.RoutingMark(uint32(l.listenOptions.RoutingMark)))
 
- 	}
 
- 	if l.listenOptions.ReuseAddr {
 
- 		listenConfig.Control = control.Append(listenConfig.Control, control.ReuseAddr())
 
- 	}
 
- 	if l.listenOptions.TCPKeepAlive >= 0 {
 
- 		keepIdle := time.Duration(l.listenOptions.TCPKeepAlive)
 
- 		if keepIdle == 0 {
 
- 			keepIdle = C.TCPKeepAliveInitial
 
- 		}
 
- 		keepInterval := time.Duration(l.listenOptions.TCPKeepAliveInterval)
 
- 		if keepInterval == 0 {
 
- 			keepInterval = C.TCPKeepAliveInterval
 
- 		}
 
- 		listenConfig.KeepAliveConfig = net.KeepAliveConfig{
 
- 			Enable:   true,
 
- 			Idle:     keepIdle,
 
- 			Interval: keepInterval,
 
- 		}
 
- 	}
 
- 	if l.listenOptions.TCPMultiPath {
 
- 		listenConfig.SetMultipathTCP(true)
 
- 	}
 
- 	if l.tproxy {
 
- 		listenConfig.Control = control.Append(listenConfig.Control, func(network, address string, conn syscall.RawConn) error {
 
- 			return control.Raw(conn, func(fd uintptr) error {
 
- 				return redir.TProxy(fd, !strings.HasSuffix(network, "4"), false)
 
- 			})
 
- 		})
 
- 	}
 
- 	tcpListener, err := ListenNetworkNamespace[net.Listener](l.listenOptions.NetNs, func() (net.Listener, error) {
 
- 		if l.listenOptions.TCPFastOpen {
 
- 			var tfoConfig tfo.ListenConfig
 
- 			tfoConfig.ListenConfig = listenConfig
 
- 			return tfoConfig.Listen(l.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
 
- 		} else {
 
- 			return listenConfig.Listen(l.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
 
- 		}
 
- 	})
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	l.logger.Info("tcp server started at ", tcpListener.Addr())
 
- 	l.tcpListener = tcpListener
 
- 	return tcpListener, err
 
- }
 
- func (l *Listener) loopTCPIn() {
 
- 	tcpListener := l.tcpListener
 
- 	var metadata adapter.InboundContext
 
- 	for {
 
- 		conn, err := tcpListener.Accept()
 
- 		if err != nil {
 
- 			//nolint:staticcheck
 
- 			if netError, isNetError := err.(net.Error); isNetError && netError.Temporary() {
 
- 				l.logger.Error(err)
 
- 				continue
 
- 			}
 
- 			if l.shutdown.Load() && E.IsClosed(err) {
 
- 				return
 
- 			}
 
- 			l.tcpListener.Close()
 
- 			l.logger.Error("tcp listener closed: ", err)
 
- 			continue
 
- 		}
 
- 		//nolint:staticcheck
 
- 		metadata.InboundDetour = l.listenOptions.Detour
 
- 		//nolint:staticcheck
 
- 		metadata.InboundOptions = l.listenOptions.InboundOptions
 
- 		metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
 
- 		metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
 
- 		ctx := log.ContextWithNewID(l.ctx)
 
- 		l.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
 
- 		go l.connHandler.NewConnectionEx(ctx, conn, metadata, nil)
 
- 	}
 
- }
 
 
  |