]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Log the rcode returned to for a query
authorMark Andrews <marka@isc.org>
Wed, 19 Jun 2019 06:20:24 +0000 (16:20 +1000)
committerMark Andrews <marka@isc.org>
Thu, 19 Sep 2024 21:44:06 +0000 (21:44 +0000)
Log to the querylog the rcode of a previous query using
the identifier 'response:' to diffenciate queries from
responses.

14 files changed:
bin/named/config.c
bin/named/control.c
bin/named/include/named/control.h
bin/named/include/named/server.h
bin/named/server.c
bin/rndc/rndc.rst
doc/arm/logging-categories.inc.rst
doc/misc/options
lib/isc/include/isc/log.h
lib/isc/log.c
lib/isccfg/namedconf.c
lib/ns/include/ns/server.h
lib/ns/query.c
util/check-categories.sh

index 70dd25942bd58d750bfe81cc74d8e9e4fa1269bc..94df346db4f48c48977d4794757cf271acf4ebe0 100644 (file)
@@ -95,10 +95,12 @@ options {\n\
 #endif
                            "\
        prefetch 2 9;\n\
+#      querylog <boolean>;\n\
        recursing-file \"named.recursing\";\n\
        recursive-clients 1000;\n\
        request-nsid false;\n\
        resolver-query-timeout 10;\n\
+#      responselog <boolean>;\n\
        rrset-order { order random; };\n\
        secroots-file \"named.secroots\";\n\
        send-cookie true;\n\
index 7a60bae870761fc56fd5e9165ec86157dfd86093..d430d903b02e09fff4ac3a184de1036be2e898ec 100644 (file)
@@ -256,6 +256,8 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly,
                result = named_server_refreshcommand(named_g_server, lex, text);
        } else if (command_compare(command, NAMED_COMMAND_RELOAD)) {
                result = named_server_reloadcommand(named_g_server, lex, text);
+       } else if (command_compare(command, NAMED_COMMAND_RESPONSELOG)) {
+               result = named_server_toggleresponselog(named_g_server, lex);
        } else if (command_compare(command, NAMED_COMMAND_RETRANSFER)) {
                result = named_server_retransfercommand(named_g_server, lex,
                                                        text);
index c00900847fd425d06b740d404f767c11d56efc0b..cb3c69c820316aa92cd4adcc033e56e3e4b92f0e 100644 (file)
@@ -54,6 +54,7 @@
 #define NAMED_COMMAND_RECURSING           "recursing"
 #define NAMED_COMMAND_REFRESH     "refresh"
 #define NAMED_COMMAND_RELOAD      "reload"
+#define NAMED_COMMAND_RESPONSELOG  "responselog"
 #define NAMED_COMMAND_RETRANSFER   "retransfer"
 #define NAMED_COMMAND_SCAN        "scan"
 #define NAMED_COMMAND_SECROOTS    "secroots"
index bfe6a238ce5086dcd25917fb6876472d1c76f183..9bf79da7187b5c994be120b95f16c2da52116aa3 100644 (file)
@@ -187,6 +187,13 @@ named_server_togglequerylog(named_server_t *server, isc_lex_t *lex);
  * but can also be used as a toggle for backward comptibility.)
  */
 
+isc_result_t
+named_server_toggleresponselog(named_server_t *server, isc_lex_t *lex);
+/*%<
+ * Enable/disable logging of responses.  (Takes "yes" or "no" argument,
+ * but can also be used as a toggle for backward comptibility.)
+ */
+
 /*%
  * Save the current NTAs for all views to files.
  */
index 83410583333034134a3c64d0a73bb176e326ab87..1fd36d01e8eaad51afb5460d3ccdc74d33189ff9 100644 (file)
@@ -9119,6 +9119,13 @@ load_configuration(const char *filename, named_server_t *server,
                                }
                        }
                }
+               obj = NULL;
+               result = named_config_get(maps, "responselog", &obj);
+               if (result == ISC_R_SUCCESS) {
+                       ns_server_setoption(server->sctx,
+                                           NS_SERVER_LOGRESPONSES,
+                                           cfg_obj_asboolean(obj));
+               }
        }
 
        obj = NULL;
@@ -10668,7 +10675,7 @@ named_server_refreshcommand(named_server_t *server, isc_lex_t *lex,
 isc_result_t
 named_server_togglequerylog(named_server_t *server, isc_lex_t *lex) {
        bool prev, value;
-       char *ptr;
+       char *ptr = NULL;
 
        /* Skip the command name. */
        ptr = next_token(lex, NULL);
@@ -10705,6 +10712,46 @@ named_server_togglequerylog(named_server_t *server, isc_lex_t *lex) {
        return (ISC_R_SUCCESS);
 }
 
+isc_result_t
+named_server_toggleresponselog(named_server_t *server, isc_lex_t *lex) {
+       bool prev, value;
+       char *ptr = NULL;
+
+       /* Skip the command name. */
+       ptr = next_token(lex, NULL);
+       if (ptr == NULL) {
+               return (ISC_R_UNEXPECTEDEND);
+       }
+
+       prev = ns_server_getoption(server->sctx, NS_SERVER_LOGRESPONSES);
+
+       ptr = next_token(lex, NULL);
+       if (ptr == NULL) {
+               value = !prev;
+       } else if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") ||
+                  !strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true"))
+       {
+               value = true;
+       } else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") ||
+                  !strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false"))
+       {
+               value = false;
+       } else {
+               return (DNS_R_SYNTAX);
+       }
+
+       if (value == prev) {
+               return (ISC_R_SUCCESS);
+       }
+
+       ns_server_setoption(server->sctx, NS_SERVER_LOGRESPONSES, value);
+
+       isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
+                     ISC_LOG_INFO, "response logging is now %s",
+                     value ? "on" : "off");
+       return (ISC_R_SUCCESS);
+}
+
 static isc_result_t
 listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
                      cfg_aclconfctx_t *actx, isc_mem_t *mctx, uint16_t family,
@@ -12087,6 +12134,12 @@ named_server_status(named_server_t *server, isc_buffer_t **text) {
                         : "OFF");
        CHECK(putstr(text, line));
 
+       snprintf(line, sizeof(line), "response logging is %s\n",
+                ns_server_getoption(server->sctx, NS_SERVER_LOGRESPONSES)
+                        ? "ON"
+                        : "OFF");
+       CHECK(putstr(text, line));
+
        snprintf(line, sizeof(line), "recursive clients: %u/%u/%u\n",
                 isc_quota_getused(&server->sctx->recursionquota),
                 isc_quota_getsoft(&server->sctx->recursionquota),
index 55ea4d3147adceb2bdb263299840ca5205f53a8b..b59f62e6722e41387067ae14030cf1e8e9e2eb54 100644 (file)
@@ -458,6 +458,17 @@ Currently supported commands are:
 
 .. program:: rndc
 
+.. option:: responselog [on | off]
+
+   This command enables or disables response logging. For backward compatibility,
+   this command can also be used without an argument to toggle response logging
+   on and off.
+
+   Unlike query logging, response logging cannot be enabled by explicitly directing
+   the ``responses`` ``category`` to a ``channel`` in the ``logging`` section
+   of :iscman:`named.conf`, but it can still be enabled by specifying
+   ``responselog yes;`` in the ``options`` section of :iscman:`named.conf`.
+
 .. option:: retransfer [-force] zone [class [view]]
 
    This command retransfers the given secondary zone from the primary server.
index c80c17fe7fae49a453ced33aee26ba4a666271ef..949631c49a29c205330171c54e4b0d1e76b02ffa 100644 (file)
@@ -56,7 +56,7 @@
     NSID options received from upstream servers.
 
 ``queries``
-    A location where queries should be logged.
+    The locations where queries should be logged.
 
     At startup, specifying the category ``queries`` also enables query logging unless the :any:`querylog` option has been specified.
 
@@ -80,6 +80,9 @@
 ``resolver``
     DNS resolution, such as the recursive lookups performed on behalf of clients by a caching name server.
 
+``responses``
+    The locations where query response summaries should be logged.
+
 ``rpz``
     Information about errors in response policy zone files, rewritten responses, and, at the highest ``debug`` levels, mere rewriting attempts.
 
index 2b281c724ca3f68bf7f945549cfd7a8dd8cbbfea..b3714e4d38aaee959a457b553ff1f43806a4ef6c 100644 (file)
@@ -260,6 +260,7 @@ options {
        resolver-use-dns64 <boolean>;
        response-padding { <address_match_element>; ... } block-size <integer>;
        response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
+       responselog <boolean>;
        reuseport <boolean>;
        root-key-sentinel <boolean>;
        rrset-order { [ class <string> ] [ type <string> ] [ name <quoted_string> ] <string> <string>; ... };
index 579e96e4ff3dfaa400f71da769d6c12a048d0579..c7d02cce9617e7a51a6193c9a4e8fbafd8b03da2 100644 (file)
@@ -146,6 +146,7 @@ enum isc_logcategory {
        NS_LOGCATEGORY_QUERY_ERRORS,
        NS_LOGCATEGORY_TAT,
        NS_LOGCATEGORY_SERVE_STALE,
+       NS_LOGCATEGORY_RESPONSES,
        /* cfg categories */
        CFG_LOGCATEGORY_CONFIG,
        /* named categories */
index 4073ce4182a726b9cdc70ff1dde6b3721d486af1..53dcb479213288ae9bfb4400fb44be74b323b759 100644 (file)
@@ -197,6 +197,7 @@ static const char *categories_description[] = {
        [NS_LOGCATEGORY_QUERY_ERRORS] = "query-errors",
        [NS_LOGCATEGORY_TAT] = "trust-anchor-telemetry",
        [NS_LOGCATEGORY_SERVE_STALE] = "serve-stale",
+       [NS_LOGCATEGORY_RESPONSES] = "responses",
        /* cfg categories */
        [CFG_LOGCATEGORY_CONFIG] = "config",
        /* named categories */
index 5d1c2abd4e7c3e16d59e5b1906818db883e7701f..9a30bdfd8d9d68a8e15db554872ff7fe1ecf7b2c 100644 (file)
@@ -1327,6 +1327,7 @@ static cfg_clausedef_t options_clauses[] = {
        { "recursive-clients", &cfg_type_uint32, 0 },
        { "reuseport", &cfg_type_boolean, 0 },
        { "reserved-sockets", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
+       { "responselog", &cfg_type_boolean, 0 },
        { "secroots-file", &cfg_type_qstring, 0 },
        { "serial-queries", NULL, CFG_CLAUSEFLAG_ANCIENT },
        { "serial-query-rate", &cfg_type_uint32, 0 },
index ec6636a0fdf6766566b8dd1d03dfebb89827419e..fa21986ca4bc2cad949d1280fb8f222c1d4b2aba 100644 (file)
@@ -49,6 +49,7 @@
 #define NS_SERVER_TRANSFERINSECS 0x00008000U /*%< -T transferinsecs */
 #define NS_SERVER_TRANSFERSLOWLY 0x00010000U /*%< -T transferslowly */
 #define NS_SERVER_TRANSFERSTUCK         0x00020000U /*%< -T transferstuck */
+#define NS_SERVER_LOGRESPONSES  0x00040000U /*%< log responses */
 
 /*%
  * Type for callback function to get hostname.
index d5c21e062198b54059591da4b6fcc6e169e7e60b..ed7d35d73f944a3784a183d57c81b3a4526d274d 100644 (file)
@@ -48,6 +48,7 @@
 #include <dns/nsec3.h>
 #include <dns/order.h>
 #include <dns/rbt.h>
+#include <dns/rcode.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
 #include <dns/rdatalist.h>
@@ -545,6 +546,30 @@ inc_stats(ns_client_t *client, isc_statscounter_t counter) {
        }
 }
 
+static inline void
+log_response(ns_client_t *client, dns_rcode_t rcode) {
+       char namebuf[DNS_NAME_FORMATSIZE];
+       char typebuf[DNS_RDATATYPE_FORMATSIZE];
+       char classbuf[DNS_RDATACLASS_FORMATSIZE];
+       char rcodebuf[20];
+       isc_buffer_t b;
+       int level = ISC_LOG_INFO;
+
+       if (!isc_log_wouldlog(level))
+               return;
+
+       dns_name_format(client->query.origqname, namebuf, sizeof(namebuf));
+       dns_rdataclass_format(client->message->rdclass, classbuf,
+                             sizeof(classbuf));
+       dns_rdatatype_format(client->query.qtype, typebuf, sizeof(typebuf));
+       isc_buffer_init(&b, rcodebuf, sizeof(rcodebuf));
+       dns_rcode_totext(rcode, &b);
+
+       ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, level,
+                     "response: %s %s %s %.*s", namebuf, classbuf, typebuf,
+                     (int)isc_buffer_usedlength(&b), rcodebuf);
+}
+
 static void
 query_send(ns_client_t *client) {
        isc_statscounter_t counter;
@@ -574,6 +599,10 @@ query_send(ns_client_t *client) {
                counter = ns_statscounter_failure;
        }
 
+       if ((client->manager->sctx->options & NS_SERVER_LOGRESPONSES) != 0) {
+               log_response(client, client->message->rcode);
+       }
+
        inc_stats(client, counter);
        ns_client_send(client);
 
@@ -585,8 +614,10 @@ query_send(ns_client_t *client) {
 static void
 query_error(ns_client_t *client, isc_result_t result, int line) {
        int loglevel = ISC_LOG_DEBUG(3);
+       dns_rcode_t rcode;
 
-       switch (dns_result_torcode(result)) {
+       rcode = dns_result_torcode(result);
+       switch (rcode) {
        case dns_rcode_servfail:
                loglevel = ISC_LOG_DEBUG(1);
                inc_stats(client, ns_statscounter_servfail);
@@ -605,6 +636,12 @@ query_error(ns_client_t *client, isc_result_t result, int line) {
 
        log_queryerror(client, result, line, loglevel);
 
+       if (client->query.origqname != NULL &&
+           (client->manager->sctx->options & NS_SERVER_LOGRESPONSES) != 0)
+       {
+               log_response(client, rcode);
+       }
+
        ns_client_error(client, result);
 
        if (!client->nodetach) {
index 2f5909181ff1682589aaf9a11541db622b940bd1..e45dafe33fbf9ed79292fc90a3427b0c268999a4 100644 (file)
@@ -34,7 +34,7 @@ for i in $list1; do
     fi
   done
   if test $ok = no; then
-    echo "$i missing from documentation."
+    echo "$i missing from doc/arm/logging-categories.rst."
     status=1
   fi
 done
@@ -46,7 +46,7 @@ for i in $list2; do
     fi
   done
   if test $ok = no; then
-    echo "$i not in code."
+    echo "documented logging category '$i' not in code."
     status=1
   fi
 done