diff --git a/candm.h b/candm.h index e4eafb7..a740aa2 100644 --- a/candm.h +++ b/candm.h @@ -284,7 +284,7 @@ typedef struct { typedef struct { uint32_t first_index; - uint32_t n_indices; + uint32_t n_clients; int32_t EOR; } REQ_ClientAccessesByIndex; @@ -351,7 +351,7 @@ typedef struct { #define PROTO_VERSION_PADDING 6 /* The maximum length of padding in request packet, currently - defined by CLIENT_ACCESSES_BY_INDEX and MANUAL_LIST */ + defined by MANUAL_LIST */ #define MAX_PADDING_LENGTH 396 /* ================================================== */ @@ -545,11 +545,14 @@ typedef struct { typedef struct { IPAddr ip; - uint32_t client_hits; - uint32_t peer_hits; - uint32_t cmd_hits_auth; - uint32_t cmd_hits_normal; - uint32_t cmd_hits_bad; + uint32_t ntp_hits; + uint32_t cmd_hits; + uint16_t ntp_drops; + uint16_t cmd_drops; + int8_t ntp_interval; + int8_t cmd_interval; + int8_t ntp_timeout_interval; + int8_t pad; uint32_t last_ntp_hit_ago; uint32_t last_cmd_hit_ago; } RPY_ClientAccesses_Client; diff --git a/client.c b/client.c index cd0977c..f8f2ecf 100644 --- a/client.c +++ b/client.c @@ -2047,87 +2047,61 @@ process_cmd_clients(char *line) { CMD_Request request; CMD_Reply reply; - unsigned long next_index; - int j; IPAddr ip; - unsigned long client_hits; - unsigned long peer_hits; - unsigned long cmd_hits_auth; - unsigned long cmd_hits_normal; - unsigned long cmd_hits_bad; - unsigned long last_ntp_hit_ago; - unsigned long last_cmd_hit_ago; - char hostname_buf[50]; - - int n_replies; - int n_indices_in_table; + uint32_t i, n_clients, next_index, n_indices; + RPY_ClientAccesses_Client *client; + char hostname[26]; next_index = 0; - printf("Hostname Client Peer CmdAuth CmdNorm CmdBad LstN LstC\n" - "========================= ====== ====== ====== ====== ====== ==== ====\n"); - - do { + printf("Hostname NTP Drop Int IntL Last Cmd Drop Int Last\n" + "===============================================================================\n"); + while (1) { request.command = htons(REQ_CLIENT_ACCESSES_BY_INDEX); request.data.client_accesses_by_index.first_index = htonl(next_index); - request.data.client_accesses_by_index.n_indices = htonl(MAX_CLIENT_ACCESSES); + request.data.client_accesses_by_index.n_clients = htonl(MAX_CLIENT_ACCESSES); - if (request_reply(&request, &reply, RPY_CLIENT_ACCESSES_BY_INDEX, 0)) { - n_replies = ntohl(reply.data.client_accesses_by_index.n_clients); - n_indices_in_table = ntohl(reply.data.client_accesses_by_index.n_indices); - if (n_replies == 0) { - goto finished; - } - for (j=0; j= n_indices_in_table) { - goto finished; - } - } else { + if (!request_reply(&request, &reply, RPY_CLIENT_ACCESSES_BY_INDEX, 0)) return 0; - } - } while (1); /* keep going until all subnets have been expanded, - down to single nodes */ -finished: + n_clients = ntohl(reply.data.client_accesses_by_index.n_clients); + n_indices = ntohl(reply.data.client_accesses_by_index.n_indices); + + for (i = 0; i < n_clients && i < MAX_CLIENT_ACCESSES; i++) { + client = &reply.data.client_accesses_by_index.clients[i]; + + UTI_IPNetworkToHost(&client->ip, &ip); + + /* UNSPEC means the record could not be found in the daemon's tables. + We shouldn't ever generate this case, but ignore it if we do. */ + if (ip.family == IPADDR_UNSPEC) + continue; + + if (no_dns) + snprintf(hostname, sizeof (hostname), "%s", UTI_IPToString(&ip)); + else + DNS_IPAddress2Name(&ip, hostname, sizeof (hostname)); + + printf("%-25s", hostname); + printf(" %6"PRIu32" %5"PRIu16" %2d %2d ", + ntohl(client->ntp_hits), ntohs(client->ntp_drops), + client->ntp_interval, client->ntp_timeout_interval); + print_seconds(ntohl(client->last_ntp_hit_ago)); + printf(" %6"PRIu32" %5"PRIu16" %2d ", + ntohl(client->cmd_hits), ntohs(client->cmd_drops), + client->cmd_interval); + print_seconds(ntohl(client->last_cmd_hit_ago)); + printf("\n"); + } + + /* Set the next index to probe based on what the server tells us */ + next_index = ntohl(reply.data.client_accesses_by_index.next_index); + + if (next_index >= n_indices || n_clients < MAX_CLIENT_ACCESSES) + break; + } + return 1; } diff --git a/clientlog.c b/clientlog.c index 6f66738..66da722 100644 --- a/clientlog.c +++ b/clientlog.c @@ -481,26 +481,41 @@ CLG_LimitCommandResponseRate(int index) /* ================================================== */ -CLG_Status -CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, - time_t now, unsigned long *n_indices) +extern int +CLG_GetNumberOfIndices(void) +{ + if (!active) + return -1; + + return ARR_GetSize(records); +} + +/* ================================================== */ + +int +CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, time_t now) { Record *record; - if (!active) - return CLG_INACTIVE; + if (!active || index < 0 || index >= ARR_GetSize(records)) + return 0; - *n_indices = ARR_GetSize(records); - if (index < 0 || index >= *n_indices) - return CLG_INDEXTOOLARGE; - record = ARR_GetElement(records, index); + if (record->ip_addr.family == IPADDR_UNSPEC) + return 0; + 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 = (record->ntp_rate - RATE_SCALE / 2) / -RATE_SCALE; + report->cmd_interval = (record->cmd_rate - RATE_SCALE / 2) / -RATE_SCALE; + report->ntp_timeout_interval = + (record->ntp_timeout_rate - RATE_SCALE / 2) / -RATE_SCALE; report->last_ntp_hit_ago = now - record->last_ntp_hit; report->last_cmd_hit_ago = now - record->last_cmd_hit; - return CLG_SUCCESS; + return 1; } diff --git a/clientlog.h b/clientlog.h index a4a429f..f604676 100644 --- a/clientlog.h +++ b/clientlog.h @@ -39,18 +39,8 @@ extern int CLG_LimitNTPResponseRate(int index); extern int CLG_LimitCommandResponseRate(int index); /* And some reporting functions, for use by chronyc. */ -/* TBD */ -typedef enum { - CLG_SUCCESS, /* All is well */ - CLG_EMPTYSUBNET, /* No hosts logged in requested subnet */ - CLG_BADSUBNET, /* Subnet requested is not 0, 8, 16 or 24 bits */ - CLG_INACTIVE, /* Facility not active */ - CLG_INDEXTOOLARGE /* Node index is higher than number of nodes present */ -} CLG_Status; - -CLG_Status -CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, - time_t now, unsigned long *n_indices); +extern int CLG_GetNumberOfIndices(void); +extern int CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, time_t now); #endif /* GOT_CLIENTLOG_H */ diff --git a/cmdmon.c b/cmdmon.c index b71b657..b246900 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -1017,50 +1017,50 @@ handle_cyclelogs(CMD_Request *rx_message, CMD_Reply *tx_message) static void handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message) { - CLG_Status result; RPT_ClientAccessByIndex_Report report; - unsigned long first_index, n_indices, n_indices_in_table; - int i, j; + RPY_ClientAccesses_Client *client; + int n_indices; + uint32_t i, j, req_first_index, req_n_clients; struct timeval now; SCH_GetLastEventTime(&now, NULL, NULL); - first_index = ntohl(rx_message->data.client_accesses_by_index.first_index); - n_indices = ntohl(rx_message->data.client_accesses_by_index.n_indices); - if (n_indices > MAX_CLIENT_ACCESSES) - n_indices = MAX_CLIENT_ACCESSES; + req_first_index = ntohl(rx_message->data.client_accesses_by_index.first_index); + 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; - tx_message->reply = htons(RPY_CLIENT_ACCESSES_BY_INDEX); - - for (i = 0, j = 0; i < n_indices; i++) { - result = CLG_GetClientAccessReportByIndex(first_index + i, &report, - now.tv_sec, &n_indices_in_table); - tx_message->data.client_accesses_by_index.n_indices = htonl(n_indices_in_table); - - switch (result) { - case CLG_SUCCESS: - UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.client_accesses_by_index.clients[j].ip); - tx_message->data.client_accesses_by_index.clients[j].client_hits = htonl(report.ntp_hits); - tx_message->data.client_accesses_by_index.clients[j].peer_hits = htonl(0); - tx_message->data.client_accesses_by_index.clients[j].cmd_hits_auth = htonl(0); - tx_message->data.client_accesses_by_index.clients[j].cmd_hits_normal = htonl(report.cmd_hits); - tx_message->data.client_accesses_by_index.clients[j].cmd_hits_bad = htonl(0); - tx_message->data.client_accesses_by_index.clients[j].last_ntp_hit_ago = htonl(report.last_ntp_hit_ago); - tx_message->data.client_accesses_by_index.clients[j].last_cmd_hit_ago = htonl(report.last_cmd_hit_ago); - j++; - break; - case CLG_INDEXTOOLARGE: - break; /* ignore this index */ - case CLG_INACTIVE: - tx_message->status = htons(STT_INACTIVE); - return; - default: - assert(0); - break; - } + n_indices = CLG_GetNumberOfIndices(); + if (n_indices < 0) { + tx_message->status = htons(STT_INACTIVE); + return; } - tx_message->data.client_accesses_by_index.next_index = htonl(first_index + i); + tx_message->reply = htons(RPY_CLIENT_ACCESSES_BY_INDEX); + tx_message->data.client_accesses_by_index.n_indices = htonl(n_indices); + + memset(tx_message->data.client_accesses_by_index.clients, 0, + sizeof (tx_message->data.client_accesses_by_index.clients)); + + for (i = req_first_index, j = 0; i < (uint32_t)n_indices && j < req_n_clients; i++) { + if (!CLG_GetClientAccessReportByIndex(i, &report, now.tv_sec)) + continue; + + client = &tx_message->data.client_accesses_by_index.clients[j++]; + + UTI_IPHostToNetwork(&report.ip_addr, &client->ip); + client->ntp_hits = htonl(report.ntp_hits); + client->cmd_hits = htonl(report.cmd_hits); + client->ntp_drops = htons(report.ntp_drops); + client->cmd_drops = htons(report.cmd_drops); + client->ntp_interval = report.ntp_interval; + client->cmd_interval = report.cmd_interval; + client->ntp_timeout_interval = report.ntp_timeout_interval; + client->last_ntp_hit_ago = htonl(report.last_ntp_hit_ago); + client->last_cmd_hit_ago = htonl(report.last_cmd_hit_ago); + } + + tx_message->data.client_accesses_by_index.next_index = htonl(i); tx_message->data.client_accesses_by_index.n_clients = htonl(j); } diff --git a/pktlength.c b/pktlength.c index e123ef4..a853465 100644 --- a/pktlength.c +++ b/pktlength.c @@ -346,17 +346,7 @@ PKL_ReplyLength(CMD_Reply *r) /* No longer supported */ return 0; case RPY_CLIENT_ACCESSES_BY_INDEX: - { - unsigned long nc = ntohl(r->data.client_accesses_by_index.n_clients); - if (r->status == htons(STT_SUCCESS)) { - if (nc > MAX_CLIENT_ACCESSES) - return 0; - return (offsetof(CMD_Reply, data.client_accesses_by_index.clients) + - nc * sizeof(RPY_ClientAccesses_Client)); - } else { - return offsetof(CMD_Reply, data); - } - } + return offsetof(CMD_Reply, data.client_accesses_by_index.EOR); case RPY_MANUAL_LIST: { unsigned long ns = ntohl(r->data.manual_list.n_samples); diff --git a/reports.h b/reports.h index b124083..24881df 100644 --- a/reports.h +++ b/reports.h @@ -88,10 +88,15 @@ typedef struct { typedef struct { IPAddr ip_addr; - unsigned long ntp_hits; - unsigned long cmd_hits; - unsigned long last_ntp_hit_ago; - unsigned long last_cmd_hit_ago; + uint32_t ntp_hits; + uint32_t cmd_hits; + uint16_t ntp_drops; + uint16_t cmd_drops; + int8_t ntp_interval; + int8_t cmd_interval; + int8_t ntp_timeout_interval; + uint32_t last_ntp_hit_ago; + uint32_t last_cmd_hit_ago; } RPT_ClientAccessByIndex_Report; typedef struct {