diff --git a/candm.h b/candm.h index 52f58d3..0abda60 100644 --- a/candm.h +++ b/candm.h @@ -92,6 +92,16 @@ password. (This time value has long since gone by) */ #define SPECIAL_UTOKEN 0x10101010 +/* Structure used to exchange timevals independent on size of time_t */ +typedef struct { + uint32_t tv_sec_high; + uint32_t tv_sec_low; + uint32_t tv_usec; +} Timeval; + +/* This is used in tv_sec_high for 32-bit timestamps */ +#define TV_NOHIGHSEC 0x7fffffff + /* The EOR (end of record) fields are used by the offsetof operator in pktlength.c, to get the number of bytes that ought to be transmitted for each packet type. */ @@ -151,12 +161,12 @@ typedef struct { } REQ_Modify_Maxupdateskew; typedef struct { - struct timeval ts; + Timeval ts; int32_t EOR; } REQ_Logon; typedef struct { - struct timeval ts; + Timeval ts; int32_t EOR; } REQ_Settime; @@ -311,7 +321,7 @@ typedef struct { Version 3 : NTP_Source message lengthened (auto_offline) - Version 4 : IPv6 addressing added + Version 4 : IPv6 addressing added, 64-bit time values */ @@ -463,8 +473,7 @@ typedef struct { typedef struct { uint32_t ref_id; uint32_t stratum; - uint32_t ref_time_s; - uint32_t ref_time_us; + Timeval ref_time; uint32_t current_correction_s; uint32_t current_correction_us; int32_t freq_ppm; @@ -487,7 +496,7 @@ typedef struct { } RPY_Sourcestats; typedef struct { - uint32_t ref_time; + Timeval ref_time; uint16_t n_samples; uint16_t n_runs; uint32_t span_seconds; @@ -540,7 +549,7 @@ typedef struct { #define MAX_MANUAL_LIST_SAMPLES 32 typedef struct { - uint32_t when; + Timeval when; int32_t slewed_offset; int32_t orig_offset; int32_t residual; diff --git a/client.c b/client.c index de074e1..4059fe3 100644 --- a/client.c +++ b/client.c @@ -1030,6 +1030,7 @@ process_cmd_password(CMD_Request *msg, char *line) char *p, *q; char *password; struct timezone tz; + struct timeval now; p = line; while (*p && isspace((unsigned char)*p)) @@ -1062,13 +1063,12 @@ process_cmd_password(CMD_Request *msg, char *line) *p = 0; } - if (gettimeofday(&msg->data.logon.ts, &tz) < 0) { + if (gettimeofday(&now, &tz) < 0) { printf("500 - Could not read time of day\n"); return 0; } else { msg->command = htons(REQ_LOGON); /* Just force a round trip so that we get tokens etc */ - msg->data.logon.ts.tv_sec = htonl(msg->data.logon.ts.tv_sec); - msg->data.logon.ts.tv_usec = htonl(msg->data.logon.ts.tv_usec); + UTI_TimevalHostToNetwork(&now, &msg->data.logon.ts); return 1; } } @@ -1713,8 +1713,7 @@ process_cmd_tracking(char *line) a, b, c, d, ""); //* TODO (no_dns) ? UTI_IPToDottedQuad(ref_id) : DNS_IPAddress2Name(ref_id)); */ printf("Stratum : %lu\n", (unsigned long) ntohl(reply.data.tracking.stratum)); - ref_time.tv_sec = ntohl(reply.data.tracking.ref_time_s); - ref_time.tv_usec = ntohl(reply.data.tracking.ref_time_us); + UTI_TimevalNetworkToHost(&reply.data.tracking.ref_time, &ref_time); ref_time_tm = *gmtime((time_t *)&ref_time.tv_sec); printf("Ref time (UTC) : %s", asctime(&ref_time_tm)); correction_tv.tv_sec = (int32_t)ntohl(reply.data.tracking.current_correction_s); @@ -1746,7 +1745,7 @@ process_cmd_rtcreport(char *line) int auth_ok; CMD_Request request; CMD_Reply reply; - time_t ref_time; + struct timeval ref_time; struct tm ref_time_tm; unsigned short n_samples; unsigned short n_runs; @@ -1775,8 +1774,8 @@ process_cmd_rtcreport(char *line) default: break; } - ref_time = (time_t) ntohl(reply.data.rtc.ref_time); - ref_time_tm = *gmtime(&ref_time); + UTI_TimevalNetworkToHost(&reply.data.rtc.ref_time, &ref_time); + ref_time_tm = *gmtime(&ref_time.tv_sec); n_samples = ntohs(reply.data.rtc.n_samples); n_runs = ntohs(reply.data.rtc.n_runs); span_seconds = ntohl(reply.data.rtc.span_seconds); @@ -2170,7 +2169,7 @@ process_cmd_manual_list(const char *line) int n_samples; RPY_ManualListSample *sample; int i; - time_t when; + struct timeval when; double slewed_offset, orig_offset, residual; request.command = htons(REQ_MANUAL_LIST); @@ -2186,11 +2185,11 @@ process_cmd_manual_list(const char *line) "====================================================\n"); for (i=0; iwhen); + UTI_TimevalNetworkToHost(&sample->when, &when); slewed_offset = WIRE2REAL(sample->slewed_offset); orig_offset = WIRE2REAL(sample->orig_offset); residual = WIRE2REAL(sample->residual); - printf("%2d %s %10.2f %10.2f %10.2f\n", i, time_to_log_form(when), slewed_offset, orig_offset, residual); + printf("%2d %s %10.2f %10.2f %10.2f\n", i, time_to_log_form(when.tv_sec), slewed_offset, orig_offset, residual); } break; case STT_NOHOSTACCESS: @@ -2251,6 +2250,7 @@ process_cmd_manual_delete(const char *line) static void process_cmd_settime(char *line) { + struct timeval ts; time_t now, new_time; CMD_Request request; CMD_Reply reply; @@ -2266,8 +2266,9 @@ process_cmd_settime(char *line) if (new_time == -1) { printf("510 - Could not parse date string\n"); } else { - request.data.settime.ts.tv_sec = htonl(new_time); - request.data.settime.ts.tv_usec = htonl(0); + ts.tv_sec = new_time; + ts.tv_usec = 0; + UTI_TimevalHostToNetwork(&ts, &request.data.settime.ts); request.command = htons(REQ_SETTIME); submit_ok = submit_request(&request, &reply, &reply_auth_ok); if (submit_ok) { diff --git a/cmdmon.c b/cmdmon.c index 0408755..ca80255 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -535,22 +535,17 @@ check_unique_ts(struct timeval *ts, struct timeval *now) static int ts_is_unique_and_not_stale(struct timeval *ts, struct timeval *now) { - long tv_sec; - struct timeval host_order_ts; int within_margin=0; int is_unique=0; long diff; - host_order_ts.tv_sec = tv_sec = ntohl(ts->tv_sec); - host_order_ts.tv_usec = ntohl(ts->tv_usec); - - diff = now->tv_sec - tv_sec; + diff = now->tv_sec - ts->tv_sec; if ((diff < TS_MARGIN) && (diff > -TS_MARGIN)) { within_margin = 1; } else { within_margin = 0; } - is_unique = check_unique_ts(&host_order_ts, now); + is_unique = check_unique_ts(ts, now); return within_margin && is_unique; } @@ -919,8 +914,7 @@ handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message) struct timeval ts; long offset_cs; double dfreq_ppm, new_afreq_ppm; - ts.tv_sec = ntohl(rx_message->data.settime.ts.tv_sec); - ts.tv_usec = ntohl(rx_message->data.settime.ts.tv_usec); + UTI_TimevalNetworkToHost(&rx_message->data.settime.ts, &ts); if (MNL_AcceptTimestamp(&ts, &offset_cs, &dfreq_ppm, &new_afreq_ppm)) { tx_message->status = htons(STT_SUCCESS); tx_message->reply = htons(RPY_MANUAL_TIMESTAMP); @@ -1377,8 +1371,7 @@ handle_tracking(CMD_Request *rx_message, CMD_Reply *tx_message) tx_message->reply = htons(RPY_TRACKING); tx_message->data.tracking.ref_id = htonl(rpt.ref_id); tx_message->data.tracking.stratum = htonl(rpt.stratum); - tx_message->data.tracking.ref_time_s = htonl(rpt.ref_time.tv_sec); - tx_message->data.tracking.ref_time_us = htonl(rpt.ref_time.tv_usec); + UTI_TimevalHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time); tx_message->data.tracking.current_correction_s = htonl(rpt.current_correction.tv_sec); tx_message->data.tracking.current_correction_us = htonl(rpt.current_correction.tv_usec); tx_message->data.tracking.freq_ppm = REAL2WIRE(rpt.freq_ppm); @@ -1424,7 +1417,7 @@ handle_rtcreport(CMD_Request *rx_message, CMD_Reply *tx_message) if (status) { tx_message->status = htons(STT_SUCCESS); tx_message->reply = htons(RPY_RTC); - tx_message->data.rtc.ref_time = htonl(report.ref_time); + UTI_TimevalHostToNetwork(&report.ref_time, &tx_message->data.rtc.ref_time); tx_message->data.rtc.n_samples = htons(report.n_samples); tx_message->data.rtc.n_runs = htons(report.n_runs); tx_message->data.rtc.span_seconds = htonl(report.span_seconds); @@ -1641,7 +1634,7 @@ handle_manual_list(CMD_Request *rx_message, CMD_Reply *tx_message) tx_message->data.manual_list.n_samples = htonl(n_samples); for (i=0; idata.manual_list.samples[i]; - sample->when = htonl(report[i].when); + UTI_TimevalHostToNetwork(&report[i].when, &sample->when); sample->slewed_offset = REAL2WIRE(report[i].slewed_offset); sample->orig_offset = REAL2WIRE(report[i].orig_offset); sample->residual = REAL2WIRE(report[i].residual); @@ -1936,11 +1929,17 @@ read_from_cmd_socket(void *anything) valid_ts = 0; - if (md5_ok && ((utoken_ok && token_ok) || - ((ntohl(rx_message.utoken) == SPECIAL_UTOKEN) && - (rx_command == REQ_LOGON) && - (valid_ts = ts_is_unique_and_not_stale(&rx_message.data.logon.ts, &now))))) { - issue_token = 1; + if (md5_ok) { + struct timeval ts; + + UTI_TimevalNetworkToHost(&rx_message.data.logon.ts, &ts); + if ((utoken_ok && token_ok) || + ((ntohl(rx_message.utoken) == SPECIAL_UTOKEN) && + (rx_command == REQ_LOGON) && + (valid_ts = ts_is_unique_and_not_stale(&ts, &now)))) + issue_token = 1; + else + issue_token = 0; } else { issue_token = 0; } diff --git a/manual.c b/manual.c index 2664f05..0290df8 100644 --- a/manual.c +++ b/manual.c @@ -287,7 +287,7 @@ MNL_ReportSamples(RPT_ManualSamplesReport *report, int max, int *n) } for (i=0; iref_time = (unsigned long) coef_ref_time; + report->ref_time.tv_sec = coef_ref_time; + report->ref_time.tv_usec = 0; report->n_samples = n_samples; report->n_runs = n_runs; if (n_samples > 1) { diff --git a/util.c b/util.c index 5717d54..2346f81 100644 --- a/util.c +++ b/util.c @@ -501,4 +501,41 @@ UTI_Int64ToTimeval(NTP_int64 *src, dest->tv_usec = (int)(0.5 + (double)(ntohl(src->lo)) / 4294.967296); } +/* ================================================== */ + +void +UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest) +{ + uint32_t sec_low, sec_high; + + dest->tv_usec = ntohl(src->tv_usec); + sec_high = ntohl(src->tv_sec_high); + sec_low = ntohl(src->tv_sec_low); + + /* get the missing bits from current time when received timestamp + is only 32-bit */ + if (sizeof (time_t) > 4 && sec_high == TV_NOHIGHSEC) { + struct timeval now; + struct timezone tz; + + gettimeofday(&now, &tz); + sec_high = now.tv_sec >> 32; + } + dest->tv_sec = (time_t)sec_high << 16 << 16 | sec_low; +} + +/* ================================================== */ + +void +UTI_TimevalHostToNetwork(struct timeval *src, Timeval *dest) +{ + dest->tv_usec = htonl(src->tv_usec); + if (sizeof (time_t) > 4) + dest->tv_sec_high = htonl(src->tv_sec >> 32); + else + dest->tv_sec_high = htonl(TV_NOHIGHSEC); + dest->tv_sec_low = htonl(src->tv_sec); +} + + /* ================================================== */ diff --git a/util.h b/util.h index 1ec2184..cddbc5c 100644 --- a/util.h +++ b/util.h @@ -35,6 +35,7 @@ #include "addressing.h" #include "ntp.h" +#include "candm.h" /* Convert a timeval into a floating point number of seconds */ extern void UTI_TimevalToDouble(struct timeval *a, double *b); @@ -96,6 +97,9 @@ extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest); extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest); +extern void UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest); +extern void UTI_TimevalHostToNetwork(struct timeval *src, Timeval *dest); + #if defined (INLINE_UTILITIES) #define INLINE_STATIC inline static #include "util.c"