aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-01-22 13:38:52 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2019-01-23 14:29:44 +0100
commitc870c7af53f44a37814dfc76ceb8ad88e290fcd8 (patch)
tree82f0ceef7f1bb33d63774be97f432ed9b99d9ec3
parentcontrib: introduce simple highlighter library (diff)
downloadWireGuard-c870c7af53f44a37814dfc76ceb8ad88e290fcd8.tar.xz
WireGuard-c870c7af53f44a37814dfc76ceb8ad88e290fcd8.zip
netlink: use __kernel_timespec for handshake time
-rw-r--r--contrib/examples/embeddable-wg-library/wireguard.h8
-rw-r--r--src/compat/compat.h16
-rw-r--r--src/netlink.c10
-rw-r--r--src/peer.h2
-rwxr-xr-xsrc/tests/netns.sh4
-rw-r--r--src/timers.c2
-rw-r--r--src/tools/containers.h8
-rw-r--r--src/tools/ipc.c4
-rw-r--r--src/tools/show.c2
-rw-r--r--src/uapi/wireguard.h2
10 files changed, 45 insertions, 13 deletions
diff --git a/contrib/examples/embeddable-wg-library/wireguard.h b/contrib/examples/embeddable-wg-library/wireguard.h
index 9ebe47c..e7a1bbf 100644
--- a/contrib/examples/embeddable-wg-library/wireguard.h
+++ b/contrib/examples/embeddable-wg-library/wireguard.h
@@ -16,6 +16,12 @@
typedef uint8_t wg_key[32];
typedef char wg_key_b64_string[((sizeof(wg_key) + 2) / 3) * 4 + 1];
+/* Cross platform __kernel_timespec */
+struct timespec64 {
+ int64_t tv_sec;
+ int64_t tv_nsec;
+};
+
typedef struct wg_allowedip {
uint16_t family;
union {
@@ -46,7 +52,7 @@ typedef struct wg_peer {
struct sockaddr_in6 addr6;
} endpoint;
- struct timespec last_handshake_time;
+ struct timespec64 last_handshake_time;
uint64_t rx_bytes, tx_bytes;
uint16_t persistent_keepalive_interval;
diff --git a/src/compat/compat.h b/src/compat/compat.h
index 15cf8bb..19dd71a 100644
--- a/src/compat/compat.h
+++ b/src/compat/compat.h
@@ -748,10 +748,24 @@ static inline void crypto_xor_cpy(u8 *dst, const u8 *src1, const u8 *src2,
#define hlist_add_behind(a, b) hlist_add_after(b, a)
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 21, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
#define totalram_pages() totalram_pages
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0)
+struct __kernel_timespec {
+ int64_t tv_sec, tv_nsec;
+};
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
+#include <linux/time64.h>
+#ifdef __kernel_timespec
+#undef __kernel_timespec
+struct __kernel_timespec {
+ int64_t tv_sec, tv_nsec;
+};
+#endif
+#endif
+
/* https://github.com/ClangBuiltLinux/linux/issues/7 */
#if defined( __clang__) && (!defined(CONFIG_CLANG_VERSION) || CONFIG_CLANG_VERSION < 80000)
#include <linux/bug.h>
diff --git a/src/netlink.c b/src/netlink.c
index bdd3150..3458c81 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -33,7 +33,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 timespec) },
+ [WGPEER_A_LAST_HANDSHAKE_TIME] = { .len = sizeof(struct __kernel_timespec) },
[WGPEER_A_RX_BYTES] = { .type = NLA_U64 },
[WGPEER_A_TX_BYTES] = { .type = NLA_U64 },
[WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED },
@@ -107,6 +107,11 @@ static int get_peer(struct wg_peer *peer, struct allowedips_cursor *rt_cursor,
goto err;
if (!rt_cursor->seq) {
+ const struct __kernel_timespec last_handshake = {
+ .tv_sec = peer->walltime_last_handshake.tv_sec,
+ .tv_nsec = peer->walltime_last_handshake.tv_nsec
+ };
+
down_read(&peer->handshake.lock);
fail = nla_put(skb, WGPEER_A_PRESHARED_KEY,
NOISE_SYMMETRIC_KEY_LEN,
@@ -116,8 +121,7 @@ static int get_peer(struct wg_peer *peer, struct allowedips_cursor *rt_cursor,
goto err;
if (nla_put(skb, WGPEER_A_LAST_HANDSHAKE_TIME,
- sizeof(peer->walltime_last_handshake),
- &peer->walltime_last_handshake) ||
+ sizeof(last_handshake), &last_handshake) ||
nla_put_u16(skb, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
peer->persistent_keepalive_interval) ||
nla_put_u64_64bit(skb, WGPEER_A_TX_BYTES, peer->tx_bytes,
diff --git a/src/peer.h b/src/peer.h
index f3cf255..2e04262 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -56,7 +56,7 @@ struct wg_peer {
u16 persistent_keepalive_interval;
bool timer_need_another_keepalive;
bool sent_lastminute_handshake;
- struct timespec walltime_last_handshake;
+ struct timespec64 walltime_last_handshake;
struct kref refcount;
struct rcu_head rcu;
struct list_head peer_list;
diff --git a/src/tests/netns.sh b/src/tests/netns.sh
index 6ef61a5..46c30e5 100755
--- a/src/tests/netns.sh
+++ b/src/tests/netns.sh
@@ -142,7 +142,7 @@ big_mtu=$(( 34816 - 1500 + $orig_mtu ))
# Test using IPv4 as outer transport
n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
-# Before calling tests, we first make sure that the stats counters are working
+# Before calling tests, we first make sure that the stats counters and timestamper are working
n2 ping -c 10 -f -W 1 192.168.241.1
{ read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip2 -stats link show dev wg0)
(( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
@@ -152,6 +152,8 @@ read _ rx_bytes tx_bytes < <(n2 wg show wg0 transfer)
(( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
read _ rx_bytes tx_bytes < <(n1 wg show wg0 transfer)
(( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) ))
+read _ timestamp < <(n1 wg show wg0 latest-handshakes)
+(( timestamp != 0 ))
tests
ip1 link set wg0 mtu $big_mtu
diff --git a/src/timers.c b/src/timers.c
index ee16c56..7614c85 100644
--- a/src/timers.c
+++ b/src/timers.c
@@ -192,7 +192,7 @@ void wg_timers_handshake_complete(struct wg_peer *peer)
del_timer(&peer->timer_retransmit_handshake);
peer->timer_handshake_attempts = 0;
peer->sent_lastminute_handshake = false;
- getnstimeofday(&peer->walltime_last_handshake);
+ ktime_get_real_ts64(&peer->walltime_last_handshake);
}
/* Should be called after an ephemeral key is created, which is before sending a
diff --git a/src/tools/containers.h b/src/tools/containers.h
index 2144052..59a213e 100644
--- a/src/tools/containers.h
+++ b/src/tools/containers.h
@@ -15,6 +15,12 @@
#include "../uapi/wireguard.h"
+/* Cross platform __kernel_timespec */
+struct timespec64 {
+ int64_t tv_sec;
+ int64_t tv_nsec;
+};
+
struct wgallowedip {
uint16_t family;
union {
@@ -45,7 +51,7 @@ struct wgpeer {
struct sockaddr_in6 addr6;
} endpoint;
- struct timespec last_handshake_time;
+ struct timespec64 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 da31eff..7ab3a62 100644
--- a/src/tools/ipc.c
+++ b/src/tools/ipc.c
@@ -420,9 +420,9 @@ static int userspace_get_device(struct wgdevice **out, const char *interface)
if (*end || allowedip->family == AF_UNSPEC || (allowedip->family == AF_INET6 && allowedip->cidr > 128) || (allowedip->family == AF_INET && allowedip->cidr > 32))
break;
} else if (peer && !strcmp(key, "last_handshake_time_sec"))
- peer->last_handshake_time.tv_sec = NUM(0xffffffffffffffffULL);
+ peer->last_handshake_time.tv_sec = NUM(0x7fffffffffffffffULL);
else if (peer && !strcmp(key, "last_handshake_time_nsec"))
- peer->last_handshake_time.tv_nsec = NUM(0xffffffffffffffffULL);
+ peer->last_handshake_time.tv_nsec = NUM(0x7fffffffffffffffULL);
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 ba6f115..4cc34ab 100644
--- a/src/tools/show.c
+++ b/src/tools/show.c
@@ -155,7 +155,7 @@ static size_t pretty_time(char *buf, const size_t len, unsigned long long left)
return offset;
}
-static char *ago(const struct timespec *t)
+static char *ago(const struct timespec64 *t)
{
static char buf[1024];
size_t offset;
diff --git a/src/uapi/wireguard.h b/src/uapi/wireguard.h
index 3db6ff8..071ce41 100644
--- a/src/uapi/wireguard.h
+++ b/src/uapi/wireguard.h
@@ -35,7 +35,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 timespec
+ * WGPEER_A_LAST_HANDSHAKE_TIME: struct __kernel_timespec
* WGPEER_A_RX_BYTES: NLA_U64
* WGPEER_A_TX_BYTES: NLA_U64
* WGPEER_A_ALLOWEDIPS: NLA_NESTED