Module: wine Branch: stable Commit: e27f163a190a8c0d2ae66b3c9ff4c991fd021828 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e27f163a190a8c0d2ae66b3c9f...
Author: Bruno Jesus 00cpxxx@gmail.com Date: Sun Jun 19 15:59:59 2016 -0300
ws2_32: Ensure default route IP addresses are returned first in gethostbyname.
Signed-off-by: Bruno Jesus 00cpxxx@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 134bf22b8c7b291717f9717f0515dc485f489aaa) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
dlls/ws2_32/socket.c | 23 +++++++++++++++++------ dlls/ws2_32/tests/sock.c | 1 - 2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index d31f0b4..6877063 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -596,7 +596,7 @@ struct per_thread_data struct route { struct in_addr addr; IF_INDEX interface; - DWORD metric; + DWORD metric, default_route; };
static INT num_startup; /* reference counter */ @@ -5931,7 +5931,14 @@ struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type) */ static int WS_compare_routes_by_metric_asc(const void *left, const void *right) { - return ((const struct route*)left)->metric - ((const struct route*)right)->metric; + const struct route *a = left, *b = right; + if (a->default_route && b->default_route) + return a->default_route - b->default_route; + if (a->default_route && !b->default_route) + return -1; + if (b->default_route && !a->default_route) + return 1; + return a->metric - b->metric; }
/*********************************************************************** @@ -5948,7 +5955,7 @@ static int WS_compare_routes_by_metric_asc(const void *left, const void *right) */ static struct WS_hostent* WS_get_local_ips( char *hostname ) { - int numroutes = 0, i, j; + int numroutes = 0, i, j, default_routes = 0; DWORD n; PIP_ADAPTER_INFO adapters = NULL, k; struct WS_hostent *hostlist = NULL; @@ -5975,10 +5982,13 @@ static struct WS_hostent* WS_get_local_ips( char *hostname ) for (n = 0; n < routes->dwNumEntries; n++) { IF_INDEX ifindex; - DWORD ifmetric; + DWORD ifmetric, ifdefault = 0; BOOL exists = FALSE;
- if (routes->table[n].u1.ForwardType != MIB_IPROUTE_TYPE_DIRECT) + /* Check if this is a default route (there may be more than one) */ + if (!routes->table[n].dwForwardDest) + ifdefault = ++default_routes; + else if (routes->table[n].u1.ForwardType != MIB_IPROUTE_TYPE_DIRECT) continue; ifindex = routes->table[n].dwForwardIfIndex; ifmetric = routes->table[n].dwForwardMetric1; @@ -5999,13 +6009,14 @@ static struct WS_hostent* WS_get_local_ips( char *hostname ) goto cleanup; /* Memory allocation error, fail gracefully */ route_addrs[numroutes].interface = ifindex; route_addrs[numroutes].metric = ifmetric; + route_addrs[numroutes].default_route = ifdefault; /* If no IP is found in the next step (for whatever reason) * then fall back to the magic loopback address. */ memcpy(&(route_addrs[numroutes].addr.s_addr), magic_loopback_addr, 4); numroutes++; } - if (numroutes == 0) + if (numroutes == 0) goto cleanup; /* No routes, fall back to the Magic IP */ /* Find the IP address associated with each found interface */ for (i = 0; i < numroutes; i++) diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 00fac77..ce09053 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4545,7 +4545,6 @@ static void test_gethostbyname(void) } } } -todo_wine ok (found_default, "failed to find the first IP from gethostbyname!\n");
cleanup: