From 24c2eae3d7f260fd20690c59d9cd880d89a13c9d Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Tue, 23 Mar 2021 20:53:19 -0700 Subject: [PATCH] use inet_ntop and inet_pton musl implementations on all platforms --- ixwebsocket/IXNetSystem.cpp | 267 +++++++++++++++++---------------- ixwebsocket/IXNetSystem.h | 9 +- ixwebsocket/IXSocketServer.cpp | 8 +- ws/ws.cpp | 2 +- 4 files changed, 148 insertions(+), 138 deletions(-) diff --git a/ixwebsocket/IXNetSystem.cpp b/ixwebsocket/IXNetSystem.cpp index 7fd55868..ff023837 100644 --- a/ixwebsocket/IXNetSystem.cpp +++ b/ixwebsocket/IXNetSystem.cpp @@ -124,147 +124,160 @@ namespace ix #endif } -} // namespace ix - -// -// mingw does not have inet_ntop and inet_pton, which were taken as is from the musl C library. -// -#if defined(_WIN32) && defined(__GNUC__) -const char* inet_ntop(int af, const void* a0, char* s, socklen_t l) -{ - const unsigned char* a = (const unsigned char*) a0; - int i, j, max, best; - char buf[100]; - - switch (af) + // + // mingw does not have inet_ntop, which were taken as is from the musl C library. + // + const char* inet_ntop(int af, const void* a0, char* s, socklen_t l) { - case AF_INET: - if (snprintf(s, l, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]) < l) return s; - break; - case AF_INET6: - if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12)) - snprintf(buf, - sizeof buf, - "%x:%x:%x:%x:%x:%x:%x:%x", - 256 * a[0] + a[1], - 256 * a[2] + a[3], - 256 * a[4] + a[5], - 256 * a[6] + a[7], - 256 * a[8] + a[9], - 256 * a[10] + a[11], - 256 * a[12] + a[13], - 256 * a[14] + a[15]); - else - snprintf(buf, - sizeof buf, - "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d", - 256 * a[0] + a[1], - 256 * a[2] + a[3], - 256 * a[4] + a[5], - 256 * a[6] + a[7], - 256 * a[8] + a[9], - 256 * a[10] + a[11], - a[12], - a[13], - a[14], - a[15]); - /* Replace longest /(^0|:)[:0]{2,}/ with "::" */ - for (i = best = 0, max = 2; buf[i]; i++) - { - if (i && buf[i] != ':') continue; - j = strspn(buf + i, ":0"); - if (j > max) best = i, max = j; - } - if (max > 3) - { - buf[best] = buf[best + 1] = ':'; - memmove(buf + best + 2, buf + best + max, i - best - max + 1); - } - if (strlen(buf) < l) - { - strcpy(s, buf); - return s; - } - break; - default: errno = EAFNOSUPPORT; return 0; - } - errno = ENOSPC; - return 0; -} +// wrapper enabled on all platforms for now +// #if defined(_WIN32) && defined(__GNUC__) +#if 1 + const unsigned char* a = (const unsigned char*) a0; + int i, j, max, best; + char buf[100]; -static int hexval(unsigned c) -{ - if (c - '0' < 10) return c - '0'; - c |= 32; - if (c - 'a' < 6) return c - 'a' + 10; - return -1; -} - -int inet_pton(int af, const char* s, void* a0) -{ - uint16_t ip[8]; - unsigned char* a = (unsigned char*) a0; - int i, j, v, d, brk = -1, need_v4 = 0; - - if (af == AF_INET) - { - for (i = 0; i < 4; i++) + switch (af) { - for (v = j = 0; j < 3 && isdigit(s[j]); j++) - v = 10 * v + s[j] - '0'; - if (j == 0 || (j > 1 && s[0] == '0') || v > 255) return 0; - a[i] = v; - if (s[j] == 0 && i == 3) return 1; - if (s[j] != '.') return 0; - s += j + 1; + case AF_INET: + if (snprintf(s, l, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]) < l) return s; + break; + case AF_INET6: + if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12)) + snprintf(buf, + sizeof buf, + "%x:%x:%x:%x:%x:%x:%x:%x", + 256 * a[0] + a[1], + 256 * a[2] + a[3], + 256 * a[4] + a[5], + 256 * a[6] + a[7], + 256 * a[8] + a[9], + 256 * a[10] + a[11], + 256 * a[12] + a[13], + 256 * a[14] + a[15]); + else + snprintf(buf, + sizeof buf, + "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d", + 256 * a[0] + a[1], + 256 * a[2] + a[3], + 256 * a[4] + a[5], + 256 * a[6] + a[7], + 256 * a[8] + a[9], + 256 * a[10] + a[11], + a[12], + a[13], + a[14], + a[15]); + /* Replace longest /(^0|:)[:0]{2,}/ with "::" */ + for (i = best = 0, max = 2; buf[i]; i++) + { + if (i && buf[i] != ':') continue; + j = strspn(buf + i, ":0"); + if (j > max) best = i, max = j; + } + if (max > 3) + { + buf[best] = buf[best + 1] = ':'; + memmove(buf + best + 2, buf + best + max, i - best - max + 1); + } + if (strlen(buf) < l) + { + strcpy(s, buf); + return s; + } + break; + default: errno = EAFNOSUPPORT; return 0; } + errno = ENOSPC; return 0; +#else + return ::inet_ntop(af, a0, s, l); +#endif } - else if (af != AF_INET6) + + static int hexval(unsigned c) { - errno = EAFNOSUPPORT; + if (c - '0' < 10) return c - '0'; + c |= 32; + if (c - 'a' < 6) return c - 'a' + 10; return -1; } - if (*s == ':' && *++s != ':') return 0; + // + // mingw does not have inet_pton, which were taken as is from the musl C library. + // + int inet_pton(int af, const char* s, void* a0) + { +// wrapper enabled on all platforms for now +// #if defined(_WIN32) && defined(__GNUC__) +#if 1 + uint16_t ip[8]; + unsigned char* a = (unsigned char*) a0; + int i, j, v, d, brk = -1, need_v4 = 0; - for (i = 0;; i++) - { - if (s[0] == ':' && brk < 0) + if (af == AF_INET) { - brk = i; - ip[i & 7] = 0; - if (!*++s) break; + for (i = 0; i < 4; i++) + { + for (v = j = 0; j < 3 && isdigit(s[j]); j++) + v = 10 * v + s[j] - '0'; + if (j == 0 || (j > 1 && s[0] == '0') || v > 255) return 0; + a[i] = v; + if (s[j] == 0 && i == 3) return 1; + if (s[j] != '.') return 0; + s += j + 1; + } + return 0; + } + else if (af != AF_INET6) + { + errno = EAFNOSUPPORT; + return -1; + } + + if (*s == ':' && *++s != ':') return 0; + + for (i = 0;; i++) + { + if (s[0] == ':' && brk < 0) + { + brk = i; + ip[i & 7] = 0; + if (!*++s) break; + if (i == 7) return 0; + continue; + } + for (v = j = 0; j < 4 && (d = hexval(s[j])) >= 0; j++) + v = 16 * v + d; + if (j == 0) return 0; + ip[i & 7] = v; + if (!s[j] && (brk >= 0 || i == 7)) break; if (i == 7) return 0; - continue; + if (s[j] != ':') + { + if (s[j] != '.' || (i < 6 && brk < 0)) return 0; + need_v4 = 1; + i++; + break; + } + s += j + 1; } - for (v = j = 0; j < 4 && (d = hexval(s[j])) >= 0; j++) - v = 16 * v + d; - if (j == 0) return 0; - ip[i & 7] = v; - if (!s[j] && (brk >= 0 || i == 7)) break; - if (i == 7) return 0; - if (s[j] != ':') + if (brk >= 0) { - if (s[j] != '.' || (i < 6 && brk < 0)) return 0; - need_v4 = 1; - i++; - break; + memmove(ip + brk + 7 - i, ip + brk, 2 * (i + 1 - brk)); + for (j = 0; j < 7 - i; j++) + ip[brk + j] = 0; } - s += j + 1; + for (j = 0; j < 8; j++) + { + *a++ = ip[j] >> 8; + *a++ = ip[j]; + } + if (need_v4 && inet_pton(AF_INET, (const char*) s, a - 4) <= 0) return 0; + return 1; +#else + return ::inet_pton(af, s, a0); +#endif } - if (brk >= 0) - { - memmove(ip + brk + 7 - i, ip + brk, 2 * (i + 1 - brk)); - for (j = 0; j < 7 - i; j++) - ip[brk + j] = 0; - } - for (j = 0; j < 8; j++) - { - *a++ = ip[j] >> 8; - *a++ = ip[j]; - } - if (need_v4 && inet_pton(AF_INET, (const char*) s, a - 4) <= 0) return 0; - return 1; -} -#endif // defined(_WIN32) && defined(__GNUC__) + +} // namespace ix diff --git a/ixwebsocket/IXNetSystem.h b/ixwebsocket/IXNetSystem.h index 384e9b1b..2bd2e38d 100644 --- a/ixwebsocket/IXNetSystem.h +++ b/ixwebsocket/IXNetSystem.h @@ -53,12 +53,6 @@ struct pollfd #include #endif -// mingw does not have those -#if defined(_WIN32) && defined(__GNUC__) -const char* inet_ntop(int af, const void* src, char* dst, socklen_t size); -int inet_pton(int af, const char* src, void* dst); -#endif - namespace ix { #ifdef _WIN32 @@ -71,4 +65,7 @@ namespace ix bool uninitNetSystem(); int poll(struct pollfd* fds, nfds_t nfds, int timeout); + + const char* inet_ntop(int af, const void* src, char* dst, socklen_t size); + int inet_pton(int af, const char* src, void* dst); } // namespace ix diff --git a/ixwebsocket/IXSocketServer.cpp b/ixwebsocket/IXSocketServer.cpp index 33bbfd71..2cc88994 100644 --- a/ixwebsocket/IXSocketServer.cpp +++ b/ixwebsocket/IXSocketServer.cpp @@ -104,7 +104,7 @@ namespace ix server.sin_family = _addressFamily; server.sin_port = htons(_port); - if (inet_pton(_addressFamily, _host.c_str(), &server.sin_addr.s_addr) <= 0) + if (ix::inet_pton(_addressFamily, _host.c_str(), &server.sin_addr.s_addr) <= 0) { std::stringstream ss; ss << "SocketServer::listen() error calling inet_pton " @@ -133,7 +133,7 @@ namespace ix server.sin6_family = _addressFamily; server.sin6_port = htons(_port); - if (inet_pton(_addressFamily, _host.c_str(), &server.sin6_addr) <= 0) + if (ix::inet_pton(_addressFamily, _host.c_str(), &server.sin6_addr) <= 0) { std::stringstream ss; ss << "SocketServer::listen() error calling inet_pton " @@ -338,7 +338,7 @@ namespace ix if (_addressFamily == AF_INET) { char remoteIp4[INET_ADDRSTRLEN]; - if (inet_ntop(AF_INET, &client.sin_addr, remoteIp4, INET_ADDRSTRLEN) == nullptr) + if (ix::inet_ntop(AF_INET, &client.sin_addr, remoteIp4, INET_ADDRSTRLEN) == nullptr) { int err = Socket::getErrno(); std::stringstream ss; @@ -357,7 +357,7 @@ namespace ix else // AF_INET6 { char remoteIp6[INET6_ADDRSTRLEN]; - if (inet_ntop(AF_INET6, &client.sin_addr, remoteIp6, INET6_ADDRSTRLEN) == nullptr) + if (ix::inet_ntop(AF_INET6, &client.sin_addr, remoteIp6, INET6_ADDRSTRLEN) == nullptr) { int err = Socket::getErrno(); std::stringstream ss; diff --git a/ws/ws.cpp b/ws/ws.cpp index 5668d507..440b6114 100644 --- a/ws/ws.cpp +++ b/ws/ws.cpp @@ -906,7 +906,7 @@ namespace ix // code which display correct results char str[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &addr, str, INET_ADDRSTRLEN); + ix::inet_ntop(AF_INET, &addr, str, INET_ADDRSTRLEN); spdlog::info("host: {} ip: {}", hostname, str);