diff -urN squid-2.4-200208062300/src/cf.data.pre squid-2.4-hosts_hack/src/cf.data.pre --- squid-2.4-200208062300/src/cf.data.pre Sun Jun 23 22:10:16 2002 +++ squid-2.4-hosts_hack/src/cf.data.pre Thu Aug 8 00:04:02 2002 @@ -1053,6 +1053,29 @@ 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: diskd_program TYPE: string DEFAULT: @DEFAULT_DISKD@ diff -urN squid-2.4-200208062300/src/fqdncache.c squid-2.4-hosts_hack/src/fqdncache.c --- squid-2.4-200208062300/src/fqdncache.c Fri Jan 12 01:51:47 2001 +++ squid-2.4-hosts_hack/src/fqdncache.c Thu Aug 8 00:21:33 2002 @@ -54,6 +54,7 @@ unsigned short locks; struct { unsigned int negcached:1; + unsigned int fromhosts:1; } flags; }; @@ -153,6 +154,26 @@ 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) @@ -458,10 +479,11 @@ 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, " %-32.32s %c%c %6d %d", 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,6 +555,41 @@ (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 diff -urN squid-2.4-200208062300/src/ipcache.c squid-2.4-hosts_hack/src/ipcache.c --- squid-2.4-200208062300/src/ipcache.c Fri Jan 12 01:51:49 2001 +++ squid-2.4-hosts_hack/src/ipcache.c Thu Aug 8 00:12:14 2002 @@ -50,6 +50,7 @@ unsigned short locks; struct { unsigned int negcached:1; + unsigned int fromhosts:1; } flags; }; @@ -163,6 +164,26 @@ 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) @@ -489,9 +510,10 @@ int k; storeAppendPrintf(sentry, " %-32.32s %c %6d %6d %2d(%2d)", hashKeyStr(&i->hash), + i->flags.fromhosts ? 'H' : ' ', 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,50 @@ (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. + * returns 0 upon success, 1 if the ip address is invalid + */ +int +ipcacheAddEntryFromHosts(const char *name, const char *ipaddr) +{ + ipcache_entry *i; + struct in_addr ip; + if (!safe_inet_addr(ipaddr, &ip)) { + if (strchr(ipaddr, ':') && strspn(ipaddr, "0123456789abcdefABCDEF:") == strlen(ipaddr)) { + debug(14, 3) ("ipcacheAddEntryFromHosts: Skipping IPv6 address '%s'\n", ipaddr); + } else { + 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(14, 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 -urN squid-2.4-200208062300/src/main.c squid-2.4-hosts_hack/src/main.c --- squid-2.4-200208062300/src/main.c Sun May 20 02:09:59 2001 +++ squid-2.4-hosts_hack/src/main.c Wed Aug 7 23:44:44 2002 @@ -351,6 +351,7 @@ _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 @@ disk_init(); /* disk_init must go before ipcache_init() */ ipcache_init(); fqdncache_init(); + parseEtcHosts(); #if USE_DNSSERVERS dnsInit(); #else diff -urN squid-2.4-200208062300/src/protos.h squid-2.4-hosts_hack/src/protos.h --- squid-2.4-200208062300/src/protos.h Sun Jun 23 22:01:03 2002 +++ squid-2.4-hosts_hack/src/protos.h Thu Aug 8 00:02:09 2002 @@ -259,6 +259,7 @@ 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 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 */ @@ -1087,6 +1089,7 @@ 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 -urN squid-2.4-200208062300/src/structs.h squid-2.4-hosts_hack/src/structs.h --- squid-2.4-200208062300/src/structs.h Sun Jun 23 22:10:17 2002 +++ squid-2.4-hosts_hack/src/structs.h Wed Aug 7 23:48:28 2002 @@ -342,6 +342,7 @@ char *debugOptions; char *pidFilename; char *mimeTablePathname; + char *etcHostsPath; char *visibleHostname; char *uniqueHostname; wordlist *hostnameAliases; diff -urN squid-2.4-200208062300/src/tools.c squid-2.4-hosts_hack/src/tools.c --- squid-2.4-200208062300/src/tools.c Sat Aug 11 20:32:43 2001 +++ squid-2.4-hosts_hack/src/tools.c Wed Aug 7 23:47:35 2002 @@ -934,3 +934,67 @@ return 0; return 1; } + +void +parseEtcHosts(void) +{ + FILE *fp; + char buf[1024]; + char buf2[512]; + char *nt = buf; + char *lt = buf; + + 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; + } +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) + setmode(fileno(fp), O_TEXT); +#endif + while (fgets(buf, 1024, fp)) { /* for each line */ + wordlist *hosts = NULL; + char *addr; + 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))) { + char *host = NULL; + if (nt == lt) { /* 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; + } + if (ipcacheAddEntryFromHosts(host, addr) != 0) + goto skip; /* invalid address, continuing is useless */ + wordlistAdd(&hosts, host); + lt = nt + 1; + } + fqdncacheAddEntryFromHosts(addr, hosts); + skip: + wordlistDestroy(&hosts); + } +}