So, is it OK to use the 30 seconds as the default dns_timeout value?
If not objection I will commit this patch later today ....
On 03/14/2011 06:35 PM, Alex Rousskov wrote:
+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));
+}
I doubt we are consistent with this everywhere, but should we try to
dump options in a format compatible with squid.conf syntax? If yes, we
could do something like this (at least):
if (var % 1000)
storeAppendPrintf(entry, "%s %d milliseconds\n", name, (int) var);
else
storeAppendPrintf(entry, "%s %d seconds\n", name, (int) (var/1000));
OK fixed.
We can also use T_SECOND_STR and T_MILLISECOND_STR in the above.
I did not use them because of the missing "s" at the end of these
strings ("second" not "seconds" etc....)
- 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);
Perhaps add a source comment explaining that while we are forced to
convert to seconds here, the exact timeout will be checked in
idnsCheckQueue()?
// Comm needs seconds but idnsCheckQueue() will check the exact timeout
done
Please consider typedef-ing uint64_t as time_msec and using time_msec
type as needed. This will help with identifying time-related values in
the future.
done
On 03/15/2011 01:25 AM, Amos Jeffries wrote:
>
> Yes. We MUST even. People use the cachemgr output these dump routines
> flow into as copy-n-paste sources for other squid.conf and tutorials.
>
>>
>> if (var % 1000)
>> storeAppendPrintf(entry, "%s %d milliseconds\n", name, (int) var);
>> else
>> storeAppendPrintf(entry, "%s %d seconds\n", name, (int) (var/1000));
>
> Please also avoid the 32-bit cast by using %"PRIu64" for all unsigned
> 64-bit display.
done
>
> Also, conversion to the largest whole time period (second, minute, hour,
> day etc as supported by the parser) would be good for user education
> through the display defaults.
I did not change this one. I do not think it is something important
because it is unusual to have big time periods, in the cases where the
user should use milliseconds...
=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc 2011-02-07 10:27:53 +0000
+++ src/cache_cf.cc 2011-03-15 12:03:25 +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(time_msec_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(time_msec_t * tptr, const char *units)
{
char *token;
double d;
- time_t m;
- time_t u;
+ time_msec_t m;
+ time_msec_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<time_t> (m * d / u);
+ *tptr = static_cast<time_msec_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<uint64_t>(86400) * 30 * 1000;
if (!strncasecmp(unit, T_YEAR_STR, strlen(T_YEAR_STR)))
- return static_cast<int>(86400 * 365.2522);
+ return static_cast<uint64_t>(86400 * 1000 * 365.2522);
if (!strncasecmp(unit, T_DECADE_STR, strlen(T_DECADE_STR)))
- return static_cast<int>(86400 * 365.2522 * 10);
+ return static_cast<uint64_t>(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,72 @@
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);
+ time_msec_t tval;
+ parseTimeLine(&tval, T_SECOND_STR);
+ *var = static_cast<time_t>(tval/1000);
}
static void
free_time_t(time_t * var)
{
*var = 0;
}
+static void
+dump_time_msec(StoreEntry * entry, const char *name, time_msec_t var)
+{
+ if (var % 1000)
+ storeAppendPrintf(entry, "%s %"PRId64" milliseconds\n", name, var);
+ else
+ storeAppendPrintf(entry, "%s %d seconds\n", name, (int)(var/1000) );
+}
+
+void
+parse_time_msec(time_msec_t * var)
+{
+ parseTimeLine(var, T_SECOND_STR);
+}
+
+static void
+free_time_msec(time_msec_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-15 11:52:25 +0000
@@ -6853,52 +6853,52 @@
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
-DEFAULT: 2 minutes
+TYPE: time_msec
+DEFAULT: 30 seconds
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
negotiate receiving larger responses back immediately without having
=== modified file 'src/dns_internal.cc'
--- src/dns_internal.cc 2011-03-06 11:48:16 +0000
+++ src/dns_internal.cc 2011-03-15 10:55:51 +0000
@@ -707,81 +707,87 @@
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);
+ // Comm needs seconds but idnsCheckQueue() will check the exact timeout
+ 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 +1330,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<idns_query*>(n->data);
/* Anything to process in the queue? */
- if (tvSubDsec(q->queue_t, current_time) < Config.Timeout.idns_retransmit )
+ if ((time_msec_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 ((time_msec_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 ((time_msec_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-15 10:38:29 +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;
+ time_msec_t idns_retransmit;
+ time_msec_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
=== modified file 'src/typedefs.h'
--- src/typedefs.h 2011-03-02 07:27:24 +0000
+++ src/typedefs.h 2011-03-15 10:40:57 +0000
@@ -174,21 +174,24 @@
class StoreEntry;
typedef void OBJH(StoreEntry *);
typedef void SIGHDLR(int sig);
typedef void STVLDCB(void *, int, int);
typedef void HLPCB(void *, char *buf);
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 double hbase_f(double);
typedef void StatHistBinDumper(StoreEntry *, int idx, double val, double size, int count);
/* MD5 cache keys */
typedef unsigned char cache_key;
/* in case we want to change it later */
typedef ssize_t mb_size_t;
typedef int STDIRSELECT(const StoreEntry *);
+
+/*Use uint64_t to store miliseconds*/
+typedef uint64_t time_msec_t;
#endif /* SQUID_TYPEDEFS_H */