/*
- * $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
};
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)
dnsFreeMemory();
dns_child_table = xcalloc(N, sizeof(dnsserver_t *));
NDnsServersAlloc = 0;
+ NDnsServersRunning = 0;
args[nargs++] = "(dnsserver)";
if (Config.onoff.res_defnames)
args[nargs++] = "-D";
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);
}
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
/*
- * $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
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[] =
{
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 *
if (fqdncacheQueueHead == NULL)
fqdncacheQueueTailP = &fqdncacheQueueHead;
safe_free(old);
+ queue_length--;
}
if (f && f->status != FQDN_PENDING)
debug_trap("fqdncacheDequeue: status != FQDN_PENDING");
fqdncache_release(f);
removed++;
}
- debug(14, 3) ("fqdncache_purgelru: removed %d entries\n", removed);
+ debug(35, 3) ("fqdncache_purgelru: removed %d entries\n", removed);
}
{
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);
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")) {
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;
}
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,
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);
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);
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);
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) {
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);
/*
- * $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
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");
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);