]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fixed some restart bugs with dnsservers. Because of switch to
authorwessels <>
Wed, 29 Jul 1998 09:57:37 +0000 (09:57 +0000)
committerwessels <>
Wed, 29 Jul 1998 09:57:37 +0000 (09:57 +0000)
events, we were calling the dnsShutdownServers func AFTER the
new dnsservers had been allocated.  Using a non-NULL callback
data when registering the event fixes this.

Also added fatal() checks for too few running dnsservers and too many
queued IP/FQDN lookups.

src/dns.cc
src/fqdncache.cc
src/ipcache.cc

index 6920ca6bdb55b20033e006144d89ea2aba59af1e..1c7d6f8ebde77ec392fa7081b4da64b5590c6d06 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns.cc,v 1.62 1998/07/25 00:16:26 wessels Exp $
+ * $Id: dns.cc,v 1.63 1998/07/29 03:57:37 wessels Exp $
  *
  * DEBUG: section 34    Dnsserver interface
  * AUTHOR: Harvest Derived
@@ -41,7 +41,22 @@ struct dnsQueueData {
 };
 
 static PF dnsShutdownRead;
+static PF dnsFDClosed;
 static dnsserver_t **dns_child_table = NULL;
+static int NDnsServersRunning = 0;
+
+static void
+dnsFDClosed(int fd, void *data)
+{
+    dnsserver_t *dns = data;
+    NDnsServersRunning--;
+    if (shutting_down || reconfiguring)
+       return;
+    debug(34, 0) ("WARNING: DNSSERVER #%d (FD %d) exited\n",
+       dns->id, fd);
+    if (NDnsServersRunning < Config.dnsChildren / 2)
+       fatal("Too few DNSSERVER processes are running");
+}
 
 dnsserver_t *
 dnsGetFirstAvailable(void)
@@ -92,6 +107,7 @@ dnsOpenServers(void)
     dnsFreeMemory();
     dns_child_table = xcalloc(N, sizeof(dnsserver_t *));
     NDnsServersAlloc = 0;
+    NDnsServersRunning = 0;
     args[nargs++] = "(dnsserver)";
     if (Config.onoff.res_defnames)
        args[nargs++] = "-D";
@@ -137,12 +153,17 @@ dnsOpenServers(void)
            snprintf(fd_note_buf, FD_DESC_SZ, "%s #%d", s, dns_child_table[k]->id);
            fd_note(dns_child_table[k]->inpipe, fd_note_buf);
            commSetNonBlocking(dns_child_table[k]->inpipe);
-           debug(34, 3) ("dnsOpenServers: 'dns_server' %d started\n", k + 1);
+           comm_add_close_handler(dns_child_table[k]->inpipe, dnsFDClosed,
+               dns_child_table[k]);
+           debug(34, 3) ("dnsOpenServers: DNSSERVER #%d started\n", k + 1);
            NDnsServersAlloc++;
+           NDnsServersRunning++;
        }
     }
     if (NDnsServersAlloc == 0 && Config.dnsChildren > 0)
        fatal("Failed to start any dnsservers");
+    if (NDnsServersRunning < Config.dnsChildren / 2)
+       fatal("Too few DNSSERVER processes are running");
     cachemgrRegister("dns", "dnsserver child process information",
        dnsStats, 0, 1);
     debug(34, 1) ("Started %d 'dnsserver' processes\n", NDnsServersAlloc);
@@ -213,8 +234,17 @@ dnsShutdownServers(void *notused)
        }
        dnsShutdownServer(dns);
     }
+    /*
+     * Here we pass in 'dns_child_table[0]' as callback data so that
+     * if the dns_child_table[] array gets freed, the event will
+     * never execute.
+     */
     if (na)
-       eventAdd("dnsShutdownServers", dnsShutdownServers, NULL, 1.0, 1);
+       eventAdd("dnsShutdownServers",
+           dnsShutdownServers,
+           dns_child_table[0],
+           1.0,
+           1);
 }
 
 void
index 4bfcc301df8b803d3b5d6ef936caf86f0424df2e..a308871e5b58c34f9fc21be68de51d63c3fc404f 100644 (file)
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: fqdncache.cc,v 1.109 1998/07/23 19:57:49 wessels Exp $
+ * $Id: fqdncache.cc,v 1.110 1998/07/29 03:57:38 wessels Exp $
  *
  * DEBUG: section 35    FQDN Cache
  * AUTHOR: Harvest Derived
@@ -82,6 +82,7 @@ static FREE fqdncacheFreeEntry;
 static hash_table *fqdn_table = NULL;
 static struct fqdncacheQueueData *fqdncacheQueueHead = NULL;
 static struct fqdncacheQueueData **fqdncacheQueueTailP = &fqdncacheQueueHead;
