github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/transport/internet/tcp_hub.go (about)

     1  package internet
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/xmplusdev/xmcore/common/net"
     7  	"github.com/xmplusdev/xmcore/transport/internet/stat"
     8  )
     9  
    10  var transportListenerCache = make(map[string]ListenFunc)
    11  
    12  func RegisterTransportListener(protocol string, listener ListenFunc) error {
    13  	if _, found := transportListenerCache[protocol]; found {
    14  		return newError(protocol, " listener already registered.").AtError()
    15  	}
    16  	transportListenerCache[protocol] = listener
    17  	return nil
    18  }
    19  
    20  type ConnHandler func(stat.Connection)
    21  
    22  type ListenFunc func(ctx context.Context, address net.Address, port net.Port, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error)
    23  
    24  type Listener interface {
    25  	Close() error
    26  	Addr() net.Addr
    27  }
    28  
    29  // ListenUnix is the UDS version of ListenTCP
    30  func ListenUnix(ctx context.Context, address net.Address, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error) {
    31  	if settings == nil {
    32  		s, err := ToMemoryStreamConfig(nil)
    33  		if err != nil {
    34  			return nil, newError("failed to create default unix stream settings").Base(err)
    35  		}
    36  		settings = s
    37  	}
    38  
    39  	protocol := settings.ProtocolName
    40  	listenFunc := transportListenerCache[protocol]
    41  	if listenFunc == nil {
    42  		return nil, newError(protocol, " unix istener not registered.").AtError()
    43  	}
    44  	listener, err := listenFunc(ctx, address, net.Port(0), settings, handler)
    45  	if err != nil {
    46  		return nil, newError("failed to listen on unix address: ", address).Base(err)
    47  	}
    48  	return listener, nil
    49  }
    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  }