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