From 36436503d956da2e8cb2ad79f5ef09ab5470e178 Mon Sep 17 00:00:00 2001 From: kiroma Date: Thu, 20 Feb 2025 11:39:18 +0100 Subject: [PATCH 1/4] Replace ipv4 inet_ntop with a handrolled function --- trantor/net/InetAddress.cc | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/trantor/net/InetAddress.cc b/trantor/net/InetAddress.cc index 245f27ea..fb1b2b5c 100644 --- a/trantor/net/InetAddress.cc +++ b/trantor/net/InetAddress.cc @@ -196,16 +196,39 @@ bool InetAddress::isLoopbackIp() const return false; } +static void byteToChars(std::string::iterator& dst, unsigned char byte) +{ + *dst = byte / 100 + '0'; + dst += byte >= 100; + *dst = byte % 100 / 10 + '0'; + dst += byte >= 10; + *dst = byte % 10 + '0'; + ++dst; +} + +static constexpr char stringInitBuffer[15]{}; +std::string iptos(unsigned inet_addr) +{ + // Initialize with a static buffer to force the constructor of string to get fully inlined + std::string out(stringInitBuffer, 15); + std::string::iterator dst = out.begin(); + byteToChars(dst, inet_addr >> 0 & 0xff); + *(dst++) = '.'; + byteToChars(dst, inet_addr >> 8 & 0xff); + *(dst++) = '.'; + byteToChars(dst, inet_addr >> 16 & 0xff); + *(dst++) = '.'; + byteToChars(dst, inet_addr >> 24 & 0xff); + out.erase(dst, out.end()); + return out; +} + std::string InetAddress::toIp() const { - char buf[64]; + char buf[INET6_ADDRSTRLEN]{}; if (addr_.sin_family == AF_INET) { -#if defined _WIN32 - ::inet_ntop(AF_INET, (PVOID)&addr_.sin_addr, buf, sizeof(buf)); -#else - ::inet_ntop(AF_INET, &addr_.sin_addr, buf, sizeof(buf)); -#endif + return iptos(addr_.sin_addr.s_addr); } else if (addr_.sin_family == AF_INET6) { From e00a702c3588bbe731cc58a1835d38b240194e93 Mon Sep 17 00:00:00 2001 From: kiroma Date: Thu, 20 Feb 2025 11:53:51 +0100 Subject: [PATCH 2/4] make iptos static --- trantor/net/InetAddress.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trantor/net/InetAddress.cc b/trantor/net/InetAddress.cc index fb1b2b5c..26af6af2 100644 --- a/trantor/net/InetAddress.cc +++ b/trantor/net/InetAddress.cc @@ -207,7 +207,7 @@ static void byteToChars(std::string::iterator& dst, unsigned char byte) } static constexpr char stringInitBuffer[15]{}; -std::string iptos(unsigned inet_addr) +static std::string iptos(unsigned inet_addr) { // Initialize with a static buffer to force the constructor of string to get fully inlined std::string out(stringInitBuffer, 15); From 103e3f517c37aec4fc4c47a7b311f579e57a91a6 Mon Sep 17 00:00:00 2001 From: kiroma Date: Thu, 20 Feb 2025 12:33:45 +0100 Subject: [PATCH 3/4] Make codegen better behaved on msvc / gcc For some reason gcc assumes that static constexpr array can be modified and does not attempt to zero init the string, reading from the array instead. Having the buffer be initialized in the function instead via a consteval seems to yield proper results. MSVC just straight up doesn't understand static initialization and attempts to initialize the static buffer on every function call. Microsoft never fails to disappoint. --- trantor/net/InetAddress.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trantor/net/InetAddress.cc b/trantor/net/InetAddress.cc index 26af6af2..18544b37 100644 --- a/trantor/net/InetAddress.cc +++ b/trantor/net/InetAddress.cc @@ -206,10 +206,10 @@ static void byteToChars(std::string::iterator& dst, unsigned char byte) ++dst; } -static constexpr char stringInitBuffer[15]{}; static std::string iptos(unsigned inet_addr) { // Initialize with a static buffer to force the constructor of string to get fully inlined + constexpr char stringInitBuffer[15]{}; std::string out(stringInitBuffer, 15); std::string::iterator dst = out.begin(); byteToChars(dst, inet_addr >> 0 & 0xff); From f7f604ddf353fc7d7832dbadb32f5e80f7040692 Mon Sep 17 00:00:00 2001 From: antao Date: Thu, 20 Feb 2025 20:53:00 +0800 Subject: [PATCH 4/4] Format... --- trantor/net/InetAddress.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/trantor/net/InetAddress.cc b/trantor/net/InetAddress.cc index 18544b37..08a0aa42 100644 --- a/trantor/net/InetAddress.cc +++ b/trantor/net/InetAddress.cc @@ -196,7 +196,7 @@ bool InetAddress::isLoopbackIp() const return false; } -static void byteToChars(std::string::iterator& dst, unsigned char byte) +static void byteToChars(std::string::iterator &dst, unsigned char byte) { *dst = byte / 100 + '0'; dst += byte >= 100; @@ -208,7 +208,8 @@ static void byteToChars(std::string::iterator& dst, unsigned char byte) static std::string iptos(unsigned inet_addr) { - // Initialize with a static buffer to force the constructor of string to get fully inlined + // Initialize with a static buffer to force the constructor of string to get + // fully inlined constexpr char stringInitBuffer[15]{}; std::string out(stringInitBuffer, 15); std::string::iterator dst = out.begin();