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

     1  package internet
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/v2fly/v2ray-core/v4/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  	listenFunc := transportListenerCache[protocol]
    40  	if listenFunc == nil {
    41  		return nil, newError(protocol, " unix istener not registered.").AtError()
    42  	}
    43  	listener, err := listenFunc(ctx, address, net.Port(0), settings, handler)
    44  	if err != nil {
    45  		return nil, newError("failed to listen on unix address: ", address).Base(err)
    46  	}
    47  	return listener, nil
    48  }
    49  
    50  func ListenTCP(ctx context.Context, address net.Address, port net.Port, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error) {
    51  	if settings == nil {
    52  		s, err := ToMemoryStreamConfig(nil)
    53  		if err != nil {
    54  			return nil, newError("failed to create default stream settings").Base(err)
    55  		}
    56  		settings = s
    57  	}
    58  
    59  	if address.Family().IsDomain() && address.Domain() == "localhost" {
    60  		address = net.LocalHostIP
    61  	}
    62  
    63  	if address.Family().IsDomain() {
    64  		return nil, newError("domain address is not allowed for listening: ", address.Domain())
    65  	}
    66  
    67  	protocol := settings.ProtocolName
    68  	listenFunc := transportListenerCache[protocol]
    69  	if listenFunc == nil {
    70  		return nil, newError(protocol, " listener not registered.").AtError()
    71  	}
    72  	listener, err := listenFunc(ctx, address, port, settings, handler)
    73  	if err != nil {
    74  		return nil, newError("failed to listen on address: ", address, ":", port).Base(err)
    75  	}
    76  	return listener, nil
    77  }
    78  
    79  // ListenSystem listens on a local address for incoming TCP connections.
    80  //
    81  // v2ray:api:beta
    82  func ListenSystem(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.Listener, error) {
    83  	return effectiveListener.Listen(ctx, addr, sockopt)
    84  }
    85  
    86  // ListenSystemPacket listens on a local address for incoming UDP connections.
    87  //
    88  // v2ray:api:beta
    89  func ListenSystemPacket(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.PacketConn, error) {
    90  	return effectiveListener.ListenPacket(ctx, addr, sockopt)
    91  }