Hi,

On Windows, if_indextoname() and if_nametoindex() do not set errno on
failure. The only indication of failure is their return value (NULL and 0,
respectively). As a result, the value of errno after these calls is
undefined and should not be used for error handling.

The attached patch fixes this issue. When if_indextoname() returns NULL,
apr_sockaddr_zone_get() now returns APR_EGENERAL instead of using errno.
When if_nametoindex() returns 0, apr_sockaddr_zone_set() now always
attempts to interpret the supplied zone identifier as a numeric value.

Suggested commit message:
[[[
Fix Windows error handling for if_indextoname() and if_nametoindex()

On Windows, if_indextoname() and if_nametoindex() do not set errno on
failure. Their return values are the only reliable indicators of success or
failure, so errno must not be used after these calls.

* network_io/unix/sockaddr.c
  (apr_sockaddr_zone_set): On Windows, do not check errno after
if_nametoindex(). Always attempt to parse the zone identifier as a numeric
value when if_nametoindex() fails.
  (apr_sockaddr_zone_get): On Windows, return APR_EGENERAL when
if_indextoname() fails instead of returning the errno.

Submitted by: Simon Atansyan <[email protected]>
]]]

1.
https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-if_indextoname
2.
https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-if_nametoindex

-- 
Simon Atanasyan
VisualSVN Software Limited
Index: network_io/unix/sockaddr.c
===================================================================
--- network_io/unix/sockaddr.c  (revision 1934744)
+++ network_io/unix/sockaddr.c  (working copy)
@@ -1239,10 +1239,12 @@
         return APR_SUCCESS;
     }
 
+#if !defined(WIN32)
     if (errno != ENODEV) {
         return errno;
     }
-    else {
+#endif
+    {
         char *endptr;
         apr_int64_t i = apr_strtoi64(zone_id, &endptr, 10);
 
@@ -1271,7 +1273,11 @@
     if (name) {
         char *buf = apr_palloc(p, IF_NAMESIZE);
         if (if_indextoname(sa->sa.sin6.sin6_scope_id, buf) == NULL)
+#if defined(WIN32)
+            return APR_EGENERAL;
+#else
             return errno;
+#endif
         *name = buf;
     }
 

Reply via email to