From: wessels <> Date: Sun, 31 Dec 2000 06:29:06 +0000 (+0000) Subject: /etc/hosts parsing patch by Chemolli Francesco. X-Git-Tag: SQUID_3_0_PRE1~1721 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0e70aa1e477db5f0fb4f9d4bc3d0576b7a0a27be;p=thirdparty%2Fsquid.git /etc/hosts parsing patch by Chemolli Francesco. --- diff --git a/src/cf.data.pre b/src/cf.data.pre index e9a08023f0..94c239dc39 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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 diff --git a/src/fqdncache.cc b/src/fqdncache.cc index 3c28fe3ccc..38c9a1e0ae 100644 --- a/src/fqdncache.cc +++ b/src/fqdncache.cc @@ -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 diff --git a/src/ipcache.cc b/src/ipcache.cc index 57922a1fb6..fa9c261fdb 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -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 diff --git a/src/main.cc b/src/main.cc index ac8d5d2512..323956989d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -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 diff --git a/src/protos.h b/src/protos.h index 5a03757900..5762122f1e 100644 --- a/src/protos.h +++ b/src/protos.h @@ -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); diff --git a/src/structs.h b/src/structs.h index d41888cbe8..38ff928d62 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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; diff --git a/src/tools.cc b/src/tools.cc index 7a916a7724..2ac22023d2 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -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); + } +}