github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/transport/internet/tcp_hub.go (about)

     1  package internet
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/v2fly/v2ray-core/v5/common/net"
     7  )
     8  
     9  var transportListenerCache = make(map[string]ListenFunc)
    10  
    11  func RegisterTransportListener(protocol string, listener ListenFunc) error {
    12  	if _, found := transportListenerCache[protocol]; found {
    13  		return newError(protocol, " listener already registered.").AtError()
    14  	}
    15  	transportListenerCache[protocol] = listener
    16  	return nil
    17  }
    18  
    19  type ConnHandler func(Connection)
    20  
    21  type ListenFunc func(ctx context.Context, address net.Address, port net.Port, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error)
    22  
    23  type Listener interface {
    24  	Close() error
    25  	Addr() net.Addr
    26  }
    27  
    28  // ListenUnix is the UDS version of ListenTCP
    29  func ListenUnix(ctx context.Context, address net.Address, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error) {
    30  	if settings == nil {
    31  		s, err := ToMemoryStreamConfig(nil)
    32  		if err != nil {
    33  			return nil, newError("failed to create default unix stream settings").Base(err)
    34  		}
    35  		settings = s
    36  	}
    37  
    38  	protocol := settings.ProtocolName
    39  
    40  	if originalProtocolName := getOriginalMessageName(settings); originalProtocolName != "" {
    41  		protocol = originalProtocolName
    42  	}
    43  
    44  	listenFunc := transportListenerCache[protocol]
    45  	if listenFunc == nil {
    46  		return nil, newError(protocol, " unix istener not registered.").AtError()
    47  	}
    48  	listener, err := listenFunc(ctx, address, net.Port(0), settings, handler)
    49  	if err != nil {
    50  		return nil, newError("failed to listen on unix address: ", address).Base(err)
    51  	}
    52  	return listener, nil
    53  }
    54  
    55  func ListenTCP(ctx context.Context, address net.Address, port net.Port, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error) {
    56  	if settings == nil {
    57  		s, err := ToMemoryStreamConfig(nil)
    58  		if err != nil {
    59  			return nil, newError("failed to create default stream settings").Base(err)
    60  		}
    61  		settings = s
    62  	}
    63  
    64  	if address.Family().IsDomain() && address.Domain() == "localhost" {
    65  		address = net.LocalHostIP
    66  	}
    67  
    68  	if address.Family().IsDomain() {
    69  		return nil, newError("domain address is not allowed for listening: ", address.Domain())
    70  	}
    71  
    72  	protocol := settings.ProtocolName
    73  
    74  	if originalProtocolName := getOriginalMessageName(settings); originalProtocolName != "" {
    75  		protocol = originalProtocolName
    76  	}
    77  
    78  	listenFunc := transportListenerCache[protocol]
    79  	if listenFunc == nil {
    80  		return nil, newError(protocol, " listener not registered.").AtError()
    81  	}
    82  	listener, err := listenFunc(ctx, address, port, settings, handler)
    83  	if err != nil {
    84  		return nil, newError("failed to listen on address: ", address, ":", port).Base(err)
    85  	}
    86  	return listener, nil
    87  }
    88  
    89  // ListenSystem listens on a local address for incoming TCP connections.
    90  //
    91  // v2ray:api:beta
    92  func ListenSystem(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.Listener, error) {
    93  	return effectiveListener.Listen(ctx, addr, sockopt)
    94  }
    95  
    96  // ListenSystemPacket listens on a local address for incoming UDP connections.
    97  //
    98  // v2ray:api:beta
    99  func ListenSystemPacket(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.PacketConn, error) {
   100  	return effectiveListener.ListenPacket(ctx, addr, sockopt)
   101  }