]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
/etc/hosts parsing patch by Chemolli Francesco.
authorwessels <>
Sun, 31 Dec 2000 06:29:06 +0000 (06:29 +0000)
committerwessels <>
Sun, 31 Dec 2000 06:29:06 +0000 (06:29 +0000)
src/cf.data.pre
src/fqdncache.cc
src/ipcache.cc
src/main.cc
src/protos.h
src/structs.h
src/tools.cc

index e9a08023f02031cd9eff91ee772aeb064e748ec3..94c239dc39747c392a99627310b1153a19509592 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $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/
@@ -1017,6 +1017,28 @@ DOC_START
        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
index 3c28fe3ccc3d5fe600259107512973bb1d98c722..38c9a1e0ae64d1bc95408ef1ee96c27076add8c8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -54,6 +54,7 @@ struct _fqdncache_entry {
     unsigned short locks;
     struct {
        unsigned int negcached:1;
+       unsigned int fromhosts:1;
     } flags;
 };
 
@@ -125,6 +126,7 @@ fqdncache_get(const char *name)
 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)
@@ -153,6 +155,26 @@ fqdncache_purgelru(void *notused)
     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)
@@ -455,13 +477,15 @@ fqdnStats(StoreEntry * sentry)
     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++)
@@ -533,8 +557,44 @@ fqdncache_restart(void)
            (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
index 57922a1fb66bc6c570779d1627a6acf00f150411..fa9c261fdb7d3fe67164a353b10825185ffabc28 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -50,6 +50,7 @@ struct _ipcache_entry {
     unsigned short locks;
     struct {
        unsigned int negcached:1;
+       unsigned int fromhosts:1;
     } flags;
 };
 
@@ -132,6 +133,7 @@ ipcache_get(const char *name)
 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)
@@ -163,6 +165,26 @@ ipcache_purgelru(void *voidnotused)
     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)
@@ -491,7 +513,7 @@ ipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry)
        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++) {
@@ -694,6 +716,46 @@ ipcache_restart(void)
            (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
index ac8d5d2512d244d2fb75c5687bf9c3702e47e743..323956989d803d2b83d015944aa71e0bbcebd9f2 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -351,6 +351,7 @@ mainReconfigure(void)
     _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();
@@ -482,6 +483,7 @@ mainInitialize(void)
        disk_init();            /* disk_init must go before ipcache_init() */
     ipcache_init();
     fqdncache_init();
+    parseEtcHosts();
 #if USE_DNSSERVERS
     dnsInit();
 #else
index 5a03757900918ad34ad0930876f82995ab5d81f0..5762122f1e1adbbe06f441c7373927fa824b2674 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -259,6 +259,7 @@ extern int fqdncacheQueueDrain(void);
 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 *);
@@ -558,6 +559,7 @@ extern void ipcacheMarkGoodAddr(const char *name, struct in_addr);
 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 */
@@ -1084,6 +1086,7 @@ extern void linklistPush(link_list **, void *);
 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);
index d41888cbe85f2757f7be90ea51d3e5a0e58ed711..38ff928d6270392b16d0d170d154033cc03b8b8c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -342,6 +342,7 @@ struct _SquidConfig {
     char *debugOptions;
     char *pidFilename;
     char *mimeTablePathname;
+    char *etcHostsPath;
     char *visibleHostname;
     char *uniqueHostname;
     wordlist *hostnameAliases;
index 7a916a7724ec77d24859281ae9618caf270374a5..2ac22023d2864b635bc730bf43b3c183549e9504 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -925,3 +925,62 @@ isPowTen(int count)
        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);
+    }
+}