From 314c17259e09d18af9fcafa9d7e8b59c5cf1e1ca Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 22 Nov 2017 16:49:56 +0100 Subject: global: switch from timeval to timespec This gets us nanoseconds instead of microseconds, which is better, and we can do this pretty much without freaking out existing userspace, which doesn't actually make use of the nano/micro seconds field: zx2c4@thinkpad ~ $ cat a.c void main() { puts(sizeof(struct timeval) == sizeof(struct timespec) ? "success" : "failure"); } zx2c4@thinkpad ~ $ gcc a.c -m64 && ./a.out success zx2c4@thinkpad ~ $ gcc a.c -m32 && ./a.out success This doesn't solve y2038 problem, but timespec64 isn't yet a thing in userspace. --- src/netlink.c | 4 ++-- src/noise.c | 6 +++--- src/peer.h | 2 +- src/timers.c | 2 +- src/tools/containers.h | 4 ++-- src/tools/ipc.c | 2 +- src/tools/show.c | 8 ++++---- src/uapi/wireguard.h | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/netlink.c b/src/netlink.c index 9297e60..7fa243e 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -30,7 +30,7 @@ static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = { [WGPEER_A_FLAGS] = { .type = NLA_U32 }, [WGPEER_A_ENDPOINT] = { .len = sizeof(struct sockaddr) }, [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]= { .type = NLA_U16 }, - [WGPEER_A_LAST_HANDSHAKE_TIME] = { .len = sizeof(struct timeval) }, + [WGPEER_A_LAST_HANDSHAKE_TIME] = { .len = sizeof(struct timespec) }, [WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, [WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED } @@ -107,7 +107,7 @@ static int get_peer(struct wireguard_peer *peer, unsigned int index, struct allo if (fail) goto err; - if (nla_put(skb, WGPEER_A_LAST_HANDSHAKE_TIME, sizeof(struct timeval), &peer->walltime_last_handshake) || nla_put_u16(skb, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval / HZ) || + if (nla_put(skb, WGPEER_A_LAST_HANDSHAKE_TIME, sizeof(struct timespec), &peer->walltime_last_handshake) || nla_put_u16(skb, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval / HZ) || nla_put_u64_64bit(skb, WGPEER_A_TX_BYTES, peer->tx_bytes, WGPEER_A_UNSPEC) || nla_put_u64_64bit(skb, WGPEER_A_RX_BYTES, peer->rx_bytes, WGPEER_A_UNSPEC)) goto err; diff --git a/src/noise.c b/src/noise.c index 6ce9b78..9d99bfa 100644 --- a/src/noise.c +++ b/src/noise.c @@ -349,12 +349,12 @@ static void message_ephemeral(u8 ephemeral_dst[NOISE_PUBLIC_KEY_LEN], const u8 e static void tai64n_now(u8 output[NOISE_TIMESTAMP_LEN]) { - struct timeval now; + struct timespec64 now; - do_gettimeofday(&now); + getnstimeofday64(&now); /* https://cr.yp.to/libtai/tai64.html */ *(__be64 *)output = cpu_to_be64(4611686018427387914ULL + now.tv_sec); - *(__be32 *)(output + sizeof(__be64)) = cpu_to_be32(1000 * now.tv_usec + 500); + *(__be32 *)(output + sizeof(__be64)) = cpu_to_be32(now.tv_nsec); } bool noise_handshake_create_initiation(struct message_handshake_initiation *dst, struct noise_handshake *handshake) diff --git a/src/peer.h b/src/peer.h index 49784d1..1e3c1ae 100644 --- a/src/peer.h +++ b/src/peer.h @@ -49,7 +49,7 @@ struct wireguard_peer { unsigned int timer_handshake_attempts; unsigned long persistent_keepalive_interval; bool timers_enabled, timer_need_another_keepalive, sent_lastminute_handshake; - struct timeval walltime_last_handshake; + struct timespec walltime_last_handshake; struct kref refcount; struct rcu_head rcu; struct list_head peer_list; diff --git a/src/timers.c b/src/timers.c index 52fff28..5f2570f 100644 --- a/src/timers.c +++ b/src/timers.c @@ -158,7 +158,7 @@ void timers_handshake_complete(struct wireguard_peer *peer) del_timer(&peer->timer_retransmit_handshake); peer->timer_handshake_attempts = 0; peer->sent_lastminute_handshake = false; - do_gettimeofday(&peer->walltime_last_handshake); + getnstimeofday(&peer->walltime_last_handshake); } /* Should be called after an ephemeral key is created, which is before sending a handshake response or after receiving a handshake response. */ diff --git a/src/tools/containers.h b/src/tools/containers.h index 58d0657..31eabea 100644 --- a/src/tools/containers.h +++ b/src/tools/containers.h @@ -6,9 +6,9 @@ #include #include +#include #include #include -#include #include #include "../uapi/wireguard.h" @@ -43,7 +43,7 @@ struct wgpeer { struct sockaddr_in6 addr6; } endpoint; - struct timeval last_handshake_time; + struct timespec last_handshake_time; uint64_t rx_bytes, tx_bytes; uint16_t persistent_keepalive_interval; diff --git a/src/tools/ipc.c b/src/tools/ipc.c index 2d24287..a88672f 100644 --- a/src/tools/ipc.c +++ b/src/tools/ipc.c @@ -427,7 +427,7 @@ static int userspace_get_device(struct wgdevice **out, const char *interface) } else if (peer && !strcmp(key, "last_handshake_time_sec")) peer->last_handshake_time.tv_sec = NUM(0xffffffffffffffffULL); else if (peer && !strcmp(key, "last_handshake_time_nsec")) - peer->last_handshake_time.tv_usec = NUM(0xffffffffffffffffULL) / 1000; + peer->last_handshake_time.tv_nsec = NUM(0xffffffffffffffffULL); else if (peer && !strcmp(key, "rx_bytes")) peer->rx_bytes = NUM(0xffffffffffffffffULL); else if (peer && !strcmp(key, "tx_bytes")) diff --git a/src/tools/show.c b/src/tools/show.c index 6ae5830..ebfdf5b 100644 --- a/src/tools/show.c +++ b/src/tools/show.c @@ -24,13 +24,13 @@ static int peer_cmp(const void *first, const void *second) time_t diff; const struct wgpeer *a = *(const void **)first, *b = *(const void **)second; - if (!a->last_handshake_time.tv_sec && !a->last_handshake_time.tv_usec && (b->last_handshake_time.tv_sec || b->last_handshake_time.tv_usec)) + if (!a->last_handshake_time.tv_sec && !a->last_handshake_time.tv_nsec && (b->last_handshake_time.tv_sec || b->last_handshake_time.tv_nsec)) return 1; - if (!b->last_handshake_time.tv_sec && !b->last_handshake_time.tv_usec && (a->last_handshake_time.tv_sec || a->last_handshake_time.tv_usec)) + if (!b->last_handshake_time.tv_sec && !b->last_handshake_time.tv_nsec && (a->last_handshake_time.tv_sec || a->last_handshake_time.tv_nsec)) return -1; diff = a->last_handshake_time.tv_sec - b->last_handshake_time.tv_sec; if (!diff) - diff = a->last_handshake_time.tv_usec - b->last_handshake_time.tv_usec; + diff = a->last_handshake_time.tv_nsec - b->last_handshake_time.tv_nsec; if (diff < 0) return 1; if (diff > 0) @@ -149,7 +149,7 @@ static size_t pretty_time(char *buf, const size_t len, unsigned long long left) return offset; } -static char *ago(const struct timeval *t) +static char *ago(const struct timespec *t) { static char buf[1024]; size_t offset; diff --git a/src/uapi/wireguard.h b/src/uapi/wireguard.h index e776f7c..411d5a4 100644 --- a/src/uapi/wireguard.h +++ b/src/uapi/wireguard.h @@ -51,7 +51,7 @@ * WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN * WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6 * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16 - * WGPEER_A_LAST_HANDSHAKE_TIME: struct timeval + * WGPEER_A_LAST_HANDSHAKE_TIME: struct timespec * WGPEER_A_RX_BYTES: NLA_U64 * WGPEER_A_TX_BYTES: NLA_U64 * WGPEER_A_ALLOWEDIPS: NLA_NESTED -- cgit v1.2.3-59-g8ed1b