Index: squid/src/cf.data.pre diff -c squid/src/cf.data.pre:1.245.2.54 squid/src/cf.data.pre:1.245.2.55 *** squid/src/cf.data.pre:1.245.2.54 Sat Nov 29 11:52:58 2003 --- squid/src/cf.data.pre Sat Dec 6 10:19:36 2003 *************** *** 1106,1112 **** NAME: dns_timeout TYPE: time_t ! DEFAULT: 5 minutes LOC: Config.Timeout.idns_query IFDEF: !USE_DNSSERVERS DOC_START --- 1106,1112 ---- NAME: dns_timeout TYPE: time_t ! DEFAULT: 2 minutes LOC: Config.Timeout.idns_query IFDEF: !USE_DNSSERVERS DOC_START *************** *** 1734,1741 **** DEFAULT: 6 hours DOC_START Upper limit on how long Squid will cache positive DNS responses. ! Default is 6 hours (360 minutes). If you want to minimize the ! use of Squid's ipcache, set this to 1, not 0. DOC_END --- 1734,1741 ---- DEFAULT: 6 hours DOC_START Upper limit on how long Squid will cache positive DNS responses. ! Default is 6 hours (360 minutes). This directive must be set ! larger than negative_dns_ttl. DOC_END *************** *** 1743,1751 **** COMMENT: time-units TYPE: time_t LOC: Config.negativeDnsTtl ! DEFAULT: 5 minutes DOC_START Time-to-Live (TTL) for negative caching of failed DNS lookups. DOC_END NAME: range_offset_limit --- 1743,1754 ---- COMMENT: time-units TYPE: time_t LOC: Config.negativeDnsTtl ! DEFAULT: 1 minute DOC_START Time-to-Live (TTL) for negative caching of failed DNS lookups. + This also makes sets the lower cache limit on positive lookups. + Minimum value is 1 second, and it is not recommendable to go + much below 10 seconds. DOC_END NAME: range_offset_limit *************** *** 1776,1792 **** ----------------------------------------------------------------------------- COMMENT_END NAME: connect_timeout COMMENT: time-units TYPE: time_t LOC: Config.Timeout.connect ! DEFAULT: 2 minutes DOC_START ! Some systems (notably Linux) can not be relied upon to properly ! time out connect(2) requests. Therefore the Squid process ! enforces its own timeout on server connections. This parameter ! specifies how long to wait for the connect to complete. The ! default is two minutes (120 seconds). DOC_END NAME: peer_connect_timeout --- 1779,1803 ---- ----------------------------------------------------------------------------- COMMENT_END + NAME: forward_timeout + COMMENT: time-units + TYPE: time_t + LOC: Config.Timeout.forward + DEFAULT: 4 minutes + DOC_START + This parameter specifies how long Squid should at most attempt in + finding a forwarding path for the request before giving up. + DOC_END + NAME: connect_timeout COMMENT: time-units TYPE: time_t LOC: Config.Timeout.connect ! DEFAULT: 1 minute DOC_START ! This parameter specifies how long to wait for the TCP connect to ! the requested server or peer to complete before Squid should ! attempt to find another path where to forward the request. DOC_END NAME: peer_connect_timeout Index: squid/src/cache_cf.c diff -c squid/src/cache_cf.c:1.396.2.15 squid/src/cache_cf.c:1.396.2.16 *** squid/src/cache_cf.c:1.396.2.15 Thu Nov 6 09:50:37 2003 --- squid/src/cache_cf.c Sat Dec 6 10:19:36 2003 *************** *** 431,436 **** --- 431,444 ---- debug(22, 0) ("WARNING: 'maxconn' ACL (%s) won't work with client_db disabled\n", a->name); } } + if (Config.negativeDnsTtl <= 0) { + debug(22, 0) ("WARNING: resetting negative_dns_ttl to 1 second\n"); + Config.negativeDnsTtl = 1; + } + if (Config.positiveDnsTtl < Config.negativeDnsTtl) { + debug(22, 0) ("NOTICE: positive_dns_ttl must be larger than negative_dns_ttl. Resetting negative_dns_ttl to match\n"); + Config.positiveDnsTtl = Config.negativeDnsTtl; + } } /* Parse a time specification from the config file. Store the Index: squid/src/dns.c diff -c squid/src/dns.c:1.86.2.1 squid/src/dns.c:1.86.2.2 *** squid/src/dns.c:1.86.2.1 Tue Nov 12 00:12:22 2002 --- squid/src/dns.c Sat Dec 6 10:19:37 2003 *************** *** 97,103 **** if (squid_curtime - first_warn > 3 * 60) fatal("DNS servers not responding for 3 minutes"); debug(34, 1) ("dnsSubmit: queue overload, rejecting %s\n", lookup); ! callback(data, "$fail Temporary network problem, please retry later"); return; } first_warn = 0; --- 97,103 ---- if (squid_curtime - first_warn > 3 * 60) fatal("DNS servers not responding for 3 minutes"); debug(34, 1) ("dnsSubmit: queue overload, rejecting %s\n", lookup); ! callback(data, (char *) "$fail Temporary network problem, please retry later"); return; } first_warn = 0; *************** *** 112,118 **** snmp_netDnsFn(variable_list * Var, snint * ErrP) { variable_list *Answer = NULL; ! debug(49, 5) ("snmp_netDnsFn: Processing request:\n", Var->name[LEN_SQ_NET + 1]); snmpDebugOid(5, Var->name, Var->name_length); *ErrP = SNMP_ERR_NOERROR; switch (Var->name[LEN_SQ_NET + 1]) { --- 112,118 ---- snmp_netDnsFn(variable_list * Var, snint * ErrP) { variable_list *Answer = NULL; ! debug(49, 5) ("snmp_netDnsFn: Processing request: %d\n", Var->name[LEN_SQ_NET + 1]); snmpDebugOid(5, Var->name, Var->name_length); *ErrP = SNMP_ERR_NOERROR; switch (Var->name[LEN_SQ_NET + 1]) { Index: squid/src/dns_internal.c diff -c squid/src/dns_internal.c:1.45.2.1 squid/src/dns_internal.c:1.45.2.2 *** squid/src/dns_internal.c:1.45.2.1 Tue Jun 25 05:44:35 2002 --- squid/src/dns_internal.c Sat Dec 6 10:19:37 2003 *************** *** 64,69 **** --- 64,71 ---- IDNSCB *callback; void *callback_data; int attempt; + const char *error; + int rcode; }; struct _ns { *************** *** 463,471 **** } dlinkDelete(&q->lru, &lru_list); idnsRcodeCount(n, q->attempt); if (n < 0) { debug(78, 3) ("idnsGrokReply: error %d\n", rfc1035_errno); ! if (-2 == n && ++q->attempt < MAX_ATTEMPT) { /* * RCODE 2 is "Server failure - The name server was * unable to process this query due to a problem with --- 465,476 ---- } dlinkDelete(&q->lru, &lru_list); idnsRcodeCount(n, q->attempt); + q->error = NULL; if (n < 0) { debug(78, 3) ("idnsGrokReply: error %d\n", rfc1035_errno); ! q->error = rfc1035_error_message; ! q->rcode = -n; ! if (q->rcode == 2 && ++q->attempt < MAX_ATTEMPT) { /* * RCODE 2 is "Server failure - The name server was * unable to process this query due to a problem with *************** *** 481,487 **** valid = cbdataValid(q->callback_data); cbdataUnlock(q->callback_data); if (valid) ! q->callback(q->callback_data, answers, n); rfc1035RRDestroy(answers, n); memFree(q, MEM_IDNS_QUERY); } --- 486,492 ---- valid = cbdataValid(q->callback_data); cbdataUnlock(q->callback_data); if (valid) ! q->callback(q->callback_data, answers, n, q->error); rfc1035RRDestroy(answers, n); memFree(q, MEM_IDNS_QUERY); } *************** *** 571,577 **** /* name servers went away; reconfiguring or shutting down */ break; q = n->data; ! if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * (1 << q->nsends % nns)) break; debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id); --- 576,582 ---- /* name servers went away; reconfiguring or shutting down */ break; q = n->data; ! if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * 1 << ((q->nsends - 1) / nns)) break; debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id); *************** *** 585,592 **** (int) q->id, q->nsends, tvSubDsec(q->start_t, current_time)); cbdataUnlock(q->callback_data); ! if (v) ! q->callback(q->callback_data, NULL, 0); memFree(q, MEM_IDNS_QUERY); } } --- 590,601 ---- (int) q->id, q->nsends, tvSubDsec(q->start_t, current_time)); cbdataUnlock(q->callback_data); ! if (v) { ! if (q->rcode != 0) ! q->callback(q->callback_data, NULL, -q->rcode, q->error); ! else ! q->callback(q->callback_data, NULL, -16, "Timeout"); ! } memFree(q, MEM_IDNS_QUERY); } } *************** *** 683,689 **** q->id = rfc1035BuildAQuery(name, q->buf, &q->sz); if (0 == q->id) { /* problem with query data -- query not sent */ ! callback(data, NULL, 0); memFree(q, MEM_IDNS_QUERY); return; } --- 692,698 ---- q->id = rfc1035BuildAQuery(name, q->buf, &q->sz); if (0 == q->id) { /* problem with query data -- query not sent */ ! callback(data, NULL, 0, "Internal error"); memFree(q, MEM_IDNS_QUERY); return; } Index: squid/src/forward.c diff -c squid/src/forward.c:1.82.2.5 squid/src/forward.c:1.82.2.6 *** squid/src/forward.c:1.82.2.5 Sat Nov 29 11:53:00 2003 --- squid/src/forward.c Sat Dec 6 10:19:37 2003 *************** *** 138,144 **** return 0; if (fwdState->origin_tries > 2) return 0; ! if (squid_curtime - fwdState->start > Config.Timeout.connect) return 0; if (fwdState->flags.dont_retry) return 0; --- 138,144 ---- return 0; if (fwdState->origin_tries > 2) return 0; ! if (squid_curtime - fwdState->start > Config.Timeout.forward) return 0; if (fwdState->flags.dont_retry) return 0; *************** *** 365,371 **** FwdServer *fs = fwdState->servers; const char *host; unsigned short port; ! time_t ctimeout; struct in_addr outgoing; unsigned short tos; assert(fs); --- 365,372 ---- FwdServer *fs = fwdState->servers; const char *host; unsigned short port; ! int ctimeout; ! int ftimeout = Config.Timeout.forward - (squid_curtime - fwdState->start); struct in_addr outgoing; unsigned short tos; assert(fs); *************** *** 386,391 **** --- 387,396 ---- port = fwdState->request->port; ctimeout = Config.Timeout.connect; } + if (ftimeout < 0) + ftimeout = 5; + if (ftimeout < ctimeout) + ctimeout = ftimeout; if (fwdCheckRetriable(fwdState)) { if ((fd = pconnPop(host, port)) >= 0) { debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd); Index: squid/src/fqdncache.c diff -c squid/src/fqdncache.c:1.149.2.3 squid/src/fqdncache.c:1.149.2.4 *** squid/src/fqdncache.c:1.149.2.3 Thu Dec 4 03:10:12 2003 --- squid/src/fqdncache.c Sat Dec 6 10:19:37 2003 *************** *** 72,81 **** #if USE_DNSSERVERS static HLPCB fqdncacheHandleReply; ! static fqdncache_entry *fqdncacheParse(const char *buf); #else static IDNSCB fqdncacheHandleReply; ! static fqdncache_entry *fqdncacheParse(rfc1035_rr *, int); #endif static void fqdncacheRelease(fqdncache_entry *); static fqdncache_entry *fqdncacheCreateEntry(const char *name); --- 72,81 ---- #if USE_DNSSERVERS static HLPCB fqdncacheHandleReply; ! static fqdncache_entry *fqdncacheParse(fqdncache_entry *, const char *buf); #else static IDNSCB fqdncacheHandleReply; ! static fqdncache_entry *fqdncacheParse(fqdncache_entry *, rfc1035_rr *, int, const char *error_message); #endif static void fqdncacheRelease(fqdncache_entry *); static fqdncache_entry *fqdncacheCreateEntry(const char *name); *************** *** 189,199 **** static void fqdncacheAddEntry(fqdncache_entry * f) { ! hash_link *e = hash_lookup(fqdn_table, f->hash.key); if (NULL != e) { ! /* avoid colission */ ! fqdncache_entry *q = (fqdncache_entry *) e; ! fqdncacheRelease(q); } hash_join(fqdn_table, &f->hash); dlinkAdd(f, &f->lru, &lru_list); --- 189,203 ---- static void fqdncacheAddEntry(fqdncache_entry * f) { ! fqdncache_entry *e = (fqdncache_entry *) hash_lookup(fqdn_table, f->hash.key); if (NULL != e) { ! /* avoid collision */ ! if (f->flags.negcached && !e->flags.negcached && e->expires > squid_curtime) { ! /* Don't waste good information */ ! fqdncacheFreeEntry(f); ! return; ! } ! fqdncacheRelease(e); } hash_join(fqdn_table, &f->hash); dlinkAdd(f, &f->lru, &lru_list); *************** *** 222,317 **** static fqdncache_entry * #if USE_DNSSERVERS ! fqdncacheParse(const char *inbuf) { LOCAL_ARRAY(char, buf, DNS_INBUF_SZ); char *token; - static fqdncache_entry f; int ttl; ! memset(&f, '\0', sizeof(f)); ! f.expires = squid_curtime; ! f.flags.negcached = 1; if (inbuf == NULL) { ! debug(35, 1) ("fqdncacheParse: Got reply\n"); ! return &f; } xstrncpy(buf, inbuf, DNS_INBUF_SZ); debug(35, 5) ("fqdncacheParse: parsing: {%s}\n", buf); token = strtok(buf, w_space); if (NULL == token) { ! debug(35, 1) ("fqdncacheParse: Got , expecting '$name'\n"); ! return &f; } if (0 == strcmp(token, "$fail")) { - f.expires = squid_curtime + Config.negativeDnsTtl; token = strtok(NULL, "\n"); assert(NULL != token); ! f.error_message = xstrdup(token); ! return &f; } if (0 != strcmp(token, "$name")) { ! debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token); ! return &f; } token = strtok(NULL, w_space); if (NULL == token) { ! debug(35, 1) ("fqdncacheParse: Got , expecting TTL\n"); ! return &f; } ! f.flags.negcached = 0; ttl = atoi(token); ! if (ttl > 0 && ttl < Config.positiveDnsTtl) ! f.expires = squid_curtime + ttl; ! else ! f.expires = squid_curtime + Config.positiveDnsTtl; token = strtok(NULL, w_space); if (NULL != token) { ! f.names[0] = xstrdup(token); ! f.name_count = 1; } ! return &f; } #else ! fqdncacheParse(rfc1035_rr * answers, int nr) { - static fqdncache_entry f; int k; ! int na = 0; ! memset(&f, '\0', sizeof(f)); ! f.expires = squid_curtime + Config.negativeDnsTtl; ! f.flags.negcached = 1; if (nr < 0) { ! debug(35, 3) ("fqdncacheParse: Lookup failed (error %d)\n", ! rfc1035_errno); ! assert(rfc1035_error_message); ! f.error_message = xstrdup(rfc1035_error_message); ! return &f; } if (nr == 0) { ! debug(35, 3) ("fqdncacheParse: No DNS records\n"); ! f.error_message = xstrdup("No DNS records"); ! return &f; } ! debug(35, 3) ("fqdncacheParse: %d answers\n", nr); assert(answers); for (k = 0; k < nr; k++) { if (answers[k].type != RFC1035_TYPE_PTR) continue; if (answers[k].class != RFC1035_CLASS_IN) continue; ! na++; ! f.flags.negcached = 0; ! f.names[0] = xstrndup(answers[k].rdata, answers[k].rdlength); ! f.name_count = 1; ! if (answers[k].ttl < Config.positiveDnsTtl) ! f.expires = squid_curtime + answers[k].ttl; ! else ! f.expires = squid_curtime + Config.positiveDnsTtl; ! return &f; ! } ! debug(35, 1) ("fqdncacheParse: No PTR record\n"); ! f.error_message = xstrdup("No PTR record"); ! return &f; } #endif --- 226,326 ---- static fqdncache_entry * #if USE_DNSSERVERS ! fqdncacheParse(fqdncache_entry * f, const char *inbuf) { LOCAL_ARRAY(char, buf, DNS_INBUF_SZ); char *token; int ttl; ! const char *name = (const char *) f->hash.key; ! f->expires = squid_curtime + Config.negativeDnsTtl; ! f->flags.negcached = 1; if (inbuf == NULL) { ! debug(35, 1) ("fqdncacheParse: Got reply in response to '%s'\n", name); ! f->error_message = xstrdup("Internal Error"); ! return f; } xstrncpy(buf, inbuf, DNS_INBUF_SZ); debug(35, 5) ("fqdncacheParse: parsing: {%s}\n", buf); token = strtok(buf, w_space); if (NULL == token) { ! debug(35, 1) ("fqdncacheParse: Got , expecting '$name' in response to '%s'\n", name); ! f->error_message = xstrdup("Internal Error"); ! return f; } if (0 == strcmp(token, "$fail")) { token = strtok(NULL, "\n"); assert(NULL != token); ! f->error_message = xstrdup(token); ! return f; } if (0 != strcmp(token, "$name")) { ! debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name' in response to '%s'\n", inbuf, name); ! f->error_message = xstrdup("Internal Error"); ! return f; } token = strtok(NULL, w_space); if (NULL == token) { ! debug(35, 1) ("fqdncacheParse: Got '%s', expecting TTL in response to '%s'\n", inbuf, name); ! f->error_message = xstrdup("Internal Error"); ! return f; } ! f->flags.negcached = 0; ttl = atoi(token); ! if (ttl == 0 || ttl > Config.positiveDnsTtl) ! ttl = Config.positiveDnsTtl; ! if (ttl < Config.negativeDnsTtl) ! ttl = Config.negativeDnsTtl; ! f->expires = squid_curtime + ttl; token = strtok(NULL, w_space); if (NULL != token) { ! f->names[0] = xstrdup(token); ! f->name_count = 1; } ! return f; } #else ! fqdncacheParse(fqdncache_entry * f, rfc1035_rr * answers, int nr, const char *error_message) { int k; ! int ttl = 0; ! const char *name = (const char *) f->hash.key; ! f->expires = squid_curtime + Config.negativeDnsTtl; ! f->flags.negcached = 1; if (nr < 0) { ! debug(35, 3) ("fqdncacheParse: Lookup of '%s' failed (%s)\n", name, error_message); ! f->error_message = xstrdup(error_message); ! return f; } if (nr == 0) { ! debug(35, 3) ("fqdncacheParse: No DNS records for '%s'\n", name); ! f->error_message = xstrdup("No DNS records"); ! return f; } ! debug(35, 3) ("fqdncacheParse: %d answers for '%s'\n", nr, name); assert(answers); for (k = 0; k < nr; k++) { if (answers[k].type != RFC1035_TYPE_PTR) continue; if (answers[k].class != RFC1035_CLASS_IN) continue; ! f->names[f->name_count++] = xstrndup(answers[k].rdata, answers[k].rdlength); ! if (ttl == 0 || answers[k].ttl < ttl) ! ttl = answers[k].ttl; ! if (f->name_count >= FQDN_MAX_NAMES) ! break; ! } ! if (f->name_count == 0) { ! debug(35, 1) ("fqdncacheParse: No PTR record\n"); ! f->error_message = xstrdup("No PTR record"); ! return f; ! } ! if (ttl == 0 || ttl > Config.positiveDnsTtl) ! ttl = Config.positiveDnsTtl; ! if (ttl < Config.negativeDnsTtl) ! ttl = Config.negativeDnsTtl; ! f->expires = squid_curtime + ttl; ! f->flags.negcached = 0; ! return f; } #endif *************** *** 319,348 **** #if USE_DNSSERVERS fqdncacheHandleReply(void *data, char *reply) #else ! fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na) #endif { int n; generic_cbdata *c = data; fqdncache_entry *f = c->data; - fqdncache_entry *x = NULL; cbdataFree(c); c = NULL; n = ++FqdncacheStats.replies; statHistCount(&statCounter.dns.svc_time, tvSubMsec(f->request_time, current_time)); #if USE_DNSSERVERS ! x = fqdncacheParse(reply); #else ! x = fqdncacheParse(answers, na); #endif - assert(x); - f->name_count = x->name_count; - for (n = 0; n < (int) f->name_count; n++) - f->names[n] = x->names[n]; - f->error_message = x->error_message; - f->expires = x->expires; - f->flags = x->flags; fqdncacheAddEntry(f); fqdncacheCallback(f); } --- 328,349 ---- #if USE_DNSSERVERS fqdncacheHandleReply(void *data, char *reply) #else ! fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message) #endif { int n; generic_cbdata *c = data; fqdncache_entry *f = c->data; cbdataFree(c); c = NULL; n = ++FqdncacheStats.replies; statHistCount(&statCounter.dns.svc_time, tvSubMsec(f->request_time, current_time)); #if USE_DNSSERVERS ! fqdncacheParse(f, reply); #else ! fqdncacheParse(f, answers, na, error_message); #endif fqdncacheAddEntry(f); fqdncacheCallback(f); } Index: squid/src/ipcache.c diff -c squid/src/ipcache.c:1.236.2.1 squid/src/ipcache.c:1.236.2.2 *** squid/src/ipcache.c:1.236.2.1 Fri Nov 28 12:14:32 2003 --- squid/src/ipcache.c Sat Dec 6 10:19:37 2003 *************** *** 77,85 **** static int ipcacheExpiredEntry(ipcache_entry *); static int ipcache_testname(void); #if USE_DNSSERVERS ! static ipcache_entry *ipcacheParse(const char *buf); #else ! static ipcache_entry *ipcacheParse(rfc1035_rr *, int); #endif static ipcache_entry *ipcache_get(const char *); static void ipcacheLockEntry(ipcache_entry *); --- 77,85 ---- static int ipcacheExpiredEntry(ipcache_entry *); static int ipcache_testname(void); #if USE_DNSSERVERS ! static ipcache_entry *ipcacheParse(ipcache_entry *, const char *buf); #else ! static ipcache_entry *ipcacheParse(ipcache_entry *, rfc1035_rr *, int, const char *error); #endif static ipcache_entry *ipcache_get(const char *); static void ipcacheLockEntry(ipcache_entry *); *************** *** 199,209 **** static void ipcacheAddEntry(ipcache_entry * i) { ! hash_link *e = hash_lookup(ip_table, i->hash.key); if (NULL != e) { ! /* avoid colission */ ! ipcache_entry *q = (ipcache_entry *) e; ! ipcacheRelease(q); } hash_join(ip_table, &i->hash); dlinkAdd(i, &i->lru, &lru_list); --- 199,213 ---- static void ipcacheAddEntry(ipcache_entry * i) { ! ipcache_entry *e = (ipcache_entry *) hash_lookup(ip_table, i->hash.key); if (NULL != e) { ! /* avoid collision */ ! if (i->flags.negcached && !e->flags.negcached && e->expires > squid_curtime) { ! /* Don't waste good information */ ! ipcacheFreeEntry(i); ! return; ! } ! ipcacheRelease(e); } hash_join(ip_table, &i->hash); dlinkAdd(i, &i->lru, &lru_list); *************** *** 230,326 **** ipcacheUnlockEntry(i); } - static ipcache_entry * #if USE_DNSSERVERS ! ipcacheParse(const char *inbuf) { LOCAL_ARRAY(char, buf, DNS_INBUF_SZ); char *token; ! static ipcache_entry i; ! int j; int k; int ipcount = 0; int ttl; char A[32][16]; ! memset(&i, '\0', sizeof(i)); ! i.expires = squid_curtime; ! i.flags.negcached = 1; if (inbuf == NULL) { debug(14, 1) ("ipcacheParse: Got reply\n"); ! i.error_message = xstrdup("Internal Squid Error"); ! return &i; } xstrncpy(buf, inbuf, DNS_INBUF_SZ); debug(14, 5) ("ipcacheParse: parsing: {%s}\n", buf); token = strtok(buf, w_space); if (NULL == token) { ! debug(14, 1) ("ipcacheParse: Got , expecting '$addr'\n"); ! return &i; } if (0 == strcmp(token, "$fail")) { - i.expires = squid_curtime + Config.negativeDnsTtl; token = strtok(NULL, "\n"); assert(NULL != token); ! i.error_message = xstrdup(token); ! return &i; } if (0 != strcmp(token, "$addr")) { ! debug(14, 1) ("ipcacheParse: Got '%s', expecting '$addr'\n", token); ! return &i; } token = strtok(NULL, w_space); if (NULL == token) { ! debug(14, 1) ("ipcacheParse: Got , expecting TTL\n"); ! return &i; } ! i.flags.negcached = 0; ttl = atoi(token); - if (ttl > 0 && ttl < Config.positiveDnsTtl) - i.expires = squid_curtime + ttl; - else - i.expires = squid_curtime + Config.positiveDnsTtl; while (NULL != (token = strtok(NULL, w_space))) { xstrncpy(A[ipcount], token, 16); if (++ipcount == 32) break; } ! if (0 == ipcount) { ! i.addrs.in_addrs = NULL; ! i.addrs.bad_mask = NULL; } else { ! i.addrs.in_addrs = xcalloc(ipcount, sizeof(struct in_addr)); ! i.addrs.bad_mask = xcalloc(ipcount, sizeof(unsigned char)); ! } ! for (j = 0, k = 0; k < ipcount; k++) { ! if (safe_inet_addr(A[k], &i.addrs.in_addrs[j])) ! j++; ! else ! debug(14, 1) ("ipcacheParse: Invalid IP address '%s'\n", A[k]); } ! i.addrs.count = (unsigned char) j; ! return &i; } #else ! ipcacheParse(rfc1035_rr * answers, int nr) { - static ipcache_entry i; int k; int j; int na = 0; ! memset(&i, '\0', sizeof(i)); ! i.expires = squid_curtime + Config.negativeDnsTtl; ! i.flags.negcached = 1; if (nr < 0) { ! debug(14, 3) ("ipcacheParse: Lookup failed (error %d)\n", ! rfc1035_errno); ! assert(rfc1035_error_message); ! i.error_message = xstrdup(rfc1035_error_message); ! return &i; } if (nr == 0) { ! debug(14, 3) ("ipcacheParse: No DNS records\n"); ! i.error_message = xstrdup("No DNS records"); ! return &i; } assert(answers); for (j = 0, k = 0; k < nr; k++) { --- 234,339 ---- ipcacheUnlockEntry(i); } #if USE_DNSSERVERS ! static ipcache_entry * ! ipcacheParse(ipcache_entry * i, const char *inbuf) { LOCAL_ARRAY(char, buf, DNS_INBUF_SZ); char *token; ! int j = 0; int k; int ipcount = 0; int ttl; char A[32][16]; ! const char *name = (const char *) i->hash.key; ! i->expires = squid_curtime + Config.negativeDnsTtl; ! i->flags.negcached = 1; ! safe_free(i->addrs.in_addrs); ! safe_free(i->addrs.bad_mask); ! safe_free(i->error_message); ! i->addrs.count = 0; if (inbuf == NULL) { debug(14, 1) ("ipcacheParse: Got reply\n"); ! i->error_message = xstrdup("Internal Squid Error"); ! return i; } xstrncpy(buf, inbuf, DNS_INBUF_SZ); debug(14, 5) ("ipcacheParse: parsing: {%s}\n", buf); token = strtok(buf, w_space); if (NULL == token) { ! debug(14, 1) ("ipcacheParse: expecting result, got '%s'\n", inbuf); ! i->error_message = xstrdup("Internal Squid Error"); ! return NULL; } if (0 == strcmp(token, "$fail")) { token = strtok(NULL, "\n"); assert(NULL != token); ! i->error_message = xstrdup(token); ! return i; } if (0 != strcmp(token, "$addr")) { ! debug(14, 1) ("ipcacheParse: expecting '$addr', got '%s' in response to '%s'\n", inbuf, name); ! i->error_message = xstrdup("Internal Squid Error"); ! return NULL; } token = strtok(NULL, w_space); if (NULL == token) { ! debug(14, 1) ("ipcacheParse: expecting data, got '%s' in response to '%s'\n", inbuf, name); ! i->error_message = xstrdup("Internal Squid Error"); ! return NULL; } ! i->flags.negcached = 0; ttl = atoi(token); while (NULL != (token = strtok(NULL, w_space))) { xstrncpy(A[ipcount], token, 16); if (++ipcount == 32) break; } ! if (ipcount <= 0) { ! debug(14, 1) ("ipcacheParse: No addresses in response to '%s'\n", name); } else { ! i->addrs.in_addrs = xcalloc(ipcount, sizeof(struct in_addr)); ! i->addrs.bad_mask = xcalloc(ipcount, sizeof(unsigned char)); ! for (j = 0, k = 0; k < ipcount; k++) { ! if (safe_inet_addr(A[k], &i->addrs.in_addrs[j])) ! j++; ! else ! debug(14, 1) ("ipcacheParse: Invalid IP address '%s' in response to '%s'\n", A[k], name); ! } } ! i->addrs.count = (unsigned char) j; ! if (ttl == 0 || ttl > Config.positiveDnsTtl) ! ttl = Config.positiveDnsTtl; ! if (ttl < Config.negativeDnsTtl) ! ttl = Config.negativeDnsTtl; ! i->expires = squid_curtime + ttl; ! return i; } #else ! static ipcache_entry * ! ipcacheParse(ipcache_entry * i, rfc1035_rr * answers, int nr, const char *error_message) { int k; int j; int na = 0; ! int ttl = 0; ! const char *name = (const char *) i->hash.key; ! i->expires = squid_curtime + Config.negativeDnsTtl; ! i->flags.negcached = 1; ! safe_free(i->addrs.in_addrs); ! safe_free(i->addrs.bad_mask); ! safe_free(i->error_message); ! i->addrs.count = 0; if (nr < 0) { ! debug(14, 3) ("ipcacheParse: Lookup failed '%s' for '%s'\n", ! error_message, (const char *) i->hash.key); ! i->error_message = xstrdup(error_message); ! return i; } if (nr == 0) { ! debug(14, 3) ("ipcacheParse: No DNS records in response to '%s'\n", name); ! i->error_message = xstrdup("No DNS records"); ! return i; } assert(answers); for (j = 0, k = 0; k < nr; k++) { *************** *** 331,363 **** na++; } if (na == 0) { ! debug(14, 1) ("ipcacheParse: No Address records\n"); ! i.error_message = xstrdup("No Address records"); ! return &i; ! } ! i.flags.negcached = 0; ! i.addrs.in_addrs = xcalloc(na, sizeof(struct in_addr)); ! i.addrs.bad_mask = xcalloc(na, sizeof(unsigned char)); ! i.addrs.count = (unsigned char) na; for (j = 0, k = 0; k < nr; k++) { if (answers[k].type != RFC1035_TYPE_A) continue; if (answers[k].class != RFC1035_CLASS_IN) continue; ! if (j == 0) { ! if (answers[k].ttl < Config.positiveDnsTtl) ! i.expires = squid_curtime + answers[k].ttl; ! else ! i.expires = squid_curtime + Config.positiveDnsTtl; ! } assert(answers[k].rdlength == 4); ! xmemcpy(&i.addrs.in_addrs[j++], answers[k].rdata, 4); debug(14, 3) ("ipcacheParse: #%d %s\n", j - 1, ! inet_ntoa(i.addrs.in_addrs[j - 1])); } assert(j == na); ! return &i; } #endif --- 344,377 ---- na++; } if (na == 0) { ! debug(14, 1) ("ipcacheParse: No Address records in response to '%s'\n", name); ! i->error_message = xstrdup("No Address records"); ! return i; ! } ! i->flags.negcached = 0; ! i->addrs.in_addrs = xcalloc(na, sizeof(struct in_addr)); ! i->addrs.bad_mask = xcalloc(na, sizeof(unsigned char)); for (j = 0, k = 0; k < nr; k++) { if (answers[k].type != RFC1035_TYPE_A) continue; if (answers[k].class != RFC1035_CLASS_IN) continue; ! if (ttl == 0 || ttl > answers[k].ttl) ! ttl = answers[k].ttl; assert(answers[k].rdlength == 4); ! xmemcpy(&i->addrs.in_addrs[j++], answers[k].rdata, 4); debug(14, 3) ("ipcacheParse: #%d %s\n", j - 1, ! inet_ntoa(i->addrs.in_addrs[j - 1])); } + i->addrs.count = (unsigned char) na; + if (ttl == 0 || ttl > Config.positiveDnsTtl) + ttl = Config.positiveDnsTtl; + if (ttl < Config.negativeDnsTtl) + ttl = Config.negativeDnsTtl; + i->expires = squid_curtime + ttl; assert(j == na); ! return i; } #endif *************** *** 365,391 **** #if USE_DNSSERVERS ipcacheHandleReply(void *data, char *reply) #else ! ipcacheHandleReply(void *data, rfc1035_rr * answers, int na) #endif { generic_cbdata *c = data; ipcache_entry *i = c->data; - ipcache_entry *x = NULL; cbdataFree(c); c = NULL; IpcacheStats.replies++; statHistCount(&statCounter.dns.svc_time, tvSubMsec(i->request_time, current_time)); #if USE_DNSSERVERS ! x = ipcacheParse(reply); #else ! x = ipcacheParse(answers, na); #endif - assert(x); - i->addrs = x->addrs; - i->error_message = x->error_message; - i->expires = x->expires; - i->flags = x->flags; ipcacheAddEntry(i); ipcacheCallback(i); } --- 379,399 ---- #if USE_DNSSERVERS ipcacheHandleReply(void *data, char *reply) #else ! ipcacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message) #endif { generic_cbdata *c = data; ipcache_entry *i = c->data; cbdataFree(c); c = NULL; IpcacheStats.replies++; statHistCount(&statCounter.dns.svc_time, tvSubMsec(i->request_time, current_time)); #if USE_DNSSERVERS ! ipcacheParse(i, reply); #else ! ipcacheParse(i, answers, na, error_message); #endif ipcacheAddEntry(i); ipcacheCallback(i); } Index: squid/src/structs.h diff -c squid/src/structs.h:1.408.2.16 squid/src/structs.h:1.408.2.17 *** squid/src/structs.h:1.408.2.16 Sat Nov 29 11:53:00 2003 --- squid/src/structs.h Sat Dec 6 10:19:38 2003 *************** *** 400,405 **** --- 400,406 ---- struct { time_t read; time_t lifetime; + time_t forward; time_t connect; time_t peer_connect; time_t request; Index: squid/src/typedefs.h diff -c squid/src/typedefs.h:1.132.2.2 squid/src/typedefs.h:1.132.2.3 *** squid/src/typedefs.h:1.132.2.2 Sun May 11 11:30:13 2003 --- squid/src/typedefs.h Sat Dec 6 10:19:38 2003 *************** *** 253,259 **** typedef int HLPSAVAIL(void *); typedef void HLPSONEQ(void *); typedef void HLPCMDOPTS(int *argc, char **argv); ! typedef void IDNSCB(void *, rfc1035_rr *, int); typedef void STINIT(SwapDir *); typedef void STNEWFS(SwapDir *); --- 253,259 ---- typedef int HLPSAVAIL(void *); typedef void HLPSONEQ(void *); typedef void HLPCMDOPTS(int *argc, char **argv); ! typedef void IDNSCB(void *, rfc1035_rr *, int, const char *); typedef void STINIT(SwapDir *); typedef void STNEWFS(SwapDir *);