github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/transport/internet/tcp_hub.go (about) 1 package internet 2 3 import ( 4 "context" 5 6 "github.com/xtls/xray-core/common/net" 7 "github.com/xtls/xray-core/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 }