diff --git a/include/opendht/utils.h b/include/opendht/utils.h index b513d45a..b1256f8f 100644 --- a/include/opendht/utils.h +++ b/include/opendht/utils.h @@ -85,6 +85,14 @@ using system_clock = std::chrono::system_clock; using time_point = clock::time_point; using duration = clock::duration; +OPENDHT_PUBLIC time_point from_system_time(system_clock::time_point t, + time_point steady_now, + system_clock::time_point system_now); +OPENDHT_PUBLIC time_point from_system_time(system_clock::time_point t); +OPENDHT_PUBLIC system_clock::time_point to_system_time(time_point t, + time_point steady_now, + system_clock::time_point system_now); +OPENDHT_PUBLIC system_clock::time_point to_system_time(time_point t); OPENDHT_PUBLIC time_point from_time_t(std::time_t t); OPENDHT_PUBLIC std::time_t to_time_t(time_point t); diff --git a/src/dht.cpp b/src/dht.cpp index 914407dd..a30bcee4 100644 --- a/src/dht.cpp +++ b/src/dht.cpp @@ -2363,6 +2363,9 @@ Dht::confirmNodes() std::vector Dht::exportValues() const { + const auto& now = scheduler.time(); + const auto system_now = system_clock::now(); + std::vector e {}; e.reserve(store.size()); for (const auto& h : store) { @@ -2375,7 +2378,7 @@ Dht::exportValues() const pk.pack_array(vals.size()); for (const auto& v : vals) { pk.pack_array(4); - pk.pack(v.created.time_since_epoch().count()); + pk.pack(to_system_time(v.created, now, system_now)); v.data->msgpack_pack(pk); if (const auto& store_addr = v.store_bucket ? v.store_bucket->getAddr() : SockAddr {}) { pk.pack_bin(store_addr.getLength()); @@ -2383,7 +2386,7 @@ Dht::exportValues() const } else { pk.pack_bin(0); } - pk.pack(v.expiration.time_since_epoch().count()); + pk.pack(to_system_time(v.expiration, now, system_now)); } ve.second = {buffer.data(), buffer.data() + buffer.size()}; e.push_back(std::move(ve)); @@ -2395,6 +2398,7 @@ void Dht::importValues(const std::vector& import) { const auto& now = scheduler.time(); + const auto system_now = system_clock::now(); unsigned imported = 0, ignored = 0; size_t imported_size = 0; @@ -2419,8 +2423,15 @@ Dht::importValues(const std::vector& import) Value tmp_val; SockAddr store_addr; try { - val_time = time_point { - time_point::duration {valel.via.array.ptr[0].as()}}; + const bool uses_system_time = valel.via.array.ptr[0].type == msgpack::type::EXT; + if (uses_system_time) { + val_time = from_system_time(valel.via.array.ptr[0].as(), + now, + system_now); + } else { + val_time = time_point { + time_point::duration {valel.via.array.ptr[0].as()}}; + } tmp_val.msgpack_unpack(valel.via.array.ptr[1]); if (valel.via.array.size >= 3) { auto addr_blob = valel.via.array.ptr[2].as(); @@ -2430,8 +2441,14 @@ Dht::importValues(const std::vector& import) } } if (valel.via.array.size >= 4) { - expiration = time_point { - time_point::duration {valel.via.array.ptr[3].as()}}; + if (uses_system_time) { + expiration = from_system_time(valel.via.array.ptr[3].as(), + now, + system_now); + } else { + expiration = time_point { + time_point::duration {valel.via.array.ptr[3].as()}}; + } } } catch (const std::exception&) { if (logger_) diff --git a/src/utils.cpp b/src/utils.cpp index 26b3631c..b3e065dc 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -238,28 +238,58 @@ operator==(const SockAddr& a, const SockAddr& b) return a.equals(b); } +time_point +from_system_time(system_clock::time_point t, time_point steady_now, system_clock::time_point system_now) +{ + if (t == system_clock::time_point::min()) + return time_point::min(); + if (t == system_clock::time_point::max()) + return time_point::max(); + auto dt = t - system_now; + if (dt > system_clock::duration(0) and steady_now > time_point::max() - dt) + return time_point::max(); + else if (dt < system_clock::duration(0) and steady_now < time_point::min() - dt) + return time_point::min(); + return steady_now + dt; +} + +time_point +from_system_time(system_clock::time_point t) +{ + return from_system_time(t, clock::now(), system_clock::now()); +} + +system_clock::time_point +to_system_time(time_point t, time_point steady_now, system_clock::time_point system_now) +{ + if (t == time_point::min()) + return system_clock::time_point::min(); + if (t == time_point::max()) + return system_clock::time_point::max(); + auto dt = t - steady_now; + if (dt > duration(0) and system_now >= system_clock::time_point::max() - dt) + return system_clock::time_point::max(); + else if (dt < duration(0) and system_now <= system_clock::time_point::min() - dt) + return system_clock::time_point::min(); + return system_now + std::chrono::duration_cast(dt); +} + +system_clock::time_point +to_system_time(time_point t) +{ + return to_system_time(t, clock::now(), system_clock::now()); +} + time_point from_time_t(std::time_t t) { - auto dt = system_clock::from_time_t(t) - system_clock::now(); - auto now = clock::now(); - if (dt > system_clock::duration(0) and now > time_point::max() - dt) - return time_point::max(); - else if (dt < system_clock::duration(0) and now < time_point::min() - dt) - return time_point::min(); - return now + dt; + return from_system_time(system_clock::from_time_t(t)); } std::time_t to_time_t(time_point t) { - auto dt = t - clock::now(); - auto now = system_clock::now(); - if (dt > duration(0) and now >= system_clock::time_point::max() - dt) - return system_clock::to_time_t(system_clock::time_point::max()); - else if (dt < duration(0) and now <= system_clock::time_point::min() - dt) - return system_clock::to_time_t(system_clock::time_point::min()); - return system_clock::to_time_t(now + std::chrono::duration_cast(dt)); + return system_clock::to_time_t(to_system_time(t)); } Blob