=== modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2011-02-07 10:27:53 +0000 +++ src/cache_cf.cc 2011-03-09 10:49:40 +0000 @@ -101,67 +101,68 @@ #if ICAP_CLIENT static void parse_icap_service_type(Adaptation::Icap::Config *); static void dump_icap_service_type(StoreEntry *, const char *, const Adaptation::Icap::Config &); static void free_icap_service_type(Adaptation::Icap::Config *); static void parse_icap_class_type(); static void parse_icap_access_type(); static void parse_icap_service_failure_limit(Adaptation::Icap::Config *); static void dump_icap_service_failure_limit(StoreEntry *, const char *, const Adaptation::Icap::Config &); static void free_icap_service_failure_limit(Adaptation::Icap::Config *); #endif #if USE_ECAP static void parse_ecap_service_type(Adaptation::Ecap::Config *); static void dump_ecap_service_type(StoreEntry *, const char *, const Adaptation::Ecap::Config &); static void free_ecap_service_type(Adaptation::Ecap::Config *); #endif CBDATA_TYPE(peer); +static const char *const T_MILLISECOND_STR = "millisecond"; static const char *const T_SECOND_STR = "second"; static const char *const T_MINUTE_STR = "minute"; static const char *const T_HOUR_STR = "hour"; static const char *const T_DAY_STR = "day"; static const char *const T_WEEK_STR = "week"; static const char *const T_FORTNIGHT_STR = "fortnight"; static const char *const T_MONTH_STR = "month"; static const char *const T_YEAR_STR = "year"; static const char *const T_DECADE_STR = "decade"; static const char *const B_BYTES_STR = "bytes"; static const char *const B_KBYTES_STR = "KB"; static const char *const B_MBYTES_STR = "MB"; static const char *const B_GBYTES_STR = "GB"; static const char *const list_sep = ", \t\n\r"; static void parse_access_log(customlog ** customlog_definitions); static int check_null_access_log(customlog *customlog_definitions); static void dump_access_log(StoreEntry * entry, const char *name, customlog * definitions); static void free_access_log(customlog ** definitions); static void update_maxobjsize(void); static void configDoConfigure(void); static void parse_refreshpattern(refresh_t **); -static int parseTimeUnits(const char *unit); -static void parseTimeLine(time_t * tptr, const char *units); +static uint64_t parseTimeUnits(const char *unit); +static void parseTimeLine(uint64_t * tptr, const char *units); static void parse_ushort(u_short * var); static void parse_string(char **); static void default_all(void); static void defaults_if_none(void); static int parse_line(char *); static void parse_obsolete(const char *); static void parseBytesLine(size_t * bptr, const char *units); #if USE_SSL static void parseBytesOptionValue(size_t * bptr, const char *units, char const * value); #endif #if !USE_DNSSERVERS static void parseBytesLineSigned(ssize_t * bptr, const char *units); #endif static size_t parseBytesUnits(const char *unit); static void free_all(void); void requirePathnameExists(const char *name, const char *path); static OBJH dump_config; #if USE_HTTP_VIOLATIONS static void dump_http_header_access(StoreEntry * entry, const char *name, header_mangler header[]); static void parse_http_header_access(header_mangler header[]); @@ -940,98 +941,101 @@ * To upgrade it where possible instead of just "Bungled config" for * directives which cannot be marked as simply aliases of the some name. * For example if the parameter order and content has changed. * Or if the directive has been completely removed. */ void parse_obsolete(const char *name) { // Directives which have been radically changed rather than removed if (!strcmp(name, "url_rewrite_concurrency")) { int cval; parse_int(&cval); debugs(3, DBG_CRITICAL, "WARNING: url_rewrite_concurrency upgrade overriding url_rewrite_children settings."); Config.redirectChildren.concurrency = cval; } } /* Parse a time specification from the config file. Store the * result in 'tptr', after converting it to 'units' */ static void -parseTimeLine(time_t * tptr, const char *units) +parseTimeLine(uint64_t * tptr, const char *units) { char *token; double d; - time_t m; - time_t u; + uint64_t m; + uint64_t u; if ((u = parseTimeUnits(units)) == 0) self_destruct(); if ((token = strtok(NULL, w_space)) == NULL) self_destruct(); d = xatof(token); m = u; /* default to 'units' if none specified */ if (0 == d) (void) 0; else if ((token = strtok(NULL, w_space)) == NULL) debugs(3, 0, "WARNING: No units on '" << config_input_line << "', assuming " << d << " " << units ); else if ((m = parseTimeUnits(token)) == 0) self_destruct(); - *tptr = static_cast (m * d / u); + *tptr = (uint64_t)(m * d); } -static int +static uint64_t parseTimeUnits(const char *unit) { - if (!strncasecmp(unit, T_SECOND_STR, strlen(T_SECOND_STR))) + if (!strncasecmp(unit, T_MILLISECOND_STR, strlen(T_MILLISECOND_STR))) return 1; + if (!strncasecmp(unit, T_SECOND_STR, strlen(T_SECOND_STR))) + return 1000; + if (!strncasecmp(unit, T_MINUTE_STR, strlen(T_MINUTE_STR))) - return 60; + return 60 * 1000; if (!strncasecmp(unit, T_HOUR_STR, strlen(T_HOUR_STR))) - return 3600; + return 3600 * 1000; if (!strncasecmp(unit, T_DAY_STR, strlen(T_DAY_STR))) - return 86400; + return 86400 * 1000; if (!strncasecmp(unit, T_WEEK_STR, strlen(T_WEEK_STR))) - return 86400 * 7; + return 86400 * 7 * 1000; if (!strncasecmp(unit, T_FORTNIGHT_STR, strlen(T_FORTNIGHT_STR))) - return 86400 * 14; + return 86400 * 14 * 1000; if (!strncasecmp(unit, T_MONTH_STR, strlen(T_MONTH_STR))) - return 86400 * 30; + return static_cast(86400) * 30 * 1000; if (!strncasecmp(unit, T_YEAR_STR, strlen(T_YEAR_STR))) - return static_cast(86400 * 365.2522); + return static_cast(86400 * 1000 * 365.2522); if (!strncasecmp(unit, T_DECADE_STR, strlen(T_DECADE_STR))) - return static_cast(86400 * 365.2522 * 10); + return static_cast(86400 * 1000 * 365.2522 * 10); debugs(3, 1, "parseTimeUnits: unknown time unit '" << unit << "'"); return 0; } static void parseBytesLine64(int64_t * bptr, const char *units) { char *token; double d; int64_t m; int64_t u; if ((u = parseBytesUnits(units)) == 0) { self_destruct(); return; } if ((token = strtok(NULL, w_space)) == NULL) { @@ -2986,49 +2990,69 @@ if (!*token) { self_destruct(); return; } *var = xstrdup((char *) token); } #define dump_eol dump_string #define free_eol free_string static void dump_time_t(StoreEntry * entry, const char *name, time_t var) { storeAppendPrintf(entry, "%s %d seconds\n", name, (int) var); } void parse_time_t(time_t * var) { - parseTimeLine(var, T_SECOND_STR); + uint64_t tval; + parseTimeLine(&tval, T_SECOND_STR); + *var = (time_t)(tval/1000); } static void free_time_t(time_t * var) { *var = 0; } +static void +dump_time_msec(StoreEntry * entry, const char *name, uint64_t var) +{ + storeAppendPrintf(entry, "%s %d seconds and %d milliseconds\n", name, (int) (var/1000), (int) (var % 1000)); +} + +void +parse_time_msec(uint64_t * var) +{ + parseTimeLine(var, T_SECOND_STR); +} + +static void +free_time_msec(uint64_t * var) +{ + *var = 0; +} + #if UNUSED_CODE static void dump_size_t(StoreEntry * entry, const char *name, size_t var) { storeAppendPrintf(entry, "%s %d\n", name, (int) var); } #endif static void dump_b_size_t(StoreEntry * entry, const char *name, size_t var) { storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_BYTES_STR); } #if !USE_DNSSERVERS static void dump_b_ssize_t(StoreEntry * entry, const char *name, ssize_t var) { storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_BYTES_STR); } === modified file 'src/cf.data.depend' --- src/cf.data.depend 2010-10-25 18:25:19 +0000 +++ src/cf.data.depend 2011-03-09 10:48:40 +0000 @@ -40,29 +40,30 @@ icap_class_type icap_service icap_service_type icap_service_failure_limit ecap_service_type int kb_int64_t kb_size_t logformat memcachemode obsolete onoff peer peer_access cache_peer acl QosConfig refreshpattern removalpolicy size_t IpAddress_list string string +time_msec time_t tristate uri_whitespace ushort wccp2_method wccp2_amethod wccp2_service wccp2_service_info wordlist === modified file 'src/cf.data.pre' --- src/cf.data.pre 2011-02-07 10:27:53 +0000 +++ src/cf.data.pre 2011-03-09 10:47:55 +0000 @@ -6853,51 +6853,51 @@ tuning. startup= Sets a minimum of how many processes are to be spawned when Squid starts or reconfigures. When set to zero the first request will cause spawning of the first child process to handle it. Starting too few will cause an initial slowdown in traffic as Squid attempts to simultaneously spawn enough processes to cope. idle= Sets a minimum of how many processes Squid is to try and keep available at all times. When traffic begins to rise above what the existing processes can handle this many more will be spawned up to the maximum configured. A minimum setting of 1 is required. DOC_END NAME: dns_retransmit_interval -TYPE: time_t +TYPE: time_msec DEFAULT: 5 seconds LOC: Config.Timeout.idns_retransmit IFDEF: !USE_DNSSERVERS DOC_START Initial retransmit interval for DNS queries. The interval is doubled each time all configured DNS servers have been tried. DOC_END NAME: dns_timeout -TYPE: time_t +TYPE: time_msec DEFAULT: 2 minutes LOC: Config.Timeout.idns_query IFDEF: !USE_DNSSERVERS DOC_START DNS Query timeout. If no response is received to a DNS query within this time all DNS servers for the queried domain are assumed to be unavailable. DOC_END NAME: dns_packet_max TYPE: b_ssize_t DEFAULT: none LOC: Config.dns.packet_max IFDEF: !USE_DNSSERVERS DOC_START Maximum number of bytes packet size to advertise via EDNS. Set to "none" to disable EDNS large packet support. For legacy reasons DNS UDP replies will default to 512 bytes which is too small for many responses. EDNS provides a means for Squid to === modified file 'src/dns_internal.cc' --- src/dns_internal.cc 2011-03-06 11:48:16 +0000 +++ src/dns_internal.cc 2011-03-09 21:08:33 +0000 @@ -707,81 +707,86 @@ if (npc) { storeAppendPrintf(sentry, "\nSearch list:\n"); for (i=0; i < npc; i++) storeAppendPrintf(sentry, "%s\n", searchpath[i].domain); storeAppendPrintf(sentry, "\n"); } } static void idnsTickleQueue(void) { if (event_queued) return; if (NULL == lru_list.tail) return; - eventAdd("idnsCheckQueue", idnsCheckQueue, NULL, 1.0, 1); + const double when = min(Config.Timeout.idns_query, Config.Timeout.idns_retransmit)/1000.0; + + eventAdd("idnsCheckQueue", idnsCheckQueue, NULL, when, 1); event_queued = 1; } static void idnsSentQueryVC(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data) { nsvc * vc = (nsvc *)data; if (flag == COMM_ERR_CLOSING) return; if (fd_table[fd].closing()) return; if (flag != COMM_OK || size <= 0) { comm_close(fd); return; } vc->busy = 0; idnsDoSendQueryVC(vc); } static void idnsDoSendQueryVC(nsvc *vc) { if (vc->busy) return; if (vc->queue->contentSize() == 0) return; MemBuf *mb = vc->queue; vc->queue = new MemBuf; vc->busy = 1; - commSetTimeout(vc->fd, Config.Timeout.idns_query, NULL, NULL); + const int timeout = (Config.Timeout.idns_query % 1000 ? + Config.Timeout.idns_query + 1000 : Config.Timeout.idns_query) / 1000; + + commSetTimeout(vc->fd, timeout, NULL, NULL); AsyncCall::Pointer call = commCbCall(78, 5, "idnsSentQueryVC", CommIoCbPtrFun(&idnsSentQueryVC, vc)); Comm::Write(vc->fd, mb, call); delete mb; } static void idnsInitVCConnected(int fd, const DnsLookupDetails &details, comm_err_t status, int xerrno, void *data) { nsvc * vc = (nsvc *)data; if (status != COMM_OK) { char buf[MAX_IPSTRLEN] = ""; if (vc->ns < nns) nameservers[vc->ns].S.NtoA(buf,MAX_IPSTRLEN); debugs(78, 1, HERE << "Failed to connect to nameserver " << buf << " using TCP: " << details); comm_close(fd); @@ -1324,58 +1329,58 @@ } static void idnsCheckQueue(void *unused) { dlink_node *n; dlink_node *p = NULL; idns_query *q; event_queued = 0; if (0 == nns) /* name servers went away; reconfiguring or shutting down */ return; for (n = lru_list.tail; n; n = p) { p = n->prev; q = static_cast(n->data); /* Anything to process in the queue? */ - if (tvSubDsec(q->queue_t, current_time) < Config.Timeout.idns_retransmit ) + if ((uint64_t)tvSubMsec(q->queue_t, current_time) < Config.Timeout.idns_retransmit ) break; /* Query timer expired? */ - if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * 1 << ((q->nsends - 1) / nns)) { + if ((uint64_t)tvSubMsec(q->sent_t, current_time) < (Config.Timeout.idns_retransmit * 1 << ((q->nsends - 1) / nns))) { dlinkDelete(&q->lru, &lru_list); q->queue_t = current_time; dlinkAdd(q, &q->lru, &lru_list); continue; } debugs(78, 3, "idnsCheckQueue: ID " << q->xact_id << " QID 0x" << std::hex << std::setfill('0') << std::setw(4) << q->msg_id << ": timeout" ); dlinkDelete(&q->lru, &lru_list); - if (tvSubDsec(q->start_t, current_time) < Config.Timeout.idns_query) { + if ((uint64_t)tvSubMsec(q->start_t, current_time) < Config.Timeout.idns_query) { idnsSendQuery(q); } else { debugs(78, 2, "idnsCheckQueue: ID " << q->xact_id << " QID 0x" << std::hex << q->msg_id << " : giving up after " << std::dec << q->nsends << " tries and " << std::setw(5)<< std::setprecision(2) << tvSubDsec(q->start_t, current_time) << " seconds"); if (q->rcode != 0) idnsCallback(q, NULL, -q->rcode, rfc1035ErrorMessage(q->rcode)); else idnsCallback(q, NULL, -16, "Timeout"); cbdataFree(q); } } idnsTickleQueue(); } static void === modified file 'src/structs.h' --- src/structs.h 2011-02-07 10:27:53 +0000 +++ src/structs.h 2011-03-08 16:01:00 +0000 @@ -175,42 +175,42 @@ struct { time_t read; time_t write; time_t lifetime; time_t connect; time_t forward; time_t peer_connect; time_t request; time_t persistent_request; time_t pconn; time_t siteSelect; time_t deadPeer; int icp_query; /* msec */ int icp_query_max; /* msec */ int icp_query_min; /* msec */ int mcast_icp_query; /* msec */ #if !USE_DNSSERVERS - time_t idns_retransmit; - time_t idns_query; + uint64_t idns_retransmit; + uint64_t idns_query; #endif } Timeout; size_t maxRequestHeaderSize; int64_t maxRequestBodySize; int64_t maxChunkedRequestBodySize; size_t maxRequestBufferSize; size_t maxReplyHeaderSize; acl_size_t *ReplyBodySize; struct { u_short icp; #if USE_HTCP u_short htcp; #endif #if SQUID_SNMP u_short snmp; #endif