Merge from appliance-head:
authorTim Potter <tpot@samba.org>
Wed, 9 Jan 2002 04:26:41 +0000 (04:26 +0000)
committerTim Potter <tpot@samba.org>
Wed, 9 Jan 2002 04:26:41 +0000 (04:26 +0000)
 - put in some level 10 debugs so we can see what internal_resolve_name()
   is doing

 - remove duplicates from returned ip list of internal_resolve_name()
(This used to be commit 08d2bcef1a4fc77d28bc0fa9e4ff5f3131cedea5)

source3/libsmb/namequery.c

index d11b1ffd780c5f02cf4e72b0aa66622dba3450fc..6bf34c730cc9bb67b3adedd441ad313bedce5fec 100644 (file)
@@ -822,9 +822,15 @@ static BOOL internal_resolve_name(const char *name, int name_type,
   BOOL allones = (strcmp(name,"255.255.255.255") == 0);
   BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
   BOOL is_address = is_ipaddress(name);
   BOOL allones = (strcmp(name,"255.255.255.255") == 0);
   BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
   BOOL is_address = is_ipaddress(name);
+  BOOL result = False;
+  struct in_addr *nodupes_iplist;
+  int i;
+
   *return_iplist = NULL;
   *return_count = 0;
 
   *return_iplist = NULL;
   *return_count = 0;
 
+  DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
+
   if (allzeros || allones || is_address) {
        *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
        if(*return_iplist == NULL) {
   if (allzeros || allones || is_address) {
        *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
        if(*return_iplist == NULL) {
@@ -849,29 +855,91 @@ static BOOL internal_resolve_name(const char *name, int name_type,
   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
          if((strequal(tok, "host") || strequal(tok, "hosts"))) {
                  if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
          if((strequal(tok, "host") || strequal(tok, "hosts"))) {
                  if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
-                         return True;
+                   result = True;
+                   goto done;
                  }
          } else if(strequal( tok, "lmhosts")) {
                  if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
                  }
          } else if(strequal( tok, "lmhosts")) {
                  if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
-                         return True;
+                   result = True;
+                   goto done;
                  }
          } else if(strequal( tok, "wins")) {
                  /* don't resolve 1D via WINS */
                  if (name_type != 0x1D &&
                      resolve_wins(name, name_type, return_iplist, return_count)) {
                  }
          } else if(strequal( tok, "wins")) {
                  /* don't resolve 1D via WINS */
                  if (name_type != 0x1D &&
                      resolve_wins(name, name_type, return_iplist, return_count)) {
-                         return True;
+                   result = True;
+                   goto done;
                  }
          } else if(strequal( tok, "bcast")) {
                  if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
                  }
          } else if(strequal( tok, "bcast")) {
                  if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
-                         return True;
+                   result = True;
+                   goto done;
                  }
          } else {
                  DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
          }
   }
 
                  }
          } else {
                  DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
          }
   }
 
+  /* All of the resolve_* functions above have returned false. */
+
   SAFE_FREE(*return_iplist);
   SAFE_FREE(*return_iplist);
+  *return_count = 0;
+
   return False;
   return False;
+
+ done:
+
+  /* Remove duplicate entries.  Some queries, notably #1c (domain
+     controllers) return the PDC in iplist[0] and then all domain
+     controllers including the PDC in iplist[1..n].  Iterating over
+     the iplist when the PDC is down will cause two sets of timeouts. */
+
+  if ((nodupes_iplist = (struct in_addr *)
+       malloc(sizeof(struct in_addr) * (*return_count)))) {
+         int nodupes_count = 0;
+
+         /* Iterate over return_iplist looking for duplicates */
+
+         for (i = 0; i < *return_count; i++) {
+                 BOOL is_dupe = False;
+                 int j;
+
+                 for (j = i + 1; j < *return_count; j++) {
+                         if (ip_equal((*return_iplist)[i], 
+                                      (*return_iplist)[j])) {
+                                 is_dupe = True;
+                                 break;
+                         }
+                 }
+
+                 if (!is_dupe) {
+
+                         /* This one not a duplicate */
+
+                         nodupes_iplist[nodupes_count] = (*return_iplist)[i];
+                         nodupes_count++;
+                 }
+         }
+         
+         /* Switcheroo with original list */
+         
+         free(*return_iplist);
+
+         *return_iplist = nodupes_iplist;
+         *return_count = nodupes_count;
+  }
+
+  /* Display some debugging info */
+
+  DEBUG(10, ("internal_resolve_name: returning %d addresses: ", 
+            *return_count));
+
+  for (i = 0; i < *return_count; i++)
+         DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
+
+  DEBUG(10, ("\n"));
+
+  return result;
 }
 
 /********************************************************
 }
 
 /********************************************************