github.com/sagernet/sing-box@v1.9.0-rc.20/inbound/default_tcp.go (about)

     1  package inbound
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  
     7  	"github.com/sagernet/sing-box/adapter"
     8  	C "github.com/sagernet/sing-box/constant"
     9  	"github.com/sagernet/sing-box/log"
    10  	"github.com/sagernet/sing/common/control"
    11  	E "github.com/sagernet/sing/common/exceptions"
    12  	M "github.com/sagernet/sing/common/metadata"
    13  	N "github.com/sagernet/sing/common/network"
    14  )
    15  
    16  func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
    17  	var err error
    18  	bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
    19  	var tcpListener net.Listener
    20  	var listenConfig net.ListenConfig
    21  	// TODO: Add an option to customize the keep alive period
    22  	listenConfig.KeepAlive = C.TCPKeepAliveInitial
    23  	listenConfig.Control = control.Append(listenConfig.Control, control.SetKeepAlivePeriod(C.TCPKeepAliveInitial, C.TCPKeepAliveInterval))
    24  	if a.listenOptions.TCPMultiPath {
    25  		if !go121Available {
    26  			return nil, E.New("MultiPath TCP requires go1.21, please recompile your binary.")
    27  		}
    28  		setMultiPathTCP(&listenConfig)
    29  	}
    30  	if a.listenOptions.TCPFastOpen {
    31  		if !go120Available {
    32  			return nil, E.New("TCP Fast Open requires go1.20, please recompile your binary.")
    33  		}
    34  		tcpListener, err = listenTFO(listenConfig, a.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
    35  	} else {
    36  		tcpListener, err = listenConfig.Listen(a.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
    37  	}
    38  	if err == nil {
    39  		a.logger.Info("tcp server started at ", tcpListener.Addr())
    40  	}
    41  	if a.listenOptions.ProxyProtocol || a.listenOptions.ProxyProtocolAcceptNoHeader {
    42  		return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
    43  	}
    44  	a.tcpListener = tcpListener
    45  	return tcpListener, err
    46  }
    47  
    48  func (a *myInboundAdapter) loopTCPIn() {
    49  	tcpListener := a.tcpListener
    50  	for {
    51  		conn, err := tcpListener.Accept()
    52  		if err != nil {
    53  			//goland:noinspection GoDeprecation
    54  			//nolint:staticcheck
    55  			if netError, isNetError := err.(net.Error); isNetError && netError.Temporary() {
    56  				a.logger.Error(err)
    57  				continue
    58  			}
    59  			if a.inShutdown.Load() && E.IsClosed(err) {
    60  				return
    61  			}
    62  			a.tcpListener.Close()
    63  			a.logger.Error("serve error: ", err)
    64  			continue
    65  		}
    66  		go a.injectTCP(conn, adapter.InboundContext{})
    67  	}
    68  }
    69  
    70  func (a *myInboundAdapter) injectTCP(conn net.Conn, metadata adapter.InboundContext) {
    71  	ctx := log.ContextWithNewID(a.ctx)
    72  	metadata = a.createMetadata(conn, metadata)
    73  	a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
    74  	hErr := a.connHandler.NewConnection(ctx, conn, metadata)
    75  	if hErr != nil {
    76  		conn.Close()
    77  		a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
    78  	}
    79  }
    80  
    81  func (a *myInboundAdapter) routeTCP(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) {
    82  	a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
    83  	hErr := a.newConnection(ctx, conn, metadata)
    84  	if hErr != nil {
    85  		conn.Close()
    86  		a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
    87  	}
    88  }