From 7495fe7f0ce6cef7dd84f36e74302c3817693936 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 24 Aug 2024 14:12:31 +0200 Subject: [PATCH 1/5] Properly configure IPv4/v6 on Windows WSPiApi.h has been created in 2000, so we can safely assume that it is available everywhere nowadays. Furthermore, `gai_strerror()` is available regardless of whether there is IPv6 support. --- win32/build/config.w32 | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 668995045725b..204b35cb58bc9 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -323,13 +323,9 @@ STDOUT.WriteBlankLines(1); /* Can we build with IPv6 support? */ ARG_ENABLE("ipv6", "Disable IPv6 support (default is turn it on if available)", "yes"); -var main_network_has_ipv6 = 0; -if (PHP_IPV6 == "yes") { - main_network_has_ipv6 = CHECK_HEADER_ADD_INCLUDE("wspiapi.h", "CFLAGS") ? 1 : 0; -} -if (main_network_has_ipv6) { +AC_DEFINE('HAVE_GAI_STRERROR', 1); +if (PHP_IPV6) { STDOUT.WriteLine("Enabling IPv6 support"); - AC_DEFINE('HAVE_GAI_STRERROR', 1); AC_DEFINE('HAVE_IPV6', 1); } From d41c4966ab24e0c5a0b0027288c4cfa63301cfdb Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 25 Aug 2024 01:20:07 +0200 Subject: [PATCH 2/5] Fix if clause --- win32/build/config.w32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 204b35cb58bc9..2740fee4bd9e7 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -324,7 +324,7 @@ STDOUT.WriteBlankLines(1); ARG_ENABLE("ipv6", "Disable IPv6 support (default is turn it on if available)", "yes"); AC_DEFINE('HAVE_GAI_STRERROR', 1); -if (PHP_IPV6) { +if (PHP_IPV6 == "yes") { STDOUT.WriteLine("Enabling IPv6 support"); AC_DEFINE('HAVE_IPV6', 1); } From b3c611b0fc8954e0d3b21bb5a76da542b0c8ba97 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 1 Sep 2024 18:55:24 +0200 Subject: [PATCH 3/5] Refactor We extract `report_getaddrinfo_failure()`, and refactor that further. While this code is now a tad bit slower, that shouldn't matter since it is error handling. We also cheat a bit, since adding a proper format specifier for `php_error_docref()` is not a proper refactoring, but more like a bug fix. --- main/network.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/main/network.c b/main/network.c index bf34043362dab..66638ef941fb1 100644 --- a/main/network.c +++ b/main/network.c @@ -143,6 +143,22 @@ PHPAPI void php_network_freeaddresses(struct sockaddr **sal) } /* }}} */ +#ifdef HAVE_GETADDRINFO +static zend_always_inline report_getaddrinfo_failure(const char *host, int errcode, zend_string **error_string) +{ + zend_string *msg = strpprintf(0, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(errcode)); + if (error_string) { + /* free error string received during previous iteration (if any) */ + if (*error_string) { + zend_string_release_ex(*error_string, 0); + } + *error_string = zend_string_copy(msg); + } + php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(msg)); + zend_string_release_ex(msg, 0); +} +#endif + /* {{{ php_network_getaddresses * Returns number of addresses, 0 for none/error */ @@ -191,16 +207,7 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka # endif if ((n = getaddrinfo(host, NULL, &hints, &res))) { - if (error_string) { - /* free error string received during previous iteration (if any) */ - if (*error_string) { - zend_string_release_ex(*error_string, 0); - } - *error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(n)); - php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string)); - } else { - php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(n)); - } + report_getaddrinfo_failure(host, n, error_string); return 0; } else if (res == NULL) { if (error_string) { From 9490658c7c4b8fe8276f9dce97a166822d9d736f Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 1 Sep 2024 19:24:53 +0200 Subject: [PATCH 4/5] Revert "Refactor" This reverts commit 7b151af2103216295ed82e87d38dae3663ddc35a. --- main/network.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/main/network.c b/main/network.c index 66638ef941fb1..bf34043362dab 100644 --- a/main/network.c +++ b/main/network.c @@ -143,22 +143,6 @@ PHPAPI void php_network_freeaddresses(struct sockaddr **sal) } /* }}} */ -#ifdef HAVE_GETADDRINFO -static zend_always_inline report_getaddrinfo_failure(const char *host, int errcode, zend_string **error_string) -{ - zend_string *msg = strpprintf(0, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(errcode)); - if (error_string) { - /* free error string received during previous iteration (if any) */ - if (*error_string) { - zend_string_release_ex(*error_string, 0); - } - *error_string = zend_string_copy(msg); - } - php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(msg)); - zend_string_release_ex(msg, 0); -} -#endif - /* {{{ php_network_getaddresses * Returns number of addresses, 0 for none/error */ @@ -207,7 +191,16 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka # endif if ((n = getaddrinfo(host, NULL, &hints, &res))) { - report_getaddrinfo_failure(host, n, error_string); + if (error_string) { + /* free error string received during previous iteration (if any) */ + if (*error_string) { + zend_string_release_ex(*error_string, 0); + } + *error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(n)); + php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string)); + } else { + php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(n)); + } return 0; } else if (res == NULL) { if (error_string) { From cf32a91f116874db2ee3f349ee600b3788038675 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 1 Sep 2024 19:37:28 +0200 Subject: [PATCH 5/5] gai_strerror() is not thread-safe on Windows First we refactor to have only a single usage of `PHP_GAI_STRERROR()` left; then we drop the macro in favor of calling the different functions conditionally in an ad-hoc style. This is necessary because the return value of `php_win32_error_to_msg` needs to be freed by the caller. The error messages are no more inline with other error messages, since `gai_strerror()` apparently always appends a period and a space. --- main/network.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/main/network.c b/main/network.c index bf34043362dab..8d1ec646f4ad0 100644 --- a/main/network.c +++ b/main/network.c @@ -88,10 +88,7 @@ const struct in6_addr in6addr_any = {0}; /* IN6ADDR_ANY_INIT; */ #endif #ifdef HAVE_GETADDRINFO -#ifdef HAVE_GAI_STRERROR -# define PHP_GAI_STRERROR(x) (gai_strerror(x)) -#else -# define PHP_GAI_STRERROR(x) (php_gai_strerror(x)) +# if !defined(PHP_WIN32) && !defined(HAVE_GAI_STRERROR) /* {{{ php_gai_strerror */ static const char *php_gai_strerror(int code) { @@ -127,7 +124,7 @@ static const char *php_gai_strerror(int code) return "Unknown error"; } /* }}} */ -#endif +# endif #endif /* {{{ php_network_freeaddresses */ @@ -191,16 +188,26 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka # endif if ((n = getaddrinfo(host, NULL, &hints, &res))) { +# if defined(PHP_WIN32) + char *gai_error = php_win32_error_to_msg(n); +# elif defined(HAVE_GAI_STRERROR) + const char *gai_error = gai_strerror(n); +# else + const char *gai_error = php_gai_strerror(n) +# endif if (error_string) { /* free error string received during previous iteration (if any) */ if (*error_string) { zend_string_release_ex(*error_string, 0); } - *error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(n)); + *error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, gai_error); php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string)); } else { - php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(n)); + php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, gai_error); } +# if PHP_WIN32 + php_win32_error_msg_free(gai_error); +# endif return 0; } else if (res == NULL) { if (error_string) {