]> jfr.im git - irc/rizon/plexus4.git/commitdiff
Add dns counters
authorAdam <redacted>
Wed, 30 Mar 2022 16:10:11 +0000 (12:10 -0400)
committerAdam <redacted>
Wed, 30 Mar 2022 21:37:38 +0000 (17:37 -0400)
include/ircd.h
modules/http_stats.c
modules/m_stats.c
src/irc_res.c

index 10bfd584db1072e5e1a92a59957f894c074f0861..4d5a13da52516eb2546cf38431d2efb8a0afac37 100644 (file)
@@ -77,6 +77,20 @@ struct ServerStatistics
   unsigned int    is_dc;   /* dns cache */
   unsigned int    is_rblc; /* cleared dnsbl caches */
   unsigned int    is_rblh; /* dnsbl cache hit */
+
+  /* dns counters */
+  uint64_t        is_dnssucc; /* successful dns response */
+  uint64_t        is_dnsfail; /* failure dns response */
+  uint64_t        is_dnsretry; /* number of retries sent */
+  uint64_t        is_dnstimeout; /* number of timed out queries */
+
+  /* dns rcode counters */
+  uint64_t        is_dnsnoerr;
+  uint64_t        is_dnsfmterr;
+  uint64_t        is_dnsservfail;
+  uint64_t        is_dnsnameerr;
+  uint64_t        is_dnsnierr;
+  uint64_t        is_dnsreferr;
 };
 
 struct Counter
index 6b6ba8725e8feec4bc19afa003486266fcf2cc48..c0d518e7e9a70536a2bf8c78c03e6f3dc845058b 100644 (file)
@@ -468,6 +468,40 @@ http_stats_ltrace(struct MHD_Connection *connection, const char *url,
   return ret;
 }
 
+static int
+http_stats_dns(struct MHD_Connection *connection, const char *url,
+               const char *method, const char *version, const char *upload_data,
+               size_t *upload_data_size)
+{
+  json_t *root = json_object();
+
+  json_object_set_new(root, "succ", json_integer(ServerStats.is_dnssucc));
+  json_object_set_new(root, "fail", json_integer(ServerStats.is_dnsfail));
+  json_object_set_new(root, "retry", json_integer(ServerStats.is_dnsretry));
+  json_object_set_new(root, "timeout", json_integer(ServerStats.is_dnstimeout));
+
+  json_object_set_new(root, "rcnoerror", json_integer(ServerStats.is_dnsnoerr));
+  json_object_set_new(root, "rcfmterr", json_integer(ServerStats.is_dnsfmterr));
+  json_object_set_new(root, "rcservfail", json_integer(ServerStats.is_dnsservfail));
+  json_object_set_new(root, "rcnameerr", json_integer(ServerStats.is_dnsnameerr));
+  json_object_set_new(root, "rcni", json_integer(ServerStats.is_dnsnierr));
+  json_object_set_new(root, "rcrefused", json_integer(ServerStats.is_dnsreferr));
+
+  const char *dump = json_dumps(root, JSON_INDENT(2));
+
+  json_decref(root);
+  root = NULL;
+
+  if (dump == NULL)
+    return MHD_NO;
+
+  struct MHD_Response *response = MHD_create_response_from_buffer(strlen(dump), (void *) dump, MHD_RESPMEM_MUST_FREE);
+  int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+  MHD_destroy_response(response);
+
+  return ret;
+}
+
 static struct HttpResource stats_http_memory =
 {
   .method = MHD_HTTP_METHOD_GET,
@@ -503,6 +537,13 @@ static struct HttpResource stats_http_ltrace =
   .handler = http_stats_ltrace
 };
 
+static struct HttpResource stats_http_dns =
+{
+  .method = MHD_HTTP_METHOD_GET,
+  .url = "/stats/dns",
+  .handler = http_stats_dns
+};
+
 #endif
 #endif
 
@@ -516,6 +557,7 @@ module_init(void)
   httpd_register(&stats_http_messages);
   httpd_register(&stats_http_listeners);
   httpd_register(&stats_http_ltrace);
+  httpd_register(&stats_http_dns);
 #endif
 #endif
 }
@@ -530,6 +572,7 @@ module_exit(void)
   httpd_unregister(&stats_http_messages);
   httpd_unregister(&stats_http_listeners);
   httpd_unregister(&stats_http_ltrace);
+  httpd_unregister(&stats_http_dns);
 #endif
 #endif
 }
index cb28f4ad84fda406e4d6eb72c9141b37aec0c8e3..fdd7352e99a266508641921e559fb95d90ef2a11 100644 (file)
@@ -1215,8 +1215,12 @@ stats_tstats(struct Client *source_p, int parc, char *parv[])
 
   sendto_one(source_p, ":%s %d %s t :accepts %u refused %u",
              me.name, RPL_STATSDEBUG, source_p->name, sp->is_ac, sp->is_ref);
