github.com/EagleQL/Xray-core@v1.4.3/transport/internet/tcp_hub.go (about)

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