Commit e27f163a authored by Bruno Jesus's avatar Bruno Jesus Committed by Michael Stefaniuc

ws2_32: Ensure default route IP addresses are returned first in gethostbyname.

Signed-off-by: 's avatarBruno Jesus <00cpxxx@gmail.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org> (cherry picked from commit 134bf22b) Signed-off-by: 's avatarMichael Stefaniuc <mstefani@winehq.org>
parent 43493262
...@@ -596,7 +596,7 @@ struct per_thread_data ...@@ -596,7 +596,7 @@ struct per_thread_data
struct route { struct route {
struct in_addr addr; struct in_addr addr;
IF_INDEX interface; IF_INDEX interface;
DWORD metric; DWORD metric, default_route;
}; };
static INT num_startup; /* reference counter */ static INT num_startup; /* reference counter */
...@@ -5931,7 +5931,14 @@ struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type) ...@@ -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) 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) ...@@ -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 ) 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; DWORD n;
PIP_ADAPTER_INFO adapters = NULL, k; PIP_ADAPTER_INFO adapters = NULL, k;
struct WS_hostent *hostlist = NULL; struct WS_hostent *hostlist = NULL;
...@@ -5975,10 +5982,13 @@ static struct WS_hostent* WS_get_local_ips( char *hostname ) ...@@ -5975,10 +5982,13 @@ static struct WS_hostent* WS_get_local_ips( char *hostname )
for (n = 0; n < routes->dwNumEntries; n++) for (n = 0; n < routes->dwNumEntries; n++)
{ {
IF_INDEX ifindex; IF_INDEX ifindex;
DWORD ifmetric; DWORD ifmetric, ifdefault = 0;
BOOL exists = FALSE; 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; continue;
ifindex = routes->table[n].dwForwardIfIndex; ifindex = routes->table[n].dwForwardIfIndex;
ifmetric = routes->table[n].dwForwardMetric1; ifmetric = routes->table[n].dwForwardMetric1;
...@@ -5999,13 +6009,14 @@ static struct WS_hostent* WS_get_local_ips( char *hostname ) ...@@ -5999,13 +6009,14 @@ static struct WS_hostent* WS_get_local_ips( char *hostname )
goto cleanup; /* Memory allocation error, fail gracefully */ goto cleanup; /* Memory allocation error, fail gracefully */
route_addrs[numroutes].interface = ifindex; route_addrs[numroutes].interface = ifindex;
route_addrs[numroutes].metric = ifmetric; route_addrs[numroutes].metric = ifmetric;
route_addrs[numroutes].default_route = ifdefault;
/* If no IP is found in the next step (for whatever reason) /* If no IP is found in the next step (for whatever reason)
* then fall back to the magic loopback address. * then fall back to the magic loopback address.
*/ */
memcpy(&(route_addrs[numroutes].addr.s_addr), magic_loopback_addr, 4); memcpy(&(route_addrs[numroutes].addr.s_addr), magic_loopback_addr, 4);
numroutes++; numroutes++;
} }
if (numroutes == 0) if (numroutes == 0)
goto cleanup; /* No routes, fall back to the Magic IP */ goto cleanup; /* No routes, fall back to the Magic IP */
/* Find the IP address associated with each found interface */ /* Find the IP address associated with each found interface */
for (i = 0; i < numroutes; i++) for (i = 0; i < numroutes; i++)
......
...@@ -4545,7 +4545,6 @@ static void test_gethostbyname(void) ...@@ -4545,7 +4545,6 @@ static void test_gethostbyname(void)
} }
} }
} }
todo_wine
ok (found_default, "failed to find the first IP from gethostbyname!\n"); ok (found_default, "failed to find the first IP from gethostbyname!\n");
cleanup: cleanup:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment