Added patch to fix ordering of IP addresses by metric if two addresses have the same metric.

This commit is contained in:
Sebastian Lackner
2014-11-30 00:20:58 +01:00
parent 50794f220a
commit 557a9e9899
5 changed files with 103 additions and 1 deletions

View File

@@ -122,6 +122,7 @@ PATCHLIST := \
wintrust-Reset_hFile.ok \
wpcap-Dynamic_Linking.ok \
ws2_32-Connect_Time.ok \
ws2_32-IP_Ordering.ok \
ws2_32-Overlapping_FDS.ok \
ws2_32-TransmitFile.ok \
ws2_32-WriteWatches.ok \
@@ -1961,6 +1962,18 @@ ws2_32-Connect_Time.ok:
echo '+ { "Sebastian Lackner", "ws2_32: Implement returning the proper time with SO_CONNECT_TIME.", 1 },'; \
) > ws2_32-Connect_Time.ok
# Patchset ws2_32-IP_Ordering
# |
# | Modified files:
# | * dlls/ws2_32/socket.c
# |
.INTERMEDIATE: ws2_32-IP_Ordering.ok
ws2_32-IP_Ordering.ok:
$(call APPLY_FILE,ws2_32-IP_Ordering/0001-ws2_32-WS_get_local_ips-Fix-ordering-of-IP-addresses.patch)
@( \
echo '+ { "Joachim Priesner", "ws2_32: WS_get_local_ips: Fix ordering of IP addresses by metric if two addresses have the same metric.", 2 },'; \
) > ws2_32-IP_Ordering.ok
# Patchset ws2_32-Overlapping_FDS
# |
# | Modified files:

View File

@@ -0,0 +1,86 @@
From d35f6c60fc0b58a5a259b386ce7cad10d4ea2688 Mon Sep 17 00:00:00 2001
From: Joachim Priesner <joachim.priesner@web.de>
Date: Tue, 28 Oct 2014 10:20:31 +0100
Subject: ws2_32: WS_get_local_ips: Fix ordering of IP addresses by metric if
two addresses have the same metric (try 2)
The previous implementation required the metrics to be mutually inequal
(because of the "this_metric > last_metric" check). If the metrics were
not mutually inequal, it would write only one address per metric value to the list
and fill up the rest of the list with the magic loopback IP address 127.12.34.56.
Try 2 that uses qsort() as suggested by Ken Thomases.
---
dlls/ws2_32/socket.c | 38 +++++++++++++++++---------------------
1 file changed, 17 insertions(+), 21 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 29ac800..09c175a 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -5167,6 +5167,17 @@ struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type)
}
/***********************************************************************
+ * WS_compare_routes_by_metric_asc (INTERNAL)
+ *
+ * Comparison function for qsort(), for sorting two routes (struct route)
+ * by metric in ascending order.
+ */
+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;
+}
+
+/***********************************************************************
* WS_get_local_ips (INTERNAL)
*
* Returns the list of local IP addresses by going through the network
@@ -5180,7 +5191,7 @@ struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type)
*/
static struct WS_hostent* WS_get_local_ips( char *hostname )
{
- int last_metric, numroutes = 0, i, j;
+ int numroutes = 0, i, j;
DWORD n;
PIP_ADAPTER_INFO adapters = NULL, k;
struct WS_hostent *hostlist = NULL;
@@ -5260,30 +5271,15 @@ static struct WS_hostent* WS_get_local_ips( char *hostname )
hostlist->h_aliases[0] = NULL; /* NULL-terminate the alias list */
hostlist->h_addrtype = AF_INET;
hostlist->h_length = sizeof(struct in_addr); /* = 4 */
- /* Reorder the entries when placing them in the host list, Windows expects
+ /* Reorder the entries before placing them in the host list. Windows expects
* the IP list in order from highest priority to lowest (the critical thing
* is that most applications expect the first IP to be the default route).
*/
- last_metric = -1;
- for (i = 0; i < numroutes; i++)
- {
- struct in_addr addr;
- int metric = 0xFFFF;
+ if (numroutes > 1)
+ qsort(route_addrs, numroutes, sizeof(*route_addrs), WS_compare_routes_by_metric_asc);
- memcpy(&addr, magic_loopback_addr, 4);
- for (j = 0; j < numroutes; j++)
- {
- int this_metric = route_addrs[j].metric;
-
- if (this_metric > last_metric && this_metric < metric)
- {
- addr = route_addrs[j].addr;
- metric = this_metric;
- }
- }
- last_metric = metric;
- (*(struct in_addr *) hostlist->h_addr_list[i]) = addr;
- }
+ for (i = 0; i < numroutes; i++)
+ (*(struct in_addr *) hostlist->h_addr_list[i]) = route_addrs[i].addr;
/* Cleanup all allocated memory except the address list,
* the address list is used by the calling app.
--
2.1.3

View File

@@ -0,0 +1 @@
Fixes: Fix ordering of IP addresses by metric if two addresses have the same metric.