diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-06-23 04:20:14 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-06-23 06:08:37 +0200 |
commit | f8b3991e881a64f47412082ae15c08285eb6880b (patch) | |
tree | c5308716de6dc4765ed466e73f5bf70829f9ecfd /src | |
parent | 66518b5ce61f74375c120a872a168585dc392ba7 (diff) |
global: use ktime boottime instead of jiffies
Since this is a network protocol, expirations need to be accounted for,
even across system suspend. On real systems, this isn't a problem, since
we're clearing all keys before suspend. But on Android, where we don't
do that, this is something of a problem. So, we switch to using boottime
instead of jiffies.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/compat/compat.h | 19 | ||||
-rw-r--r-- | src/cookie.c | 12 | ||||
-rw-r--r-- | src/cookie.h | 4 | ||||
-rw-r--r-- | src/device.c | 2 | ||||
-rw-r--r-- | src/messages.h | 18 | ||||
-rw-r--r-- | src/netlink.c | 4 | ||||
-rw-r--r-- | src/noise.c | 6 | ||||
-rw-r--r-- | src/noise.h | 6 | ||||
-rw-r--r-- | src/peer.c | 2 | ||||
-rw-r--r-- | src/peer.h | 4 | ||||
-rw-r--r-- | src/ratelimiter.c | 6 | ||||
-rw-r--r-- | src/receive.c | 12 | ||||
-rw-r--r-- | src/send.c | 13 | ||||
-rw-r--r-- | src/timers.c | 20 | ||||
-rw-r--r-- | src/timers.h | 5 |
15 files changed, 69 insertions, 64 deletions
diff --git a/src/compat/compat.h b/src/compat/compat.h index ba2f028..d0efdb9 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -84,13 +84,6 @@ #define IP6_ECN_set_ce(a, b) IP6_ECN_set_ce(b) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) -#define time_is_before_jiffies64(a) time_after64(get_jiffies_64(), a) -#define time_is_after_jiffies64(a) time_before64(get_jiffies_64(), a) -#define time_is_before_eq_jiffies64(a) time_after_eq64(get_jiffies_64(), a) -#define time_is_after_eq_jiffies64(a) time_before_eq64(get_jiffies_64(), a) -#endif - #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) && IS_ENABLED(CONFIG_IPV6) && !defined(ISRHEL7) #include <net/ipv6.h> struct ipv6_stub_type { @@ -335,9 +328,17 @@ static inline int get_random_bytes_wait(void *buf, int nbytes) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) && !defined(ISRHEL7) #include <linux/ktime.h> -static inline u64 ktime_get_ns(void) +static inline u64 ktime_get_boot_ns(void) +{ + return ktime_to_ns(ktime_get_boottime()); +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) && !defined(ISRHEL7) +#include <linux/ktime.h> +static inline bool ktime_after(const ktime_t cmp1, const ktime_t cmp2) { - return ktime_to_ns(ktime_get()); + return ktime_compare(cmp1, cmp2) > 0; } #endif diff --git a/src/cookie.c b/src/cookie.c index 41f6ddb..b7054fa 100644 --- a/src/cookie.c +++ b/src/cookie.c @@ -8,17 +8,17 @@ #include "device.h" #include "messages.h" #include "ratelimiter.h" +#include "timers.h" #include "crypto/blake2s.h" #include "crypto/chacha20poly1305.h" -#include <linux/jiffies.h> #include <net/ipv6.h> #include <crypto/algapi.h> void cookie_checker_init(struct cookie_checker *checker, struct wireguard_device *wg) { init_rwsem(&checker->secret_lock); - checker->secret_birthdate = get_jiffies_64(); + checker->secret_birthdate = ktime_get_boottime(); get_random_bytes(checker->secret, NOISE_HASH_LEN); checker->device = wg; } @@ -77,9 +77,9 @@ static void make_cookie(u8 cookie[COOKIE_LEN], struct sk_buff *skb, struct cooki { struct blake2s_state state; - if (!time_is_after_jiffies64(checker->secret_birthdate + COOKIE_SECRET_MAX_AGE)) { + if (has_expired(checker->secret_birthdate, COOKIE_SECRET_MAX_AGE)) { down_write(&checker->secret_lock); - checker->secret_birthdate = get_jiffies_64(); + checker->secret_birthdate = ktime_get_boottime(); get_random_bytes(checker->secret, NOISE_HASH_LEN); up_write(&checker->secret_lock); } @@ -141,7 +141,7 @@ void cookie_add_mac_to_packet(void *message, size_t len, struct wireguard_peer * up_write(&peer->latest_cookie.lock); down_read(&peer->latest_cookie.lock); - if (peer->latest_cookie.is_valid && time_is_after_jiffies64(peer->latest_cookie.birthdate + COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY)) + if (peer->latest_cookie.is_valid && !has_expired(peer->latest_cookie.birthdate, COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY)) compute_mac2(macs->mac2, message, len, peer->latest_cookie.cookie); else memset(macs->mac2, 0, COOKIE_LEN); @@ -182,7 +182,7 @@ void cookie_message_consume(struct message_handshake_cookie *src, struct wiregua if (ret) { down_write(&entry->peer->latest_cookie.lock); memcpy(entry->peer->latest_cookie.cookie, cookie, COOKIE_LEN); - entry->peer->latest_cookie.birthdate = get_jiffies_64(); + entry->peer->latest_cookie.birthdate = ktime_get_boottime(); entry->peer->latest_cookie.is_valid = true; entry->peer->latest_cookie.have_sent_mac1 = false; up_write(&entry->peer->latest_cookie.lock); diff --git a/src/cookie.h b/src/cookie.h index 9f519ef..e83c256 100644 --- a/src/cookie.h +++ b/src/cookie.h @@ -15,13 +15,13 @@ struct cookie_checker { u8 secret[NOISE_HASH_LEN]; u8 cookie_encryption_key[NOISE_SYMMETRIC_KEY_LEN]; u8 message_mac1_key[NOISE_SYMMETRIC_KEY_LEN]; - u64 secret_birthdate; + ktime_t secret_birthdate; struct rw_semaphore secret_lock; struct wireguard_device *device; }; struct cookie { - u64 birthdate; + ktime_t birthdate; bool is_valid; u8 cookie[COOKIE_LEN]; bool have_sent_mac1; diff --git a/src/device.c b/src/device.c index 40b9e5c..7d5df17 100644 --- a/src/device.c +++ b/src/device.c @@ -105,7 +105,7 @@ static int stop(struct net_device *dev) timers_stop(peer); noise_handshake_clear(&peer->handshake); noise_keypairs_clear(&peer->keypairs); - peer->last_sent_handshake = get_jiffies_64() - REKEY_TIMEOUT - HZ; + peer->last_sent_handshake = ktime_sub_ns(ktime_get_boottime(), (u64)(REKEY_TIMEOUT + 1) * NSEC_PER_SEC); } mutex_unlock(&wg->device_update_lock); skb_queue_purge(&wg->incoming_handshakes); diff --git a/src/messages.h b/src/messages.h index f3d47ef..2983af0 100644 --- a/src/messages.h +++ b/src/messages.h @@ -27,8 +27,8 @@ enum noise_lengths { #define noise_encrypted_len(plain_len) (plain_len + NOISE_AUTHTAG_LEN) enum cookie_values { - COOKIE_SECRET_MAX_AGE = 2 * 60 * HZ, - COOKIE_SECRET_LATENCY = 5 * HZ, + COOKIE_SECRET_MAX_AGE = 2 * 60, + COOKIE_SECRET_LATENCY = 5, COOKIE_NONCE_LEN = XCHACHA20POLY1305_NONCELEN, COOKIE_LEN = 16 }; @@ -42,14 +42,14 @@ enum counter_values { enum limits { REKEY_AFTER_MESSAGES = U64_MAX - 0xffff, REJECT_AFTER_MESSAGES = U64_MAX - COUNTER_WINDOW_SIZE - 1, - REKEY_TIMEOUT = 5 * HZ, - REKEY_TIMEOUT_JITTER_MAX = HZ / 3, - REKEY_AFTER_TIME = 120 * HZ, - REJECT_AFTER_TIME = 180 * HZ, - INITIATIONS_PER_SECOND = HZ / 50, + REKEY_TIMEOUT = 5, + REKEY_TIMEOUT_JITTER_MAX_JIFFIES = HZ / 3, + REKEY_AFTER_TIME = 120, + REJECT_AFTER_TIME = 180, + INITIATIONS_PER_SECOND = 50, MAX_PEERS_PER_DEVICE = 1U << 20, - KEEPALIVE_TIMEOUT = 10 * HZ, - MAX_TIMER_HANDSHAKES = (90 * HZ) / REKEY_TIMEOUT, + KEEPALIVE_TIMEOUT = 10, + MAX_TIMER_HANDSHAKES = 90 / REKEY_TIMEOUT, MAX_QUEUED_INCOMING_HANDSHAKES = 4096, /* TODO: replace this with DQL */ MAX_STAGED_PACKETS = 128, MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */ diff --git a/src/netlink.c b/src/netlink.c index 2f5157d..aef743f 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -110,7 +110,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 timespec), &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) || 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; @@ -376,7 +376,7 @@ static int set_peer(struct wireguard_device *wg, struct nlattr **attrs) const u16 persistent_keepalive_interval = nla_get_u16(attrs[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]); const bool send_keepalive = !peer->persistent_keepalive_interval && persistent_keepalive_interval && netif_running(wg->dev); - peer->persistent_keepalive_interval = (unsigned long)persistent_keepalive_interval * HZ; + peer->persistent_keepalive_interval = persistent_keepalive_interval; if (send_keepalive) packet_send_keepalive(peer); } diff --git a/src/noise.c b/src/noise.c index b3e5f8f..7b3c4d6 100644 --- a/src/noise.c +++ b/src/noise.c @@ -284,7 +284,7 @@ static void symmetric_key_init(struct noise_symmetric_key *key) spin_lock_init(&key->counter.receive.lock); atomic64_set(&key->counter.counter, 0); memset(key->counter.receive.backtrack, 0, sizeof(key->counter.receive.backtrack)); - key->birthdate = get_jiffies_64(); + key->birthdate = ktime_get_boottime(); key->is_valid = true; } @@ -461,7 +461,7 @@ struct wireguard_peer *noise_handshake_consume_initiation(struct message_handsha down_read(&handshake->lock); replay_attack = memcmp(t, handshake->latest_timestamp, NOISE_TIMESTAMP_LEN) <= 0; - flood_attack = !time_is_before_jiffies64(handshake->last_initiation_consumption + INITIATIONS_PER_SECOND); + flood_attack = ktime_after(ktime_add_ns(handshake->last_initiation_consumption, NSEC_PER_SEC / INITIATIONS_PER_SECOND), ktime_get_boottime()); up_read(&handshake->lock); if (replay_attack || flood_attack) { peer_put(wg_peer); @@ -476,7 +476,7 @@ struct wireguard_peer *noise_handshake_consume_initiation(struct message_handsha memcpy(handshake->hash, hash, NOISE_HASH_LEN); memcpy(handshake->chaining_key, chaining_key, NOISE_HASH_LEN); handshake->remote_index = src->sender_index; - handshake->last_initiation_consumption = get_jiffies_64(); + handshake->last_initiation_consumption = ktime_get_boottime(); handshake->state = HANDSHAKE_CONSUMED_INITIATION; up_write(&handshake->lock); diff --git a/src/noise.h b/src/noise.h index 5eb3a88..ec1a59d 100644 --- a/src/noise.h +++ b/src/noise.h @@ -16,7 +16,7 @@ #include <linux/atomic.h> #include <linux/rwsem.h> #include <linux/mutex.h> -#include <linux/jiffies.h> +#include <linux/ktime.h> #include <linux/kref.h> union noise_counter { @@ -31,7 +31,7 @@ union noise_counter { struct noise_symmetric_key { u8 key[NOISE_SYMMETRIC_KEY_LEN]; union noise_counter counter; - u64 birthdate; + ktime_t birthdate; bool is_valid; }; @@ -72,7 +72,7 @@ struct noise_handshake { struct index_hashtable_entry entry; enum noise_handshake_state state; - u64 last_initiation_consumption; + ktime_t last_initiation_consumption; struct noise_static_identity *static_identity; @@ -55,7 +55,7 @@ struct wireguard_peer *peer_create(struct wireguard_device *wg, const u8 public_ skb_queue_head_init(&peer->staged_packet_queue); list_add_tail(&peer->peer_list, &wg->peer_list); pubkey_hashtable_add(&wg->peer_hashtable, peer); - peer->last_sent_handshake = get_jiffies_64() - REKEY_TIMEOUT - HZ; + peer->last_sent_handshake = ktime_sub_ns(ktime_get_boottime(), (u64)(REKEY_TIMEOUT + 1) * NSEC_PER_SEC); pr_debug("%s: Peer %llu created\n", wg->dev->name, peer->internal_id); return peer; } @@ -43,14 +43,14 @@ struct wireguard_peer { struct dst_cache endpoint_cache; rwlock_t endpoint_lock; struct noise_handshake handshake; - u64 last_sent_handshake; + ktime_t last_sent_handshake; struct work_struct transmit_handshake_work, clear_peer_work; struct cookie latest_cookie; struct hlist_node pubkey_hash; u64 rx_bytes, tx_bytes; struct timer_list timer_retransmit_handshake, timer_send_keepalive, timer_new_handshake, timer_zero_key_material, timer_persistent_keepalive; unsigned int timer_handshake_attempts; - unsigned long persistent_keepalive_interval; + u16 persistent_keepalive_interval; bool timers_enabled, timer_need_another_keepalive, sent_lastminute_handshake; struct timespec walltime_last_handshake; struct kref refcount; diff --git a/src/ratelimiter.c b/src/ratelimiter.c index e1afcd6..e35bf64 100644 --- a/src/ratelimiter.c +++ b/src/ratelimiter.c @@ -57,7 +57,7 @@ static void gc_entries(struct work_struct *work) unsigned int i; struct ratelimiter_entry *entry; struct hlist_node *temp; - const u64 now = ktime_get_ns(); + const u64 now = ktime_get_boot_ns(); for (i = 0; i < table_size; ++i) { spin_lock(&table_lock); @@ -107,7 +107,7 @@ bool ratelimiter_allow(struct sk_buff *skb, struct net *net) * tokens, rather than as part of the rate. */ spin_lock(&entry->lock); - now = ktime_get_ns(); + now = ktime_get_boot_ns(); tokens = min_t(u64, TOKEN_MAX, entry->tokens + now - entry->last_time_ns); entry->last_time_ns = now; ret = tokens >= PACKET_COST; @@ -130,7 +130,7 @@ bool ratelimiter_allow(struct sk_buff *skb, struct net *net) entry->ip = data.ip; INIT_HLIST_NODE(&entry->hash); spin_lock_init(&entry->lock); - entry->last_time_ns = ktime_get_ns(); + entry->last_time_ns = ktime_get_boot_ns(); entry->tokens = TOKEN_MAX - PACKET_COST; spin_lock(&table_lock); hlist_add_head_rcu(&entry->hash, bucket); diff --git a/src/receive.c b/src/receive.c index ac23e47..080e466 100644 --- a/src/receive.c +++ b/src/receive.c @@ -80,7 +80,7 @@ static inline int skb_prepare_header(struct sk_buff *skb, struct wireguard_devic static void receive_handshake_packet(struct wireguard_device *wg, struct sk_buff *skb) { - static u64 last_under_load; /* Yes this is global, so that our load calculation applies to the whole system. */ + static ktime_t last_under_load; /* Yes this is global, so that our load calculation applies to the whole system. */ struct wireguard_peer *peer = NULL; bool under_load; enum cookie_mac_state mac_state; @@ -94,9 +94,9 @@ static void receive_handshake_packet(struct wireguard_device *wg, struct sk_buff under_load = skb_queue_len(&wg->incoming_handshakes) >= MAX_QUEUED_INCOMING_HANDSHAKES / 8; if (under_load) - last_under_load = get_jiffies_64(); - else if (last_under_load) - under_load = time_is_after_jiffies64(last_under_load + HZ); + last_under_load = ktime_get_boottime(); + else if (ktime_to_ns(last_under_load)) + under_load = !has_expired(last_under_load, 1); mac_state = cookie_validate_packet(&wg->cookie_checker, skb, under_load); if ((under_load && mac_state == VALID_MAC_WITH_COOKIE) || (!under_load && mac_state == VALID_MAC_BUT_NO_COOKIE)) packet_needs_cookie = false; @@ -190,7 +190,7 @@ static inline void keep_key_fresh(struct wireguard_peer *peer) rcu_read_lock_bh(); keypair = rcu_dereference_bh(peer->keypairs.current_keypair); if (likely(keypair && keypair->sending.is_valid) && keypair->i_am_the_initiator && - unlikely(time_is_before_eq_jiffies64(keypair->sending.birthdate + REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT))) + unlikely(has_expired(keypair->sending.birthdate, REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT))) send = true; rcu_read_unlock_bh(); @@ -210,7 +210,7 @@ static inline bool skb_decrypt(struct sk_buff *skb, struct noise_symmetric_key * if (unlikely(!key)) return false; - if (unlikely(!key->is_valid || time_is_before_eq_jiffies64(key->birthdate + REJECT_AFTER_TIME) || key->counter.receive.counter >= REJECT_AFTER_MESSAGES)) { + if (unlikely(!key->is_valid || has_expired(key->birthdate, REJECT_AFTER_TIME) || key->counter.receive.counter >= REJECT_AFTER_MESSAGES)) { key->is_valid = false; return false; } @@ -15,7 +15,6 @@ #include <linux/uio.h> #include <linux/inetdevice.h> #include <linux/socket.h> -#include <linux/jiffies.h> #include <net/ip_tunnels.h> #include <net/udp.h> #include <net/sock.h> @@ -25,11 +24,11 @@ static void packet_send_handshake_initiation(struct wireguard_peer *peer) struct message_handshake_initiation packet; down_write(&peer->handshake.lock); - if (!time_is_before_jiffies64(peer->last_sent_handshake + REKEY_TIMEOUT)) { + if (!has_expired(peer->last_sent_handshake, REKEY_TIMEOUT)) { up_write(&peer->handshake.lock); return; /* This function is rate limited. */ } - peer->last_sent_handshake = get_jiffies_64(); + peer->last_sent_handshake = ktime_get_boottime(); up_write(&peer->handshake.lock); net_dbg_ratelimited("%s: Sending handshake initiation to peer %llu (%pISpfsc)\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr); @@ -59,7 +58,7 @@ void packet_send_queued_handshake_initiation(struct wireguard_peer *peer, bool i /* First checking the timestamp here is just an optimization; it will * be caught while properly locked inside the actual work queue. */ - if (!time_is_before_jiffies64(peer->last_sent_handshake + REKEY_TIMEOUT)) + if (!has_expired(peer->last_sent_handshake, REKEY_TIMEOUT)) return; peer = peer_rcu_get(peer); @@ -73,7 +72,7 @@ void packet_send_handshake_response(struct wireguard_peer *peer) struct message_handshake_response packet; net_dbg_ratelimited("%s: Sending handshake response to peer %llu (%pISpfsc)\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr); - peer->last_sent_handshake = get_jiffies_64(); + peer->last_sent_handshake = ktime_get_boottime(); if (noise_handshake_create_response(&packet, &peer->handshake)) { cookie_add_mac_to_packet(&packet, sizeof(packet), peer); @@ -104,7 +103,7 @@ static inline void keep_key_fresh(struct wireguard_peer *peer) keypair = rcu_dereference_bh(peer->keypairs.current_keypair); if (likely(keypair && keypair->sending.is_valid) && (unlikely(atomic64_read(&keypair->sending.counter.counter) > REKEY_AFTER_MESSAGES) || - (keypair->i_am_the_initiator && unlikely(time_is_before_eq_jiffies64(keypair->sending.birthdate + REKEY_AFTER_TIME))))) + (keypair->i_am_the_initiator && unlikely(has_expired(keypair->sending.birthdate, REKEY_AFTER_TIME))))) send = true; rcu_read_unlock_bh(); @@ -306,7 +305,7 @@ void packet_send_staged_packets(struct wireguard_peer *peer) key = &keypair->sending; if (unlikely(!key || !key->is_valid)) goto out_nokey; - if (unlikely(time_is_before_eq_jiffies64(key->birthdate + REJECT_AFTER_TIME))) + if (unlikely(has_expired(key->birthdate, REJECT_AFTER_TIME))) goto out_invalid; /* After we know we have a somewhat valid key, we now try to assign nonces to diff --git a/src/timers.c b/src/timers.c index d3150de..d351fde 100644 --- a/src/timers.c +++ b/src/timers.c @@ -45,10 +45,10 @@ static void expired_retransmit_handshake(struct timer_list *timer) * of a partial exchange. */ if (likely(timers_active(peer)) && !timer_pending(&peer->timer_zero_key_material)) - mod_timer(&peer->timer_zero_key_material, jiffies + (REJECT_AFTER_TIME * 3)); + mod_timer(&peer->timer_zero_key_material, jiffies + REJECT_AFTER_TIME * 3 * HZ); } else { ++peer->timer_handshake_attempts; - pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr, REKEY_TIMEOUT / HZ, peer->timer_handshake_attempts + 1); + pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr, REKEY_TIMEOUT, peer->timer_handshake_attempts + 1); /* We clear the endpoint address src address, in case this is the cause of trouble. */ socket_clear_peer_endpoint_src(peer); @@ -66,7 +66,7 @@ static void expired_send_keepalive(struct timer_list *timer) if (peer->timer_need_another_keepalive) { peer->timer_need_another_keepalive = false; if (likely(timers_active(peer))) - mod_timer(&peer->timer_send_keepalive, jiffies + KEEPALIVE_TIMEOUT); + mod_timer(&peer->timer_send_keepalive, jiffies + KEEPALIVE_TIMEOUT * HZ); } peer_put(peer); } @@ -75,7 +75,7 @@ static void expired_new_handshake(struct timer_list *timer) { peer_get_from_timer(timer_new_handshake); - pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr, (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) / HZ); + pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr, KEEPALIVE_TIMEOUT + REKEY_TIMEOUT); /* We clear the endpoint address src address, in case this is the cause of trouble. */ socket_clear_peer_endpoint_src(peer); packet_send_queued_handshake_initiation(peer, false); @@ -93,7 +93,7 @@ static void queued_expired_zero_key_material(struct work_struct *work) { struct wireguard_peer *peer = container_of(work, struct wireguard_peer, clear_peer_work); - pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr, (REJECT_AFTER_TIME * 3) / HZ); + pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr, REJECT_AFTER_TIME * 3); noise_handshake_clear(&peer->handshake); noise_keypairs_clear(&peer->keypairs); peer_put(peer); @@ -112,7 +112,7 @@ static void expired_send_persistent_keepalive(struct timer_list *timer) void timers_data_sent(struct wireguard_peer *peer) { if (likely(timers_active(peer)) && !timer_pending(&peer->timer_new_handshake)) - mod_timer(&peer->timer_new_handshake, jiffies + KEEPALIVE_TIMEOUT + REKEY_TIMEOUT); + mod_timer(&peer->timer_new_handshake, jiffies + (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * HZ); } /* Should be called after an authenticated data packet is received. */ @@ -120,7 +120,7 @@ void timers_data_received(struct wireguard_peer *peer) { if (likely(timers_active(peer))) { if (!timer_pending(&peer->timer_send_keepalive)) - mod_timer(&peer->timer_send_keepalive, jiffies + KEEPALIVE_TIMEOUT); + mod_timer(&peer->timer_send_keepalive, jiffies + KEEPALIVE_TIMEOUT * HZ); else peer->timer_need_another_keepalive = true; } @@ -144,7 +144,7 @@ void timers_any_authenticated_packet_received(struct wireguard_peer *peer) void timers_handshake_initiated(struct wireguard_peer *peer) { if (likely(timers_active(peer))) - mod_timer(&peer->timer_retransmit_handshake, jiffies + REKEY_TIMEOUT + prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX)); + mod_timer(&peer->timer_retransmit_handshake, jiffies + REKEY_TIMEOUT * HZ + prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); } /* Should be called after a handshake response message is received and processed or when getting key confirmation via the first data message. */ @@ -161,14 +161,14 @@ void timers_handshake_complete(struct wireguard_peer *peer) void timers_session_derived(struct wireguard_peer *peer) { if (likely(timers_active(peer))) - mod_timer(&peer->timer_zero_key_material, jiffies + (REJECT_AFTER_TIME * 3)); + mod_timer(&peer->timer_zero_key_material, jiffies + REJECT_AFTER_TIME * 3 * HZ); } /* Should be called before a packet with authentication -- keepalive, data, or handshake -- is sent, or after one is received. */ void timers_any_authenticated_packet_traversal(struct wireguard_peer *peer) { if (peer->persistent_keepalive_interval && likely(timers_active(peer))) - mod_timer(&peer->timer_persistent_keepalive, jiffies + peer->persistent_keepalive_interval); + mod_timer(&peer->timer_persistent_keepalive, jiffies + peer->persistent_keepalive_interval * HZ); } void timers_init(struct wireguard_peer *peer) diff --git a/src/timers.h b/src/timers.h index 6c67a6a..5a691c8 100644 --- a/src/timers.h +++ b/src/timers.h @@ -19,4 +19,9 @@ void timers_handshake_complete(struct wireguard_peer *peer); void timers_session_derived(struct wireguard_peer *peer); void timers_any_authenticated_packet_traversal(struct wireguard_peer *peer); +static inline bool has_expired(ktime_t birthday, u64 expiration_seconds) +{ + return !ktime_after(ktime_add_ns(birthday, expiration_seconds * NSEC_PER_SEC), ktime_get_boottime()); +} + #endif /* _WG_TIMERS_H */ |