1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. |
4 | */ |
5 | |
6 | #include "timers.h" |
7 | #include "device.h" |
8 | #include "peer.h" |
9 | #include "queueing.h" |
10 | #include "socket.h" |
11 | |
12 | /* |
13 | * - Timer for retransmitting the handshake if we don't hear back after |
14 | * `REKEY_TIMEOUT + jitter` ms. |
15 | * |
16 | * - Timer for sending empty packet if we have received a packet but after have |
17 | * not sent one for `KEEPALIVE_TIMEOUT` ms. |
18 | * |
19 | * - Timer for initiating new handshake if we have sent a packet but after have |
20 | * not received one (even empty) for `(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) + |
21 | * jitter` ms. |
22 | * |
23 | * - Timer for zeroing out all ephemeral keys after `(REJECT_AFTER_TIME * 3)` ms |
24 | * if no new keys have been received. |
25 | * |
26 | * - Timer for, if enabled, sending an empty authenticated packet every user- |
27 | * specified seconds. |
28 | */ |
29 | |
30 | static inline void mod_peer_timer(struct wg_peer *peer, |
31 | struct timer_list *timer, |
32 | unsigned long expires) |
33 | { |
34 | rcu_read_lock_bh(); |
35 | if (likely(netif_running(peer->device->dev) && |
36 | !READ_ONCE(peer->is_dead))) |
37 | mod_timer(timer, expires); |
38 | rcu_read_unlock_bh(); |
39 | } |
40 | |
41 | static void wg_expired_retransmit_handshake(struct timer_list *timer) |
42 | { |
43 | struct wg_peer *peer = from_timer(peer, timer, |
44 | timer_retransmit_handshake); |
45 | |
46 | if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) { |
47 | pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d attempts, giving up\n" , |
48 | peer->device->dev->name, peer->internal_id, |
49 | &peer->endpoint.addr, (int)MAX_TIMER_HANDSHAKES + 2); |
50 | |
51 | del_timer(timer: &peer->timer_send_keepalive); |
52 | /* We drop all packets without a keypair and don't try again, |
53 | * if we try unsuccessfully for too long to make a handshake. |
54 | */ |
55 | wg_packet_purge_staged_packets(peer); |
56 | |
57 | /* We set a timer for destroying any residue that might be left |
58 | * of a partial exchange. |
59 | */ |
60 | if (!timer_pending(timer: &peer->timer_zero_key_material)) |
61 | mod_peer_timer(peer, timer: &peer->timer_zero_key_material, |
62 | expires: jiffies + REJECT_AFTER_TIME * 3 * HZ); |
63 | } else { |
64 | ++peer->timer_handshake_attempts; |
65 | pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n" , |
66 | peer->device->dev->name, peer->internal_id, |
67 | &peer->endpoint.addr, (int)REKEY_TIMEOUT, |
68 | peer->timer_handshake_attempts + 1); |
69 | |
70 | /* We clear the endpoint address src address, in case this is |
71 | * the cause of trouble. |
72 | */ |
73 | wg_socket_clear_peer_endpoint_src(peer); |
74 | |
75 | wg_packet_send_queued_handshake_initiation(peer, is_retry: true); |
76 | } |
77 | } |
78 | |
79 | static void wg_expired_send_keepalive(struct timer_list *timer) |
80 | { |
81 | struct wg_peer *peer = from_timer(peer, timer, timer_send_keepalive); |
82 | |
83 | wg_packet_send_keepalive(peer); |
84 | if (peer->timer_need_another_keepalive) { |
85 | peer->timer_need_another_keepalive = false; |
86 | mod_peer_timer(peer, timer: &peer->timer_send_keepalive, |
87 | expires: jiffies + KEEPALIVE_TIMEOUT * HZ); |
88 | } |
89 | } |
90 | |
91 | static void wg_expired_new_handshake(struct timer_list *timer) |
92 | { |
93 | struct wg_peer *peer = from_timer(peer, timer, timer_new_handshake); |
94 | |
95 | pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n" , |
96 | peer->device->dev->name, peer->internal_id, |
97 | &peer->endpoint.addr, (int)(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT)); |
98 | /* We clear the endpoint address src address, in case this is the cause |
99 | * of trouble. |
100 | */ |
101 | wg_socket_clear_peer_endpoint_src(peer); |
102 | wg_packet_send_queued_handshake_initiation(peer, is_retry: false); |
103 | } |
104 | |
105 | static void wg_expired_zero_key_material(struct timer_list *timer) |
106 | { |
107 | struct wg_peer *peer = from_timer(peer, timer, timer_zero_key_material); |
108 | |
109 | rcu_read_lock_bh(); |
110 | if (!READ_ONCE(peer->is_dead)) { |
111 | wg_peer_get(peer); |
112 | if (!queue_work(wq: peer->device->handshake_send_wq, |
113 | work: &peer->clear_peer_work)) |
114 | /* If the work was already on the queue, we want to drop |
115 | * the extra reference. |
116 | */ |
117 | wg_peer_put(peer); |
118 | } |
119 | rcu_read_unlock_bh(); |
120 | } |
121 | |
122 | static void wg_queued_expired_zero_key_material(struct work_struct *work) |
123 | { |
124 | struct wg_peer *peer = container_of(work, struct wg_peer, |
125 | clear_peer_work); |
126 | |
127 | pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n" , |
128 | peer->device->dev->name, peer->internal_id, |
129 | &peer->endpoint.addr, (int)REJECT_AFTER_TIME * 3); |
130 | wg_noise_handshake_clear(handshake: &peer->handshake); |
131 | wg_noise_keypairs_clear(keypairs: &peer->keypairs); |
132 | wg_peer_put(peer); |
133 | } |
134 | |
135 | static void wg_expired_send_persistent_keepalive(struct timer_list *timer) |
136 | { |
137 | struct wg_peer *peer = from_timer(peer, timer, |
138 | timer_persistent_keepalive); |
139 | |
140 | if (likely(peer->persistent_keepalive_interval)) |
141 | wg_packet_send_keepalive(peer); |
142 | } |
143 | |
144 | /* Should be called after an authenticated data packet is sent. */ |
145 | void wg_timers_data_sent(struct wg_peer *peer) |
146 | { |
147 | if (!timer_pending(timer: &peer->timer_new_handshake)) |
148 | mod_peer_timer(peer, timer: &peer->timer_new_handshake, |
149 | expires: jiffies + (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * HZ + |
150 | get_random_u32_below(ceil: REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); |
151 | } |
152 | |
153 | /* Should be called after an authenticated data packet is received. */ |
154 | void wg_timers_data_received(struct wg_peer *peer) |
155 | { |
156 | if (likely(netif_running(peer->device->dev))) { |
157 | if (!timer_pending(timer: &peer->timer_send_keepalive)) |
158 | mod_peer_timer(peer, timer: &peer->timer_send_keepalive, |
159 | expires: jiffies + KEEPALIVE_TIMEOUT * HZ); |
160 | else |
161 | peer->timer_need_another_keepalive = true; |
162 | } |
163 | } |
164 | |
165 | /* Should be called after any type of authenticated packet is sent, whether |
166 | * keepalive, data, or handshake. |
167 | */ |
168 | void wg_timers_any_authenticated_packet_sent(struct wg_peer *peer) |
169 | { |
170 | del_timer(timer: &peer->timer_send_keepalive); |
171 | } |
172 | |
173 | /* Should be called after any type of authenticated packet is received, whether |
174 | * keepalive, data, or handshake. |
175 | */ |
176 | void wg_timers_any_authenticated_packet_received(struct wg_peer *peer) |
177 | { |
178 | del_timer(timer: &peer->timer_new_handshake); |
179 | } |
180 | |
181 | /* Should be called after a handshake initiation message is sent. */ |
182 | void wg_timers_handshake_initiated(struct wg_peer *peer) |
183 | { |
184 | mod_peer_timer(peer, timer: &peer->timer_retransmit_handshake, |
185 | expires: jiffies + REKEY_TIMEOUT * HZ + |
186 | get_random_u32_below(ceil: REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); |
187 | } |
188 | |
189 | /* Should be called after a handshake response message is received and processed |
190 | * or when getting key confirmation via the first data message. |
191 | */ |
192 | void wg_timers_handshake_complete(struct wg_peer *peer) |
193 | { |
194 | del_timer(timer: &peer->timer_retransmit_handshake); |
195 | peer->timer_handshake_attempts = 0; |
196 | peer->sent_lastminute_handshake = false; |
197 | ktime_get_real_ts64(tv: &peer->walltime_last_handshake); |
198 | } |
199 | |
200 | /* Should be called after an ephemeral key is created, which is before sending a |
201 | * handshake response or after receiving a handshake response. |
202 | */ |
203 | void wg_timers_session_derived(struct wg_peer *peer) |
204 | { |
205 | mod_peer_timer(peer, timer: &peer->timer_zero_key_material, |
206 | expires: jiffies + REJECT_AFTER_TIME * 3 * HZ); |
207 | } |
208 | |
209 | /* Should be called before a packet with authentication, whether |
210 | * keepalive, data, or handshakem is sent, or after one is received. |
211 | */ |
212 | void wg_timers_any_authenticated_packet_traversal(struct wg_peer *peer) |
213 | { |
214 | if (peer->persistent_keepalive_interval) |
215 | mod_peer_timer(peer, timer: &peer->timer_persistent_keepalive, |
216 | expires: jiffies + peer->persistent_keepalive_interval * HZ); |
217 | } |
218 | |
219 | void wg_timers_init(struct wg_peer *peer) |
220 | { |
221 | timer_setup(&peer->timer_retransmit_handshake, |
222 | wg_expired_retransmit_handshake, 0); |
223 | timer_setup(&peer->timer_send_keepalive, wg_expired_send_keepalive, 0); |
224 | timer_setup(&peer->timer_new_handshake, wg_expired_new_handshake, 0); |
225 | timer_setup(&peer->timer_zero_key_material, |
226 | wg_expired_zero_key_material, 0); |
227 | timer_setup(&peer->timer_persistent_keepalive, |
228 | wg_expired_send_persistent_keepalive, 0); |
229 | INIT_WORK(&peer->clear_peer_work, wg_queued_expired_zero_key_material); |
230 | peer->timer_handshake_attempts = 0; |
231 | peer->sent_lastminute_handshake = false; |
232 | peer->timer_need_another_keepalive = false; |
233 | } |
234 | |
235 | void wg_timers_stop(struct wg_peer *peer) |
236 | { |
237 | timer_delete_sync(timer: &peer->timer_retransmit_handshake); |
238 | timer_delete_sync(timer: &peer->timer_send_keepalive); |
239 | timer_delete_sync(timer: &peer->timer_new_handshake); |
240 | timer_delete_sync(timer: &peer->timer_zero_key_material); |
241 | timer_delete_sync(timer: &peer->timer_persistent_keepalive); |
242 | flush_work(work: &peer->clear_peer_work); |
243 | } |
244 | |