Joachim Priesner : ws2_32: Use qsort() to order routes by metric in WS_get_local_ips.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 2 13:40:21 CST 2014


Module: wine
Branch: master
Commit: 6eba688f2cbf13303419bee64ef4ff6511fbf380
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6eba688f2cbf13303419bee64ef4ff6511fbf380

Author: Joachim Priesner <joachim.priesner at web.de>
Date:   Tue Dec  2 10:24:11 2014 +0100

ws2_32: Use qsort() to order routes by metric in WS_get_local_ips.

---

 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..142e964 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(struct route), 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.




More information about the wine-cvs mailing list