diff --git a/candm.h b/candm.h index cf7c317..af55966 100644 --- a/candm.h +++ b/candm.h @@ -91,7 +91,8 @@ #define REQ_SMOOTHING 51 #define REQ_SMOOTHTIME 52 #define REQ_REFRESH 53 -#define N_REQUEST_TYPES 54 +#define REQ_SERVER_STATS 54 +#define N_REQUEST_TYPES 55 /* Special utoken value used to log on with first exchange being the password. (This time value has long since gone by) */ @@ -433,7 +434,8 @@ typedef struct { #define RPY_MANUAL_LIST 11 #define RPY_ACTIVITY 12 #define RPY_SMOOTHING 13 -#define N_REPLY_TYPES 14 +#define RPY_SERVER_STATS 14 +#define N_REPLY_TYPES 15 /* Status codes */ #define STT_SUCCESS 0 @@ -569,6 +571,15 @@ typedef struct { int32_t EOR; } RPY_ClientAccessesByIndex; +typedef struct { + uint32_t ntp_hits; + uint32_t cmd_hits; + uint32_t ntp_drops; + uint32_t cmd_drops; + uint32_t log_drops; + int32_t EOR; +} RPY_ServerStats; + #define MAX_MANUAL_LIST_SAMPLES 16 typedef struct { @@ -630,6 +641,7 @@ typedef struct { RPY_Sourcestats sourcestats; RPY_Rtc rtc; RPY_ClientAccessesByIndex client_accesses_by_index; + RPY_ServerStats server_stats; RPY_ManualList manual_list; RPY_Activity activity; RPY_Smoothing smoothing; diff --git a/clientlog.c b/clientlog.c index 942d85e..48db784 100644 --- a/clientlog.c +++ b/clientlog.c @@ -611,3 +611,15 @@ CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *repo return 1; } + +/* ================================================== */ + +void +CLG_GetServerStatsReport(RPT_ServerStatsReport *report) +{ + report->ntp_hits = total_ntp_hits; + report->cmd_hits = total_cmd_hits; + report->ntp_drops = total_ntp_drops; + report->cmd_drops = total_cmd_drops; + report->log_drops = total_record_drops; +} diff --git a/clientlog.h b/clientlog.h index 2f68e53..6f77b35 100644 --- a/clientlog.h +++ b/clientlog.h @@ -42,5 +42,6 @@ extern int CLG_LimitCommandResponseRate(int index); extern int CLG_GetNumberOfIndices(void); extern int CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timeval *now); +extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report); #endif /* GOT_CLIENTLOG_H */ diff --git a/cmdmon.c b/cmdmon.c index 3322cb7..e5b6cd2 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -130,6 +130,7 @@ static const char permissions[] = { PERMIT_OPEN, /* SMOOTHING */ PERMIT_AUTH, /* SMOOTHTIME */ PERMIT_AUTH, /* REFRESH */ + PERMIT_AUTH, /* SERVER_STATS */ }; /* ================================================== */ @@ -1146,6 +1147,22 @@ handle_refresh(CMD_Request *rx_message, CMD_Reply *tx_message) NSR_RefreshAddresses(); } +/* ================================================== */ + +static void +handle_server_stats(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + RPT_ServerStatsReport report; + + CLG_GetServerStatsReport(&report); + tx_message->reply = htons(RPY_SERVER_STATS); + tx_message->data.server_stats.ntp_hits = htonl(report.ntp_hits); + tx_message->data.server_stats.cmd_hits = htonl(report.cmd_hits); + tx_message->data.server_stats.ntp_drops = htonl(report.ntp_drops); + tx_message->data.server_stats.cmd_drops = htonl(report.cmd_drops); + tx_message->data.server_stats.log_drops = htonl(report.log_drops); +} + /* ================================================== */ /* Read a packet and process it */ @@ -1534,6 +1551,10 @@ read_from_cmd_socket(void *anything) handle_refresh(&rx_message, &tx_message); break; + case REQ_SERVER_STATS: + handle_server_stats(&rx_message, &tx_message); + break; + default: assert(0); break; diff --git a/pktlength.c b/pktlength.c index a853465..4b24e40 100644 --- a/pktlength.c +++ b/pktlength.c @@ -152,6 +152,8 @@ command_unpadded_length(CMD_Request *r) return offsetof(CMD_Request, data.smoothtime.EOR); case REQ_REFRESH: return offsetof(CMD_Request, data.null.EOR); + case REQ_SERVER_STATS: + return offsetof(CMD_Request, data.null.EOR); default: /* If we fall through the switch, it most likely means we've forgotten to implement a new case */ assert(0); @@ -308,6 +310,8 @@ PKL_CommandPaddingLength(CMD_Request *r) return PADDING_LENGTH(data.smoothtime.EOR, data.null.EOR); case REQ_REFRESH: return PADDING_LENGTH(data.null.EOR, data.null.EOR); + case REQ_SERVER_STATS: + return PADDING_LENGTH(data.null.EOR, data.server_stats.EOR); default: /* If we fall through the switch, it most likely means we've forgotten to implement a new case */ assert(0); @@ -363,6 +367,8 @@ PKL_ReplyLength(CMD_Reply *r) return offsetof(CMD_Reply, data.activity.EOR); case RPY_SMOOTHING: return offsetof(CMD_Reply, data.smoothing.EOR); + case RPY_SERVER_STATS: + return offsetof(CMD_Reply, data.server_stats.EOR); default: assert(0); } diff --git a/reports.h b/reports.h index c6529d6..193d933 100644 --- a/reports.h +++ b/reports.h @@ -99,6 +99,14 @@ typedef struct { uint32_t last_cmd_hit_ago; } RPT_ClientAccessByIndex_Report; +typedef struct { + uint32_t ntp_hits; + uint32_t cmd_hits; + uint32_t ntp_drops; + uint32_t cmd_drops; + uint32_t log_drops; +} RPT_ServerStatsReport; + typedef struct { struct timeval when; double slewed_offset;