+static int queue_length = 0;
 
 static char fqdncache_status_char[] =
 {
@@ -97,10 +98,24 @@ static long fqdncache_high = 200;
 static void
 fqdncacheEnqueue(fqdncache_entry * f)
 {
+    static time_t last_warning = 0;
     struct fqdncacheQueueData *new = xcalloc(1, sizeof(struct fqdncacheQueueData));
     new->f = f;
     *fqdncacheQueueTailP = new;
     fqdncacheQueueTailP = &new->next;
+    queue_length++;
+    if (queue_length < NDnsServersAlloc)
+       return;
+    if (squid_curtime - last_warning < 600)
+       return;
+    last_warning = squid_curtime;
+    debug(35, 0) ("fqdncacheEnqueue: WARNING: All dnsservers are busy.\n");
+    debug(35, 0) ("fqdncacheEnqueue: WARNING: %d DNS lookups queued\n", queue_length);
+    if (queue_length > NDnsServersAlloc * 2)
+       fatal("Too many queued DNS lookups");
+    if (Config.dnsChildren >= DefaultDnsChildrenMax)
+       return;
+    debug(35, 1) ("fqdncacheEnqueue: Consider increasing 'dns_children' in your config file.\n");
 }
 
 static void *
@@ -115,6 +130,7 @@ fqdncacheDequeue(void)
        if (fqdncacheQueueHead == NULL)
            fqdncacheQueueTailP = &fqdncacheQueueHead;
        safe_free(old);
+       queue_length--;
     }
     if (f && f->status != FQDN_PENDING)
        debug_trap("fqdncacheDequeue: status != FQDN_PENDING");
@@ -193,7 +209,7 @@ fqdncache_purgelru(void *notused)
        fqdncache_release(f);
        removed++;
     }
-    debug(14, 3) ("fqdncache_purgelru: removed %d entries\n", removed);
+    debug(35, 3) ("fqdncache_purgelru: removed %d entries\n", removed);
 }
 
 
