cmdmon: add ntpdata command
This commit is contained in:
parent
7255f9ef74
commit
535ca64bba
11 changed files with 205 additions and 2 deletions
45
candm.h
45
candm.h
|
@ -94,7 +94,8 @@
|
|||
#define REQ_SERVER_STATS 54
|
||||
#define REQ_CLIENT_ACCESSES_BY_INDEX2 55
|
||||
#define REQ_LOCAL2 56
|
||||
#define N_REQUEST_TYPES 57
|
||||
#define REQ_NTP_DATA 57
|
||||
#define N_REQUEST_TYPES 58
|
||||
|
||||
/* Structure used to exchange timespecs independent of time_t size */
|
||||
typedef struct {
|
||||
|
@ -310,6 +311,11 @@ typedef struct {
|
|||
int32_t EOR;
|
||||
} REQ_SmoothTime;
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip_addr;
|
||||
int32_t EOR;
|
||||
} REQ_NTPData;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#define PKT_TYPE_CMD_REQUEST 1
|
||||
|
@ -410,6 +416,7 @@ typedef struct {
|
|||
REQ_ManualDelete manual_delete;
|
||||
REQ_ReselectDistance reselect_distance;
|
||||
REQ_SmoothTime smoothtime;
|
||||
REQ_NTPData ntp_data;
|
||||
} data; /* Command specific parameters */
|
||||
|
||||
/* Padding used to prevent traffic amplification. It only defines the
|
||||
|
@ -443,7 +450,8 @@ typedef struct {
|
|||
#define RPY_SMOOTHING 13
|
||||
#define RPY_SERVER_STATS 14
|
||||
#define RPY_CLIENT_ACCESSES_BY_INDEX2 15
|
||||
#define N_REPLY_TYPES 16
|
||||
#define RPY_NTP_DATA 16
|
||||
#define N_REPLY_TYPES 17
|
||||
|
||||
/* Status codes */
|
||||
#define STT_SUCCESS 0
|
||||
|
@ -625,6 +633,38 @@ typedef struct {
|
|||
int32_t EOR;
|
||||
} RPY_Smoothing;
|
||||
|
||||
#define RPY_NTP_FLAGS_TESTS 0x3ff
|
||||
#define RPY_NTP_FLAG_INTERLEAVED 0x4000
|
||||
#define RPY_NTP_FLAG_AUTHENTICATED 0x8000
|
||||
|
||||
typedef struct {
|
||||
IPAddr remote_addr;
|
||||
IPAddr local_addr;
|
||||
uint16_t remote_port;
|
||||
uint8_t leap;
|
||||
uint8_t version;
|
||||
uint8_t mode;
|
||||
uint8_t stratum;
|
||||
int8_t poll;
|
||||
int8_t precision;
|
||||
Float root_delay;
|
||||
Float root_dispersion;
|
||||
uint32_t ref_id;
|
||||
Timespec ref_time;
|
||||
Float offset;
|
||||
Float peer_delay;
|
||||
Float peer_dispersion;
|
||||
Float response_time;
|
||||
Float jitter_asymmetry;
|
||||
uint16_t flags;
|
||||
uint8_t tx_tss_char;
|
||||
uint8_t rx_tss_char;
|
||||
uint32_t total_tx_count;
|
||||
uint32_t total_rx_count;
|
||||
uint32_t total_valid_count;
|
||||
int32_t EOR;
|
||||
} RPY_NTPData;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version;
|
||||
uint8_t pkt_type;
|
||||
|
@ -653,6 +693,7 @@ typedef struct {
|
|||
RPY_ManualList manual_list;
|
||||
RPY_Activity activity;
|
||||
RPY_Smoothing smoothing;
|
||||
RPY_NTPData ntp_data;
|
||||
} data; /* Reply specific parameters */
|
||||
|
||||
} CMD_Reply;
|
||||
|
|
48
cmdmon.c
48
cmdmon.c
|
@ -133,6 +133,7 @@ static const char permissions[] = {
|
|||
PERMIT_AUTH, /* SERVER_STATS */
|
||||
PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX2 */
|
||||
PERMIT_AUTH, /* LOCAL2 */
|
||||
PERMIT_AUTH, /* NTP_DATA */
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -1186,6 +1187,49 @@ handle_server_stats(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
tx_message->data.server_stats.log_drops = htonl(report.log_drops);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_ntp_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
RPT_NTPReport report;
|
||||
|
||||
UTI_IPNetworkToHost(&rx_message->data.ntp_data.ip_addr, &report.remote_addr);
|
||||
|
||||
if (!NSR_GetNTPReport(&report)) {
|
||||
tx_message->status = htons(STT_NOSUCHSOURCE);
|
||||
return;
|
||||
}
|
||||
|
||||
tx_message->reply = htons(RPY_NTP_DATA);
|
||||
UTI_IPHostToNetwork(&report.remote_addr, &tx_message->data.ntp_data.remote_addr);
|
||||
UTI_IPHostToNetwork(&report.local_addr, &tx_message->data.ntp_data.local_addr);
|
||||
tx_message->data.ntp_data.remote_port = htons(report.remote_port);
|
||||
tx_message->data.ntp_data.leap = report.leap;
|
||||
tx_message->data.ntp_data.version = report.version;
|
||||
tx_message->data.ntp_data.mode = report.mode;
|
||||
tx_message->data.ntp_data.stratum = report.stratum;
|
||||
tx_message->data.ntp_data.poll = report.poll;
|
||||
tx_message->data.ntp_data.precision = report.precision;
|
||||
tx_message->data.ntp_data.root_delay = UTI_FloatHostToNetwork(report.root_delay);
|
||||
tx_message->data.ntp_data.root_dispersion = UTI_FloatHostToNetwork(report.root_dispersion);
|
||||
tx_message->data.ntp_data.ref_id = htonl(report.ref_id);
|
||||
UTI_TimespecHostToNetwork(&report.ref_time, &tx_message->data.ntp_data.ref_time);
|
||||
tx_message->data.ntp_data.offset = UTI_FloatHostToNetwork(report.offset);
|
||||
tx_message->data.ntp_data.peer_delay = UTI_FloatHostToNetwork(report.peer_delay);
|
||||
tx_message->data.ntp_data.peer_dispersion = UTI_FloatHostToNetwork(report.peer_dispersion);
|
||||
tx_message->data.ntp_data.response_time = UTI_FloatHostToNetwork(report.response_time);
|
||||
tx_message->data.ntp_data.jitter_asymmetry = UTI_FloatHostToNetwork(report.jitter_asymmetry);
|
||||
tx_message->data.ntp_data.flags = htons((report.tests & RPY_NTP_FLAGS_TESTS) |
|
||||
(report.interleaved ? RPY_NTP_FLAG_INTERLEAVED : 0) |
|
||||
(report.authenticated ? RPY_NTP_FLAG_AUTHENTICATED : 0));
|
||||
tx_message->data.ntp_data.tx_tss_char = report.tx_tss_char;
|
||||
tx_message->data.ntp_data.rx_tss_char = report.rx_tss_char;
|
||||
tx_message->data.ntp_data.total_tx_count = htonl(report.total_tx_count);
|
||||
tx_message->data.ntp_data.total_rx_count = htonl(report.total_rx_count);
|
||||
tx_message->data.ntp_data.total_valid_count = htonl(report.total_valid_count);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Read a packet and process it */
|
||||
|
||||
|
@ -1573,6 +1617,10 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
|
|||
handle_server_stats(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
case REQ_NTP_DATA:
|
||||
handle_ntp_data(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_LOG(LOGF_CmdMon, "Unhandled command %d", rx_command);
|
||||
tx_message.status = htons(STT_FAILED);
|
||||
|
|
44
ntp_core.c
44
ntp_core.c
|
@ -186,6 +186,8 @@ struct NCR_Instance_Record {
|
|||
int burst_good_samples_to_go;
|
||||
int burst_total_samples_to_go;
|
||||
|
||||
/* Report from last valid response */
|
||||
RPT_NTPReport report;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -558,6 +560,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
|
|||
result->local_tx.source = NTP_TS_DAEMON;
|
||||
result->burst_good_samples_to_go = 0;
|
||||
result->burst_total_samples_to_go = 0;
|
||||
memset(&result->report, 0, sizeof (result->report));
|
||||
|
||||
NCR_ResetInstance(result);
|
||||
|
||||
|
@ -1073,6 +1076,8 @@ transmit_timeout(void *arg)
|
|||
++inst->tx_count;
|
||||
inst->valid_rx = 0;
|
||||
inst->updated_timestamps = 0;
|
||||
if (sent)
|
||||
inst->report.total_tx_count++;
|
||||
|
||||
/* If the source loses connectivity and our packets are still being sent,
|
||||
back off the sampling rate to reduce the network traffic. If it's the
|
||||
|
@ -1284,6 +1289,8 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
|
|||
|
||||
stats = SRC_GetSourcestats(inst->source);
|
||||
|
||||
inst->report.total_rx_count++;
|
||||
|
||||
pkt_leap = NTP_LVM_TO_LEAP(message->lvm);
|
||||
pkt_refid = ntohl(message->reference_id);
|
||||
pkt_root_delay = UTI_Ntp32ToDouble(message->root_delay);
|
||||
|
@ -1585,6 +1592,35 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
|
|||
assert(inst->tx_timeout_id);
|
||||
restart_timeout(inst, delay_time);
|
||||
}
|
||||
|
||||
/* Update the NTP report */
|
||||
inst->report.remote_addr = inst->remote_addr.ip_addr;
|
||||
inst->report.local_addr = inst->local_addr.ip_addr;
|
||||
inst->report.remote_port = inst->remote_addr.port;
|
||||
inst->report.leap = NTP_LVM_TO_LEAP(message->lvm);
|
||||
inst->report.version = NTP_LVM_TO_VERSION(message->lvm);
|
||||
inst->report.mode = NTP_LVM_TO_MODE(message->lvm);
|
||||
inst->report.stratum = message->stratum;
|
||||
inst->report.poll = message->poll;
|
||||
inst->report.precision = message->precision;
|
||||
inst->report.root_delay = pkt_root_delay;
|
||||
inst->report.root_dispersion = pkt_root_dispersion;
|
||||
inst->report.ref_id = pkt_refid;
|
||||
UTI_Ntp64ToTimespec(&message->reference_ts, &inst->report.ref_time);
|
||||
inst->report.offset = offset;
|
||||
inst->report.peer_delay = delay;
|
||||
inst->report.peer_dispersion = dispersion;
|
||||
inst->report.response_time = server_interval;
|
||||
inst->report.jitter_asymmetry = SST_GetJitterAsymmetry(stats);
|
||||
inst->report.tests = ((((((((test1 << 1 | test2) << 1 | test3) << 1 |
|
||||
test5) << 1 | test6) << 1 | test7) << 1 |
|
||||
testA) << 1 | testB) << 1 | testC) << 1 | testD;
|
||||
inst->report.interleaved = interleaved_packet;
|
||||
inst->report.authenticated = inst->auth_mode != AUTH_NONE;
|
||||
inst->report.tx_tss_char = tss_chars[inst->local_tx.source];
|
||||
inst->report.rx_tss_char = tss_chars[sample_rx_tss];
|
||||
|
||||
inst->report.total_valid_count++;
|
||||
}
|
||||
|
||||
/* Do measurement logging */
|
||||
|
@ -2140,6 +2176,14 @@ NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timespec *n
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
NCR_GetNTPReport(NCR_Instance inst, RPT_NTPReport *report)
|
||||
{
|
||||
*report = inst->report;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
|
||||
{
|
||||
|
|
|
@ -123,6 +123,7 @@ extern void NCR_ModifyPolltarget(NCR_Instance inst, int new_poll_target);
|
|||
extern void NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_samples);
|
||||
|
||||
extern void NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timespec *now);
|
||||
extern void NCR_GetNTPReport(NCR_Instance inst, RPT_NTPReport *report);
|
||||
|
||||
extern int NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int NCR_CheckAccessRestriction(IPAddr *ip_addr);
|
||||
|
|
|
@ -1120,6 +1120,26 @@ NSR_ReportSource(RPT_SourceReport *report, struct timespec *now)
|
|||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* The ip address is assumed to be completed on input, that is how we
|
||||
identify the source record. */
|
||||
|
||||
int
|
||||
NSR_GetNTPReport(RPT_NTPReport *report)
|
||||
{
|
||||
NTP_Remote_Address rem_addr;
|
||||
int slot, found;
|
||||
|
||||
rem_addr.ip_addr = report->remote_addr;
|
||||
rem_addr.port = 0;
|
||||
find_slot(&rem_addr, &slot, &found);
|
||||
if (!found)
|
||||
return 0;
|
||||
|
||||
NCR_GetNTPReport(get_record(slot)->data, report);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
|
|
|
@ -129,6 +129,8 @@ extern int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, IPAd
|
|||
|
||||
extern void NSR_ReportSource(RPT_SourceReport *report, struct timespec *now);
|
||||
|
||||
extern int NSR_GetNTPReport(RPT_NTPReport *report);
|
||||
|
||||
extern void NSR_GetActivityReport(RPT_ActivityReport *report);
|
||||
|
||||
#endif /* GOT_NTP_SOURCES_H */
|
||||
|
|
|
@ -113,6 +113,7 @@ static const struct request_length request_lengths[] = {
|
|||
REQ_LENGTH_ENTRY(client_accesses_by_index,
|
||||
client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX2 */
|
||||
REQ_LENGTH_ENTRY(local, null), /* LOCAL2 */
|
||||
REQ_LENGTH_ENTRY(ntp_data, ntp_data), /* NTP_DATA */
|
||||
};
|
||||
|
||||
static const uint16_t reply_lengths[] = {
|
||||
|
@ -132,6 +133,7 @@ static const uint16_t reply_lengths[] = {
|
|||
RPY_LENGTH_ENTRY(smoothing), /* SMOOTHING */
|
||||
RPY_LENGTH_ENTRY(server_stats), /* SERVER_STATS */
|
||||
RPY_LENGTH_ENTRY(client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX2 */
|
||||
RPY_LENGTH_ENTRY(ntp_data), /* NTP_DATA */
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
|
|
29
reports.h
29
reports.h
|
@ -131,4 +131,33 @@ typedef struct {
|
|||
double remaining_time;
|
||||
} RPT_SmoothingReport;
|
||||
|
||||
typedef struct {
|
||||
IPAddr remote_addr;
|
||||
IPAddr local_addr;
|
||||
uint16_t remote_port;
|
||||
uint8_t leap;
|
||||
uint8_t version;
|
||||
uint8_t mode;
|
||||
uint8_t stratum;
|
||||
int8_t poll;
|
||||
int8_t precision;
|
||||
double root_delay;
|
||||
double root_dispersion;
|
||||
uint32_t ref_id;
|
||||
struct timespec ref_time;
|
||||
double offset;
|
||||
double peer_delay;
|
||||
double peer_dispersion;
|
||||
double response_time;
|
||||
double jitter_asymmetry;
|
||||
uint16_t tests;
|
||||
int interleaved;
|
||||
int authenticated;
|
||||
char tx_tss_char;
|
||||
char rx_tss_char;
|
||||
uint32_t total_tx_count;
|
||||
uint32_t total_rx_count;
|
||||
uint32_t total_valid_count;
|
||||
} RPT_NTPReport;
|
||||
|
||||
#endif /* GOT_REPORTS_H */
|
||||
|
|
|
@ -994,3 +994,11 @@ SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct ti
|
|||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
SST_GetJitterAsymmetry(SST_Stats inst)
|
||||
{
|
||||
return inst->asymmetry;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -139,5 +139,7 @@ extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *repor
|
|||
|
||||
extern int SST_Samples(SST_Stats inst);
|
||||
|
||||
extern double SST_GetJitterAsymmetry(SST_Stats inst);
|
||||
|
||||
#endif /* GOT_SOURCESTATS_H */
|
||||
|
||||
|
|
6
stubs.c
6
stubs.c
|
@ -297,6 +297,12 @@ NSR_ReportSource(RPT_SourceReport *report, struct timespec *now)
|
|||
memset(report, 0, sizeof (*report));
|
||||
}
|
||||
|
||||
int
|
||||
NSR_GetNTPReport(RPT_NTPReport *report)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
NSR_GetActivityReport(RPT_ActivityReport *report)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue