]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
cmdmon: limit reported clients by number of packets
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 18 May 2020 11:58:55 +0000 (13:58 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Mon, 18 May 2020 15:39:22 +0000 (17:39 +0200)
Add a new field to the CLIENT_ACCESSES_BY_INDEX request to specify the
minimum number of NTP or cmdmon packets for a client to be reported.

Add -p option to the chronyc clients command to specify the threshold
(by default 0). This option can be used to minimize the number of cmdmon
requests when interested only in clients sending a large number
of requests.

candm.h
client.c
clientlog.c
clientlog.h
cmdmon.c
doc/chronyc.adoc

diff --git a/candm.h b/candm.h
index 92df80cdb5a124dde0c71ed7356280e919899c3b..9d5448cc22389f9b705b5cb4592088ca2b03f506 100644 (file)
--- a/candm.h
+++ b/candm.h
@@ -322,6 +322,7 @@ typedef struct {
 typedef struct {
   uint32_t first_index;
   uint32_t n_clients;
+  uint32_t min_hits;
   uint32_t reset;
   int32_t EOR;
 } REQ_ClientAccessesByIndex;
index 34cb6792f821bbd432db47f865368785b145a0df..b786b58f98dc3e0cdcf55daf0a9a93009073049f 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1243,7 +1243,7 @@ give_help(void)
     "\0(e.g. Sep 25, 2015 16:30:05 or 16:30:05)\0"
     "\0\0NTP access:\0\0"
     "accheck <address>\0Check whether address is allowed\0"
-    "clients [-r]\0Report on clients that have accessed the server\0"
+    "clients [-p <packets>] [-r]\0Report on clients that accessed the server\0"
     "serverstats\0Display statistics of the server\0"
     "allow [<subnet>]\0Allow access to subnet as a default\0"
     "allow all [<subnet>]\0Allow access to subnet and all children\0"
@@ -2673,18 +2673,27 @@ process_cmd_clients(char *line)
   CMD_Request request;
   CMD_Reply reply;
   IPAddr ip;
-  uint32_t i, n_clients, next_index, n_indices, reset;
+  uint32_t i, n_clients, next_index, n_indices, min_hits, reset;
   RPY_ClientAccesses_Client *client;
-  char name[50], *opt;
+  char name[50], *opt, *arg;
 
   next_index = 0;
+  min_hits = 0;
   reset = 0;
 
   while (*line) {
     opt = line;
     line = CPS_SplitWord(line);
-    if (strcmp(opt, "-r") == 0)
+    if (strcmp(opt, "-p") == 0) {
+      arg = line;
+      line = CPS_SplitWord(line);
+      if (sscanf(arg, "%"SCNu32, &min_hits) != 1) {
+        LOG(LOGS_ERR, "Invalid syntax for clients command");
+        return 0;
+      }
+    } else if (strcmp(opt, "-r") == 0) {
       reset = 1;
+    }
   }
 
   print_header("Hostname                      NTP   Drop Int IntL Last     Cmd   Drop Int  Last");
@@ -2693,6 +2702,7 @@ process_cmd_clients(char *line)
     request.command = htons(REQ_CLIENT_ACCESSES_BY_INDEX3);
     request.data.client_accesses_by_index.first_index = htonl(next_index);
     request.data.client_accesses_by_index.n_clients = htonl(MAX_CLIENT_ACCESSES);
+    request.data.client_accesses_by_index.min_hits = htonl(min_hits);
     request.data.client_accesses_by_index.reset = htonl(reset);
 
     if (!request_reply(&request, &reply, RPY_CLIENT_ACCESSES_BY_INDEX2, 0))
index 99a10744966be88fe28eca5c1a922cfd93122477..aee3c18145b4eb1a731b87a1096becb1842272fe 100644 (file)
@@ -653,11 +653,12 @@ static uint32_t get_last_ago(uint32_t x, uint32_t y)
 /* ================================================== */
 
 int
-CLG_GetClientAccessReportByIndex(int index, int reset,
+CLG_GetClientAccessReportByIndex(int index, int reset, uint32_t min_hits,
                                  RPT_ClientAccessByIndex_Report *report, struct timespec *now)
 {
   Record *record;
   uint32_t now_ts;
+  int r;
 
   if (!active || index < 0 || index >= ARR_GetSize(records))
     return 0;
@@ -667,25 +668,30 @@ CLG_GetClientAccessReportByIndex(int index, int reset,
   if (record->ip_addr.family == IPADDR_UNSPEC)
     return 0;
 
-  now_ts = get_ts_from_timespec(now);
-
-  report->ip_addr = record->ip_addr;
-  report->ntp_hits = record->ntp_hits;
-  report->cmd_hits = record->cmd_hits;
-  report->ntp_drops = record->ntp_drops;
-  report->cmd_drops = record->cmd_drops;
-  report->ntp_interval = get_interval(record->ntp_rate);
-  report->cmd_interval = get_interval(record->cmd_rate);
-  report->ntp_timeout_interval = get_interval(record->ntp_timeout_rate);
-  report->last_ntp_hit_ago = get_last_ago(now_ts, record->last_ntp_hit);
-  report->last_cmd_hit_ago = get_last_ago(now_ts, record->last_cmd_hit);
+  r = min_hits == 0 ||
+      record->ntp_hits >= min_hits || record->cmd_hits >= min_hits;
+
+  if (r) {
+    now_ts = get_ts_from_timespec(now);
+
+    report->ip_addr = record->ip_addr;
+    report->ntp_hits = record->ntp_hits;
+    report->cmd_hits = record->cmd_hits;
+    report->ntp_drops = record->ntp_drops;
+    report->cmd_drops = record->cmd_drops;
+    report->ntp_interval = get_interval(record->ntp_rate);
+    report->cmd_interval = get_interval(record->cmd_rate);
+    report->ntp_timeout_interval = get_interval(record->ntp_timeout_rate);
+    report->last_ntp_hit_ago = get_last_ago(now_ts, record->last_ntp_hit);
+    report->last_cmd_hit_ago = get_last_ago(now_ts, record->last_cmd_hit);
+  }
 
   if (reset) {
     record->ntp_hits = record->cmd_hits = 0;
     record->ntp_drops = record->cmd_drops = 0;
   }
 
-  return 1;
+  return r;
 }
 
 /* ================================================== */
index 1d0fc6a39f6a0025fe5c381a1a8d871248ffc873..e2976215194a468640235cb9331032243b33a74a 100644 (file)
@@ -44,7 +44,7 @@ extern int CLG_GetNtpMinPoll(void);
 /* And some reporting functions, for use by chronyc. */
 
 extern int CLG_GetNumberOfIndices(void);
-extern int CLG_GetClientAccessReportByIndex(int index, int reset,
+extern int CLG_GetClientAccessReportByIndex(int index, int reset, uint32_t min_hits,
                                             RPT_ClientAccessByIndex_Report *report,
                                             struct timespec *now);
 extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report);
index 341cc1d5287e3a469be6f993ab761ed05bc02b89..6d9962eea2271fe7d1404980c6d5f8199b968608 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -1002,7 +1002,7 @@ handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
   RPT_ClientAccessByIndex_Report report;
   RPY_ClientAccesses_Client *client;
   int n_indices;
-  uint32_t i, j, req_first_index, req_n_clients, req_reset;
+  uint32_t i, j, req_first_index, req_n_clients, req_min_hits, req_reset;
   struct timespec now;
 
   SCH_GetLastEventTime(&now, NULL, NULL);
@@ -1011,6 +1011,7 @@ handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
   req_n_clients = ntohl(rx_message->data.client_accesses_by_index.n_clients);
   if (req_n_clients > MAX_CLIENT_ACCESSES)
     req_n_clients = MAX_CLIENT_ACCESSES;
+  req_min_hits = ntohl(rx_message->data.client_accesses_by_index.min_hits);
   req_reset = ntohl(rx_message->data.client_accesses_by_index.reset);
 
   n_indices = CLG_GetNumberOfIndices();
@@ -1023,7 +1024,7 @@ handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
   tx_message->data.client_accesses_by_index.n_indices = htonl(n_indices);
 
   for (i = req_first_index, j = 0; i < (uint32_t)n_indices && j < req_n_clients; i++) {
-    if (!CLG_GetClientAccessReportByIndex(i, req_reset, &report, &now))
+    if (!CLG_GetClientAccessReportByIndex(i, req_reset, req_min_hits, &report, &now))
       continue;
 
     client = &tx_message->data.client_accesses_by_index.clients[j++];
index 3e5d3d3639073b76c05e29ecb08cf509e5a4ef7a..0156e9da163f6aafe2fc271a047b716e2bc3349a 100644 (file)
@@ -954,13 +954,16 @@ This command can be used to examine the effect of a series of *allow*, *allow
 all*, *deny*, and *deny all* commands specified either via *chronyc*, or in
 *chronyd*'s configuration file.
 
-[[clients]]*clients* [*-r*]::
+[[clients]]*clients* [*-p* _packets_] *[*-r*]::
 This command shows a list of clients that have accessed the server, through
 either the NTP or command ports. It does not include accesses over
 the Unix domain command socket.
 +
-If the *-r* option is specified, *chronyd* will reset the counters of received
-and dropped packets after reporting the current values.
+The *-p* option specifies the minimum number of received NTP or command
+packets needed to include a client in the list. The default value is 0, i.e.
+all clients are reported. If the *-r* option is specified, *chronyd* will reset
+the counters of received and dropped packets after reporting the current
+values.
 +
 An example of the output is:
 +