cmdmon: limit reported clients by number of packets
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.
This commit is contained in:
parent
ee2220f2e7
commit
28cf4acf13
6 changed files with 44 additions and 23 deletions
1
candm.h
1
candm.h
|
@ -322,6 +322,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t first_index;
|
uint32_t first_index;
|
||||||
uint32_t n_clients;
|
uint32_t n_clients;
|
||||||
|
uint32_t min_hits;
|
||||||
uint32_t reset;
|
uint32_t reset;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_ClientAccessesByIndex;
|
} REQ_ClientAccessesByIndex;
|
||||||
|
|
18
client.c
18
client.c
|
@ -1243,7 +1243,7 @@ give_help(void)
|
||||||
"\0(e.g. Sep 25, 2015 16:30:05 or 16:30:05)\0"
|
"\0(e.g. Sep 25, 2015 16:30:05 or 16:30:05)\0"
|
||||||
"\0\0NTP access:\0\0"
|
"\0\0NTP access:\0\0"
|
||||||
"accheck <address>\0Check whether address is allowed\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"
|
"serverstats\0Display statistics of the server\0"
|
||||||
"allow [<subnet>]\0Allow access to subnet as a default\0"
|
"allow [<subnet>]\0Allow access to subnet as a default\0"
|
||||||
"allow all [<subnet>]\0Allow access to subnet and all children\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_Request request;
|
||||||
CMD_Reply reply;
|
CMD_Reply reply;
|
||||||
IPAddr ip;
|
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;
|
RPY_ClientAccesses_Client *client;
|
||||||
char name[50], *opt;
|
char name[50], *opt, *arg;
|
||||||
|
|
||||||
next_index = 0;
|
next_index = 0;
|
||||||
|
min_hits = 0;
|
||||||
reset = 0;
|
reset = 0;
|
||||||
|
|
||||||
while (*line) {
|
while (*line) {
|
||||||
opt = line;
|
opt = line;
|
||||||
line = CPS_SplitWord(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;
|
reset = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_header("Hostname NTP Drop Int IntL Last Cmd Drop Int Last");
|
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.command = htons(REQ_CLIENT_ACCESSES_BY_INDEX3);
|
||||||
request.data.client_accesses_by_index.first_index = htonl(next_index);
|
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.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);
|
request.data.client_accesses_by_index.reset = htonl(reset);
|
||||||
|
|
||||||
if (!request_reply(&request, &reply, RPY_CLIENT_ACCESSES_BY_INDEX2, 0))
|
if (!request_reply(&request, &reply, RPY_CLIENT_ACCESSES_BY_INDEX2, 0))
|
||||||
|
|
32
clientlog.c
32
clientlog.c
|
@ -653,11 +653,12 @@ static uint32_t get_last_ago(uint32_t x, uint32_t y)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
CLG_GetClientAccessReportByIndex(int index, int reset,
|
CLG_GetClientAccessReportByIndex(int index, int reset, uint32_t min_hits,
|
||||||
RPT_ClientAccessByIndex_Report *report, struct timespec *now)
|
RPT_ClientAccessByIndex_Report *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
Record *record;
|
Record *record;
|
||||||
uint32_t now_ts;
|
uint32_t now_ts;
|
||||||
|
int r;
|
||||||
|
|
||||||
if (!active || index < 0 || index >= ARR_GetSize(records))
|
if (!active || index < 0 || index >= ARR_GetSize(records))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -667,25 +668,30 @@ CLG_GetClientAccessReportByIndex(int index, int reset,
|
||||||
if (record->ip_addr.family == IPADDR_UNSPEC)
|
if (record->ip_addr.family == IPADDR_UNSPEC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
now_ts = get_ts_from_timespec(now);
|
r = min_hits == 0 ||
|
||||||
|
record->ntp_hits >= min_hits || record->cmd_hits >= min_hits;
|
||||||
|
|
||||||
report->ip_addr = record->ip_addr;
|
if (r) {
|
||||||
report->ntp_hits = record->ntp_hits;
|
now_ts = get_ts_from_timespec(now);
|
||||||
report->cmd_hits = record->cmd_hits;
|
|
||||||
report->ntp_drops = record->ntp_drops;
|
report->ip_addr = record->ip_addr;
|
||||||
report->cmd_drops = record->cmd_drops;
|
report->ntp_hits = record->ntp_hits;
|
||||||
report->ntp_interval = get_interval(record->ntp_rate);
|
report->cmd_hits = record->cmd_hits;
|
||||||
report->cmd_interval = get_interval(record->cmd_rate);
|
report->ntp_drops = record->ntp_drops;
|
||||||
report->ntp_timeout_interval = get_interval(record->ntp_timeout_rate);
|
report->cmd_drops = record->cmd_drops;
|
||||||
report->last_ntp_hit_ago = get_last_ago(now_ts, record->last_ntp_hit);
|
report->ntp_interval = get_interval(record->ntp_rate);
|
||||||
report->last_cmd_hit_ago = get_last_ago(now_ts, record->last_cmd_hit);
|
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) {
|
if (reset) {
|
||||||
record->ntp_hits = record->cmd_hits = 0;
|
record->ntp_hits = record->cmd_hits = 0;
|
||||||
record->ntp_drops = record->cmd_drops = 0;
|
record->ntp_drops = record->cmd_drops = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
|
@ -44,7 +44,7 @@ extern int CLG_GetNtpMinPoll(void);
|
||||||
/* And some reporting functions, for use by chronyc. */
|
/* And some reporting functions, for use by chronyc. */
|
||||||
|
|
||||||
extern int CLG_GetNumberOfIndices(void);
|
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,
|
RPT_ClientAccessByIndex_Report *report,
|
||||||
struct timespec *now);
|
struct timespec *now);
|
||||||
extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report);
|
extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report);
|
||||||
|
|
5
cmdmon.c
5
cmdmon.c
|
@ -1002,7 +1002,7 @@ handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
RPT_ClientAccessByIndex_Report report;
|
RPT_ClientAccessByIndex_Report report;
|
||||||
RPY_ClientAccesses_Client *client;
|
RPY_ClientAccesses_Client *client;
|
||||||
int n_indices;
|
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;
|
struct timespec now;
|
||||||
|
|
||||||
SCH_GetLastEventTime(&now, NULL, NULL);
|
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);
|
req_n_clients = ntohl(rx_message->data.client_accesses_by_index.n_clients);
|
||||||
if (req_n_clients > MAX_CLIENT_ACCESSES)
|
if (req_n_clients > MAX_CLIENT_ACCESSES)
|
||||||
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);
|
req_reset = ntohl(rx_message->data.client_accesses_by_index.reset);
|
||||||
|
|
||||||
n_indices = CLG_GetNumberOfIndices();
|
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);
|
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++) {
|
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;
|
continue;
|
||||||
|
|
||||||
client = &tx_message->data.client_accesses_by_index.clients[j++];
|
client = &tx_message->data.client_accesses_by_index.clients[j++];
|
||||||
|
|
|
@ -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
|
all*, *deny*, and *deny all* commands specified either via *chronyc*, or in
|
||||||
*chronyd*'s configuration file.
|
*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
|
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
|
either the NTP or command ports. It does not include accesses over
|
||||||
the Unix domain command socket.
|
the Unix domain command socket.
|
||||||
+
|
+
|
||||||
If the *-r* option is specified, *chronyd* will reset the counters of received
|
The *-p* option specifies the minimum number of received NTP or command
|
||||||
and dropped packets after reporting the current values.
|
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:
|
An example of the output is:
|
||||||
+
|
+
|
||||||
|
|
Loading…
Reference in a new issue