]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
cmdmon: allow client records to be reset
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 18 May 2020 11:28:49 +0000 (13:28 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Mon, 18 May 2020 15:39:18 +0000 (17:39 +0200)
Add a flag to the CLIENT_ACCESSES_BY_INDEX request to reset the
NTP/cmdmon hits/dropped counters after reporting the current values.

Add -r option to the chronyc clients command to perform the reset. This
should make it easier to find clients that send large number of requests
over short periods of time.

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

diff --git a/candm.h b/candm.h
index 0a0ea98fd46837692ee994e0601162afb2991541..92df80cdb5a124dde0c71ed7356280e919899c3b 100644 (file)
--- a/candm.h
+++ b/candm.h
 #define REQ_NTP_SOURCE_NAME 65
 #define REQ_RESET_SOURCES 66
 #define REQ_AUTH_DATA 67
-#define N_REQUEST_TYPES 68
+#define REQ_CLIENT_ACCESSES_BY_INDEX3 68
+#define N_REQUEST_TYPES 69
 
 /* Structure used to exchange timespecs independent of time_t size */
 typedef struct {
@@ -321,6 +322,7 @@ typedef struct {
 typedef struct {
   uint32_t first_index;
   uint32_t n_clients;
+  uint32_t reset;
   int32_t EOR;
 } REQ_ClientAccessesByIndex;
 
index 77c9184844a478ce17af34fa84881f53da381d82..34cb6792f821bbd432db47f865368785b145a0df 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\0Report on clients that have accessed the server\0"
+    "clients [-r]\0Report on clients that have 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;
+  uint32_t i, n_clients, next_index, n_indices, reset;
   RPY_ClientAccesses_Client *client;
-  char name[50];
+  char name[50], *opt;
 
   next_index = 0;
+  reset = 0;
+
+  while (*line) {
+    opt = line;
+    line = CPS_SplitWord(line);
+    if (strcmp(opt, "-r") == 0)
+      reset = 1;
+  }
 
   print_header("Hostname                      NTP   Drop Int IntL Last     Cmd   Drop Int  Last");
 
   while (1) {
-    request.command = htons(REQ_CLIENT_ACCESSES_BY_INDEX2);
+    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.reset = htonl(reset);
 
     if (!request_reply(&request, &reply, RPY_CLIENT_ACCESSES_BY_INDEX2, 0))
       return 0;
index 86962a75b256154cded77082f296d2d81c4f7787..99a10744966be88fe28eca5c1a922cfd93122477 100644 (file)
@@ -653,7 +653,8 @@ static uint32_t get_last_ago(uint32_t x, uint32_t y)
 /* ================================================== */
 
 int
-CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timespec *now)
+CLG_GetClientAccessReportByIndex(int index, int reset,
+                                 RPT_ClientAccessByIndex_Report *report, struct timespec *now)
 {
   Record *record;
   uint32_t now_ts;
@@ -679,6 +680,11 @@ CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *repo
   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;
 }
 
index 552c7671b1c552fc2b2926884fc0967858b0b8e9..1d0fc6a39f6a0025fe5c381a1a8d871248ffc873 100644 (file)
@@ -44,7 +44,9 @@ extern int CLG_GetNtpMinPoll(void);
 /* And some reporting functions, for use by chronyc. */
 
 extern int CLG_GetNumberOfIndices(void);
-extern int CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timespec *now);
+extern int CLG_GetClientAccessReportByIndex(int index, int reset,
+                                            RPT_ClientAccessByIndex_Report *report,
+                                            struct timespec *now);
 extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report);
 
 #endif /* GOT_CLIENTLOG_H */
index 9a7927f086eccb08dd21b2a9333dd5a94668d02a..341cc1d5287e3a469be6f993ab761ed05bc02b89 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -137,6 +137,7 @@ static const char permissions[] = {
   PERMIT_OPEN, /* NTP_SOURCE_NAME */
   PERMIT_AUTH, /* RESET_SOURCES */
   PERMIT_AUTH, /* AUTH_DATA */
+  PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX3 */
 };
 
 /* ================================================== */
@@ -1001,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;
+  uint32_t i, j, req_first_index, req_n_clients, req_reset;
   struct timespec now;
 
   SCH_GetLastEventTime(&now, NULL, NULL);
@@ -1010,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_reset = ntohl(rx_message->data.client_accesses_by_index.reset);
 
   n_indices = CLG_GetNumberOfIndices();
   if (n_indices < 0) {
@@ -1021,7 +1023,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, &report, &now))
+    if (!CLG_GetClientAccessReportByIndex(i, req_reset, &report, &now))
       continue;
 
     client = &tx_message->data.client_accesses_by_index.clients[j++];
@@ -1594,7 +1596,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
           handle_cyclelogs(&rx_message, &tx_message);
           break;
 
-        case REQ_CLIENT_ACCESSES_BY_INDEX2:
+        case REQ_CLIENT_ACCESSES_BY_INDEX3:
           handle_client_accesses_by_index(&rx_message, &tx_message);
           break;
 
index 514a95fae1cbb740b2f701991d89dc5ea3117147..3e5d3d3639073b76c05e29ecb08cf509e5a4ef7a 100644 (file)
@@ -954,10 +954,13 @@ 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*::
+[[clients]]*clients* [*-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. There are no arguments.
+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.
 +
 An example of the output is:
 +
index 69032db29e7405ad8f1ea7bda28007d8148d65a3..3a7b2ea5dfd804f3a7e75f49d92d3e4d9a323bd0 100644 (file)
@@ -110,8 +110,7 @@ static const struct request_length request_lengths[] = {
   REQ_LENGTH_ENTRY(smoothtime, null),           /* SMOOTHTIME */
   REQ_LENGTH_ENTRY(null, null),                 /* REFRESH */
   REQ_LENGTH_ENTRY(null, server_stats),         /* SERVER_STATS */
-  REQ_LENGTH_ENTRY(client_accesses_by_index,
-                   client_accesses_by_index),   /* CLIENT_ACCESSES_BY_INDEX2 */
+  { 0, 0 },                                     /* CLIENT_ACCESSES_BY_INDEX2 - not supported */
   REQ_LENGTH_ENTRY(local, null),                /* LOCAL2 */
   REQ_LENGTH_ENTRY(ntp_data, ntp_data),         /* NTP_DATA */
   { 0, 0 },                                     /* ADD_SERVER2 */
@@ -125,6 +124,8 @@ static const struct request_length request_lengths[] = {
                    ntp_source_name),            /* NTP_SOURCE_NAME */
   REQ_LENGTH_ENTRY(null, null),                 /* RESET_SOURCES */
   REQ_LENGTH_ENTRY(auth_data, auth_data),       /* AUTH_DATA */
+  REQ_LENGTH_ENTRY(client_accesses_by_index,
+                   client_accesses_by_index),   /* CLIENT_ACCESSES_BY_INDEX3 */
 };
 
 static const uint16_t reply_lengths[] = {