#
-# $Id: cf.data.pre,v 1.201 2000/12/18 21:52:40 hno Exp $
+# $Id: cf.data.pre,v 1.202 2000/12/30 23:29:06 wessels Exp $
#
#
# SQUID Internet Object Cache http://squid.nlanr.net/Squid/
Example: dns_nameservers 10.0.0.1 192.172.0.4
DOC_END
+NAME: hosts_file
+TYPE: string
+DEFAULT: /etc/hosts
+LOC: Config.etcHostsPath
+DOC_START
+ Location of the host-local IP name-address associations
+ database. Most Operating Systems have such a file: under
+ Un*X it's by default in /etc/hosts MS-Windows NT/2000 places
+ that in %SystemRoot%(by default
+ c:\winnt)\system32\drivers\etc\hosts, while Windows 9x/ME
+ places that in %windir%(usually c:\windows)\hosts
+
+ The file contains newline-separated definitions, in the
+ form ip_address_in_dotted_form name [name ...] names are
+ whitespace-separated. lines beginnng with an hash (#)
+ character are comments.
+
+ The file is checked at startup and upon configuration. If
+ set to 'none', it won't be checked. If append_domain is
+ used, that domain will be added to domain-local (i.e. not
+ containing any dot character) host definitions.
+DOC_END
NAME: unlinkd_program
IFDEF: USE_UNLINKD
/*
- * $Id: fqdncache.cc,v 1.143 2000/11/30 20:28:32 wessels Exp $
+ * $Id: fqdncache.cc,v 1.144 2000/12/30 23:29:06 wessels Exp $
*
* DEBUG: section 35 FQDN Cache
* AUTHOR: Harvest Derived
unsigned short locks;
struct {
unsigned int negcached:1;
+ unsigned int fromhosts:1;
} flags;
};
static int
fqdncacheExpiredEntry(const fqdncache_entry * f)
{
+ /* all static entries are locked, so this takes care of them too */
if (f->locks != 0)
return 0;
if (f->expires > squid_curtime)
debug(35, 9) ("fqdncache_purgelru: removed %d entries\n", removed);
}
+static void
+purge_entries_fromhosts(void)
+{
+ dlink_node *m = lru_list.head;
+ fqdncache_entry *i = NULL;
+ fqdncache_entry *t;
+ while (m) {
+ if (i != NULL) { /* need to delay deletion */
+ fqdncacheRelease(i); /* we just override locks */
+ i = NULL;
+ }
+ t = m->data;
+ if (t->flags.fromhosts)
+ i = t;
+ m = m->next;
+ }
+ if (i != NULL)
+ fqdncacheRelease(i);
+}
+
/* create blank fqdncache_entry */
static fqdncache_entry *
fqdncacheCreateEntry(const char *name)
storeAppendPrintf(sentry, "Blocking calls to gethostbyaddr(): %d\n",
FqdncacheStats.ghba_calls);
storeAppendPrintf(sentry, "FQDN Cache Contents:\n\n");
-
+ storeAppendPrintf(sentry, "%-15.15s %3s %3s %3s %s\n",
+ "Address", "Flg", "TTL", "Cnt", "Hostnames");
hash_first(fqdn_table);
while ((f = (fqdncache_entry *) hash_next(fqdn_table))) {
- ttl = (f->expires - squid_curtime);
- storeAppendPrintf(sentry, " %-32.32s %c %6d %d",
+ ttl = (f->flags.fromhosts ? -1 : (f->expires - squid_curtime));
+ storeAppendPrintf(sentry, "%-15.15s %c%c %3.3d % 3d",
hashKeyStr(&f->hash),
f->flags.negcached ? 'N' : ' ',
+ f->flags.fromhosts ? 'H' : ' ',
ttl,
(int) f->name_count);
for (k = 0; k < (int) f->name_count; k++)
(float) FQDN_HIGH_WATER) / (float) 100);
fqdncache_low = (long) (((float) Config.fqdncache.size *
(float) FQDN_LOW_WATER) / (float) 100);
+ purge_entries_fromhosts();
+}
+
+/*
+ * adds a "static" entry from /etc/hosts. the worldist is to be
+ * managed by the caller, including pointed-to strings
+ */
+void
+fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames)
+{
+ fqdncache_entry *fce;
+ int j = 0;
+ if ((fce = fqdncache_get(addr))) {
+ if (1 == fce->flags.fromhosts) {
+ fqdncacheUnlockEntry(fce);
+ } else if (fce->locks > 0) {
+ debug(35, 1) ("fqdncacheAddEntryFromHosts: can't add static entry for locked address '%s'\n", addr);
+ return;
+ } else {
+ fqdncacheRelease(fce);
+ }
+ }
+ fce = fqdncacheCreateEntry(addr);
+ while (hostnames) {
+ fce->names[j] = xstrdup(hostnames->key);
+ j++;
+ hostnames = hostnames->next;
+ if (j >= FQDN_MAX_NAMES)
+ break;
+ }
+ fce->name_count = j;
+ fce->names[j] = NULL; /* it's safe */
+ fce->flags.fromhosts = 1;
+ fqdncacheAddEntry(fce);
+ fqdncacheLockEntry(fce);
}
+
#ifdef SQUID_SNMP
/*
* The function to return the fqdn statistics via SNMP
/*
- * $Id: ipcache.cc,v 1.227 2000/10/31 23:48:13 wessels Exp $
+ * $Id: ipcache.cc,v 1.228 2000/12/30 23:29:06 wessels Exp $
*
* DEBUG: section 14 IP Cache
* AUTHOR: Harvest Derived
unsigned short locks;
struct {
unsigned int negcached:1;
+ unsigned int fromhosts:1;
} flags;
};
static int
ipcacheExpiredEntry(ipcache_entry * i)
{
+ /* all static entries are locked, so this takes care of them too */
if (i->locks != 0)
return 0;
if (i->addrs.count == 0)
debug(14, 9) ("ipcache_purgelru: removed %d entries\n", removed);
}
+/* purges entries added from /etc/hosts (or whatever). */
+static void
+purge_entries_fromhosts(void)
+{
+ dlink_node *m = lru_list.head;
+ ipcache_entry *i = NULL, *t;
+ while (m) {
+ if (i != NULL) { /* need to delay deletion */
+ ipcacheRelease(i); /* we just override locks */
+ i = NULL;
+ }
+ t = m->data;
+ if (t->flags.fromhosts)
+ i = t;
+ m = m->next;
+ }
+ if (i != NULL)
+ ipcacheRelease(i);
+}
+
/* create blank ipcache_entry */
static ipcache_entry *
ipcacheCreateEntry(const char *name)
hashKeyStr(&i->hash),
i->flags.negcached ? 'N' : ' ',
(int) (squid_curtime - i->lastref),
- (int) (i->expires - squid_curtime),
+ (int) ((i->flags.fromhosts ? -1 : i->expires - squid_curtime)),
(int) i->addrs.count,
(int) i->addrs.badcount);
for (k = 0; k < (int) i->addrs.count; k++) {
(float) Config.ipcache.high) / (float) 100);
ipcache_low = (long) (((float) Config.ipcache.size *
(float) Config.ipcache.low) / (float) 100);
+ purge_entries_fromhosts();
+}
+
+/*
+ * adds a "static" entry from /etc/hosts. the worldist is to be
+ * managed by the caller, including pointed-to strings
+ */
+int
+ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
+{
+ ipcache_entry *i;
+ struct in_addr ip;
+ if (!safe_inet_addr(ipaddr, &ip)) {
+ debug(14, 1) ("ipcacheAddEntryFromHosts: bad IP address '%s'\n",
+ ipaddr);
+ return 1;
+ }
+ if ((i = ipcache_get(name))) {
+ if (1 == i->flags.fromhosts) {
+ ipcacheUnlockEntry(i);
+ } else if (i->locks > 0) {
+ debug(35, 1) ("ipcacheAddEntryFromHosts: can't add static entry"
+ " for locked name '%s'\n", name);
+ return 1;
+ } else {
+ ipcacheRelease(i);
+ }
+ }
+ i = ipcacheCreateEntry(name);
+ i->addrs.count = 1;
+ i->addrs.cur = 0;
+ i->addrs.badcount = 0;
+ i->addrs.in_addrs = xcalloc(1, sizeof(struct in_addr));
+ i->addrs.bad_mask = xcalloc(1, sizeof(unsigned char));
+ i->addrs.in_addrs[0].s_addr = ip.s_addr;
+ i->addrs.bad_mask[0] = FALSE;
+ i->flags.fromhosts = 1;
+ ipcacheAddEntry(i);
+ ipcacheLockEntry(i);
+ return 0;
}
#ifdef SQUID_SNMP
/*
- * $Id: main.cc,v 1.324 2000/12/09 01:47:18 wessels Exp $
+ * $Id: main.cc,v 1.325 2000/12/30 23:29:07 wessels Exp $
*
* DEBUG: section 1 Startup and Main Loop
* AUTHOR: Harvest Derived
_db_init(Config.Log.log, Config.debugOptions);
ipcache_restart(); /* clear stuck entries */
fqdncache_restart(); /* sigh, fqdncache too */
+ parseEtcHosts();
errorInitialize(); /* reload error pages */
#if USE_DNSSERVERS
dnsInit();
disk_init(); /* disk_init must go before ipcache_init() */
ipcache_init();
fqdncache_init();
+ parseEtcHosts();
#if USE_DNSSERVERS
dnsInit();
#else
/*
- * $Id: protos.h,v 1.388 2000/12/05 09:15:59 wessels Exp $
+ * $Id: protos.h,v 1.389 2000/12/30 23:29:07 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
extern void fqdncacheFreeMemory(void);
extern void fqdncache_restart(void);
extern EVH fqdncache_purgelru;
+extern void fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames);
extern void ftpStart(FwdState *);
extern char *ftpUrlWith2f(const request_t *);
extern void ipcacheFreeMemory(void);
extern ipcache_addrs *ipcacheCheckNumeric(const char *name);
extern void ipcache_restart(void);
+extern int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr);
/* MemBuf */
/* init with specific sizes */
extern void *linklistShift(link_list **);
extern int xrename(const char *from, const char *to);
extern int isPowTen(int);
+extern void parseEtcHosts(void);
#if USE_HTCP
extern void htcpInit(void);
/*
- * $Id: structs.h,v 1.367 2000/12/09 01:47:19 wessels Exp $
+ * $Id: structs.h,v 1.368 2000/12/30 23:29:07 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
char *debugOptions;
char *pidFilename;
char *mimeTablePathname;
+ char *etcHostsPath;
char *visibleHostname;
char *uniqueHostname;
wordlist *hostnameAliases;
/*
- * $Id: tools.cc,v 1.199 2000/12/05 09:16:01 wessels Exp $
+ * $Id: tools.cc,v 1.200 2000/12/30 23:29:08 wessels Exp $
*
* DEBUG: section 21 Misc Functions
* AUTHOR: Harvest Derived
return 0;
return 1;
}
+
+void
+parseEtcHosts(void)
+{
+ FILE *fp;
+ char buf[1024];
+ char buf2[512];
+ char *nt = buf;
+ char *lt = buf;
+ char *addr = buf;
+ char *host = NULL;
+ if (NULL == Config.etcHostsPath)
+ return;
+ if (0 == strcmp(Config.etcHostsPath, "none"))
+ return;
+ fp = fopen(Config.etcHostsPath, "r");
+ if (fp == NULL) {
+ debug(1, 1) ("parseEtcHosts: %s: %s\n",
+ Config.etcHostsPath, xstrerror());
+ return;
+ }
+ while (fgets(buf, 1024, fp)) { /* for each line */
+ wordlist *hosts = NULL;
+ if (buf[0] == '#') /* MS-windows likes to add comments */
+ continue;
+ lt = buf;
+ addr = buf;
+ debug(1, 5) ("etc_hosts: line is '%s'\n", buf);
+ nt = strpbrk(lt, w_space);
+ if (nt == NULL) /* empty line */
+ continue;
+ *nt = '\0'; /* null-terminate the address */
+ debug(1, 5) ("etc_hosts: address is '%s'\n", addr);
+ lt = nt + 1;
+ while ((nt = strpbrk(lt, w_space))) {
+ if (nt - lt == 1) { /* multiple spaces */
+ debug(1, 5) ("etc_hosts: multiple spaces, skipping\n");
+ lt = nt + 1;
+ continue;
+ }
+ *nt = '\0';
+ debug(1, 5) ("etc_hosts: got hostname '%s'\n", lt);
+ if (Config.appendDomain && !strchr(lt, '.')) {
+ /* I know it's ugly, but it's only at reconfig */
+ strncpy(buf2, lt, 512);
+ strncat(buf2, Config.appendDomain, 512 - strlen(lt));
+ host = buf2;
+ } else {
+ host = lt;
+ }
+ wordlistAdd(&hosts, host);
+ if (ipcacheAddEntryFromHosts(host, addr) != 0)
+ continue; /* invalid address, continuing is useless */
+ lt = nt + 1;
+ }
+ fqdncacheAddEntryFromHosts(addr, hosts);
+ wordlistDestroy(&hosts);
+ }
+}