github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/inbound/default_tcp.go (about) 1 package inbound 2 3 import ( 4 "context" 5 "net" 6 "time" 7 8 "github.com/inazumav/sing-box/adapter" 9 "github.com/inazumav/sing-box/common/proxyproto" 10 "github.com/inazumav/sing-box/log" 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 if a.listenOptions.TCPMultiPath { 22 if !go121Available { 23 return nil, E.New("MultiPath TCP requires go1.21, please recompile your binary.") 24 } 25 setMultiPathTCP(&listenConfig) 26 } 27 if a.listenOptions.TCPFastOpen { 28 if !go120Available { 29 return nil, E.New("TCP Fast Open requires go1.20, please recompile your binary.") 30 } 31 tcpListener, err = listenTFO(listenConfig, a.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String()) 32 } else { 33 tcpListener, err = listenConfig.Listen(a.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String()) 34 } 35 if err == nil { 36 a.logger.Info("tcp server started at ", tcpListener.Addr()) 37 } 38 if a.listenOptions.ProxyProtocol { 39 a.logger.Debug("proxy protocol enabled") 40 tcpListener = &proxyproto.Listener{Listener: tcpListener, AcceptNoHeader: a.listenOptions.ProxyProtocolAcceptNoHeader} 41 } 42 a.tcpListener = tcpListener 43 return tcpListener, err 44 } 45 46 func (a *myInboundAdapter) loopTCPIn() { 47 tcpListener := a.tcpListener 48 for { 49 conn, err := tcpListener.Accept() 50 if err != nil { 51 //goland:noinspection GoDeprecation 52 //nolint:staticcheck 53 if netError, isNetError := err.(net.Error); isNetError && netError.Temporary() { 54 a.logger.Error(err) 55 continue 56 } 57 if a.inShutdown.Load() && E.IsClosed(err) { 58 return 59 } 60 a.tcpListener.Close() 61 a.logger.Error("serve error: ", err) 62 continue 63 } 64 go a.injectTCP(conn, adapter.InboundContext{}) 65 } 66 } 67 68 type DelayCloseConn struct { 69 time time.Duration 70 net.Conn 71 } 72 73 func (d *DelayCloseConn) Close() error { 74 time.Sleep(d.time) 75 return d.Conn.Close() 76 } 77 78 func (a *myInboundAdapter) injectTCP(conn net.Conn, metadata adapter.InboundContext) { 79 if a.listenOptions.DelayClose != 0 { 80 conn = &DelayCloseConn{ 81 time: time.Second * time.Duration(a.listenOptions.DelayClose), 82 Conn: conn, 83 } 84 } 85 ctx := log.ContextWithNewID(a.ctx) 86 metadata = a.createMetadata(conn, metadata) 87 a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source) 88 hErr := a.connHandler.NewConnection(ctx, conn, metadata) 89 if hErr != nil { 90 conn.Close() 91 a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source)) 92 } 93 } 94 95 func (a *myInboundAdapter) routeTCP(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) { 96 a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source) 97 hErr := a.newConnection(ctx, conn, metadata) 98 if hErr != nil { 99 conn.Close() 100 a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source)) 101 } 102 }