Use an adjusted monotonic clock

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët
2019-07-19 12:55:55 +00:00
parent 0ae6656bdb
commit b2ff2b6276

52
mud.c
View File

@@ -33,6 +33,10 @@
#define MUD_V4V6 0 #define MUD_V4V6 0
#endif #endif
#if defined __APPLE__
#include <mach/mach_time.h>
#endif
#if defined IP_PKTINFO #if defined IP_PKTINFO
#define MUD_PKTINFO IP_PKTINFO #define MUD_PKTINFO IP_PKTINFO
#define MUD_PKTINFO_SRC(X) &((struct in_pktinfo *)(X))->ipi_addr #define MUD_PKTINFO_SRC(X) &((struct in_pktinfo *)(X))->ipi_addr
@@ -156,6 +160,7 @@ struct mud {
} decrypt, difftime, keyx; } decrypt, difftime, keyx;
} bad; } bad;
uint64_t window; uint64_t window;
uint64_t base_time;
}; };
static int static int
@@ -269,21 +274,34 @@ mud_read48(const unsigned char *src)
} }
static uint64_t static uint64_t
mud_now(void) mud_gettimeofday(void)
{ {
uint64_t now;
#if defined CLOCK_REALTIME
struct timespec tv;
clock_gettime(CLOCK_REALTIME, &tv);
now = (uint64_t)tv.tv_sec * MUD_ONE_SEC
+ (uint64_t)tv.tv_nsec / MUD_ONE_MSEC;
#else
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
now = (uint64_t)tv.tv_sec * MUD_ONE_SEC return MUD_TIME_MASK(0
+ (uint64_t)tv.tv_usec; + (uint64_t)tv.tv_sec * MUD_ONE_SEC
+ (uint64_t)tv.tv_usec);
}
static uint64_t
mud_now(struct mud *mud)
{
#if defined __APPLE__
static mach_timebase_info_data_t mtid;
if (!mtid.denom)
mach_timebase_info(&mtid);
return MUD_TIME_MASK(mud->base_time
+ (mach_absolute_time() * mtid.numer / mtid.denom)
/ 1000ULL);
#elif defined CLOCK_MONOTONIC
struct timespec tv;
clock_gettime(CLOCK_MONOTONIC, &tv);
return MUD_TIME_MASK(mud->base_time
+ (uint64_t)tv.tv_sec * MUD_ONE_SEC
+ (uint64_t)tv.tv_nsec / MUD_ONE_MSEC);
#else
return mud_gettimeofday();
#endif #endif
return MUD_TIME_MASK(now);
} }
static uint64_t static uint64_t
@@ -962,6 +980,12 @@ mud_create(struct sockaddr *addr)
memcpy(&mud->addr, addr, addrlen); memcpy(&mud->addr, addr, addrlen);
uint64_t now = mud_now(mud);
uint64_t base_time = mud_gettimeofday();
if (base_time > now)
mud->base_time = base_time - now;
return mud; return mud;
} }
@@ -1342,7 +1366,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
(packet_size <= (ssize_t)MUD_PKT_MIN_SIZE)) (packet_size <= (ssize_t)MUD_PKT_MIN_SIZE))
return 0; return 0;
const uint64_t now = mud_now(); const uint64_t now = mud_now(mud);
const uint64_t send_time = mud_read48(packet); const uint64_t send_time = mud_read48(packet);
mud_unmapv4(&addr); mud_unmapv4(&addr);
@@ -1472,7 +1496,7 @@ mud_update(struct mud *mud, uint64_t now)
long long
mud_send_wait(struct mud *mud) mud_send_wait(struct mud *mud)
{ {
const uint64_t now = mud_now(); const uint64_t now = mud_now(mud);
mud_update(mud, now); mud_update(mud, now);
@@ -1519,7 +1543,7 @@ mud_send(struct mud *mud, const void *data, size_t size, unsigned tc)
} }
unsigned char packet[MUD_PKT_MAX_SIZE]; unsigned char packet[MUD_PKT_MAX_SIZE];
const uint64_t now = mud_now(); const uint64_t now = mud_now(mud);
const int packet_size = mud_encrypt(mud, now, const int packet_size = mud_encrypt(mud, now,
packet, sizeof(packet), packet, sizeof(packet),
data, size); data, size);