Skip to content

Commit

Permalink
port: UnixTime port using sys/time.h
Browse files Browse the repository at this point in the history
  • Loading branch information
yoursunny committed Jan 24, 2021
1 parent f818961 commit 0abcd71
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 54 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ISC License

Copyright (c) 2020, Junxiao Shi
Copyright (c) 2020-2021, Junxiao Shi

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
Expand Down
29 changes: 29 additions & 0 deletions examples/unittest/unittest.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,34 @@
#include <Arduino.h>
#include <ArduinoUnit.h>

test(Clock)
{
using Clock = ndnph::port::Clock;
using UnixTime = ndnph::port::UnixTime;

auto u0 = UnixTime::now();
auto t0 = Clock::now();
auto t1 = Clock::add(t0, 20);
Clock::sleep(100);
auto t2 = Clock::now();
auto u2 = UnixTime::now();

assertEqual(Clock::sub(t0, t1), -20);
assertEqual(Clock::sub(t1, t0), 20);
assertTrue(Clock::isBefore(t0, t1));
assertTrue(Clock::isBefore(t0, t2));
assertTrue(Clock::isBefore(t1, t2));
assertFalse(Clock::isBefore(t1, t0));
assertFalse(Clock::isBefore(t2, t0));
assertFalse(Clock::isBefore(t2, t1));

if (UnixTime::valid(u0)) {
auto uDiff = static_cast<int>(u2 - u0);
auto tDiff = 1000 * Clock::sub(t2, t0);
assertLess(std::abs(uDiff - tDiff), 10000); // allow 10ms error
}
}

test(PacketPrint)
{
ndnph::StaticRegion<1024> region;
Expand Down Expand Up @@ -39,6 +67,7 @@ void
setup()
{
Serial.begin(115200);
Serial.println();
}

void
Expand Down
5 changes: 1 addition & 4 deletions programs/keychain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,7 @@ certsign(int argc, char** argv)

ndnph::EcPublicKey pub;
ndnph::cli::inputCertificate(region, &pub);
ndnph::ValidityPeriod vp;
time(&vp.notBefore);
vp.notAfter = vp.notBefore + 86400 * 90;

auto vp = ndnph::ValidityPeriod::daysFromNow(90);
auto cert = pub.buildCertificate(region, pub.getName(), vp, issuerPvt);
ndnph::cli::output(cert);
return true;
Expand Down
1 change: 1 addition & 0 deletions src/NDNph.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ndnph/port/random/port.hpp"
#include "ndnph/port/sha256/port.hpp"
#include "ndnph/port/timingsafe/port.hpp"
#include "ndnph/port/unixtime/port.hpp"
#include "ndnph/an.hpp"
#include "ndnph/app/ndncert/an.hpp"
#include "ndnph/app/ndncert/client.hpp"
Expand Down
5 changes: 2 additions & 3 deletions src/ndnph/app/ndncert/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,9 @@ class Client : public PacketHandler
return;
}

time_t now = time(nullptr);
auto validity = certificate::getValidity(m_profile.cert)
.intersect(ValidityPeriod(now, now + m_profile.maxValidityPeriod));
if (!validity.includes(now)) {
.intersect(ValidityPeriod::secondsFromNow(m_profile.maxValidityPeriod));
if (!validity.includesUnix()) {
return;
}

Expand Down
3 changes: 1 addition & 2 deletions src/ndnph/app/ndncert/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,11 +536,10 @@ class PossessionChallenge : public Challenge
StaticRegion<2048> temp;
ndnph::Data data = temp.create<ndnph::Data>();
assert(!!data);
time_t now = time(nullptr);

m_region.reset();
if (!(m_cert.makeDecoder().decode(data) && m_pub.import(temp, data) &&
certificate::getValidity(data).includes(now))) {
certificate::getValidity(data).includesUnix())) {
// don't reveal the error until proof is submitted
m_pub = EcPublicKey();
}
Expand Down
1 change: 1 addition & 0 deletions src/ndnph/face/packet-handler.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef NDNPH_FACE_PACKET_HANDLER_HPP
#define NDNPH_FACE_PACKET_HANDLER_HPP

#include "../port/clock/port.hpp"
#include "face.hpp"

