From: Francis Dupont Date: Fri, 29 May 2015 14:01:15 +0000 (+0200) Subject: [sedhcpv6] added NTP code in util lib X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=5c011e199c057378e171ea6634c8d60ba0e46ca7;p=thirdparty%2Fkea.git [sedhcpv6] added NTP code in util lib --- diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am index 2bd0cff8c0..222a90b26f 100644 --- a/src/lib/util/Makefile.am +++ b/src/lib/util/Makefile.am @@ -13,6 +13,7 @@ libkea_util_la_SOURCES = boost_time_utils.h boost_time_utils.cc libkea_util_la_SOURCES += csv_file.h csv_file.cc libkea_util_la_SOURCES += filename.h filename.cc libkea_util_la_SOURCES += locks.h lru_list.h +libkea_util_la_SOURCES += ntp_utils.h ntp_utils.cc libkea_util_la_SOURCES += strutil.h strutil.cc libkea_util_la_SOURCES += buffer.h io_utilities.h libkea_util_la_SOURCES += time_utilities.h time_utilities.cc diff --git a/src/lib/util/ntp_utils.cc b/src/lib/util/ntp_utils.cc new file mode 100644 index 0000000000..fe73329726 --- /dev/null +++ b/src/lib/util/ntp_utils.cc @@ -0,0 +1,140 @@ +// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include +#include + +namespace isc { +namespace util { + +namespace { + +// \brief seconds between 1900 and 1970 epochs +const uint32_t EPOCH_ADJUST = 2208988800UL; + +// \brief Allowed delta (300s / 5mn) +const double DELTA = 300.; + +// \brief Allowed fuzz factor (1s) +const double FUZZ = 1.; + +// \brief Allowed clock drift (.01s) +const double DRIFT = .01; +} + +Ntp::Ntp() : ntp_sec_(0), ntp_fraction_(0) +{ +} + +Ntp::Ntp(uint64_t sec, uint16_t fraction) + : ntp_sec_(sec), ntp_fraction_(fraction) +{ +} + +Ntp::Ntp(struct timeval tv) +{ + ntp_sec_ = static_cast(tv.tv_sec) + EPOCH_ADJUST; + uint32_t fcvt = (tv.tv_usec * 65536U) / 1000000UL; + ntp_fraction_ = static_cast(fcvt & 0xffff); +} + +Ntp::Ntp(double secs, time_t base) +{ + double intpart; + double fracpart = std::modf(secs, &intpart); + ntp_sec_ = static_cast(intpart) + base + EPOCH_ADJUST; + ntp_fraction_ = static_cast(floor(fracpart * 65536.)); +} + +bool Ntp::from_binary(std::vector binary) +{ + if (binary.size() != 8) { + return (false); + } + ntp_sec_ = static_cast(binary[0]) << 40; + ntp_sec_ |= static_cast(binary[1]) << 32; + ntp_sec_ |= binary[2] << 24; + ntp_sec_ |= binary[3] << 16; + ntp_sec_ |= binary[4] << 8; + ntp_sec_ |= binary[5]; + ntp_fraction_ = binary[6] << 8; + ntp_fraction_ |= binary[7]; + return (true); +} + +std::vector Ntp::to_binary() const +{ + std::vector ret(8); + ret[0] = static_cast((ntp_sec_ >> 40) & 0xff); + ret[1] = static_cast((ntp_sec_ >> 32) & 0xff); + ret[2] = static_cast((ntp_sec_ >> 24) & 0xff); + ret[3] = static_cast((ntp_sec_ >> 16) & 0xff); + ret[4] = static_cast((ntp_sec_ >> 8) & 0xff); + ret[5] = static_cast(ntp_sec_ & 0xff); + ret[6] = static_cast((ntp_fraction_ >> 8) & 0xff); + ret[7] = static_cast(ntp_fraction_ & 0xff); + return (ret); +} + +double Ntp::secs(time_t base) const +{ + double ret = static_cast(ntp_sec_ - base - EPOCH_ADJUST); + ret += static_cast(ntp_fraction_ * (1./65536.)); + return (ret); +} + +bool Ntp::verify_new(const Ntp& rd_new, const Ntp& ts_new, time_t base) +{ + double drd_new = rd_new.secs(base); + double dts_new = ts_new.secs(base); + if (drd_new >= dts_new) { + if ((drd_new - dts_new) < DELTA) { + return (true); + } else { + return (false); + } + } else { + if ((dts_new - drd_new) < DELTA) { + return (true); + } else { + return (false); + } + } +} + +bool Ntp::verify(const Ntp& rd_new, const Ntp& ts_new, + const Ntp& rd_last, const Ntp& ts_last, + time_t base, bool* to_update) +{ + double drd_new = rd_new.secs(base); + double drd_last = rd_last.secs(base); + if (drd_new < drd_last) { + return (false); + } + double dts_new = ts_new.secs(base); + double dts_last = ts_last.secs(base); + double expected = dts_last - FUZZ; + expected += (drd_new - drd_last) * (1. - DRIFT); + if (expected >= dts_new + FUZZ) { + return (false); + } else { + if (dts_new > dts_last) { + *to_update = true; + } + return (true); + } +} + +} +} diff --git a/src/lib/util/ntp_utils.h b/src/lib/util/ntp_utils.h new file mode 100644 index 0000000000..bc2fcfcf98 --- /dev/null +++ b/src/lib/util/ntp_utils.h @@ -0,0 +1,72 @@ +// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#ifndef KEA_NTP_UTILS_H +#define KEA_NTP_UTILS_H + +#include +#include + +#include +#include + +namespace isc { +namespace util { + +/// +/// \brief NTP (RFC 5905) time +/// +/// External representation: uint64_t seconds, uint16_t fractional +/// Network representation: 48+16 bit unsigned fixed point +struct Ntp { + // \brief seconds sinec 1900 + uint64_t ntp_sec_; + + // \brief 1/65536th of seconds + uint16_t ntp_fraction_; + + // \brief Default constructor + Ntp(); + + // \brief Standard constructor + Ntp(uint64_t sec, uint16_t fraction); + + // \brief Conversion from timeval + Ntp(struct timeval tv); + + // \brief Conversion from based double + Ntp(double secs, time_t base); + + // \brief Conversion from network + bool from_binary(std::vector binary); + + // \brief Conversion to network + std::vector to_binary() const; + + // \brief Conversion to based double + double secs(time_t base) const; + + // \brief Verify a timestamp without cache + static bool verify_new(const Ntp& rd_new, const Ntp& ts_new, time_t base); + + // \brief Verify a timestamp with cache + static bool verify(const Ntp& rd_new, const Ntp& ts_new, + const Ntp& rd_last, const Ntp& ts_last, + time_t base, bool* to_update); +}; + +} // end of isc::util namespace +} // end of isc namespace + +#endif // KEA_NTP_UTILS_H