diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libsmb/namequery.c | 41 | ||||
-rw-r--r-- | source3/libsmb/nmblib.c | 4 |
2 files changed, 43 insertions, 2 deletions
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 75e2458964..242601d1da 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -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; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9a37b4252a..ba0d8cee5d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -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); } /**************************************************************************** |