diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-10-19 15:46:28 +0900 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-10-19 17:22:13 +0900 |
commit | 09847c27d4b9af8ce296215ed270ebfb4d08b23c (patch) | |
tree | 3465992e6488c7b685a166e08387ddebeb53604d /src/send.c | |
parent | timers: always delay handshakes for responder (diff) | |
download | wireguard-monolithic-historical-09847c27d4b9af8ce296215ed270ebfb4d08b23c.tar.xz wireguard-monolithic-historical-09847c27d4b9af8ce296215ed270ebfb4d08b23c.zip |
timers: only have initiator rekey
If it's time to rekey, and the responder sends a message, the initator
will begin the rekeying when sending his response message. In the worst
case, this response message will actually just be the keepalive. This
generally works well, with the one edge case of the message arriving
less than 10 seconds before key expiration, in which the keepalive is
not sufficient. In this case, we simply rehandshake immediately.
Diffstat (limited to 'src/send.c')
-rw-r--r-- | src/send.c | 42 |
1 files changed, 15 insertions, 27 deletions
@@ -31,6 +31,12 @@ void packet_send_handshake_initiation(struct wireguard_peer *peer) } } +void packet_send_handshake_initiation_ratelimited(struct wireguard_peer *peer) +{ + if (time_is_before_jiffies64(peer->last_sent_handshake + REKEY_TIMEOUT)) + packet_queue_send_handshake_initiation(peer); +} + void packet_send_handshake_response(struct wireguard_peer *peer) { struct message_handshake_response packet; @@ -68,12 +74,6 @@ void packet_queue_send_handshake_initiation(struct wireguard_peer *peer) peer_put(peer); /* If the work was already queued, we want to drop the extra reference */ } -static inline void ratelimit_packet_send_handshake_initiation(struct wireguard_peer *peer) -{ - if (time_is_before_jiffies64(peer->last_sent_handshake + REKEY_TIMEOUT)) - packet_queue_send_handshake_initiation(peer); -} - void packet_send_handshake_cookie(struct wireguard_device *wg, struct sk_buff *initiating_skb, void *data, size_t data_len, __le32 sender_index) { struct message_handshake_cookie packet; @@ -90,30 +90,18 @@ void packet_send_handshake_cookie(struct wireguard_device *wg, struct sk_buff *i static inline void keep_key_fresh(struct wireguard_peer *peer) { struct noise_keypair *keypair; + bool send = false; rcu_read_lock(); keypair = rcu_dereference(peer->keypairs.current_keypair); - if (unlikely(!keypair || !keypair->sending.is_valid)) { - rcu_read_unlock(); - return; - } + 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))))) + send = true; + rcu_read_unlock(); - if (atomic64_read(&keypair->sending.counter.counter) > REKEY_AFTER_MESSAGES || - time_is_before_eq_jiffies64(keypair->sending.birthdate + REKEY_AFTER_TIME)) { - rcu_read_unlock(); - /* The initiator can try it immediately, but the responder has to wait a bit, - * to prevent the thundering herd effect. */ - if (keypair->i_am_the_initiator) - ratelimit_packet_send_handshake_initiation(peer); - else { - /* If it's going to be dead soon, we rekey early. */ - if (time_is_before_eq_jiffies64(keypair->sending.birthdate + REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT)) - timers_delay_handshake(peer, REKEY_TIMEOUT / 2); - else /* Otherwise rekey at the usual staggered delay. */ - timers_delay_handshake(peer, REKEY_TIMEOUT / 2 + REKEY_TIMEOUT * 2); - } - } else - rcu_read_unlock(); + if (send) + packet_send_handshake_initiation_ratelimited(peer); } void packet_send_keepalive(struct wireguard_peer *peer) @@ -233,7 +221,7 @@ int packet_send_queue(struct wireguard_peer *peer) case -ENOKEY: /* ENOKEY means that we don't have a valid session for the peer, which * means we should initiate a session, and then requeue everything. */ - ratelimit_packet_send_handshake_initiation(peer); + packet_send_handshake_initiation_ratelimited(peer); goto requeue; case -EBUSY: /* EBUSY happens when the parallel workers are all filled up, in which |