void test_OffsetCalculationPositiveOffset(void) { struct pkt rpkt; rpkt.precision = -16; // 0,000015259 rpkt.rootdelay = HTONS_FP(DTOUFP(0.125)); rpkt.rootdisp = HTONS_FP(DTOUFP(0.25)); // Synch Distance: (0.125+0.25)/2.0 == 0.1875 l_fp reftime; get_systime(&reftime); HTONL_FP(&reftime, &rpkt.reftime); l_fp tmp; // T1 - Originate timestamp tmp.l_ui = 1000000000UL; tmp.l_uf = 0UL; HTONL_FP(&tmp, &rpkt.org); // T2 - Receive timestamp tmp.l_ui = 1000000001UL; tmp.l_uf = 2147483648UL; HTONL_FP(&tmp, &rpkt.rec); // T3 - Transmit timestamp tmp.l_ui = 1000000002UL; tmp.l_uf = 0UL; HTONL_FP(&tmp, &rpkt.xmt); // T4 - Destination timestamp as standard timeval tmp.l_ui = 1000000001UL; tmp.l_uf = 0UL; struct timeval dst; TSTOTV(&tmp, &dst); dst.tv_sec -= JAN_1970; double offset, precision, synch_distance; offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance); TEST_ASSERT_EQUAL_DOUBLE(1.25, offset); TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(16), precision); // 1.1250150000000001 ? TEST_ASSERT_EQUAL_DOUBLE(1.125015, synch_distance); }
void test_OffsetCalculationNegativeOffset(void) { struct pkt rpkt; l_fp reftime, tmp; struct timeval dst; double offset, precision, synch_distance; rpkt.precision = -1; rpkt.rootdelay = HTONS_FP(DTOUFP(0.5)); rpkt.rootdisp = HTONS_FP(DTOUFP(0.5)); /* Synch Distance is (0.5+0.5)/2.0, or 0.5 */ get_systime(&reftime); HTONL_FP(&reftime, &rpkt.reftime); /* T1 - Originate timestamp */ tmp.l_ui = 1000000001UL; tmp.l_uf = 0UL; HTONL_FP(&tmp, &rpkt.org); /* T2 - Receive timestamp */ tmp.l_ui = 1000000000UL; tmp.l_uf = 2147483648UL; HTONL_FP(&tmp, &rpkt.rec); /*/ T3 - Transmit timestamp */ tmp.l_ui = 1000000001UL; tmp.l_uf = 2147483648UL; HTONL_FP(&tmp, &rpkt.xmt); /* T4 - Destination timestamp as standard timeval */ tmp.l_ui = 1000000003UL; tmp.l_uf = 0UL; TSTOTV(&tmp, &dst); dst.tv_sec -= JAN_1970; offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance); TEST_ASSERT_EQUAL_DOUBLE(-1, offset); TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(1), precision); TEST_ASSERT_EQUAL_DOUBLE(1.3333483333333334, synch_distance); }
TEST_F(mainTest, OffsetCalculationNegativeOffset) { pkt rpkt; rpkt.precision = -1; rpkt.rootdelay = HTONS_FP(DTOUFP(0.5)); rpkt.rootdisp = HTONS_FP(DTOUFP(0.5)); // Synch Distance is (0.5+0.5)/2.0, or 0.5 l_fp reftime; get_systime(&reftime); HTONL_FP(&reftime, &rpkt.reftime); l_fp tmp; // T1 - Originate timestamp tmp.l_ui = 1000000001UL; tmp.l_uf = 0UL; HTONL_FP(&tmp, &rpkt.org); // T2 - Receive timestamp tmp.l_ui = 1000000000UL; tmp.l_uf = 2147483648UL; HTONL_FP(&tmp, &rpkt.rec); // T3 - Transmit timestamp tmp.l_ui = 1000000001UL; tmp.l_uf = 2147483648UL; HTONL_FP(&tmp, &rpkt.xmt); // T4 - Destination timestamp as standard timeval tmp.l_ui = 1000000003UL; tmp.l_uf = 0UL; timeval dst; TSTOTV(&tmp, &dst); dst.tv_sec -= JAN_1970; double offset, precision, synch_distance; offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance); EXPECT_DOUBLE_EQ(-1, offset); EXPECT_DOUBLE_EQ(1. / ULOGTOD(1), precision); EXPECT_DOUBLE_EQ(1.3333483333333334, synch_distance); }
int handle_pkt ( int rpktl, struct pkt *rpkt, struct addrinfo *host ) { struct timeval tv_dst; int sw_case, digits; char *hostname = NULL, *ref, *ts_str = NULL; double offset, precision, root_dispersion; char addr_buf[INET6_ADDRSTRLEN]; char *p_SNTP_PRETEND_TIME; if(rpktl > 0) sw_case = 1; else sw_case = rpktl; switch(sw_case) { case SERVER_UNUSEABLE: return -1; break; case PACKET_UNUSEABLE: break; case SERVER_AUTH_FAIL: break; case KOD_DEMOBILIZE: /* Received a DENY or RESTR KOD packet */ hostname = addrinfo_to_str(host); ref = (char *)&rpkt->refid; add_entry(hostname, ref); if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp handle_pkt: Received KOD packet with code: %c%c%c%c from %s, demobilizing all connections\n", ref[0], ref[1], ref[2], ref[3], hostname); msyslog(LOG_WARNING, "Received a KOD packet with code %c%c%c%c from %s, demobilizing all connections", ref[0], ref[1], ref[2], ref[3], hostname); break; case KOD_RATE: /* Hmm... probably we should sleep a bit here */ break; case 1: if (ENABLED_OPT(NORMALVERBOSE)) { getnameinfo(host->ai_addr, host->ai_addrlen, addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST); printf("sntp handle_pkt: Received %i bytes from %s\n", rpktl, addr_buf); } GETTIMEOFDAY(&tv_dst, (struct timezone *)NULL); p_SNTP_PRETEND_TIME = getenv("SNTP_PRETEND_TIME"); if (p_SNTP_PRETEND_TIME) { long long input_time; sscanf(p_SNTP_PRETEND_TIME, "%lld", &input_time); tv_dst.tv_sec = (time_t)input_time; } offset_calculation(rpkt, rpktl, &tv_dst, &offset, &precision, &root_dispersion); for (digits = 0; (precision *= 10.) < 1.; ++digits) /* empty */ ; if (digits > 6) digits = 6; ts_str = tv_to_str(&tv_dst); printf("%s ", ts_str); if (offset > 0) printf("+"); printf("%.*f", digits, offset); if (root_dispersion > 0.) printf(" +/- %f secs", root_dispersion); printf("\n"); free(ts_str); if (p_SNTP_PRETEND_TIME) return 0; if (ENABLED_OPT(SETTOD) || ENABLED_OPT(ADJTIME)) return set_time(offset); return 0; } return 1; }
int handle_pkt( int rpktl, struct pkt * rpkt, sockaddr_u * host, const char * hostname ) { char disptxt[32]; const char * addrtxt; struct timeval tv_dst; int cnt; int sw_case; int digits; int stratum; char * ref; char * ts_str; const char * leaptxt; double offset; double precision; double synch_distance; char * p_SNTP_PRETEND_TIME; time_t pretend_time; #if SIZEOF_TIME_T == 8 long long ll; #else long l; #endif ts_str = NULL; if (rpktl > 0) sw_case = 1; else sw_case = rpktl; switch (sw_case) { case SERVER_UNUSEABLE: return -1; break; case PACKET_UNUSEABLE: break; case SERVER_AUTH_FAIL: break; case KOD_DEMOBILIZE: /* Received a DENY or RESTR KOD packet */ addrtxt = stoa(host); ref = (char *)&rpkt->refid; add_entry(addrtxt, ref); msyslog(LOG_WARNING, "KOD code %c%c%c%c from %s %s", ref[0], ref[1], ref[2], ref[3], addrtxt, hostname); break; case KOD_RATE: /* ** Hmm... ** We should probably call add_entry() with an ** expiration timestamp of several seconds in the future, ** and back-off even more if we get more RATE responses. */ break; case 1: TRACE(3, ("handle_pkt: %d bytes from %s %s\n", rpktl, stoa(host), hostname)); gettimeofday_cached(base, &tv_dst); p_SNTP_PRETEND_TIME = getenv("SNTP_PRETEND_TIME"); if (p_SNTP_PRETEND_TIME) { pretend_time = 0; #if SIZEOF_TIME_T == 4 if (1 == sscanf(p_SNTP_PRETEND_TIME, "%ld", &l)) pretend_time = (time_t)l; #elif SIZEOF_TIME_T == 8 if (1 == sscanf(p_SNTP_PRETEND_TIME, "%lld", &ll)) pretend_time = (time_t)ll; #else # include "GRONK: unexpected value for SIZEOF_TIME_T" #endif if (0 != pretend_time) tv_dst.tv_sec = pretend_time; } offset_calculation(rpkt, rpktl, &tv_dst, &offset, &precision, &synch_distance); time_derived = TRUE; for (digits = 0; (precision *= 10.) < 1.; ++digits) /* empty */ ; if (digits > 6) digits = 6; ts_str = tv_to_str(&tv_dst); stratum = rpkt->stratum; if (0 == stratum) stratum = 16; if (synch_distance > 0.) { cnt = snprintf(disptxt, sizeof(disptxt), " +/- %f", synch_distance); if ((size_t)cnt >= sizeof(disptxt)) snprintf(disptxt, sizeof(disptxt), "ERROR %d >= %d", cnt, (int)sizeof(disptxt)); } else { disptxt[0] = '\0'; } switch (PKT_LEAP(rpkt->li_vn_mode)) { case LEAP_NOWARNING: leaptxt = "no-leap"; break; case LEAP_ADDSECOND: leaptxt = "add-leap"; break; case LEAP_DELSECOND: leaptxt = "del-leap"; break; case LEAP_NOTINSYNC: leaptxt = "unsync"; break; default: leaptxt = "LEAP-ERROR"; break; } msyslog(LOG_INFO, "%s %+.*f%s %s s%d %s%s", ts_str, digits, offset, disptxt, hostnameaddr(hostname, host), stratum, leaptxt, (time_adjusted) ? " [excess]" : ""); free(ts_str); if (p_SNTP_PRETEND_TIME) return 0; if (!time_adjusted && (ENABLED_OPT(STEP) || ENABLED_OPT(SLEW))) return set_time(offset); return EX_OK; } return 1; }