github.com/v2fly/v2ray-core/v4@v4.45.2/transport/internet/tcp/hub.go (about)

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