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