diff --git a/CHANGES b/CHANGES index 819ccb008b..6911ae672b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +4290. [func] The timers returned by the statistics channel + (indicating current time, server boot time, and + most recent reconfiguration time) are now reported + with millisecond accuracy. [RT #40082] + 4289. [bug] The server could crash due to memory being used after it was freed if a zone transfer timed out. [RT #41297] diff --git a/bin/named/bind9.xsl b/bin/named/bind9.xsl index 7b8bab1095..079f3b48f6 100644 --- a/bin/named/bind9.xsl +++ b/bin/named/bind9.xsl @@ -17,7 +17,7 @@ - + diff --git a/bin/named/bind9.xsl.h b/bin/named/bind9.xsl.h index b42e7f19b4..d97279642c 100644 --- a/bin/named/bind9.xsl.h +++ b/bin/named/bind9.xsl.h @@ -22,7 +22,7 @@ static char xslmsg[] = "\n" "\n" " \n" - " \n" + " \n" " \n" " \n" " \n" diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c index a0b727f8f9..8353eef47b 100644 --- a/bin/named/statschannel.c +++ b/bin/named/statschannel.c @@ -1411,9 +1411,9 @@ static isc_result_t generatexml(ns_server_t *server, isc_uint32_t flags, int *buflen, xmlChar **buf) { - char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"]; - char configtime[sizeof "yyyy-mm-ddThh:mm:ssZ"]; - char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"]; + char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; + char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; + char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; isc_time_t now; xmlTextWriterPtr writer = NULL; xmlDocPtr doc = NULL; @@ -1433,9 +1433,9 @@ generatexml(ns_server_t *server, isc_uint32_t flags, isc_result_t result; isc_time_now(&now); - isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime); - isc_time_formatISO8601(&ns_g_configtime, configtime, sizeof configtime); - isc_time_formatISO8601(&now, nowstr, sizeof nowstr); + isc_time_formatISO8601ms(&ns_g_boottime, boottime, sizeof boottime); + isc_time_formatISO8601ms(&ns_g_configtime, configtime, sizeof configtime); + isc_time_formatISO8601ms(&now, nowstr, sizeof nowstr); writer = xmlNewTextWriterDoc(&doc, 0); if (writer == NULL) @@ -1445,7 +1445,7 @@ generatexml(ns_server_t *server, isc_uint32_t flags, ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\"")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", - ISC_XMLCHAR "3.7")); + ISC_XMLCHAR "3.8")); /* Set common fields for statistics dump */ dumparg.type = isc_statsformat_xml; @@ -2071,9 +2071,9 @@ generatejson(ns_server_t *server, size_t *msglen, isc_uint64_t tcpinsizestat_values[dns_sizecounter_in_max]; isc_uint64_t tcpoutsizestat_values[dns_sizecounter_out_max]; stats_dumparg_t dumparg; - char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"]; - char configtime[sizeof "yyyy-mm-ddThh:mm:ssZ"]; - char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"]; + char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; + char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; + char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; isc_time_t now; REQUIRE(msglen != NULL); @@ -2092,11 +2092,11 @@ generatejson(ns_server_t *server, size_t *msglen, json_object_object_add(bindstats, "json-stats-version", obj); isc_time_now(&now); - isc_time_formatISO8601(&ns_g_boottime, + isc_time_formatISO8601ms(&ns_g_boottime, boottime, sizeof(boottime)); - isc_time_formatISO8601(&ns_g_configtime, + isc_time_formatISO8601ms(&ns_g_configtime, configtime, sizeof configtime); - isc_time_formatISO8601(&now, nowstr, sizeof(nowstr)); + isc_time_formatISO8601ms(&now, nowstr, sizeof(nowstr)); obj = json_object_new_string(boottime); CHECKMEM(obj); diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index f36340ed5b..da7e3d4e1a 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -564,6 +564,13 @@
Feature Changes + + + The timers returned by the statistics channel (indicating current + time, server boot time, and most recent reconfiguration time) are + now reported with millisecond accuracy. [RT #40082] + + Updated the compiled in addresses for H.ROOT-SERVERS.NET. diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h index fd767040ae..ee45ce8f40 100644 --- a/lib/isc/unix/include/isc/time.h +++ b/lib/isc/unix/include/isc/time.h @@ -346,6 +346,20 @@ isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len); * */ +void +isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len); +/*%< + * Format the time 't' into the buffer 'buf' of length 'len', + * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.sssZ" + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + *\li 'len' > 0 + *\li 'buf' points to an array of at least len chars + * + */ + ISC_LANG_ENDDECLS #endif /* ISC_TIME_H */ diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c index 97ccfa0677..522cad0409 100644 --- a/lib/isc/unix/time.c +++ b/lib/isc/unix/time.c @@ -39,6 +39,7 @@ #define NS_PER_S 1000000000 /*%< Nanoseconds per second. */ #define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */ +#define NS_PER_MS 1000000 /*%< Nanoseconds per millisecond. */ #define US_PER_S 1000000 /*%< Microseconds per second. */ /* @@ -392,7 +393,7 @@ isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { INSIST(flen < len); if (flen != 0) snprintf(buf + flen, len - flen, - ".%03u", t->nanoseconds / 1000000); + ".%03u", t->nanoseconds / NS_PER_MS); else { strncpy(buf, "99-Bad-9999 99:99:99.999", len); buf[len - 1] = 0; @@ -443,3 +444,20 @@ isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); INSIST(flen < len); } + +void +isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) { + time_t now; + unsigned int flen; + + REQUIRE(len > 0); + + now = (time_t)t->seconds; + flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); + INSIST(flen < len); + if (flen == len - 5) { + flen -= 1; /* rewind one character */ + snprintf(buf + flen, len - flen, ".%03uZ", + t->nanoseconds / NS_PER_MS); + } +} diff --git a/lib/isc/win32/include/isc/time.h b/lib/isc/win32/include/isc/time.h index 5b97c53588..b48ccf8160 100644 --- a/lib/isc/win32/include/isc/time.h +++ b/lib/isc/win32/include/isc/time.h @@ -310,6 +310,20 @@ isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len); * */ +void +isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len); +/*%< + * Format the time 't' into the buffer 'buf' of length 'len', + * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.sssZ" + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + *\li 'len' > 0 + *\li 'buf' points to an array of at least len chars + * + */ + isc_uint32_t isc_time_seconds(const isc_time_t *t); /*%< diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 42e32e1d78..f4d4025e0f 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -681,6 +681,7 @@ isc_thread_setconcurrency isc_time_add isc_time_compare isc_time_formatISO8601 +isc_time_formatISO8601ms isc_time_formathttptimestamp isc_time_formattimestamp isc_time_isepoch diff --git a/lib/isc/win32/time.c b/lib/isc/win32/time.c index e478edcb82..54c8b472aa 100644 --- a/lib/isc/win32/time.c +++ b/lib/isc/win32/time.c @@ -343,7 +343,7 @@ isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { char DateBuf[50]; char TimeBuf[50]; -/* strtime() format: "%Y-%m-%dT%H:%M:%SZ" */ + /* strtime() format: "%Y-%m-%dT%H:%M:%SZ" */ REQUIRE(len > 0); if (FileTimeToSystemTime(&t->absolute, &st)) { @@ -357,3 +357,25 @@ isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { buf[0] = 0; } } + +void +isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) { + SYSTEMTIME st; + char DateBuf[50]; + char TimeBuf[50]; + + /* strtime() format: "%Y-%m-%dT%H:%M:%S.SSSZ" */ + + REQUIRE(len > 0); + if (FileTimeToSystemTime(&t->absolute, &st)) { + GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd", + DateBuf, 50); + GetTimeFormat(LOCALE_NEUTRAL, + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, + &st, "hh':'mm':'ss", TimeBuf, 50); + snprintf(buf, len, "%sT%s.%03uZ", DateBuf, TimeBuf, + st.wMilliseconds); + } else { + buf[0] = 0; + } +}