#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) */
#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
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 {
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;
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;
+}
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 */
PERMIT_OPEN, /* SMOOTHING */
PERMIT_AUTH, /* SMOOTHTIME */
PERMIT_AUTH, /* REFRESH */
+ PERMIT_AUTH, /* SERVER_STATS */
};
/* ================================================== */
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 */
handle_refresh(&rx_message, &tx_message);
break;
+ case REQ_SERVER_STATS:
+ handle_server_stats(&rx_message, &tx_message);
+ break;
+
default:
assert(0);
break;
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);
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);
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);
}
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;