github.com/xraypb/xray-core@v1.6.6/transport/internet/tcp/hub.go (about)

     1  package tcp
     2  
     3  import (
     4  	"context"
     5  	gotls "crypto/tls"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/xraypb/xray-core/common"
    10  	"github.com/xraypb/xray-core/common/net"
    11  	"github.com/xraypb/xray-core/common/session"
    12  	"github.com/xraypb/xray-core/transport/internet"
    13  	"github.com/xraypb/xray-core/transport/internet/stat"
    14  	"github.com/xraypb/xray-core/transport/internet/tls"
    15  	"github.com/xraypb/xray-core/transport/internet/xtls"
    16  	goxtls "github.com/xtls/go"
    17  )
    18  
    19  // Listener is an internet.Listener that listens for TCP connections.
    20  type Listener struct {
    21  	listener   net.Listener
    22  	tlsConfig  *gotls.Config
    23  	xtlsConfig *goxtls.Config
    24  	authConfig internet.ConnectionAuthenticator
    25  	config     *Config
    26  	addConn    internet.ConnHandler
    27  	locker     *internet.FileLocker // for unix domain socket
    28  }
    29  
    30  // ListenTCP creates a new Listener based on configurations.
    31  func ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {
    32  	l := &Listener{
    33  		addConn: handler,
    34  	}
    35  	tcpSettings := streamSettings.ProtocolSettings.(*Config)
    36  	l.config = tcpSettings
    37  	if l.config != nil {
    38  		if streamSettings.SocketSettings == nil {
    39  			streamSettings.SocketSettings = &internet.SocketConfig{}
    40  		}
    41  		streamSettings.SocketSettings.AcceptProxyProtocol = l.config.AcceptProxyProtocol || streamSettings.SocketSettings.AcceptProxyProtocol
    42  	}
    43  	var listener net.Listener
    44  	var err error
    45  	if port == net.Port(0) { // unix
    46  		listener, err = internet.ListenSystem(ctx, &net.UnixAddr{
    47  			Name: address.Domain(),
    48  			Net:  "unix",
    49  		}, streamSettings.SocketSettings)
    50  		if err != nil {
    51  			return nil, newError("failed to listen Unix Domain Socket on ", address).Base(err)
    52  		}
    53  		newError("listening Unix Domain Socket on ", address).WriteToLog(session.ExportIDToError(ctx))
    54  		locker := ctx.Value(address.Domain())
    55  		if locker != nil {
    56  			l.locker = locker.(*internet.FileLocker)
    57  		}
    58  	} else {
    59  		listener, err = internet.ListenSystem(ctx, &net.TCPAddr{
    60  			IP:   address.IP(),
    61  			Port: int(port),
    62  		}, streamSettings.SocketSettings)
    63  		if err != nil {
    64  			return nil, newError("failed to listen TCP on ", address, ":", port).Base(err)
    65  		}
    66  		newError("listening TCP on ", address, ":", port).WriteToLog(session.ExportIDToError(ctx))
    67  	}
    68  
    69  	if streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol {
    70  		newError("accepting PROXY protocol").AtWarning().WriteToLog(session.ExportIDToError(ctx))
    71  	}
    72  
    73  	l.listener = listener
    74  
    75  	if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
    76  		l.tlsConfig = config.GetTLSConfig()
    77  	}
    78  	if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
    79  		l.xtlsConfig = config.GetXTLSConfig()
    80  	}
    81  
    82  	if tcpSettings.HeaderSettings != nil {
    83  		headerConfig, err := tcpSettings.HeaderSettings.GetInstance()
    84  		if err != nil {
    85  			return nil, newError("invalid header settings").Base(err).AtError()
    86  		}
    87  		auth, err := internet.CreateConnectionAuthenticator(headerConfig)
    88  		if err != nil {
    89  			return nil, newError("invalid header settings.").Base(err).AtError()
    90  		}
    91  		l.authConfig = auth
    92  	}
    93  
    94  	go l.keepAccepting()
    95  	return l, nil
    96  }
    97  
    98  func (v *Listener) keepAccepting() {
    99  	for {
   100  		conn, err := v.listener.Accept()
   101  		if err != nil {
   102  			errStr := err.Error()
   103  			if strings.Contains(errStr, "closed") {
   104  				break
   105  			}
   106  			newError("failed to accepted raw connections").Base(err).AtWarning().WriteToLog()
   107  			if strings.Contains(errStr, "too many") {
   108  				time.Sleep(time.Millisecond * 500)
   109  			}
   110  			continue
   111  		}
   112  
   113  		if v.tlsConfig != nil {
   114  			conn = tls.Server(conn, v.tlsConfig)
   115  		} else if v.xtlsConfig != nil {
   116  			conn = xtls.Server(conn, v.xtlsConfig)
   117  		}
   118  		if v.authConfig != nil {
   119  			conn = v.authConfig.Server(conn)
   120  		}
   121  
   122  		v.addConn(stat.Connection(conn))
   123  	}
   124  }
   125  
   126  // Addr implements internet.Listener.Addr.
   127  func (v *Listener) Addr() net.Addr {
   128  	return v.listener.Addr()
   129  }
   130  
   131  // Close implements internet.Listener.Close.
   132  func (v *Listener) Close() error {
   133  	if v.locker != nil {
   134  		v.locker.Release()
   135  	}
   136  	return v.listener.Close()
   137  }
   138  
   139  func init() {
   140  	common.Must(internet.RegisterTransportListener(protocolName, ListenTCP))
   141  }