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 }