sort name query responses by how far they are from our interface
authorAndrew Tridgell <tridge@samba.org>
Mon, 1 Jul 2002 05:09:29 +0000 (05:09 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 1 Jul 2002 05:09:29 +0000 (05:09 +0000)
broadcast addresses. This makes it far more likely that we will try to
talk to an interface that is routable from one of our interfaces.

source/libsmb/namequery.c
source/libsmb/nmblib.c

index 75e2458964781096a772ef7ce03f6ca2fe2a17cc..242601d1da2b0bdf792bbef7ca58df1e1464b54d 100644 (file)
@@ -298,6 +298,44 @@ BOOL name_register(int fd, const char *name, int name_type,
   return True;
 }
 
+
+/*
+  comparison function used by sort_ip_list
+*/
+static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
+{
+       int max_bits1=0, max_bits2=0;
+       int num_interfaces = iface_count();
+       int i;
+
+       for (i=0;i<num_interfaces;i++) {
+               struct in_addr ip;
+               int bits1, bits2;
+               ip = *iface_n_bcast(i);
+               bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
+               bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
+               max_bits1 = MAX(bits1, max_bits1);
+               max_bits2 = MAX(bits2, max_bits2);
+       }       
+
+       return max_bits2 - max_bits1;
+}
+
+/*
+  sort an IP list so that names that are close to one of our interfaces 
+  are at the top. This prevents the problem where a WINS server returns an IP that
+  is not reachable from our subnet as the first match
+*/
+static void sort_ip_list(struct in_addr *iplist, int count)
+{
+       if (count <= 1) {
+               return;
+       }
+
+       qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);    
+}
+
+
 /****************************************************************************
  Do a netbios name query to find someones IP.
  Returns an array of IP addresses or NULL if none.
@@ -475,6 +513,9 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
                *timed_out = True;
        }
 
+       /* sort the ip list so we choose close servers first if possible */
+       sort_ip_list(ip_list, *count);
+
        return ip_list;
 }
 
index 9a37b4252a449303a7c998cc1cb6b3443e2896a4..ba0d8cee5de10ea5f61e948904aed16379f6f873 100644 (file)
@@ -1045,7 +1045,7 @@ BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
 /****************************************************************************
 return the number of bits that match between two 4 character buffers
   ***************************************************************************/
-static int matching_bits(uchar *p1, uchar *p2)
+int matching_quad_bits(uchar *p1, uchar *p2)
 {
        int i, j, ret = 0;
        for (i=0; i<4; i++) {
@@ -1071,7 +1071,7 @@ compare two query reply records
   ***************************************************************************/
 static int name_query_comp(uchar *p1, uchar *p2)
 {
-       return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
+       return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
 }
 
 /****************************************************************************