diff options
Diffstat (limited to 'src/receive.c')
-rw-r--r-- | src/receive.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/receive.c b/src/receive.c index 58a0086..6dda410 100644 --- a/src/receive.c +++ b/src/receive.c @@ -123,7 +123,6 @@ static void receive_handshake_packet(struct wireguard_device *wg, void *data, si return; } net_dbg_ratelimited("Receiving handshake initiation from peer %Lu (%pISpfsc)\n", peer->internal_id, &addr); - timers_handshake_received(peer); update_latest_addr(peer, skb); packet_send_handshake_response(peer); break; @@ -139,10 +138,10 @@ static void receive_handshake_packet(struct wireguard_device *wg, void *data, si return; } net_dbg_ratelimited("Receiving handshake response from peer %Lu (%pISpfsc)\n", peer->internal_id, &addr); - timers_handshake_received(peer); if (noise_handshake_begin_session(&peer->handshake, &peer->keypairs, true)) { timers_ephemeral_key_created(peer); timers_handshake_complete(peer); + peer->sent_lastminute_handshake = false; packet_send_queue(peer); } break; @@ -179,6 +178,26 @@ void packet_process_queued_handshake_packets(struct work_struct *work) } } +static void keep_key_fresh(struct wireguard_peer *peer) +{ + struct noise_keypair *keypair; + bool send = false; + if (peer->sent_lastminute_handshake) + return; + + rcu_read_lock(); + keypair = rcu_dereference(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))) + send = true; + rcu_read_unlock(); + + if (send) { + peer->sent_lastminute_handshake = true; + packet_send_handshake_initiation_ratelimited(peer); + } +} + struct packet_cb { u8 ds; }; @@ -198,8 +217,12 @@ static void receive_data_packet(struct sk_buff *skb, struct wireguard_peer *peer wg = peer->device; dev = netdev_pub(wg); - if (unlikely(used_new_key)) + if (unlikely(used_new_key)) { + peer->sent_lastminute_handshake = false; packet_send_queue(peer); + } + + keep_key_fresh(peer); /* A packet with length 0 is a keepalive packet */ if (unlikely(!skb->len)) { |