bool isLocalSocketAddress(const StaticString &address) { switch (getSocketAddressType(address)) { case SAT_UNIX: return true; case SAT_TCP: { string host; unsigned short port; parseTcpSocketAddress(address, host, port); return host == "127.0.0.1" || host == "::1" || host == "localhost"; } default: throw ArgumentException("Unsupported socket address type"); } }
void parseTcpSocketAddress(const StaticString &address, string &host, unsigned short &port) { if (getSocketAddressType(address) != SAT_TCP) { throw ArgumentException("Not a valid TCP socket address"); } vector<string> args; string begin(address.c_str() + sizeof("tcp://") - 1, address.size() - sizeof("tcp://") + 1); split(begin, ':', args); if (args.size() != 2) { throw ArgumentException("Not a valid TCP socket address"); } else { host = args[0]; port = atoi(args[1].c_str()); } }
int connectToServer(const StaticString &address) { TRACE_POINT(); switch (getSocketAddressType(address)) { case SAT_UNIX: return connectToUnixServer(parseUnixSocketAddress(address)); case SAT_TCP: { string host; unsigned short port; parseTcpSocketAddress(address, host, port); return connectToTcpServer(host, port); } default: throw ArgumentException(string("Unknown address type for '") + address + "'"); } }
int createServer(const StaticString &address, unsigned int backlogSize, bool autoDelete) { TRACE_POINT(); switch (getSocketAddressType(address)) { case SAT_UNIX: return createUnixServer(parseUnixSocketAddress(address), backlogSize, autoDelete); case SAT_TCP: { string host; unsigned short port; parseTcpSocketAddress(address, host, port); return createTcpServer(host.c_str(), port, backlogSize); } default: throw ArgumentException(string("Unknown address type for '") + address + "'"); } }
void parseTcpSocketAddress(const StaticString &address, string &host, unsigned short &port) { if (getSocketAddressType(address) != SAT_TCP) { throw ArgumentException("Not a valid TCP socket address"); } StaticString hostAndPort(address.data() + sizeof("tcp://") - 1, address.size() - sizeof("tcp://") + 1); if (hostAndPort.empty()) { throw ArgumentException("Not a valid TCP socket address"); } if (hostAndPort[0] == '[') { // IPv6 address, e.g.: // [::1]:3000 const char *hostEnd = (const char *) memchr(hostAndPort.data(), ']', hostAndPort.size()); if (hostEnd == NULL || hostAndPort.size() <= string::size_type(hostEnd - hostAndPort.data()) + 3) { throw ArgumentException("Not a valid TCP socket address"); } const char *sep = hostEnd + 1; host.assign(hostAndPort.data() + 1, hostEnd - hostAndPort.data() - 1); port = stringToUint(StaticString( sep + 1, hostAndPort.data() + hostAndPort.size() - sep - 1 )); } else { // IPv4 address, e.g.: // 127.0.0.1:3000 const char *sep = (const char *) memchr(hostAndPort.data(), ':', hostAndPort.size()); if (sep == NULL || hostAndPort.size() <= string::size_type(sep - hostAndPort.data()) + 2) { throw ArgumentException("Not a valid TCP socket address"); } host.assign(hostAndPort.data(), sep - hostAndPort.data()); port = stringToUint(StaticString( sep + 1, hostAndPort.data() + hostAndPort.size() - sep - 1 )); } }
void setupNonBlockingSocket(NConnect_State &state, const StaticString &address) { TRACE_POINT(); state.type = getSocketAddressType(address); switch (state.type) { case SAT_UNIX: setupNonBlockingUnixSocket(state.s_unix, parseUnixSocketAddress(address)); break; case SAT_TCP: { string host; unsigned short port; parseTcpSocketAddress(address, host, port); setupNonBlockingTcpSocket(state.s_tcp, host, port); break; } default: throw ArgumentException(string("Unknown address type for '") + address + "'"); } }