summaryrefslogtreecommitdiffhomepage
path: root/src/receive.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/receive.c')
-rw-r--r--src/receive.c29
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)) {