[PATCH 0/2] MR10825: ws2_32: Exclude not found and loopback addresses in get_local_ips() if others present.
Fixes a regression introduced by d48e8d03bd679480c24671908f1d2e4c0851bd65. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59690 Before the regression commit loopback forward addresses were (wrongly) not present on Linux. GetAdaptersInfo() doesn't return loopback interface, that's why the address stays as 'magic_loopback_addr'. But even if we properly found loopback adapter that wouldn't change much, loopback address is only supposed to be returned if there is no real network adapters / addresses active at all (there is already a test for that but the test didn't work due to 'magic loopback address' substituted in Wine). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10825
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/ws2_32/tests/protocol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c index 5da1bd3eae4..9c0e2f443ff 100644 --- a/dlls/ws2_32/tests/protocol.c +++ b/dlls/ws2_32/tests/protocol.c @@ -2637,14 +2637,14 @@ static void test_gethostbyname(void) for (count = 0; addr_list[count] != NULL; count++) { char *ip = inet_ntoa(*addr_list[count]); - if (!strcmp(ip, "127.0.0.1")) + if (!strcmp(ip, "127.0.0.1") || !strcmp(ip, "127.12.34.56") /* Wine hack loopback addr substitute */) local_ip = TRUE; if (winetest_debug > 1) trace("%s\n", ip); } if (local_ip) { - ok(count == 1, "expected 127.0.0.1 to be the only IP returned\n"); + todo_wine ok(count == 1, "expected 127.0.0.1 to be the only IP returned\n"); skip("Only the loopback address is present, skipping tests\n"); return; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10825
From: Paul Gofman <pgofman@codeweavers.com> Fixes a regression introduced by d48e8d03bd679480c24671908f1d2e4c0851bd65. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59690 --- dlls/ws2_32/protocol.c | 17 ++++++++++++++++- dlls/ws2_32/tests/protocol.c | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c index 9751c7a4d23..647409d84a3 100644 --- a/dlls/ws2_32/protocol.c +++ b/dlls/ws2_32/protocol.c @@ -802,7 +802,7 @@ static int __cdecl compare_routes_by_metric_asc( const void *left, const void *r */ static struct hostent *get_local_ips( char *hostname ) { - int numroutes = 0, i, j, default_routes = 0; + int numroutes = 0, i, j, default_routes = 0, matched_routes = 0; IP_ADAPTER_INFO *adapters = NULL, *k; struct hostent *hostlist = NULL; MIB_IPFORWARDTABLE *routes = NULL; @@ -876,10 +876,25 @@ static struct hostent *get_local_ips( char *hostname ) char *ip = k->IpAddressList.IpAddress.String; if (route_addrs[i].interface == k->Index) + { route_addrs[i].addr.s_addr = inet_addr(ip); + if (memcmp( &route_addrs[i].addr.s_addr, magic_loopback_addr, 4 )) ++matched_routes; + } } } + if (matched_routes) + { + for (i = 0; i < numroutes; ++i) + { + if (!memcmp( &route_addrs[i].addr.s_addr, magic_loopback_addr, 4 )) + { + --numroutes; + memmove( &route_addrs[i], &route_addrs[i + 1], sizeof(*route_addrs) * (numroutes - i) ); + --i; + } + } + } /* Allocate a hostent and enough memory for all the IPs, * including the NULL at the end of the list. */ diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c index 9c0e2f443ff..0e87ee04ce5 100644 --- a/dlls/ws2_32/tests/protocol.c +++ b/dlls/ws2_32/tests/protocol.c @@ -2644,7 +2644,7 @@ static void test_gethostbyname(void) if (local_ip) { - todo_wine ok(count == 1, "expected 127.0.0.1 to be the only IP returned\n"); + ok(count == 1, "expected 127.0.0.1 to be the only IP returned\n"); skip("Only the loopback address is present, skipping tests\n"); return; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10825
Okay, this code has always been a little tough to follow. Rough history: 1. Magic loopback address was introduced (presumably so that 127.0.0.1 would never be returned, this is _probably_ wrong) 2. Only one local IP was returned, causing some applications to do the wrong thing if it's the wrong one 3. All local IPs returned, being sorted by routing metric. Magic loopback address used as fallback to preserve behavior. 4. Improved support for other networking features added (actual route information, etc.) 5. Adding the _local_ routes means that the "return local IPs by route metric" routine adds the loopback IPs to the list (this is definitely wrong) So, the proposed patch here removes these loopback IPs (and ones that aren't found in the routing list) from the list of returned addresses. This appears to me to be correct. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10825#note_139067
This merge request was approved by Erich Hoover. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10825
participants (3)
-
Erich Hoover (@ehoover) -
Paul Gofman -
Paul Gofman (@gofman)