@@ -228,7 +244,7 @@ fqdncacheAddNew(const char *name, const struct hostent *hp, fqdncache_status_t s
 {
     fqdncache_entry *f;
     assert(fqdncache_get(name) == NULL);
-    debug(14, 10) ("fqdncacheAddNew: Adding '%s', status=%c\n",
+    debug(35, 10) ("fqdncacheAddNew: Adding '%s', status=%c\n",
        name,
        fqdncache_status_char[status]);
     f = fqdncache_create(name);
@@ -274,13 +290,13 @@ fqdncacheParse(const char *inbuf, dnsserver_t * dnsData)
     static fqdncache_entry f;
     int ttl;
     xstrncpy(buf, inbuf, DNS_INBUF_SZ);
-    debug(14, 5) ("fqdncacheParse: parsing:\n%s", buf);
+    debug(35, 5) ("fqdncacheParse: parsing:\n%s", buf);
     memset(&f, '\0', sizeof(f));
     f.expires = squid_curtime;
     f.status = FQDN_NEGATIVE_CACHED;
     token = strtok(buf, w_space);
     if (NULL == token) {
-       debug(14, 1) ("fqdncacheParse: Got <NULL>, expecting '$name'\n");
+       debug(35, 1) ("fqdncacheParse: Got <NULL>, expecting '$name'\n");
        return &f;
     }
     if (0 == strcmp(token, "$fail")) {
@@ -291,12 +307,12 @@ fqdncacheParse(const char *inbuf, dnsserver_t * dnsData)
        return &f;
     }
     if (0 != strcmp(token, "$name")) {
-       debug(14, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token);
+       debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token);
        return &f;
     }
     token = strtok(NULL, w_space);
     if (NULL == token) {
-       debug(14, 1) ("fqdncacheParse: Got <NULL>, expecting TTL\n");
+       debug(35, 1) ("fqdncacheParse: Got <NULL>, expecting TTL\n");
        return &f;
     }
     f.status = FQDN_CACHED;
@@ -383,7 +399,7 @@ fqdncache_dnsHandleRead(int fd, void *data)
        }
        fqdncacheUnlockEntry(f);        /* unlock from FQDN_DISPATCHED */
     } else {
-       debug(14, 5) ("fqdncache_dnsHandleRead: Incomplete reply\n");
+       debug(35, 5) ("fqdncache_dnsHandleRead: Incomplete reply\n");
        commSetSelect(fd,
            COMM_SELECT_READ,
            fqdncache_dnsHandleRead,
@@ -459,7 +475,7 @@ fqdncache_nbgethostbyaddr(struct in_addr addr, FQDNH * handler, void *handlerDat
        FqdncacheStats.pending_hits++;
        fqdncacheAddPending(f, handler, handlerData);
        if (squid_curtime - f->expires > 600) {
-           debug(14, 0) ("fqdncache_nbgethostbyname: '%s' PENDING for %d seconds, aborting\n", name,
+           debug(35, 0) ("fqdncache_nbgethostbyname: '%s' PENDING for %d seconds, aborting\n", name,
                (int) (squid_curtime + Config.negativeDnsTtl - f->expires));
            fqdncacheChangeKey(f);
            fqdncache_call_pending(f);
@@ -536,7 +552,7 @@ fqdncache_init(void)
     fqdncache_low = (long) (((float) MAX_FQDN *
            (float) FQDN_LOW_WATER) / (float) 100);
     n = hashPrime(fqdncache_high / 4);
-    fqdn_table = hash_create((HASHCMP*) strcmp, n, hash4);
+    fqdn_table = hash_create((HASHCMP *) strcmp, n, hash4);
     cachemgrRegister("fqdncache",
        "FQDN Cache Stats and Contents",
        fqdnStats, 0, 1);
@@ -629,6 +645,7 @@ fqdnStats(StoreEntry * sentry)
        FqdncacheStats.misses);
     storeAppendPrintf(sentry, "Blocking calls to gethostbyaddr(): %d\n",
        FqdncacheStats.ghba_calls);
+    storeAppendPrintf(sentry, "pending queue length: %d\n", queue_length);
     storeAppendPrintf(sentry, "FQDN Cache Contents:\n\n");
 
     hash_first(fqdn_table);
@@ -736,7 +753,7 @@ fqdncacheChangeKey(fqdncache_entry * f)
     LOCAL_ARRAY(char, new_key, 256);
     hash_link *table_entry = hash_lookup(fqdn_table, f->name);
     if (table_entry == NULL) {
-       debug(14, 0) ("fqdncacheChangeKey: Could not find key '%s'\n", f->name);
+       debug(35, 0) ("fqdncacheChangeKey: Could not find key '%s'\n", f->name);
        return;
     }
     if (f != (fqdncache_entry *) table_entry) {
@@ -746,7 +763,7 @@ fqdncacheChangeKey(fqdncache_entry * f)
     hash_remove_link(fqdn_table, table_entry);
     snprintf(new_key, 256, "%d/", ++index);
     strncat(new_key, f->name, 128);
-    debug(14, 1) ("fqdncacheChangeKey: from '%s' to '%s'\n", f->name, new_key);
+    debug(35, 1) ("fqdncacheChangeKey: from '%s' to '%s'\n", f->name, new_key);
     safe_free(f->name);
     f->name = xstrdup(new_key);
     hash_join(fqdn_table, (hash_link *) f);
index e6738d00ea8fd9ef9c6e3e67f8547bce44528c72..b4aa1a799ac20c08203a9e4b0790eec98a6c759f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ipcache.cc,v 1.195 1998/07/23 19:57:50 wessels Exp $
+ * $Id: ipcache.cc,v 1.196 1998/07/29 03:57:39 wessels Exp $
  *
  * DEBUG: section 14    IP Cache
  * AUTHOR: Harvest Derived
@@ -112,8 +112,10 @@ ipcacheEnqueue(ipcache_entry * i)
     if (squid_curtime - last_warning < 600)
        return;
     last_warning = squid_curtime;
-    debug(14, 1) ("ipcacheEnqueue: WARNING: All dnsservers are busy.\n");
-    debug(14, 1) ("ipcacheEnqueue: WARNING: %d DNS lookups queued\n", queue_length);
+    debug(14, 0) ("ipcacheEnqueue: WARNING: All dnsservers are busy.\n");
+    debug(14, 0) ("ipcacheEnqueue: WARNING: %d DNS lookups queued\n", queue_length);
+    if (queue_length > NDnsServersAlloc * 2)
+       fatal("Too many queued DNS lookups");
     if (Config.dnsChildren >= DefaultDnsChildrenMax)
        return;
     debug(14, 1) ("ipcacheEnqueue: Consider increasing 'dns_children' in your config file.\n");
@@ -604,7 +606,7 @@ ipcache_init(void)
     ipcache_low = (long) (((float) Config.ipcache.size *
            (float) Config.ipcache.low) / (float) 100);
     n = hashPrime(ipcache_high / 4);
-    ip_table = hash_create((HASHCMP*) strcmp, n, hash4);
+    ip_table = hash_create((HASHCMP *) strcmp, n, hash4);
     cachemgrRegister("ipcache",
        "IP Cache Stats and Contents",
        stat_ipcache_get, 0, 1);