From 273da62aecd61e8c0d7db962119ff679897b22cd Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 9 Jun 2015 12:51:49 +0200 Subject: [PATCH] cmdmon: add smoothtime command This adds a command to reset or activate the time smoothing process. --- candm.h | 14 ++++++++++++-- cmdmon.c | 34 ++++++++++++++++++++++++++++++++++ pktlength.c | 4 ++++ smooth.c | 20 ++++++++++++++------ smooth.h | 2 ++ 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/candm.h b/candm.h index 956db9e..f3bea3a 100644 --- a/candm.h +++ b/candm.h @@ -90,7 +90,8 @@ #define REQ_RESELECTDISTANCE 49 #define REQ_MODIFY_MAKESTEP 50 #define REQ_SMOOTHING 51 -#define N_REQUEST_TYPES 52 +#define REQ_SMOOTHTIME 52 +#define N_REQUEST_TYPES 53 /* Special utoken value used to log on with first exchange being the password. (This time value has long since gone by) */ @@ -297,6 +298,14 @@ typedef struct { int32_t EOR; } REQ_ReselectDistance; +#define REQ_SMOOTHTIME_RESET 0 +#define REQ_SMOOTHTIME_ACTIVATE 1 + +typedef struct { + int32_t option; + int32_t EOR; +} REQ_SmoothTime; + /* ================================================== */ #define PKT_TYPE_CMD_REQUEST 1 @@ -326,7 +335,7 @@ typedef struct { Version 6 : added padding to requests to prevent amplification attack, changed maximum number of samples in manual list to 16, new commands: modify - makestep + makestep, smoothing report, smoothtime command */ #define PROTO_VERSION_NUMBER 6 @@ -388,6 +397,7 @@ typedef struct { REQ_ClientAccessesByIndex client_accesses_by_index; REQ_ManualDelete manual_delete; REQ_ReselectDistance reselect_distance; + REQ_SmoothTime smoothtime; } data; /* Command specific parameters */ /* The following fields only set the maximum size of the packet. diff --git a/cmdmon.c b/cmdmon.c index 2d71b8d..82e6f4a 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -164,6 +164,7 @@ static const char permissions[] = { PERMIT_AUTH, /* RESELECTDISTANCE */ PERMIT_AUTH, /* MODIFY_MAKESTEP */ PERMIT_OPEN, /* SMOOTHING */ + PERMIT_AUTH, /* SMOOTHTIME */ }; /* ================================================== */ @@ -1250,6 +1251,35 @@ handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message) /* ================================================== */ +static void +handle_smoothtime(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + struct timeval now; + int option; + + if (!SMT_IsEnabled()) { + tx_message->status = htons(STT_NOTENABLED); + return; + } + + option = ntohl(rx_message->data.smoothtime.option); + SCH_GetLastEventTime(&now, NULL, NULL); + + switch (option) { + case REQ_SMOOTHTIME_RESET: + SMT_Reset(&now); + break; + case REQ_SMOOTHTIME_ACTIVATE: + SMT_Activate(&now); + break; + default: + tx_message->status = htons(STT_INVALID); + break; + } +} + +/* ================================================== */ + static void handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message) { @@ -1920,6 +1950,10 @@ read_from_cmd_socket(void *anything) handle_smoothing(&rx_message, &tx_message); break; + case REQ_SMOOTHTIME: + handle_smoothtime(&rx_message, &tx_message); + break; + case REQ_SOURCESTATS: handle_sourcestats(&rx_message, &tx_message); break; diff --git a/pktlength.c b/pktlength.c index 72c3171..be773c2 100644 --- a/pktlength.c +++ b/pktlength.c @@ -148,6 +148,8 @@ command_unpadded_length(CMD_Request *r) return offsetof(CMD_Request, data.modify_polltarget.EOR); case REQ_SMOOTHING: return offsetof(CMD_Request, data.null.EOR); + case REQ_SMOOTHTIME: + return offsetof(CMD_Request, data.smoothtime.EOR); default: /* If we fall through the switch, it most likely means we've forgotten to implement a new case */ assert(0); @@ -300,6 +302,8 @@ PKL_CommandPaddingLength(CMD_Request *r) return PADDING_LENGTH(data.modify_polltarget.EOR, data.null.EOR); case REQ_SMOOTHING: return PADDING_LENGTH(data.null.EOR, data.smoothing.EOR); + case REQ_SMOOTHTIME: + return PADDING_LENGTH(data.smoothtime.EOR, data.null.EOR); default: /* If we fall through the switch, it most likely means we've forgotten to implement a new case */ assert(0); diff --git a/smooth.c b/smooth.c index bfd7529..ae64ca3 100644 --- a/smooth.c +++ b/smooth.c @@ -199,12 +199,8 @@ update_smoothing(struct timeval *now, double offset, double freq) { /* Don't accept offset/frequency until the clock has stabilized */ if (locked) { - if (REF_GetSkew() / max_wander < UNLOCK_SKEW_WANDER_RATIO || leap_only_mode) { - LOG(LOGS_INFO, LOGF_Smooth, "Time smoothing activated%s", leap_only_mode ? - " (leap seconds only)" : ""); - locked = 0; - last_update = *now; - } + if (REF_GetSkew() / max_wander < UNLOCK_SKEW_WANDER_RATIO || leap_only_mode) + SMT_Activate(now); return; } @@ -274,6 +270,18 @@ SMT_GetOffset(struct timeval *now) return offset; } +void +SMT_Activate(struct timeval *now) +{ + if (!enabled || !locked) + return; + + LOG(LOGS_INFO, LOGF_Smooth, "Time smoothing activated%s", leap_only_mode ? + " (leap seconds only)" : ""); + locked = 0; + last_update = *now; +} + void SMT_Reset(struct timeval *now) { diff --git a/smooth.h b/smooth.h index 1cf6814..72e67af 100644 --- a/smooth.h +++ b/smooth.h @@ -37,6 +37,8 @@ extern int SMT_IsEnabled(void); extern double SMT_GetOffset(struct timeval *now); +extern void SMT_Activate(struct timeval *now); + extern void SMT_Reset(struct timeval *now); extern void SMT_Leap(struct timeval *now, int leap);