-  sendto_one(source_p, ":%s %d %s t :dns cache %u dnsbl cache hit (clear) %u dnsbl cache hit %u",
+  sendto_one(source_p, ":%s %d %s t :dnsbl cache %u dnsbl cache hit (clear) %u dnsbl cache hit %u",
              me.name, RPL_STATSDEBUG, source_p->name, sp->is_dc, sp->is_rblc, sp->is_rblh);
+  sendto_one(source_p, ":%s %d %s t :dns rcode noerror %lu fmterr %lu servfail %lu nameerr %lu ni %lu refused %lu",
+             me.name, RPL_STATSDEBUG, source_p->name, sp->is_dnsnoerr, sp->is_dnsfmterr, sp->is_dnsservfail, sp->is_dnsnameerr, sp->is_dnsnierr, sp->is_dnsreferr);
+  sendto_one(source_p, ":%s %d %s t :dns query succ %lu fail %lu retry %lu timeout %lu",
+             me.name, RPL_STATSDEBUG, source_p->name, sp->is_dnssucc, sp->is_dnsfail, sp->is_dnsretry, sp->is_dnstimeout);
   sendto_one(source_p, ":%s %d %s t :unknown commands %u prefixes %u",
              me.name, RPL_STATSDEBUG, source_p->name, sp->is_unco, sp->is_unpf);
   sendto_one(source_p, ":%s %d %s t :nick collisions %u unknown closes %u",
index 6bd71f6b39fd56741f913025b5e5424cdd49959e..5bba38a7c443a068db6f4b9077af97bbee697281 100644 (file)
@@ -248,6 +248,7 @@ timeout_query_list(time_t now)
     {
       ++request->ns->failure_count;
       request->timeout += request->timeout;
+      ++ServerStats.is_dnstimeout;
       resend_query(request); /* this may delete the request if there are no more retries */
     }
     else
@@ -587,9 +588,12 @@ resend_query(struct reslist *request)
     unlink_request(request);
     (*request->callback)(request->callback_ctx, NULL, NULL);
     rem_request(request);
+    ++ServerStats.is_dnsfail;
     return;
   }
 
+  ++ServerStats.is_dnsretry;
+
   /* move query to the end of the list */
   assert(dlinkFind(&request_list_timeout, request));
   dlinkDelete(&request->tnode, &request_list_timeout);
@@ -761,6 +765,32 @@ proc_answer(struct reslist *request, HEADER *header, unsigned char *buf, unsigne
   return 1;
 }
 
+static void
+record_rcode_stats(unsigned int rcode)
+{
+  switch (rcode)
+  {
+    case NO_ERRORS:
+      ++ServerStats.is_dnsnoerr;
+      break;
+    case FMTERROR:
+      ++ServerStats.is_dnsfmterr;
+      break;
+    case SERVFAIL:
+      ++ServerStats.is_dnsservfail;
+      break;
+    case NXDOMAIN:
+      ++ServerStats.is_dnsnameerr;
+      break;
+    case NOTIMP:
+      ++ServerStats.is_dnsnierr;
+      break;
+    case REFUSED:
+      ++ServerStats.is_dnsreferr;
+      break;
+  }
+}
+
 /*
  * res_readreply - read a dns reply from the nameserver and process it.
  */
@@ -826,6 +856,8 @@ res_readreply(fde_t *fd, void *data)
     server->failure_count += 3;
   }
 
+  record_rcode_stats(header->rcode);
+
   if (header->rcode != NO_ERRORS || header->ancount == 0)
   {
     switch (header->rcode)
@@ -837,15 +869,19 @@ res_readreply(fde_t *fd, void *data)
         ++server->failure_count;
         resend_query(request);
         break;
+      case NO_ERRORS:
       case NXDOMAIN:
         /* this is a good answer, domain doesn't exist */
         server->failure_count /= 4;
-        /* FALLTHROUGH */
+        ++ServerStats.is_dnssucc;
+        goto unlink;
       default:
         /*
          * If a bad error was returned, stop here and don't
          * send any more (no retries granted).
          */
+        ++ServerStats.is_dnsfail;
+      unlink:
         unlink_request(request);
         (*request->callback)(request->callback_ctx, NULL, NULL);
         rem_request(request);
@@ -874,6 +910,7 @@ res_readreply(fde_t *fd, void *data)
        * don't bother trying again, the client address doesn't resolve
        */
       ++server->failure_count;
+      ++ServerStats.is_dnsfail;
       unlink_request(request);
       (*request->callback)(request->callback_ctx, NULL, NULL);
       rem_request(request);
@@ -910,6 +947,7 @@ res_readreply(fde_t *fd, void *data)
   }
 
   server->failure_count /= 4;
+  ++ServerStats.is_dnssucc;
 }
 
 void