namespace ndnph {
Expand Down
5 changes: 2 additions & 3 deletions src/ndnph/keychain/certificate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,11 @@ makeCertName(Region& region, const Name& input, const Component& issuerId, const
* @param region where to allocate memory.
* @param input subject name, key name, or certificate name; only key name is taken.
* @param issuerId specified issuerId.
* @param version version from timestamp; if unspecified, time() will be used if it has
* a reasonable value, otherwise it's randomly generated.
* @param version version number; default is current Unix timestamp or a random number.
* @return certificate name, or an empty name upon failure.
*/
inline Name
makeCertName(Region& region, const Name& input, const Component& issuerId, time_t version = 0)
makeCertName(Region& region, const Name& input, const Component& issuerId, uint64_t version = 0)
{
return toKeyName(region, input)
.append(region,
Expand Down
22 changes: 21 additions & 1 deletion src/ndnph/keychain/validity-period.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define NDNPH_KEYCHAIN_VALIDITY_PERIOD_HPP

#include "../an.hpp"
#include "../port/unixtime/port.hpp"
#include "../tlv/ev-decoder.hpp"
#include "../tlv/value.hpp"

Expand Down Expand Up @@ -45,19 +46,38 @@ class ValidityPeriod
return ValidityPeriod(540109800, MAX_TIME);
}

/** @brief Get a ValidityPeriod from now until @c seconds later. */
static ValidityPeriod secondsFromNow(uint64_t seconds)
{
time_t now = port::UnixTime::now() / 1000000;
return ValidityPeriod(now, now + seconds);
}

/** @brief Get a ValidityPeriod from now until @c days later. */
static ValidityPeriod daysFromNow(uint64_t days)
{
return secondsFromNow(86400 * days);
}

ValidityPeriod() = default;

explicit ValidityPeriod(time_t notBefore, time_t notAfter)
: notBefore(notBefore)
, notAfter(notAfter)
{}

/** @brief Determine whether the specified timestamp is within validity period. */
/** @brief Determine whether the timestamp (in seconds) is within validity period. */
bool includes(time_t t)
{
return notBefore <= t && t <= notAfter;
}

/** @brief Determine whether the Unix timestamp (in microseconds) is within validity period. */
bool includesUnix(uint64_t t = port::UnixTime::now())
{
return includes(t / 1000000);
}

/** @brief Calculate the intersection of this and @c other ValidityPeriod. */
ValidityPeriod intersect(const ValidityPeriod& other) const
{
Expand Down
34 changes: 19 additions & 15 deletions src/ndnph/packet/convention.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define NDNPH_PACKET_CONVENTION_HPP

#include "../port/random/port.hpp"
#include "../port/unixtime/port.hpp"
#include "../tlv/nni.hpp"
#include "component.hpp"

Expand All @@ -28,47 +29,47 @@ class RandomValue
class TimeValue
{
public:
enum Unit
{
Seconds = 1000000,
Milliseconds = 1000,
Microseconds = 1,
};

/**
* @brief Constructor.
* @param t timestamp, or 0 to use current time.
* @param t timestamp in microseconds, or 0 to use current time.
* @param unit time unit.
* @param allowFallback if true, use RandomValue() when clock is unavailable.
*/
explicit TimeValue(time_t t = 0, uint64_t unit = Microseconds, bool allowFallback = false)
explicit TimeValue(uint64_t t = 0, uint64_t unit = Microseconds, bool allowFallback = false)
: m_t(t)
, m_unit(unit)
, m_allowFallback(allowFallback)
{}

enum Unit
{
Seconds = 1,
Milliseconds = 1000,
Microseconds = 1000000,
};

/**
* @brief Generate TLV-VALUE.
* @return whether success and the number.
*/
std::pair<bool, uint64_t> toNumber() const
{
time_t t = m_t;
uint64_t t = m_t;
if (t == 0) {
time(&t);
if (t < 540109800) {
t = port::UnixTime::now();
if (!port::UnixTime::valid(t)) {
if (m_allowFallback) {
return RandomValue().toNumber();
} else {
return std::make_pair(false, 0);
}
}
}
return std::make_pair(true, t * m_unit);
return std::make_pair(true, t / m_unit);
}

private:
time_t m_t;
uint64_t m_t;
uint64_t m_unit;
bool m_allowFallback;
};
Expand Down Expand Up @@ -148,6 +149,9 @@ class TypedNumber
bool ok = false;
uint64_t value = 0;
std::tie(ok, value) = gen.toNumber();
if (!ok) {
return Component(region, 0, nullptr);
}
return create(region, value);
}

Expand Down Expand Up @@ -251,7 +255,7 @@ using Version = detail::TypedNumber<TT::VersionNameComponent>;
* Supported operations include those in convention::Segment, and:
* @code
* name.append<convention::Timestamp>(region, convention::RandomValue());
* name.append<convention::Timestamp>(region, convention::TimeValue(now));
* name.append<convention::Timestamp>(region, convention::TimeValue(port::UnixTime::now()));
* @endcode
*/
using Timestamp = detail::TypedNumber<TT::TimestampNameComponent>;
Expand Down
18 changes: 3 additions & 15 deletions src/ndnph/packet/sig-info.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef NDNPH_PACKET_SIG_INFO_HPP
#define NDNPH_PACKET_SIG_INFO_HPP

#include "../port/clock/port.hpp"
#include "../port/random/port.hpp"
#include "../port/unixtime/port.hpp"
#include "../tlv/ev-decoder.hpp"
#include "name.hpp"

Expand Down Expand Up @@ -217,17 +217,6 @@ class Time
public:
using Order = std::integral_constant<int, 2>;

/**
* @brief Constructor.
* @param now current Unix timestamp; the default is obtaining from @c time() function.
* Passing an invalid timestmap (including when @c time() function is unavailable)
* would result in validation failures.
*/
explicit Time(uint64_t now = time(nullptr) * 1000)
: m_base(port::Clock::now())
, m_initial(now)
{}

tlv::NniElement<> create()
{
uint64_t timestamp = std::max(now(), m_last + 1);
Expand All @@ -250,12 +239,11 @@ class Time
private:
uint64_t now() const
{
return m_initial + port::Clock::sub(port::Clock::now(), m_base);
// SigTime field uses milliseconds
return port::UnixTime::now() / 1000;
}

private:
const port::Clock::Time m_base;
const uint64_t m_initial;
uint64_t m_last = 0;
};

Expand Down
21 changes: 13 additions & 8 deletions src/ndnph/port/clock/ino.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,44 @@
namespace ndnph {
namespace port_clock_ino {

using TimeMillis = decltype(::millis());

/** @brief Clock implemented with Arduino API. */
class Clock
{
public:
Clock() = delete;

using Time = decltype(::millis());
struct Time
{
TimeMillis ms = 0;
};

static Time now()
{
return ::millis();
return Time{ .ms = ::millis() };
}

static Time add(Time t, int ms)
{
return t + ms;
return Time{ .ms = t.ms + ms };
}

static int sub(Time a, Time b)
{
if (isBefore(a, b)) {
Time diff = b - a;
auto diff = b.ms - a.ms;
return -static_cast<int>(diff);
}
Time diff = a - b;
auto diff = a.ms - b.ms;
return static_cast<int>(diff);
}

static bool isBefore(Time a, Time b)
{
static_assert(std::is_unsigned<Time>::value, "");
Time diff = a - b;
return diff > std::numeric_limits<Time>::max() / 2;
static_assert(std::is_unsigned<TimeMillis>::value, "");
auto diff = a.ms - b.ms;
return diff > std::numeric_limits<TimeMillis>::max() / 2;
}

static void sleep(int ms)
Expand Down
11 changes: 11 additions & 0 deletions src/ndnph/port/unixtime/port.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef NDNPH_PORT_UNIXTIME_PORT_HPP
#define NDNPH_PORT_UNIXTIME_PORT_HPP

#if defined(NDNPH_PORT_UNIXTIME_CUSTOM)
// using custom unixtime port
#else
#define NDNPH_PORT_UNIXTIME_SYSTIME
#include "systime.hpp"
#endif

#endif // NDNPH_PORT_UNIXTIME_PORT_HPP
Loading

0 comments on commit 0abcd71

Please sign in to comment.