diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet_tunnels.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnels.c | 3728 |
1 files changed, 0 insertions, 3728 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c deleted file mode 100644 index cabbeed0c..000000000 --- a/src/cadet/gnunet-service-cadet_tunnels.c +++ /dev/null | |||
@@ -1,3728 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013, 2017, 2018 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file cadet/gnunet-service-cadet_tunnels.c | ||
22 | * @brief Information we track per tunnel. | ||
23 | * @author Bartlomiej Polot | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * FIXME: | ||
27 | * - proper connection evaluation during connection management: | ||
28 | * + consider quality (or quality spread?) of current connection set | ||
29 | * when deciding how often to do maintenance | ||
30 | * + interact with PEER to drive DHT GET/PUT operations based | ||
31 | * on how much we like our connections | ||
32 | */ | ||
33 | #include "platform.h" | ||
34 | #include "gnunet_util_lib.h" | ||
35 | #include "gnunet_statistics_service.h" | ||
36 | #include "gnunet_signatures.h" | ||
37 | #include "cadet_protocol.h" | ||
38 | #include "gnunet-service-cadet_channel.h" | ||
39 | #include "gnunet-service-cadet_connection.h" | ||
40 | #include "gnunet-service-cadet_tunnels.h" | ||
41 | #include "gnunet-service-cadet_peer.h" | ||
42 | #include "gnunet-service-cadet_paths.h" | ||
43 | |||
44 | |||
45 | #define LOG(level, ...) GNUNET_log_from (level, "cadet-tun", __VA_ARGS__) | ||
46 | |||
47 | /** | ||
48 | * How often do we try to decrypt payload with unverified key | ||
49 | * material? Used to limit CPU increase upon receiving bogus | ||
50 | * KX. | ||
51 | */ | ||
52 | #define MAX_UNVERIFIED_ATTEMPTS 16 | ||
53 | |||
54 | /** | ||
55 | * How long do we wait until tearing down an idle tunnel? | ||
56 | */ | ||
57 | #define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply ( \ | ||
58 | GNUNET_TIME_UNIT_SECONDS, 90) | ||
59 | |||
60 | /** | ||
61 | * How long do we wait initially before retransmitting the KX? | ||
62 | * TODO: replace by 2 RTT if/once we have connection-level RTT data! | ||
63 | */ | ||
64 | #define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply ( \ | ||
65 | GNUNET_TIME_UNIT_MILLISECONDS, 250) | ||
66 | |||
67 | /** | ||
68 | * Maximum number of skipped keys we keep in memory per tunnel. | ||
69 | */ | ||
70 | #define MAX_SKIPPED_KEYS 64 | ||
71 | |||
72 | /** | ||
73 | * Maximum number of keys (and thus ratchet steps) we are willing to | ||
74 | * skip before we decide this is either a bogus packet or a DoS-attempt. | ||
75 | */ | ||
76 | #define MAX_KEY_GAP 256 | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Struct to old keys for skipped messages while advancing the Axolotl ratchet. | ||
81 | */ | ||
82 | struct CadetTunnelSkippedKey | ||
83 | { | ||
84 | /** | ||
85 | * DLL next. | ||
86 | */ | ||
87 | struct CadetTunnelSkippedKey *next; | ||
88 | |||
89 | /** | ||
90 | * DLL prev. | ||
91 | */ | ||
92 | struct CadetTunnelSkippedKey *prev; | ||
93 | |||
94 | /** | ||
95 | * When was this key stored (for timeout). | ||
96 | */ | ||
97 | struct GNUNET_TIME_Absolute timestamp; | ||
98 | |||
99 | /** | ||
100 | * Header key. | ||
101 | */ | ||
102 | struct GNUNET_CRYPTO_SymmetricSessionKey HK; | ||
103 | |||
104 | /** | ||
105 | * Message key. | ||
106 | */ | ||
107 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
108 | |||
109 | /** | ||
110 | * Key number for a given HK. | ||
111 | */ | ||
112 | unsigned int Kn; | ||
113 | }; | ||
114 | |||
115 | |||
116 | /** | ||
117 | * Axolotl data, according to https://github.com/trevp/axolotl/wiki . | ||
118 | */ | ||
119 | struct CadetTunnelAxolotl | ||
120 | { | ||
121 | /** | ||
122 | * A (double linked) list of stored message keys and associated header keys | ||
123 | * for "skipped" messages, i.e. messages that have not been | ||
124 | * received despite the reception of more recent messages, (head). | ||
125 | */ | ||
126 | struct CadetTunnelSkippedKey *skipped_head; | ||
127 | |||
128 | /** | ||
129 | * Skipped messages' keys DLL, tail. | ||
130 | */ | ||
131 | struct CadetTunnelSkippedKey *skipped_tail; | ||
132 | |||
133 | /** | ||
134 | * 32-byte root key which gets updated by DH ratchet. | ||
135 | */ | ||
136 | struct GNUNET_CRYPTO_SymmetricSessionKey RK; | ||
137 | |||
138 | /** | ||
139 | * 32-byte header key (currently used for sending). | ||
140 | */ | ||
141 | struct GNUNET_CRYPTO_SymmetricSessionKey HKs; | ||
142 | |||
143 | /** | ||
144 | * 32-byte header key (currently used for receiving) | ||
145 | */ | ||
146 | struct GNUNET_CRYPTO_SymmetricSessionKey HKr; | ||
147 | |||
148 | /** | ||
149 | * 32-byte next header key (for sending), used once the | ||
150 | * ratchet advances. We are sure that the sender has this | ||
151 | * key as well only after @e ratchet_allowed is #GNUNET_YES. | ||
152 | */ | ||
153 | struct GNUNET_CRYPTO_SymmetricSessionKey NHKs; | ||
154 | |||
155 | /** | ||
156 | * 32-byte next header key (for receiving). To be tried | ||
157 | * when decrypting with @e HKr fails and thus the sender | ||
158 | * may have advanced the ratchet. | ||
159 | */ | ||
160 | struct GNUNET_CRYPTO_SymmetricSessionKey NHKr; | ||
161 | |||
162 | /** | ||
163 | * 32-byte chain keys (used for forward-secrecy) for | ||
164 | * sending messages. Updated for every message. | ||
165 | */ | ||
166 | struct GNUNET_CRYPTO_SymmetricSessionKey CKs; | ||
167 | |||
168 | /** | ||
169 | * 32-byte chain keys (used for forward-secrecy) for | ||
170 | * receiving messages. Updated for every message. If | ||
171 | * messages are skipped, the respective derived MKs | ||
172 | * (and the current @HKr) are kept in the @e skipped_head DLL. | ||
173 | */ | ||
174 | struct GNUNET_CRYPTO_SymmetricSessionKey CKr; | ||
175 | |||
176 | /** | ||
177 | * ECDH for key exchange (A0 / B0). | ||
178 | */ | ||
179 | struct GNUNET_CRYPTO_EcdhePrivateKey kx_0; | ||
180 | |||
181 | /** | ||
182 | * ECDH Ratchet key (our private key in the current DH). | ||
183 | */ | ||
184 | struct GNUNET_CRYPTO_EcdhePrivateKey DHRs; | ||
185 | |||
186 | /** | ||
187 | * ECDH Ratchet key (other peer's public key in the current DH). | ||
188 | */ | ||
189 | struct GNUNET_CRYPTO_EcdhePublicKey DHRr; | ||
190 | |||
191 | /** | ||
192 | * Last ephemeral public key received from the other peer, | ||
193 | * for duplicate detection. | ||
194 | */ | ||
195 | struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral; | ||
196 | |||
197 | /** | ||
198 | * Time when the current ratchet expires and a new one is triggered | ||
199 | * (if @e ratchet_allowed is #GNUNET_YES). | ||
200 | */ | ||
201 | struct GNUNET_TIME_Absolute ratchet_expiration; | ||
202 | |||
203 | /** | ||
204 | * Number of elements in @a skipped_head <-> @a skipped_tail. | ||
205 | */ | ||
206 | unsigned int skipped; | ||
207 | |||
208 | /** | ||
209 | * Message number (reset to 0 with each new ratchet, next message to send). | ||
210 | */ | ||
211 | uint32_t Ns; | ||
212 | |||
213 | /** | ||
214 | * Message number (reset to 0 with each new ratchet, next message to recv). | ||
215 | */ | ||
216 | uint32_t Nr; | ||
217 | |||
218 | /** | ||
219 | * Previous message numbers (# of msgs sent under prev ratchet) | ||
220 | */ | ||
221 | uint32_t PNs; | ||
222 | |||
223 | /** | ||
224 | * True (#GNUNET_YES) if we have to send a new ratchet key in next msg. | ||
225 | */ | ||
226 | int ratchet_flag; | ||
227 | |||
228 | /** | ||
229 | * True (#GNUNET_YES) if we have received a message from the | ||
230 | * other peer that uses the keys from our last ratchet step. | ||
231 | * This implies that we are again allowed to advance the ratchet, | ||
232 | * otherwise we have to wait until the other peer sees our current | ||
233 | * ephemeral key and advances first. | ||
234 | * | ||
235 | * #GNUNET_NO if we have advanced the ratched but lack any evidence | ||
236 | * that the other peer has noticed this. | ||
237 | */ | ||
238 | int ratchet_allowed; | ||
239 | |||
240 | /** | ||
241 | * Number of messages received since our last ratchet advance. | ||
242 | * | ||
243 | * If this counter = 0, we cannot send a new ratchet key in the next | ||
244 | * message. | ||
245 | * | ||
246 | * If this counter > 0, we could (but don't have to) send a new key. | ||
247 | * | ||
248 | * Once the @e ratchet_counter is larger than | ||
249 | * #ratchet_messages (or @e ratchet_expiration time has past), and | ||
250 | * @e ratchet_allowed is #GNUNET_YES, we advance the ratchet. | ||
251 | */ | ||
252 | unsigned int ratchet_counter; | ||
253 | }; | ||
254 | |||
255 | |||
256 | /** | ||
257 | * Struct used to save messages in a non-ready tunnel to send once connected. | ||
258 | */ | ||
259 | struct CadetTunnelQueueEntry | ||
260 | { | ||
261 | /** | ||
262 | * We are entries in a DLL | ||
263 | */ | ||
264 | struct CadetTunnelQueueEntry *next; | ||
265 | |||
266 | /** | ||
267 | * We are entries in a DLL | ||
268 | */ | ||
269 | struct CadetTunnelQueueEntry *prev; | ||
270 | |||
271 | /** | ||
272 | * Tunnel these messages belong in. | ||
273 | */ | ||
274 | struct CadetTunnel *t; | ||
275 | |||
276 | /** | ||
277 | * Continuation to call once sent (on the channel layer). | ||
278 | */ | ||
279 | GCT_SendContinuation cont; | ||
280 | |||
281 | /** | ||
282 | * Closure for @c cont. | ||
283 | */ | ||
284 | void *cont_cls; | ||
285 | |||
286 | /** | ||
287 | * Envelope of message to send follows. | ||
288 | */ | ||
289 | struct GNUNET_MQ_Envelope *env; | ||
290 | |||
291 | /** | ||
292 | * Where to put the connection identifier into the payload | ||
293 | * of the message in @e env once we have it? | ||
294 | */ | ||
295 | struct GNUNET_CADET_ConnectionTunnelIdentifier *cid; | ||
296 | }; | ||
297 | |||
298 | |||
299 | /** | ||
300 | * Struct containing all information regarding a tunnel to a peer. | ||
301 | */ | ||
302 | struct CadetTunnel | ||
303 | { | ||
304 | /** | ||
305 | * Destination of the tunnel. | ||
306 | */ | ||
307 | struct CadetPeer *destination; | ||
308 | |||
309 | /** | ||
310 | * Peer's ephemeral key, to recreate @c e_key and @c d_key when own | ||
311 | * ephemeral key changes. | ||
312 | */ | ||
313 | struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key; | ||
314 | |||
315 | /** | ||
316 | * Encryption ("our") key. It is only "confirmed" if kx_ctx is NULL. | ||
317 | */ | ||
318 | struct GNUNET_CRYPTO_SymmetricSessionKey e_key; | ||
319 | |||
320 | /** | ||
321 | * Decryption ("their") key. It is only "confirmed" if kx_ctx is NULL. | ||
322 | */ | ||
323 | struct GNUNET_CRYPTO_SymmetricSessionKey d_key; | ||
324 | |||
325 | /** | ||
326 | * Axolotl info. | ||
327 | */ | ||
328 | struct CadetTunnelAxolotl ax; | ||
329 | |||
330 | /** | ||
331 | * Unverified Axolotl info, used only if we got a fresh KX (not a | ||
332 | * KX_AUTH) while our end of the tunnel was still up. In this case, | ||
333 | * we keep the fresh KX around but do not put it into action until | ||
334 | * we got encrypted payload that assures us of the authenticity of | ||
335 | * the KX. | ||
336 | */ | ||
337 | struct CadetTunnelAxolotl *unverified_ax; | ||
338 | |||
339 | /** | ||
340 | * Task scheduled if there are no more channels using the tunnel. | ||
341 | */ | ||
342 | struct GNUNET_SCHEDULER_Task *destroy_task; | ||
343 | |||
344 | /** | ||
345 | * Task to trim connections if too many are present. | ||
346 | */ | ||
347 | struct GNUNET_SCHEDULER_Task *maintain_connections_task; | ||
348 | |||
349 | /** | ||
350 | * Task to send messages from queue (if possible). | ||
351 | */ | ||
352 | struct GNUNET_SCHEDULER_Task *send_task; | ||
353 | |||
354 | /** | ||
355 | * Task to trigger KX. | ||
356 | */ | ||
357 | struct GNUNET_SCHEDULER_Task *kx_task; | ||
358 | |||
359 | /** | ||
360 | * Tokenizer for decrypted messages. | ||
361 | */ | ||
362 | struct GNUNET_MessageStreamTokenizer *mst; | ||
363 | |||
364 | /** | ||
365 | * Dispatcher for decrypted messages only (do NOT use for sending!). | ||
366 | */ | ||
367 | struct GNUNET_MQ_Handle *mq; | ||
368 | |||
369 | /** | ||
370 | * DLL of ready connections that are actively used to reach the destination peer. | ||
371 | */ | ||
372 | struct CadetTConnection *connection_ready_head; | ||
373 | |||
374 | /** | ||
375 | * DLL of ready connections that are actively used to reach the destination peer. | ||
376 | */ | ||
377 | struct CadetTConnection *connection_ready_tail; | ||
378 | |||
379 | /** | ||
380 | * DLL of connections that we maintain that might be used to reach the destination peer. | ||
381 | */ | ||
382 | struct CadetTConnection *connection_busy_head; | ||
383 | |||
384 | /** | ||
385 | * DLL of connections that we maintain that might be used to reach the destination peer. | ||
386 | */ | ||
387 | struct CadetTConnection *connection_busy_tail; | ||
388 | |||
389 | /** | ||
390 | * Channels inside this tunnel. Maps | ||
391 | * `struct GNUNET_CADET_ChannelTunnelNumber` to a `struct CadetChannel`. | ||
392 | */ | ||
393 | struct GNUNET_CONTAINER_MultiHashMap32 *channels; | ||
394 | |||
395 | /** | ||
396 | * Channel ID for the next created channel in this tunnel. | ||
397 | */ | ||
398 | struct GNUNET_CADET_ChannelTunnelNumber next_ctn; | ||
399 | |||
400 | /** | ||
401 | * Queued messages, to transmit once tunnel gets connected. | ||
402 | */ | ||
403 | struct CadetTunnelQueueEntry *tq_head; | ||
404 | |||
405 | /** | ||
406 | * Queued messages, to transmit once tunnel gets connected. | ||
407 | */ | ||
408 | struct CadetTunnelQueueEntry *tq_tail; | ||
409 | |||
410 | /** | ||
411 | * Identification of the connection from which we are currently processing | ||
412 | * a message. Only valid (non-NULL) during #handle_decrypted() and the | ||
413 | * handle-*()-functions called from our @e mq during that function. | ||
414 | */ | ||
415 | struct CadetTConnection *current_ct; | ||
416 | |||
417 | /** | ||
418 | * How long do we wait until we retry the KX? | ||
419 | */ | ||
420 | struct GNUNET_TIME_Relative kx_retry_delay; | ||
421 | |||
422 | /** | ||
423 | * When do we try the next KX? | ||
424 | */ | ||
425 | struct GNUNET_TIME_Absolute next_kx_attempt; | ||
426 | |||
427 | /** | ||
428 | * Number of connections in the @e connection_ready_head DLL. | ||
429 | */ | ||
430 | unsigned int num_ready_connections; | ||
431 | |||
432 | /** | ||
433 | * Number of connections in the @e connection_busy_head DLL. | ||
434 | */ | ||
435 | unsigned int num_busy_connections; | ||
436 | |||
437 | /** | ||
438 | * How often have we tried and failed to decrypt a message using | ||
439 | * the unverified KX material from @e unverified_ax? Used to | ||
440 | * stop trying after #MAX_UNVERIFIED_ATTEMPTS. | ||
441 | */ | ||
442 | unsigned int unverified_attempts; | ||
443 | |||
444 | /** | ||
445 | * Number of entries in the @e tq_head DLL. | ||
446 | */ | ||
447 | unsigned int tq_len; | ||
448 | |||
449 | /** | ||
450 | * State of the tunnel encryption. | ||
451 | */ | ||
452 | enum CadetTunnelEState estate; | ||
453 | |||
454 | /** | ||
455 | * Force triggering KX_AUTH independent of @e estate. | ||
456 | */ | ||
457 | int kx_auth_requested; | ||
458 | }; | ||
459 | |||
460 | |||
461 | /** | ||
462 | * Am I Alice or Betty (some call her Bob), or talking to myself? | ||
463 | * | ||
464 | * @param other the other peer | ||
465 | * @return #GNUNET_YES for Alice, #GNUNET_NO for Betty, #GNUNET_SYSERR if talking to myself | ||
466 | */ | ||
467 | int | ||
468 | GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other) | ||
469 | { | ||
470 | if (0 > GNUNET_memcmp (&my_full_id, | ||
471 | other)) | ||
472 | return GNUNET_YES; | ||
473 | else if (0 < GNUNET_memcmp (&my_full_id, | ||
474 | other)) | ||
475 | return GNUNET_NO; | ||
476 | else | ||
477 | { | ||
478 | GNUNET_break_op (0); | ||
479 | return GNUNET_SYSERR; | ||
480 | } | ||
481 | } | ||
482 | |||
483 | |||
484 | /** | ||
485 | * Connection @a ct is now unready, clear it's ready flag | ||
486 | * and move it from the ready DLL to the busy DLL. | ||
487 | * | ||
488 | * @param ct connection to move to unready status | ||
489 | */ | ||
490 | static void | ||
491 | mark_connection_unready (struct CadetTConnection *ct) | ||
492 | { | ||
493 | struct CadetTunnel *t = ct->t; | ||
494 | |||
495 | GNUNET_assert (GNUNET_YES == ct->is_ready); | ||
496 | GNUNET_CONTAINER_DLL_remove (t->connection_ready_head, | ||
497 | t->connection_ready_tail, | ||
498 | ct); | ||
499 | GNUNET_assert (0 < t->num_ready_connections); | ||
500 | t->num_ready_connections--; | ||
501 | ct->is_ready = GNUNET_NO; | ||
502 | GNUNET_CONTAINER_DLL_insert (t->connection_busy_head, | ||
503 | t->connection_busy_tail, | ||
504 | ct); | ||
505 | t->num_busy_connections++; | ||
506 | } | ||
507 | |||
508 | |||
509 | /** | ||
510 | * Get the static string for the peer this tunnel is directed. | ||
511 | * | ||
512 | * @param t Tunnel. | ||
513 | * | ||
514 | * @return Static string the destination peer's ID. | ||
515 | */ | ||
516 | const char * | ||
517 | GCT_2s (const struct CadetTunnel *t) | ||
518 | { | ||
519 | static char buf[64]; | ||
520 | |||
521 | if (NULL == t) | ||
522 | return "Tunnel(NULL)"; | ||
523 | GNUNET_snprintf (buf, | ||
524 | sizeof(buf), | ||
525 | "Tunnel %s", | ||
526 | GNUNET_i2s (GCP_get_id (t->destination))); | ||
527 | return buf; | ||
528 | } | ||
529 | |||
530 | |||
531 | /** | ||
532 | * Get string description for tunnel encryption state. | ||
533 | * | ||
534 | * @param es Tunnel state. | ||
535 | * | ||
536 | * @return String representation. | ||
537 | */ | ||
538 | static const char * | ||
539 | estate2s (enum CadetTunnelEState es) | ||
540 | { | ||
541 | static char buf[32]; | ||
542 | |||
543 | switch (es) | ||
544 | { | ||
545 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
546 | return "CADET_TUNNEL_KEY_UNINITIALIZED"; | ||
547 | case CADET_TUNNEL_KEY_AX_RECV: | ||
548 | return "CADET_TUNNEL_KEY_AX_RECV"; | ||
549 | case CADET_TUNNEL_KEY_AX_SENT: | ||
550 | return "CADET_TUNNEL_KEY_AX_SENT"; | ||
551 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: | ||
552 | return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV"; | ||
553 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
554 | return "CADET_TUNNEL_KEY_AX_AUTH_SENT"; | ||
555 | case CADET_TUNNEL_KEY_OK: | ||
556 | return "CADET_TUNNEL_KEY_OK"; | ||
557 | } | ||
558 | GNUNET_snprintf (buf, | ||
559 | sizeof(buf), | ||
560 | "%u (UNKNOWN STATE)", | ||
561 | es); | ||
562 | return buf; | ||
563 | } | ||
564 | |||
565 | |||
566 | /** | ||
567 | * Return the peer to which this tunnel goes. | ||
568 | * | ||
569 | * @param t a tunnel | ||
570 | * @return the destination of the tunnel | ||
571 | */ | ||
572 | struct CadetPeer * | ||
573 | GCT_get_destination (struct CadetTunnel *t) | ||
574 | { | ||
575 | return t->destination; | ||
576 | } | ||
577 | |||
578 | |||
579 | /** | ||
580 | * Count channels of a tunnel. | ||
581 | * | ||
582 | * @param t Tunnel on which to count. | ||
583 | * | ||
584 | * @return Number of channels. | ||
585 | */ | ||
586 | unsigned int | ||
587 | GCT_count_channels (struct CadetTunnel *t) | ||
588 | { | ||
589 | return GNUNET_CONTAINER_multihashmap32_size (t->channels); | ||
590 | } | ||
591 | |||
592 | |||
593 | /** | ||
594 | * Lookup a channel by its @a ctn. | ||
595 | * | ||
596 | * @param t tunnel to look in | ||
597 | * @param ctn number of channel to find | ||
598 | * @return NULL if channel does not exist | ||
599 | */ | ||
600 | struct CadetChannel * | ||
601 | lookup_channel (struct CadetTunnel *t, | ||
602 | struct GNUNET_CADET_ChannelTunnelNumber ctn) | ||
603 | { | ||
604 | return GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
605 | ntohl (ctn.cn)); | ||
606 | } | ||
607 | |||
608 | |||
609 | /** | ||
610 | * Count all created connections of a tunnel. Not necessarily ready connections! | ||
611 | * | ||
612 | * @param t Tunnel on which to count. | ||
613 | * | ||
614 | * @return Number of connections created, either being established or ready. | ||
615 | */ | ||
616 | unsigned int | ||
617 | GCT_count_any_connections (const struct CadetTunnel *t) | ||
618 | { | ||
619 | return t->num_ready_connections + t->num_busy_connections; | ||
620 | } | ||
621 | |||
622 | |||
623 | /** | ||
624 | * Find first connection that is ready in the list of | ||
625 | * our connections. Picks ready connections round-robin. | ||
626 | * | ||
627 | * @param t tunnel to search | ||
628 | * @return NULL if we have no connection that is ready | ||
629 | */ | ||
630 | static struct CadetTConnection * | ||
631 | get_ready_connection (struct CadetTunnel *t) | ||
632 | { | ||
633 | struct CadetTConnection *hd = t->connection_ready_head; | ||
634 | |||
635 | GNUNET_assert ((NULL == hd) || | ||
636 | (GNUNET_YES == hd->is_ready)); | ||
637 | return hd; | ||
638 | } | ||
639 | |||
640 | |||
641 | /** | ||
642 | * Get the encryption state of a tunnel. | ||
643 | * | ||
644 | * @param t Tunnel. | ||
645 | * | ||
646 | * @return Tunnel's encryption state. | ||
647 | */ | ||
648 | enum CadetTunnelEState | ||
649 | GCT_get_estate (struct CadetTunnel *t) | ||
650 | { | ||
651 | return t->estate; | ||
652 | } | ||
653 | |||
654 | |||
655 | /** | ||
656 | * Called when either we have a new connection, or a new message in the | ||
657 | * queue, or some existing connection has transmission capacity. Looks | ||
658 | * at our message queue and if there is a message, picks a connection | ||
659 | * to send it on. | ||
660 | * | ||
661 | * @param cls the `struct CadetTunnel` to process messages on | ||
662 | */ | ||
663 | static void | ||
664 | trigger_transmissions (void *cls); | ||
665 | |||
666 | |||
667 | /* ************************************** start core crypto ***************************** */ | ||
668 | |||
669 | |||
670 | /** | ||
671 | * Create a new Axolotl ephemeral (ratchet) key. | ||
672 | * | ||
673 | * @param ax key material to update | ||
674 | */ | ||
675 | static void | ||
676 | new_ephemeral (struct CadetTunnelAxolotl *ax) | ||
677 | { | ||
678 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
679 | "Creating new ephemeral ratchet key (DHRs)\n"); | ||
680 | GNUNET_CRYPTO_ecdhe_key_create (&ax->DHRs); | ||
681 | } | ||
682 | |||
683 | |||
684 | /** | ||
685 | * Calculate HMAC. | ||
686 | * | ||
687 | * @param plaintext Content to HMAC. | ||
688 | * @param size Size of @c plaintext. | ||
689 | * @param iv Initialization vector for the message. | ||
690 | * @param key Key to use. | ||
691 | * @param hmac[out] Destination to store the HMAC. | ||
692 | */ | ||
693 | static void | ||
694 | t_hmac (const void *plaintext, | ||
695 | size_t size, | ||
696 | uint32_t iv, | ||
697 | const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
698 | struct GNUNET_ShortHashCode *hmac) | ||
699 | { | ||
700 | static const char ctx[] = "cadet authentication key"; | ||
701 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
702 | struct GNUNET_HashCode hash; | ||
703 | |||
704 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, | ||
705 | key, | ||
706 | &iv, sizeof(iv), | ||
707 | key, sizeof(*key), | ||
708 | ctx, sizeof(ctx), | ||
709 | NULL); | ||
710 | /* Two step: GNUNET_ShortHash is only 256 bits, | ||
711 | GNUNET_HashCode is 512, so we truncate. */ | ||
712 | GNUNET_CRYPTO_hmac (&auth_key, | ||
713 | plaintext, | ||
714 | size, | ||
715 | &hash); | ||
716 | GNUNET_memcpy (hmac, | ||
717 | &hash, | ||
718 | sizeof(*hmac)); | ||
719 | } | ||
720 | |||
721 | |||
722 | /** | ||
723 | * Perform a HMAC. | ||
724 | * | ||
725 | * @param key Key to use. | ||
726 | * @param[out] hash Resulting HMAC. | ||
727 | * @param source Source key material (data to HMAC). | ||
728 | * @param len Length of @a source. | ||
729 | */ | ||
730 | static void | ||
731 | t_ax_hmac_hash (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
732 | struct GNUNET_HashCode *hash, | ||
733 | const void *source, | ||
734 | unsigned int len) | ||
735 | { | ||
736 | static const char ctx[] = "axolotl HMAC-HASH"; | ||
737 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
738 | |||
739 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, | ||
740 | key, | ||
741 | ctx, sizeof(ctx), | ||
742 | NULL); | ||
743 | GNUNET_CRYPTO_hmac (&auth_key, | ||
744 | source, | ||
745 | len, | ||
746 | hash); | ||
747 | } | ||
748 | |||
749 | |||
750 | /** | ||
751 | * Derive a symmetric encryption key from an HMAC-HASH. | ||
752 | * | ||
753 | * @param key Key to use for the HMAC. | ||
754 | * @param[out] out Key to generate. | ||
755 | * @param source Source key material (data to HMAC). | ||
756 | * @param len Length of @a source. | ||
757 | */ | ||
758 | static void | ||
759 | t_hmac_derive_key (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
760 | struct GNUNET_CRYPTO_SymmetricSessionKey *out, | ||
761 | const void *source, | ||
762 | unsigned int len) | ||
763 | { | ||
764 | static const char ctx[] = "axolotl derive key"; | ||
765 | struct GNUNET_HashCode h; | ||
766 | |||
767 | t_ax_hmac_hash (key, | ||
768 | &h, | ||
769 | source, | ||
770 | len); | ||
771 | GNUNET_CRYPTO_kdf (out, sizeof(*out), | ||
772 | ctx, sizeof(ctx), | ||
773 | &h, sizeof(h), | ||
774 | NULL); | ||
775 | } | ||
776 | |||
777 | |||
778 | /** | ||
779 | * Encrypt data with the axolotl tunnel key. | ||
780 | * | ||
781 | * @param ax key material to use. | ||
782 | * @param dst Destination with @a size bytes for the encrypted data. | ||
783 | * @param src Source of the plaintext. Can overlap with @c dst, must contain @a size bytes | ||
784 | * @param size Size of the buffers at @a src and @a dst | ||
785 | */ | ||
786 | static void | ||
787 | t_ax_encrypt (struct CadetTunnelAxolotl *ax, | ||
788 | void *dst, | ||
789 | const void *src, | ||
790 | size_t size) | ||
791 | { | ||
792 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
793 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
794 | size_t out_size; | ||
795 | |||
796 | ax->ratchet_counter++; | ||
797 | if ((GNUNET_YES == ax->ratchet_allowed) && | ||
798 | ((ratchet_messages <= ax->ratchet_counter) || | ||
799 | (0 == GNUNET_TIME_absolute_get_remaining ( | ||
800 | ax->ratchet_expiration).rel_value_us))) | ||
801 | { | ||
802 | ax->ratchet_flag = GNUNET_YES; | ||
803 | } | ||
804 | if (GNUNET_YES == ax->ratchet_flag) | ||
805 | { | ||
806 | /* Advance ratchet */ | ||
807 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; | ||
808 | struct GNUNET_HashCode dh; | ||
809 | struct GNUNET_HashCode hmac; | ||
810 | static const char ctx[] = "axolotl ratchet"; | ||
811 | |||
812 | new_ephemeral (ax); | ||
813 | ax->HKs = ax->NHKs; | ||
814 | |||
815 | /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */ | ||
816 | GNUNET_CRYPTO_ecc_ecdh (&ax->DHRs, | ||
817 | &ax->DHRr, | ||
818 | &dh); | ||
819 | t_ax_hmac_hash (&ax->RK, | ||
820 | &hmac, | ||
821 | &dh, | ||
822 | sizeof(dh)); | ||
823 | GNUNET_CRYPTO_kdf (keys, sizeof(keys), | ||
824 | ctx, sizeof(ctx), | ||
825 | &hmac, sizeof(hmac), | ||
826 | NULL); | ||
827 | ax->RK = keys[0]; | ||
828 | ax->NHKs = keys[1]; | ||
829 | ax->CKs = keys[2]; | ||
830 | |||
831 | ax->PNs = ax->Ns; | ||
832 | ax->Ns = 0; | ||
833 | ax->ratchet_flag = GNUNET_NO; | ||
834 | ax->ratchet_allowed = GNUNET_NO; | ||
835 | ax->ratchet_counter = 0; | ||
836 | ax->ratchet_expiration | ||
837 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
838 | ratchet_time); | ||
839 | } | ||
840 | |||
841 | t_hmac_derive_key (&ax->CKs, | ||
842 | &MK, | ||
843 | "0", | ||
844 | 1); | ||
845 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
846 | &MK, | ||
847 | NULL, 0, | ||
848 | NULL); | ||
849 | |||
850 | out_size = GNUNET_CRYPTO_symmetric_encrypt (src, | ||
851 | size, | ||
852 | &MK, | ||
853 | &iv, | ||
854 | dst); | ||
855 | GNUNET_assert (size == out_size); | ||
856 | t_hmac_derive_key (&ax->CKs, | ||
857 | &ax->CKs, | ||
858 | "1", | ||
859 | 1); | ||
860 | } | ||
861 | |||
862 | |||
863 | /** | ||
864 | * Decrypt data with the axolotl tunnel key. | ||
865 | * | ||
866 | * @param ax key material to use. | ||
867 | * @param dst Destination for the decrypted data, must contain @a size bytes. | ||
868 | * @param src Source of the ciphertext. Can overlap with @c dst, must contain @a size bytes. | ||
869 | * @param size Size of the @a src and @a dst buffers | ||
870 | */ | ||
871 | static void | ||
872 | t_ax_decrypt (struct CadetTunnelAxolotl *ax, | ||
873 | void *dst, | ||
874 | const void *src, | ||
875 | size_t size) | ||
876 | { | ||
877 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
878 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
879 | size_t out_size; | ||
880 | |||
881 | t_hmac_derive_key (&ax->CKr, | ||
882 | &MK, | ||
883 | "0", | ||
884 | 1); | ||
885 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
886 | &MK, | ||
887 | NULL, 0, | ||
888 | NULL); | ||
889 | GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader)); | ||
890 | out_size = GNUNET_CRYPTO_symmetric_decrypt (src, | ||
891 | size, | ||
892 | &MK, | ||
893 | &iv, | ||
894 | dst); | ||
895 | GNUNET_assert (out_size == size); | ||
896 | t_hmac_derive_key (&ax->CKr, | ||
897 | &ax->CKr, | ||
898 | "1", | ||
899 | 1); | ||
900 | } | ||
901 | |||
902 | |||
903 | /** | ||
904 | * Encrypt header with the axolotl header key. | ||
905 | * | ||
906 | * @param ax key material to use. | ||
907 | * @param[in|out] msg Message whose header to encrypt. | ||
908 | */ | ||
909 | static void | ||
910 | t_h_encrypt (struct CadetTunnelAxolotl *ax, | ||
911 | struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
912 | { | ||
913 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
914 | size_t out_size; | ||
915 | |||
916 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
917 | &ax->HKs, | ||
918 | NULL, 0, | ||
919 | NULL); | ||
920 | out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header, | ||
921 | sizeof(struct | ||
922 | GNUNET_CADET_AxHeader), | ||
923 | &ax->HKs, | ||
924 | &iv, | ||
925 | &msg->ax_header); | ||
926 | GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size); | ||
927 | } | ||
928 | |||
929 | |||
930 | /** | ||
931 | * Decrypt header with the current axolotl header key. | ||
932 | * | ||
933 | * @param ax key material to use. | ||
934 | * @param src Message whose header to decrypt. | ||
935 | * @param dst Where to decrypt header to. | ||
936 | */ | ||
937 | static void | ||
938 | t_h_decrypt (struct CadetTunnelAxolotl *ax, | ||
939 | const struct GNUNET_CADET_TunnelEncryptedMessage *src, | ||
940 | struct GNUNET_CADET_TunnelEncryptedMessage *dst) | ||
941 | { | ||
942 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
943 | size_t out_size; | ||
944 | |||
945 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
946 | &ax->HKr, | ||
947 | NULL, 0, | ||
948 | NULL); | ||
949 | out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->ax_header.Ns, | ||
950 | sizeof(struct | ||
951 | GNUNET_CADET_AxHeader), | ||
952 | &ax->HKr, | ||
953 | &iv, | ||
954 | &dst->ax_header.Ns); | ||
955 | GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size); | ||
956 | } | ||
957 | |||
958 | |||
959 | /** | ||
960 | * Delete a key from the list of skipped keys. | ||
961 | * | ||
962 | * @param ax key material to delete @a key from. | ||
963 | * @param key Key to delete. | ||
964 | */ | ||
965 | static void | ||
966 | delete_skipped_key (struct CadetTunnelAxolotl *ax, | ||
967 | struct CadetTunnelSkippedKey *key) | ||
968 | { | ||
969 | GNUNET_CONTAINER_DLL_remove (ax->skipped_head, | ||
970 | ax->skipped_tail, | ||
971 | key); | ||
972 | GNUNET_free (key); | ||
973 | ax->skipped--; | ||
974 | } | ||
975 | |||
976 | |||
977 | /** | ||
978 | * Decrypt and verify data with the appropriate tunnel key and verify that the | ||
979 | * data has not been altered since it was sent by the remote peer. | ||
980 | * | ||
981 | * @param ax key material to use. | ||
982 | * @param dst Destination for the plaintext. | ||
983 | * @param src Source of the message. Can overlap with @c dst. | ||
984 | * @param size Size of the message. | ||
985 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
986 | */ | ||
987 | static ssize_t | ||
988 | try_old_ax_keys (struct CadetTunnelAxolotl *ax, | ||
989 | void *dst, | ||
990 | const struct GNUNET_CADET_TunnelEncryptedMessage *src, | ||
991 | size_t size) | ||
992 | { | ||
993 | struct CadetTunnelSkippedKey *key; | ||
994 | struct GNUNET_ShortHashCode *hmac; | ||
995 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
996 | struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header; | ||
997 | struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK; | ||
998 | size_t esize; | ||
999 | size_t res; | ||
1000 | size_t len; | ||
1001 | unsigned int N; | ||
1002 | |||
1003 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1004 | "Trying skipped keys\n"); | ||
1005 | hmac = &plaintext_header.hmac; | ||
1006 | esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage); | ||
1007 | |||
1008 | /* Find a correct Header Key */ | ||
1009 | valid_HK = NULL; | ||
1010 | for (key = ax->skipped_head; NULL != key; key = key->next) | ||
1011 | { | ||
1012 | t_hmac (&src->ax_header, | ||
1013 | sizeof(struct GNUNET_CADET_AxHeader) + esize, | ||
1014 | 0, | ||
1015 | &key->HK, | ||
1016 | hmac); | ||
1017 | if (0 == GNUNET_memcmp (hmac, | ||
1018 | &src->hmac)) | ||
1019 | { | ||
1020 | valid_HK = &key->HK; | ||
1021 | break; | ||
1022 | } | ||
1023 | } | ||
1024 | if (NULL == key) | ||
1025 | return -1; | ||
1026 | |||
1027 | /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */ | ||
1028 | GNUNET_assert (size > sizeof(struct GNUNET_CADET_TunnelEncryptedMessage)); | ||
1029 | len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage); | ||
1030 | GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader)); | ||
1031 | |||
1032 | /* Decrypt header */ | ||
1033 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
1034 | &key->HK, | ||
1035 | NULL, 0, | ||
1036 | NULL); | ||
1037 | res = GNUNET_CRYPTO_symmetric_decrypt (&src->ax_header.Ns, | ||
1038 | sizeof(struct GNUNET_CADET_AxHeader), | ||
1039 | &key->HK, | ||
1040 | &iv, | ||
1041 | &plaintext_header.ax_header.Ns); | ||
1042 | GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res); | ||
1043 | |||
1044 | /* Find the correct message key */ | ||
1045 | N = ntohl (plaintext_header.ax_header.Ns); | ||
1046 | while ((NULL != key) && | ||
1047 | (N != key->Kn)) | ||
1048 | key = key->next; | ||
1049 | if ((NULL == key) || | ||
1050 | (0 != GNUNET_memcmp (&key->HK, | ||
1051 | valid_HK))) | ||
1052 | return -1; | ||
1053 | |||
1054 | /* Decrypt payload */ | ||
1055 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
1056 | &key->MK, | ||
1057 | NULL, | ||
1058 | 0, | ||
1059 | NULL); | ||
1060 | res = GNUNET_CRYPTO_symmetric_decrypt (&src[1], | ||
1061 | len, | ||
1062 | &key->MK, | ||
1063 | &iv, | ||
1064 | dst); | ||
1065 | delete_skipped_key (ax, | ||
1066 | key); | ||
1067 | return res; | ||
1068 | } | ||
1069 | |||
1070 | |||
1071 | /** | ||
1072 | * Delete a key from the list of skipped keys. | ||
1073 | * | ||
1074 | * @param ax key material to delete from. | ||
1075 | * @param HKr Header Key to use. | ||
1076 | */ | ||
1077 | static void | ||
1078 | store_skipped_key (struct CadetTunnelAxolotl *ax, | ||
1079 | const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr) | ||
1080 | { | ||
1081 | struct CadetTunnelSkippedKey *key; | ||
1082 | |||
1083 | key = GNUNET_new (struct CadetTunnelSkippedKey); | ||
1084 | key->timestamp = GNUNET_TIME_absolute_get (); | ||
1085 | key->Kn = ax->Nr; | ||
1086 | key->HK = ax->HKr; | ||
1087 | t_hmac_derive_key (&ax->CKr, | ||
1088 | &key->MK, | ||
1089 | "0", | ||
1090 | 1); | ||
1091 | t_hmac_derive_key (&ax->CKr, | ||
1092 | &ax->CKr, | ||
1093 | "1", | ||
1094 | 1); | ||
1095 | GNUNET_CONTAINER_DLL_insert (ax->skipped_head, | ||
1096 | ax->skipped_tail, | ||
1097 | key); | ||
1098 | ax->skipped++; | ||
1099 | ax->Nr++; | ||
1100 | } | ||
1101 | |||
1102 | |||
1103 | /** | ||
1104 | * Stage skipped AX keys and calculate the message key. | ||
1105 | * Stores each HK and MK for skipped messages. | ||
1106 | * | ||
1107 | * @param ax key material to use | ||
1108 | * @param HKr Header key. | ||
1109 | * @param Np Received meesage number. | ||
1110 | * @return #GNUNET_OK if keys were stored. | ||
1111 | * #GNUNET_SYSERR if an error occurred (@a Np not expected). | ||
1112 | */ | ||
1113 | static int | ||
1114 | store_ax_keys (struct CadetTunnelAxolotl *ax, | ||
1115 | const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, | ||
1116 | uint32_t Np) | ||
1117 | { | ||
1118 | int gap; | ||
1119 | |||
1120 | gap = Np - ax->Nr; | ||
1121 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1122 | "Storing skipped keys [%u, %u)\n", | ||
1123 | ax->Nr, | ||
1124 | Np); | ||
1125 | if (MAX_KEY_GAP < gap) | ||
1126 | { | ||
1127 | /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */ | ||
1128 | /* TODO: start new key exchange on return */ | ||
1129 | GNUNET_break_op (0); | ||
1130 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1131 | "Got message %u, expected %u+\n", | ||
1132 | Np, | ||
1133 | ax->Nr); | ||
1134 | return GNUNET_SYSERR; | ||
1135 | } | ||
1136 | if (0 > gap) | ||
1137 | { | ||
1138 | /* Delayed message: don't store keys, flag to try old keys. */ | ||
1139 | return GNUNET_SYSERR; | ||
1140 | } | ||
1141 | |||
1142 | while (ax->Nr < Np) | ||
1143 | store_skipped_key (ax, | ||
1144 | HKr); | ||
1145 | |||
1146 | while (ax->skipped > MAX_SKIPPED_KEYS) | ||
1147 | delete_skipped_key (ax, | ||
1148 | ax->skipped_tail); | ||
1149 | return GNUNET_OK; | ||
1150 | } | ||
1151 | |||
1152 | |||
1153 | /** | ||
1154 | * Decrypt and verify data with the appropriate tunnel key and verify that the | ||
1155 | * data has not been altered since it was sent by the remote peer. | ||
1156 | * | ||
1157 | * @param ax key material to use | ||
1158 | * @param dst Destination for the plaintext. | ||
1159 | * @param src Source of the message. Can overlap with @c dst. | ||
1160 | * @param size Size of the message. | ||
1161 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
1162 | */ | ||
1163 | static ssize_t | ||
1164 | t_ax_decrypt_and_validate (struct CadetTunnelAxolotl *ax, | ||
1165 | void *dst, | ||
1166 | const struct | ||
1167 | GNUNET_CADET_TunnelEncryptedMessage *src, | ||
1168 | size_t size) | ||
1169 | { | ||
1170 | struct GNUNET_ShortHashCode msg_hmac; | ||
1171 | struct GNUNET_HashCode hmac; | ||
1172 | struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header; | ||
1173 | uint32_t Np; | ||
1174 | uint32_t PNp; | ||
1175 | size_t esize; /* Size of encryped payload */ | ||
1176 | |||
1177 | esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage); | ||
1178 | |||
1179 | /* Try current HK */ | ||
1180 | t_hmac (&src->ax_header, | ||
1181 | sizeof(struct GNUNET_CADET_AxHeader) + esize, | ||
1182 | 0, &ax->HKr, | ||
1183 | &msg_hmac); | ||
1184 | if (0 != GNUNET_memcmp (&msg_hmac, | ||
1185 | &src->hmac)) | ||
1186 | { | ||
1187 | static const char ctx[] = "axolotl ratchet"; | ||
1188 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */ | ||
1189 | struct GNUNET_CRYPTO_SymmetricSessionKey HK; | ||
1190 | struct GNUNET_HashCode dh; | ||
1191 | struct GNUNET_CRYPTO_EcdhePublicKey *DHRp; | ||
1192 | |||
1193 | /* Try Next HK */ | ||
1194 | t_hmac (&src->ax_header, | ||
1195 | sizeof(struct GNUNET_CADET_AxHeader) + esize, | ||
1196 | 0, | ||
1197 | &ax->NHKr, | ||
1198 | &msg_hmac); | ||
1199 | if (0 != GNUNET_memcmp (&msg_hmac, | ||
1200 | &src->hmac)) | ||
1201 | { | ||
1202 | /* Try the skipped keys, if that fails, we're out of luck. */ | ||
1203 | return try_old_ax_keys (ax, | ||
1204 | dst, | ||
1205 | src, | ||
1206 | size); | ||
1207 | } | ||
1208 | HK = ax->HKr; | ||
1209 | ax->HKr = ax->NHKr; | ||
1210 | t_h_decrypt (ax, | ||
1211 | src, | ||
1212 | &plaintext_header); | ||
1213 | Np = ntohl (plaintext_header.ax_header.Ns); | ||
1214 | PNp = ntohl (plaintext_header.ax_header.PNs); | ||
1215 | DHRp = &plaintext_header.ax_header.DHRs; | ||
1216 | store_ax_keys (ax, | ||
1217 | &HK, | ||
1218 | PNp); | ||
1219 | |||
1220 | /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */ | ||
1221 | GNUNET_CRYPTO_ecc_ecdh (&ax->DHRs, | ||
1222 | DHRp, | ||
1223 | &dh); | ||
1224 | t_ax_hmac_hash (&ax->RK, | ||
1225 | &hmac, | ||
1226 | &dh, sizeof(dh)); | ||
1227 | GNUNET_CRYPTO_kdf (keys, sizeof(keys), | ||
1228 | ctx, sizeof(ctx), | ||
1229 | &hmac, sizeof(hmac), | ||
1230 | NULL); | ||
1231 | |||
1232 | /* Commit "purported" keys */ | ||
1233 | ax->RK = keys[0]; | ||
1234 | ax->NHKr = keys[1]; | ||
1235 | ax->CKr = keys[2]; | ||
1236 | ax->DHRr = *DHRp; | ||
1237 | ax->Nr = 0; | ||
1238 | ax->ratchet_allowed = GNUNET_YES; | ||
1239 | } | ||
1240 | else | ||
1241 | { | ||
1242 | t_h_decrypt (ax, | ||
1243 | src, | ||
1244 | &plaintext_header); | ||
1245 | Np = ntohl (plaintext_header.ax_header.Ns); | ||
1246 | PNp = ntohl (plaintext_header.ax_header.PNs); | ||
1247 | } | ||
1248 | if ((Np != ax->Nr) && | ||
1249 | (GNUNET_OK != store_ax_keys (ax, | ||
1250 | &ax->HKr, | ||
1251 | Np))) | ||
1252 | { | ||
1253 | /* Try the skipped keys, if that fails, we're out of luck. */ | ||
1254 | return try_old_ax_keys (ax, | ||
1255 | dst, | ||
1256 | src, | ||
1257 | size); | ||
1258 | } | ||
1259 | |||
1260 | t_ax_decrypt (ax, | ||
1261 | dst, | ||
1262 | &src[1], | ||
1263 | esize); | ||
1264 | ax->Nr = Np + 1; | ||
1265 | return esize; | ||
1266 | } | ||
1267 | |||
1268 | |||
1269 | /** | ||
1270 | * Our tunnel became ready for the first time, notify channels | ||
1271 | * that have been waiting. | ||
1272 | * | ||
1273 | * @param cls our tunnel, not used | ||
1274 | * @param key unique ID of the channel, not used | ||
1275 | * @param value the `struct CadetChannel` to notify | ||
1276 | * @return #GNUNET_OK (continue to iterate) | ||
1277 | */ | ||
1278 | static int | ||
1279 | notify_tunnel_up_cb (void *cls, | ||
1280 | uint32_t key, | ||
1281 | void *value) | ||
1282 | { | ||
1283 | struct CadetChannel *ch = value; | ||
1284 | |||
1285 | GCCH_tunnel_up (ch); | ||
1286 | return GNUNET_OK; | ||
1287 | } | ||
1288 | |||
1289 | |||
1290 | /** | ||
1291 | * Change the tunnel encryption state. | ||
1292 | * If the encryption state changes to OK, stop the rekey task. | ||
1293 | * | ||
1294 | * @param t Tunnel whose encryption state to change, or NULL. | ||
1295 | * @param state New encryption state. | ||
1296 | */ | ||
1297 | void | ||
1298 | GCT_change_estate (struct CadetTunnel *t, | ||
1299 | enum CadetTunnelEState state) | ||
1300 | { | ||
1301 | enum CadetTunnelEState old = t->estate; | ||
1302 | |||
1303 | t->estate = state; | ||
1304 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1305 | "%s estate changed from %s to %s\n", | ||
1306 | GCT_2s (t), | ||
1307 | estate2s (old), | ||
1308 | estate2s (state)); | ||
1309 | |||
1310 | if ((CADET_TUNNEL_KEY_OK != old) && | ||
1311 | (CADET_TUNNEL_KEY_OK == t->estate)) | ||
1312 | { | ||
1313 | if (NULL != t->kx_task) | ||
1314 | { | ||
1315 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
1316 | t->kx_task = NULL; | ||
1317 | } | ||
1318 | /* notify all channels that have been waiting */ | ||
1319 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
1320 | ¬ify_tunnel_up_cb, | ||
1321 | t); | ||
1322 | if (NULL != t->send_task) | ||
1323 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
1324 | t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
1325 | t); | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | |||
1330 | /** | ||
1331 | * Send a KX message. | ||
1332 | * | ||
1333 | * @param t tunnel on which to send the KX_AUTH | ||
1334 | * @param ct Tunnel and connection on which to send the KX_AUTH, NULL if | ||
1335 | * we are to find one that is ready. | ||
1336 | * @param ax axolotl key context to use | ||
1337 | */ | ||
1338 | static void | ||
1339 | send_kx (struct CadetTunnel *t, | ||
1340 | struct CadetTConnection *ct, | ||
1341 | struct CadetTunnelAxolotl *ax) | ||
1342 | { | ||
1343 | struct CadetConnection *cc; | ||
1344 | struct GNUNET_MQ_Envelope *env; | ||
1345 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; | ||
1346 | enum GNUNET_CADET_KX_Flags flags; | ||
1347 | |||
1348 | if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination))) | ||
1349 | return; /* only Alice may send KX */ | ||
1350 | if ((NULL == ct) || | ||
1351 | (GNUNET_NO == ct->is_ready)) | ||
1352 | ct = get_ready_connection (t); | ||
1353 | if (NULL == ct) | ||
1354 | { | ||
1355 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1356 | "Wanted to send %s in state %s, but no connection is ready, deferring\n", | ||
1357 | GCT_2s (t), | ||
1358 | estate2s (t->estate)); | ||
1359 | t->next_kx_attempt = GNUNET_TIME_absolute_get (); | ||
1360 | return; | ||
1361 | } | ||
1362 | cc = ct->cc; | ||
1363 | env = GNUNET_MQ_msg (msg, | ||
1364 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); | ||
1365 | flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */ | ||
1366 | msg->flags = htonl (flags); | ||
1367 | msg->cid = *GCC_get_id (cc); | ||
1368 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0, | ||
1369 | &msg->ephemeral_key); | ||
1370 | #if DEBUG_KX | ||
1371 | msg->ephemeral_key_XXX = ax->kx_0; | ||
1372 | msg->private_key_XXX = *my_private_key; | ||
1373 | #endif | ||
1374 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1375 | "Sending KX message to %s with ephemeral %s on CID %s\n", | ||
1376 | GCT_2s (t), | ||
1377 | GNUNET_e2s (&msg->ephemeral_key), | ||
1378 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
1379 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, | ||
1380 | &msg->ratchet_key); | ||
1381 | mark_connection_unready (ct); | ||
1382 | t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay); | ||
1383 | t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay); | ||
1384 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | ||
1385 | GCT_change_estate (t, | ||
1386 | CADET_TUNNEL_KEY_AX_SENT); | ||
1387 | else if (CADET_TUNNEL_KEY_AX_RECV == t->estate) | ||
1388 | GCT_change_estate (t, | ||
1389 | CADET_TUNNEL_KEY_AX_SENT_AND_RECV); | ||
1390 | GCC_transmit (cc, | ||
1391 | env); | ||
1392 | GNUNET_STATISTICS_update (stats, | ||
1393 | "# KX transmitted", | ||
1394 | 1, | ||
1395 | GNUNET_NO); | ||
1396 | } | ||
1397 | |||
1398 | |||
1399 | /** | ||
1400 | * Send a KX_AUTH message. | ||
1401 | * | ||
1402 | * @param t tunnel on which to send the KX_AUTH | ||
1403 | * @param ct Tunnel and connection on which to send the KX_AUTH, NULL if | ||
1404 | * we are to find one that is ready. | ||
1405 | * @param ax axolotl key context to use | ||
1406 | * @param force_reply Force the other peer to reply with a KX_AUTH message | ||
1407 | * (set if we would like to transmit right now, but cannot) | ||
1408 | */ | ||
1409 | static void | ||
1410 | send_kx_auth (struct CadetTunnel *t, | ||
1411 | struct CadetTConnection *ct, | ||
1412 | struct CadetTunnelAxolotl *ax, | ||
1413 | int force_reply) | ||
1414 | { | ||
1415 | struct CadetConnection *cc; | ||
1416 | struct GNUNET_MQ_Envelope *env; | ||
1417 | struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg; | ||
1418 | enum GNUNET_CADET_KX_Flags flags; | ||
1419 | |||
1420 | if ((NULL == ct) || | ||
1421 | (GNUNET_NO == ct->is_ready)) | ||
1422 | ct = get_ready_connection (t); | ||
1423 | if (NULL == ct) | ||
1424 | { | ||
1425 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1426 | "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n", | ||
1427 | GCT_2s (t)); | ||
1428 | t->next_kx_attempt = GNUNET_TIME_absolute_get (); | ||
1429 | t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */ | ||
1430 | return; | ||
1431 | } | ||
1432 | t->kx_auth_requested = GNUNET_NO; /* clear flag */ | ||
1433 | cc = ct->cc; | ||
1434 | env = GNUNET_MQ_msg (msg, | ||
1435 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH); | ||
1436 | flags = GNUNET_CADET_KX_FLAG_NONE; | ||
1437 | if (GNUNET_YES == force_reply) | ||
1438 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; | ||
1439 | msg->kx.flags = htonl (flags); | ||
1440 | msg->kx.cid = *GCC_get_id (cc); | ||
1441 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0, | ||
1442 | &msg->kx.ephemeral_key); | ||
1443 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, | ||
1444 | &msg->kx.ratchet_key); | ||
1445 | #if DEBUG_KX | ||
1446 | msg->kx.ephemeral_key_XXX = ax->kx_0; | ||
1447 | msg->kx.private_key_XXX = *my_private_key; | ||
1448 | msg->r_ephemeral_key_XXX = ax->last_ephemeral; | ||
1449 | #endif | ||
1450 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1451 | "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n", | ||
1452 | GCT_2s (t), | ||
1453 | GNUNET_e2s (&msg->kx.ephemeral_key), | ||
1454 | GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel)); | ||
1455 | |||
1456 | /* Compute authenticator (this is the main difference to #send_kx()) */ | ||
1457 | GNUNET_CRYPTO_hash (&ax->RK, | ||
1458 | sizeof(ax->RK), | ||
1459 | &msg->auth); | ||
1460 | /* Compute when to be triggered again; actual job will | ||
1461 | be scheduled via #connection_ready_cb() */ | ||
1462 | t->kx_retry_delay | ||
1463 | = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay); | ||
1464 | t->next_kx_attempt | ||
1465 | = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay); | ||
1466 | |||
1467 | /* Send via cc, mark it as unready */ | ||
1468 | mark_connection_unready (ct); | ||
1469 | |||
1470 | /* Update state machine, unless we are already OK */ | ||
1471 | if (CADET_TUNNEL_KEY_OK != t->estate) | ||
1472 | GCT_change_estate (t, | ||
1473 | CADET_TUNNEL_KEY_AX_AUTH_SENT); | ||
1474 | GCC_transmit (cc, | ||
1475 | env); | ||
1476 | GNUNET_STATISTICS_update (stats, | ||
1477 | "# KX_AUTH transmitted", | ||
1478 | 1, | ||
1479 | GNUNET_NO); | ||
1480 | } | ||
1481 | |||
1482 | |||
1483 | /** | ||
1484 | * Cleanup state used by @a ax. | ||
1485 | * | ||
1486 | * @param ax state to free, but not memory of @a ax itself | ||
1487 | */ | ||
1488 | static void | ||
1489 | cleanup_ax (struct CadetTunnelAxolotl *ax) | ||
1490 | { | ||
1491 | while (NULL != ax->skipped_head) | ||
1492 | delete_skipped_key (ax, | ||
1493 | ax->skipped_head); | ||
1494 | GNUNET_assert (0 == ax->skipped); | ||
1495 | GNUNET_CRYPTO_ecdhe_key_clear (&ax->kx_0); | ||
1496 | GNUNET_CRYPTO_ecdhe_key_clear (&ax->DHRs); | ||
1497 | } | ||
1498 | |||
1499 | |||
1500 | /** | ||
1501 | * Update our Axolotl key state based on the KX data we received. | ||
1502 | * Computes the new chain keys, and root keys, etc, and also checks | ||
1503 | * whether this is a replay of the current chain. | ||
1504 | * | ||
1505 | * @param[in|out] axolotl chain key state to recompute | ||
1506 | * @param pid peer identity of the other peer | ||
1507 | * @param ephemeral_key ephemeral public key of the other peer | ||
1508 | * @param ratchet_key senders next ephemeral public key | ||
1509 | * @return #GNUNET_OK on success, #GNUNET_NO if the resulting | ||
1510 | * root key is already in @a ax and thus the KX is useless; | ||
1511 | * #GNUNET_SYSERR on hard errors (i.e. @a pid is #my_full_id) | ||
1512 | */ | ||
1513 | static int | ||
1514 | update_ax_by_kx (struct CadetTunnelAxolotl *ax, | ||
1515 | const struct GNUNET_PeerIdentity *pid, | ||
1516 | const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, | ||
1517 | const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key) | ||
1518 | { | ||
1519 | struct GNUNET_HashCode key_material[3]; | ||
1520 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[5]; | ||
1521 | const char salt[] = "CADET Axolotl salt"; | ||
1522 | int am_I_alice; | ||
1523 | |||
1524 | if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid))) | ||
1525 | { | ||
1526 | GNUNET_break_op (0); | ||
1527 | return GNUNET_SYSERR; | ||
1528 | } | ||
1529 | if (0 == GNUNET_memcmp (&ax->DHRr, | ||
1530 | ratchet_key)) | ||
1531 | { | ||
1532 | GNUNET_STATISTICS_update (stats, | ||
1533 | "# Ratchet key already known", | ||
1534 | 1, | ||
1535 | GNUNET_NO); | ||
1536 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1537 | "Ratchet key already known. Ignoring KX.\n"); | ||
1538 | return GNUNET_NO; | ||
1539 | } | ||
1540 | |||
1541 | ax->DHRr = *ratchet_key; | ||
1542 | ax->last_ephemeral = *ephemeral_key; | ||
1543 | /* ECDH A B0 */ | ||
1544 | if (GNUNET_YES == am_I_alice) | ||
1545 | { | ||
1546 | GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* a */ | ||
1547 | ephemeral_key, /* B0 */ | ||
1548 | &key_material[0]); | ||
1549 | } | ||
1550 | else | ||
1551 | { | ||
1552 | GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */ | ||
1553 | &pid->public_key, /* A */ | ||
1554 | &key_material[0]); | ||
1555 | } | ||
1556 | /* ECDH A0 B */ | ||
1557 | if (GNUNET_YES == am_I_alice) | ||
1558 | { | ||
1559 | GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */ | ||
1560 | &pid->public_key, /* B */ | ||
1561 | &key_material[1]); | ||
1562 | } | ||
1563 | else | ||
1564 | { | ||
1565 | GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* b */ | ||
1566 | ephemeral_key, /* A0 */ | ||
1567 | &key_material[1]); | ||
1568 | } | ||
1569 | |||
1570 | /* ECDH A0 B0 */ | ||
1571 | GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */ | ||
1572 | ephemeral_key, /* B0 or A0 */ | ||
1573 | &key_material[2]); | ||
1574 | /* KDF */ | ||
1575 | GNUNET_CRYPTO_kdf (keys, sizeof(keys), | ||
1576 | salt, sizeof(salt), | ||
1577 | &key_material, sizeof(key_material), | ||
1578 | NULL); | ||
1579 | |||
1580 | if (0 == memcmp (&ax->RK, | ||
1581 | &keys[0], | ||
1582 | sizeof(ax->RK))) | ||
1583 | { | ||
1584 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1585 | "Root key already known. Ignoring KX.\n"); | ||
1586 | GNUNET_STATISTICS_update (stats, | ||
1587 | "# Root key already known", | ||
1588 | 1, | ||
1589 | GNUNET_NO); | ||
1590 | return GNUNET_NO; | ||
1591 | } | ||
1592 | |||
1593 | ax->RK = keys[0]; | ||
1594 | if (GNUNET_YES == am_I_alice) | ||
1595 | { | ||
1596 | ax->HKr = keys[1]; | ||
1597 | ax->NHKs = keys[2]; | ||
1598 | ax->NHKr = keys[3]; | ||
1599 | ax->CKr = keys[4]; | ||
1600 | ax->ratchet_flag = GNUNET_YES; | ||
1601 | } | ||
1602 | else | ||
1603 | { | ||
1604 | ax->HKs = keys[1]; | ||
1605 | ax->NHKr = keys[2]; | ||
1606 | ax->NHKs = keys[3]; | ||
1607 | ax->CKs = keys[4]; | ||
1608 | ax->ratchet_flag = GNUNET_NO; | ||
1609 | ax->ratchet_expiration | ||
1610 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
1611 | ratchet_time); | ||
1612 | } | ||
1613 | return GNUNET_OK; | ||
1614 | } | ||
1615 | |||
1616 | |||
1617 | /** | ||
1618 | * Try to redo the KX or KX_AUTH handshake, if we can. | ||
1619 | * | ||
1620 | * @param cls the `struct CadetTunnel` to do KX for. | ||
1621 | */ | ||
1622 | static void | ||
1623 | retry_kx (void *cls) | ||
1624 | { | ||
1625 | struct CadetTunnel *t = cls; | ||
1626 | struct CadetTunnelAxolotl *ax; | ||
1627 | |||
1628 | t->kx_task = NULL; | ||
1629 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1630 | "Trying to make KX progress on %s in state %s\n", | ||
1631 | GCT_2s (t), | ||
1632 | estate2s (t->estate)); | ||
1633 | switch (t->estate) | ||
1634 | { | ||
1635 | case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */ | ||
1636 | case CADET_TUNNEL_KEY_AX_SENT: /* trying again */ | ||
1637 | send_kx (t, | ||
1638 | NULL, | ||
1639 | &t->ax); | ||
1640 | break; | ||
1641 | |||
1642 | case CADET_TUNNEL_KEY_AX_RECV: | ||
1643 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: | ||
1644 | /* We are responding, so only require reply | ||
1645 | if WE have a channel waiting. */ | ||
1646 | if (NULL != t->unverified_ax) | ||
1647 | { | ||
1648 | /* Send AX_AUTH so we might get this one verified */ | ||
1649 | ax = t->unverified_ax; | ||
1650 | } | ||
1651 | else | ||
1652 | { | ||
1653 | /* How can this be? */ | ||
1654 | GNUNET_break (0); | ||
1655 | ax = &t->ax; | ||
1656 | } | ||
1657 | send_kx_auth (t, | ||
1658 | NULL, | ||
1659 | ax, | ||
1660 | (0 == GCT_count_channels (t)) | ||
1661 | ? GNUNET_NO | ||
1662 | : GNUNET_YES); | ||
1663 | break; | ||
1664 | |||
1665 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
1666 | /* We are responding, so only require reply | ||
1667 | if WE have a channel waiting. */ | ||
1668 | if (NULL != t->unverified_ax) | ||
1669 | { | ||
1670 | /* Send AX_AUTH so we might get this one verified */ | ||
1671 | ax = t->unverified_ax; | ||
1672 | } | ||
1673 | else | ||
1674 | { | ||
1675 | /* How can this be? */ | ||
1676 | GNUNET_break (0); | ||
1677 | ax = &t->ax; | ||
1678 | } | ||
1679 | send_kx_auth (t, | ||
1680 | NULL, | ||
1681 | ax, | ||
1682 | (0 == GCT_count_channels (t)) | ||
1683 | ? GNUNET_NO | ||
1684 | : GNUNET_YES); | ||
1685 | break; | ||
1686 | |||
1687 | case CADET_TUNNEL_KEY_OK: | ||
1688 | /* Must have been the *other* peer asking us to | ||
1689 | respond with a KX_AUTH. */ | ||
1690 | if (NULL != t->unverified_ax) | ||
1691 | { | ||
1692 | /* Sending AX_AUTH in response to AX so we might get this one verified */ | ||
1693 | ax = t->unverified_ax; | ||
1694 | } | ||
1695 | else | ||
1696 | { | ||
1697 | /* Sending AX_AUTH in response to AX_AUTH */ | ||
1698 | ax = &t->ax; | ||
1699 | } | ||
1700 | send_kx_auth (t, | ||
1701 | NULL, | ||
1702 | ax, | ||
1703 | GNUNET_NO); | ||
1704 | break; | ||
1705 | } | ||
1706 | } | ||
1707 | |||
1708 | |||
1709 | /** | ||
1710 | * Handle KX message that lacks authentication (and which will thus | ||
1711 | * only be considered authenticated after we respond with our own | ||
1712 | * KX_AUTH and finally successfully decrypt payload). | ||
1713 | * | ||
1714 | * @param ct connection/tunnel combo that received encrypted message | ||
1715 | * @param msg the key exchange message | ||
1716 | */ | ||
1717 | void | ||
1718 | GCT_handle_kx (struct CadetTConnection *ct, | ||
1719 | const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) | ||
1720 | { | ||
1721 | struct CadetTunnel *t = ct->t; | ||
1722 | int ret; | ||
1723 | |||
1724 | GNUNET_STATISTICS_update (stats, | ||
1725 | "# KX received", | ||
1726 | 1, | ||
1727 | GNUNET_NO); | ||
1728 | if (GNUNET_YES == | ||
1729 | GCT_alice_or_betty (GCP_get_id (t->destination))) | ||
1730 | { | ||
1731 | /* Betty/Bob is not allowed to send KX! */ | ||
1732 | GNUNET_break_op (0); | ||
1733 | return; | ||
1734 | } | ||
1735 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1736 | "Received KX message from %s with ephemeral %s from %s on connection %s\n", | ||
1737 | GCT_2s (t), | ||
1738 | GNUNET_e2s (&msg->ephemeral_key), | ||
1739 | GNUNET_i2s (GCP_get_id (t->destination)), | ||
1740 | GCC_2s (ct->cc)); | ||
1741 | #if 1 | ||
1742 | if ((0 == | ||
1743 | memcmp (&t->ax.DHRr, | ||
1744 | &msg->ratchet_key, | ||
1745 | sizeof(msg->ratchet_key))) && | ||
1746 | (0 == | ||
1747 | memcmp (&t->ax.last_ephemeral, | ||
1748 | &msg->ephemeral_key, | ||
1749 | sizeof(msg->ephemeral_key)))) | ||
1750 | |||
1751 | { | ||
1752 | GNUNET_STATISTICS_update (stats, | ||
1753 | "# Duplicate KX received", | ||
1754 | 1, | ||
1755 | GNUNET_NO); | ||
1756 | send_kx_auth (t, | ||
1757 | ct, | ||
1758 | &t->ax, | ||
1759 | GNUNET_NO); | ||
1760 | return; | ||
1761 | } | ||
1762 | #endif | ||
1763 | /* We only keep ONE unverified KX around, so if there is an existing one, | ||
1764 | clean it up. */ | ||
1765 | if (NULL != t->unverified_ax) | ||
1766 | { | ||
1767 | if ((0 == | ||
1768 | memcmp (&t->unverified_ax->DHRr, | ||
1769 | &msg->ratchet_key, | ||
1770 | sizeof(msg->ratchet_key))) && | ||
1771 | (0 == | ||
1772 | memcmp (&t->unverified_ax->last_ephemeral, | ||
1773 | &msg->ephemeral_key, | ||
1774 | sizeof(msg->ephemeral_key)))) | ||
1775 | { | ||
1776 | GNUNET_STATISTICS_update (stats, | ||
1777 | "# Duplicate unverified KX received", | ||
1778 | 1, | ||
1779 | GNUNET_NO); | ||
1780 | #if 1 | ||
1781 | send_kx_auth (t, | ||
1782 | ct, | ||
1783 | t->unverified_ax, | ||
1784 | GNUNET_NO); | ||
1785 | return; | ||
1786 | #endif | ||
1787 | } | ||
1788 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1789 | "Dropping old unverified KX state.\n"); | ||
1790 | GNUNET_STATISTICS_update (stats, | ||
1791 | "# Unverified KX dropped for fresh KX", | ||
1792 | 1, | ||
1793 | GNUNET_NO); | ||
1794 | GNUNET_break (NULL == t->unverified_ax->skipped_head); | ||
1795 | memset (t->unverified_ax, | ||
1796 | 0, | ||
1797 | sizeof(struct CadetTunnelAxolotl)); | ||
1798 | } | ||
1799 | else | ||
1800 | { | ||
1801 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1802 | "Creating fresh unverified KX for %s\n", | ||
1803 | GCT_2s (t)); | ||
1804 | GNUNET_STATISTICS_update (stats, | ||
1805 | "# Fresh KX setup", | ||
1806 | 1, | ||
1807 | GNUNET_NO); | ||
1808 | t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl); | ||
1809 | } | ||
1810 | /* Set as the 'current' RK/DHRr the one we are currently using, | ||
1811 | so that the duplicate-detection logic of | ||
1812 | #update_ax_by_kx can work. */ | ||
1813 | t->unverified_ax->RK = t->ax.RK; | ||
1814 | t->unverified_ax->DHRr = t->ax.DHRr; | ||
1815 | t->unverified_ax->DHRs = t->ax.DHRs; | ||
1816 | t->unverified_ax->kx_0 = t->ax.kx_0; | ||
1817 | t->unverified_attempts = 0; | ||
1818 | |||
1819 | /* Update 'ax' by the new key material */ | ||
1820 | ret = update_ax_by_kx (t->unverified_ax, | ||
1821 | GCP_get_id (t->destination), | ||
1822 | &msg->ephemeral_key, | ||
1823 | &msg->ratchet_key); | ||
1824 | GNUNET_break (GNUNET_SYSERR != ret); | ||
1825 | if (GNUNET_OK != ret) | ||
1826 | { | ||
1827 | GNUNET_STATISTICS_update (stats, | ||
1828 | "# Useless KX", | ||
1829 | 1, | ||
1830 | GNUNET_NO); | ||
1831 | return; /* duplicate KX, nothing to do */ | ||
1832 | } | ||
1833 | /* move ahead in our state machine */ | ||
1834 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | ||
1835 | GCT_change_estate (t, | ||
1836 | CADET_TUNNEL_KEY_AX_RECV); | ||
1837 | else if (CADET_TUNNEL_KEY_AX_SENT == t->estate) | ||
1838 | GCT_change_estate (t, | ||
1839 | CADET_TUNNEL_KEY_AX_SENT_AND_RECV); | ||
1840 | |||
1841 | /* KX is still not done, try again our end. */ | ||
1842 | if (CADET_TUNNEL_KEY_OK != t->estate) | ||
1843 | { | ||
1844 | if (NULL != t->kx_task) | ||
1845 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
1846 | t->kx_task | ||
1847 | = GNUNET_SCHEDULER_add_now (&retry_kx, | ||
1848 | t); | ||
1849 | } | ||
1850 | } | ||
1851 | |||
1852 | |||
1853 | #if DEBUG_KX | ||
1854 | static void | ||
1855 | check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1, | ||
1856 | const struct GNUNET_CRYPTO_EcdhePrivateKey *e2) | ||
1857 | { | ||
1858 | struct GNUNET_CRYPTO_EcdhePublicKey p1; | ||
1859 | struct GNUNET_CRYPTO_EcdhePublicKey p2; | ||
1860 | struct GNUNET_HashCode hc1; | ||
1861 | struct GNUNET_HashCode hc2; | ||
1862 | |||
1863 | GNUNET_CRYPTO_ecdhe_key_get_public (e1, | ||
1864 | &p1); | ||
1865 | GNUNET_CRYPTO_ecdhe_key_get_public (e2, | ||
1866 | &p2); | ||
1867 | GNUNET_assert (GNUNET_OK == | ||
1868 | GNUNET_CRYPTO_ecc_ecdh (e1, | ||
1869 | &p2, | ||
1870 | &hc1)); | ||
1871 | GNUNET_assert (GNUNET_OK == | ||
1872 | GNUNET_CRYPTO_ecc_ecdh (e2, | ||
1873 | &p1, | ||
1874 | &hc2)); | ||
1875 | GNUNET_break (0 == GNUNET_memcmp (&hc1, | ||
1876 | &hc2)); | ||
1877 | } | ||
1878 | |||
1879 | |||
1880 | static void | ||
1881 | check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1, | ||
1882 | const struct GNUNET_CRYPTO_EddsaPrivateKey *e2) | ||
1883 | { | ||
1884 | struct GNUNET_CRYPTO_EcdhePublicKey p1; | ||
1885 | struct GNUNET_CRYPTO_EddsaPublicKey p2; | ||
1886 | struct GNUNET_HashCode hc1; | ||
1887 | struct GNUNET_HashCode hc2; | ||
1888 | |||
1889 | GNUNET_CRYPTO_ecdhe_key_get_public (e1, | ||
1890 | &p1); | ||
1891 | GNUNET_CRYPTO_eddsa_key_get_public (e2, | ||
1892 | &p2); | ||
1893 | GNUNET_assert (GNUNET_OK == | ||
1894 | GNUNET_CRYPTO_ecdh_eddsa (e1, | ||
1895 | &p2, | ||
1896 | &hc1)); | ||
1897 | GNUNET_assert (GNUNET_OK == | ||
1898 | GNUNET_CRYPTO_eddsa_ecdh (e2, | ||
1899 | &p1, | ||
1900 | &hc2)); | ||
1901 | GNUNET_break (0 == GNUNET_memcmp (&hc1, | ||
1902 | &hc2)); | ||
1903 | } | ||
1904 | |||
1905 | |||
1906 | static void | ||
1907 | test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1, | ||
1908 | const struct GNUNET_CRYPTO_EcdhePrivateKey *e2, | ||
1909 | const struct GNUNET_CRYPTO_EddsaPrivateKey *d1, | ||
1910 | const struct GNUNET_CRYPTO_EddsaPrivateKey *d2) | ||
1911 | { | ||
1912 | check_ee (e1, e2); | ||
1913 | check_ed (e1, d2); | ||
1914 | check_ed (e2, d1); | ||
1915 | } | ||
1916 | |||
1917 | |||
1918 | #endif | ||
1919 | |||
1920 | |||
1921 | /** | ||
1922 | * Handle KX_AUTH message. | ||
1923 | * | ||
1924 | * @param ct connection/tunnel combo that received encrypted message | ||
1925 | * @param msg the key exchange message | ||
1926 | */ | ||
1927 | void | ||
1928 | GCT_handle_kx_auth (struct CadetTConnection *ct, | ||
1929 | const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg) | ||
1930 | { | ||
1931 | struct CadetTunnel *t = ct->t; | ||
1932 | struct CadetTunnelAxolotl ax_tmp; | ||
1933 | struct GNUNET_HashCode kx_auth; | ||
1934 | int ret; | ||
1935 | |||
1936 | GNUNET_STATISTICS_update (stats, | ||
1937 | "# KX_AUTH received", | ||
1938 | 1, | ||
1939 | GNUNET_NO); | ||
1940 | if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) || | ||
1941 | (CADET_TUNNEL_KEY_AX_RECV == t->estate)) | ||
1942 | { | ||
1943 | /* Confusing, we got a KX_AUTH before we even send our own | ||
1944 | KX. This should not happen. We'll send our own KX ASAP anyway, | ||
1945 | so let's ignore this here. */ | ||
1946 | GNUNET_break_op (0); | ||
1947 | return; | ||
1948 | } | ||
1949 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1950 | "Handling KX_AUTH message from %s with ephemeral %s\n", | ||
1951 | GCT_2s (t), | ||
1952 | GNUNET_e2s (&msg->kx.ephemeral_key)); | ||
1953 | /* We do everything in ax_tmp until we've checked the authentication | ||
1954 | so we don't clobber anything we care about by accident. */ | ||
1955 | ax_tmp = t->ax; | ||
1956 | |||
1957 | /* Update 'ax' by the new key material */ | ||
1958 | ret = update_ax_by_kx (&ax_tmp, | ||
1959 | GCP_get_id (t->destination), | ||
1960 | &msg->kx.ephemeral_key, | ||
1961 | &msg->kx.ratchet_key); | ||
1962 | if (GNUNET_OK != ret) | ||
1963 | { | ||
1964 | if (GNUNET_NO == ret) | ||
1965 | GNUNET_STATISTICS_update (stats, | ||
1966 | "# redundant KX_AUTH received", | ||
1967 | 1, | ||
1968 | GNUNET_NO); | ||
1969 | else | ||
1970 | GNUNET_break (0); /* connect to self!? */ | ||
1971 | return; | ||
1972 | } | ||
1973 | GNUNET_CRYPTO_hash (&ax_tmp.RK, | ||
1974 | sizeof(ax_tmp.RK), | ||
1975 | &kx_auth); | ||
1976 | if (0 != GNUNET_memcmp (&kx_auth, | ||
1977 | &msg->auth)) | ||
1978 | { | ||
1979 | /* This KX_AUTH is not using the latest KX/KX_AUTH data | ||
1980 | we transmitted to the sender, refuse it, try KX again. */ | ||
1981 | GNUNET_STATISTICS_update (stats, | ||
1982 | "# KX_AUTH not using our last KX received (auth failure)", | ||
1983 | 1, | ||
1984 | GNUNET_NO); | ||
1985 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1986 | "KX AUTH mismatch!\n"); | ||
1987 | #if DEBUG_KX | ||
1988 | { | ||
1989 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; | ||
1990 | |||
1991 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax_tmp.kx_0, | ||
1992 | &ephemeral_key); | ||
1993 | if (0 != GNUNET_memcmp (&ephemeral_key, | ||
1994 | &msg->r_ephemeral_key_XXX)) | ||
1995 | { | ||
1996 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1997 | "My ephemeral is %s!\n", | ||
1998 | GNUNET_e2s (&ephemeral_key)); | ||
1999 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2000 | "Response is for ephemeral %s!\n", | ||
2001 | GNUNET_e2s (&msg->r_ephemeral_key_XXX)); | ||
2002 | } | ||
2003 | else | ||
2004 | { | ||
2005 | test_crypto_bug (&ax_tmp.kx_0, | ||
2006 | &msg->kx.ephemeral_key_XXX, | ||
2007 | my_private_key, | ||
2008 | &msg->kx.private_key_XXX); | ||
2009 | } | ||
2010 | } | ||
2011 | #endif | ||
2012 | if (NULL == t->kx_task) | ||
2013 | t->kx_task | ||
2014 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, | ||
2015 | &retry_kx, | ||
2016 | t); | ||
2017 | return; | ||
2018 | } | ||
2019 | /* Yep, we're good. */ | ||
2020 | t->ax = ax_tmp; | ||
2021 | if (NULL != t->unverified_ax) | ||
2022 | { | ||
2023 | /* We got some "stale" KX before, drop that. */ | ||
2024 | cleanup_ax (t->unverified_ax); | ||
2025 | GNUNET_free (t->unverified_ax); | ||
2026 | t->unverified_ax = NULL; | ||
2027 | } | ||
2028 | |||
2029 | /* move ahead in our state machine */ | ||
2030 | switch (t->estate) | ||
2031 | { | ||
2032 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
2033 | case CADET_TUNNEL_KEY_AX_RECV: | ||
2034 | /* Checked above, this is impossible. */ | ||
2035 | GNUNET_assert (0); | ||
2036 | break; | ||
2037 | |||
2038 | case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */ | ||
2039 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */ | ||
2040 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */ | ||
2041 | GCT_change_estate (t, | ||
2042 | CADET_TUNNEL_KEY_OK); | ||
2043 | break; | ||
2044 | |||
2045 | case CADET_TUNNEL_KEY_OK: | ||
2046 | /* Did not expect another KX_AUTH, but so what, still acceptable. | ||
2047 | Nothing to do here. */ | ||
2048 | break; | ||
2049 | } | ||
2050 | if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags))) | ||
2051 | { | ||
2052 | send_kx_auth (t, | ||
2053 | NULL, | ||
2054 | &t->ax, | ||
2055 | GNUNET_NO); | ||
2056 | } | ||
2057 | } | ||
2058 | |||
2059 | |||
2060 | /* ************************************** end core crypto ***************************** */ | ||
2061 | |||
2062 | |||
2063 | /** | ||
2064 | * Compute the next free channel tunnel number for this tunnel. | ||
2065 | * | ||
2066 | * @param t the tunnel | ||
2067 | * @return unused number that can uniquely identify a channel in the tunnel | ||
2068 | */ | ||
2069 | static struct GNUNET_CADET_ChannelTunnelNumber | ||
2070 | get_next_free_ctn (struct CadetTunnel *t) | ||
2071 | { | ||
2072 | #define HIGH_BIT 0x8000000 | ||
2073 | struct GNUNET_CADET_ChannelTunnelNumber ret; | ||
2074 | uint32_t ctn; | ||
2075 | int cmp; | ||
2076 | uint32_t highbit; | ||
2077 | |||
2078 | cmp = GNUNET_memcmp (&my_full_id, | ||
2079 | GCP_get_id (GCT_get_destination (t))); | ||
2080 | if (0 < cmp) | ||
2081 | highbit = HIGH_BIT; | ||
2082 | else if (0 > cmp) | ||
2083 | highbit = 0; | ||
2084 | else | ||
2085 | GNUNET_assert (0); // loopback must never go here! | ||
2086 | ctn = ntohl (t->next_ctn.cn); | ||
2087 | while (NULL != | ||
2088 | GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
2089 | ctn | highbit)) | ||
2090 | { | ||
2091 | ctn = ((ctn + 1) & (~HIGH_BIT)); | ||
2092 | } | ||
2093 | t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT)); | ||
2094 | ret.cn = htonl (ctn | highbit); | ||
2095 | return ret; | ||
2096 | } | ||
2097 | |||
2098 | |||
2099 | /** | ||
2100 | * Add a channel to a tunnel, and notify channel that we are ready | ||
2101 | * for transmission if we are already up. Otherwise that notification | ||
2102 | * will be done later in #notify_tunnel_up_cb(). | ||
2103 | * | ||
2104 | * @param t Tunnel. | ||
2105 | * @param ch Channel | ||
2106 | * @return unique number identifying @a ch within @a t | ||
2107 | */ | ||
2108 | struct GNUNET_CADET_ChannelTunnelNumber | ||
2109 | GCT_add_channel (struct CadetTunnel *t, | ||
2110 | struct CadetChannel *ch) | ||
2111 | { | ||
2112 | struct GNUNET_CADET_ChannelTunnelNumber ctn; | ||
2113 | |||
2114 | ctn = get_next_free_ctn (t); | ||
2115 | if (NULL != t->destroy_task) | ||
2116 | { | ||
2117 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
2118 | t->destroy_task = NULL; | ||
2119 | } | ||
2120 | GNUNET_assert (GNUNET_YES == | ||
2121 | GNUNET_CONTAINER_multihashmap32_put (t->channels, | ||
2122 | ntohl (ctn.cn), | ||
2123 | ch, | ||
2124 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
2125 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2126 | "Adding %s to %s with state %d\n", | ||
2127 | GCCH_2s (ch), | ||
2128 | GCT_2s (t), | ||
2129 | t->estate); | ||
2130 | switch (t->estate) | ||
2131 | { | ||
2132 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
2133 | /* waiting for connection to start KX */ | ||
2134 | break; | ||
2135 | |||
2136 | case CADET_TUNNEL_KEY_AX_RECV: | ||
2137 | case CADET_TUNNEL_KEY_AX_SENT: | ||
2138 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: | ||
2139 | /* we're currently waiting for KX to complete */ | ||
2140 | break; | ||
2141 | |||
2142 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
2143 | /* waiting for OTHER peer to send us data, | ||
2144 | we might need to prompt more aggressively! */ | ||
2145 | if (NULL == t->kx_task) | ||
2146 | t->kx_task | ||
2147 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, | ||
2148 | &retry_kx, | ||
2149 | t); | ||
2150 | break; | ||
2151 | |||
2152 | case CADET_TUNNEL_KEY_OK: | ||
2153 | /* We are ready. Tell the new channel that we are up. */ | ||
2154 | GCCH_tunnel_up (ch); | ||
2155 | break; | ||
2156 | } | ||
2157 | return ctn; | ||
2158 | } | ||
2159 | |||
2160 | |||
2161 | /** | ||
2162 | * We lost a connection, remove it from our list and clean up | ||
2163 | * the connection object itself. | ||
2164 | * | ||
2165 | * @param ct binding of connection to tunnel of the connection that was lost. | ||
2166 | */ | ||
2167 | void | ||
2168 | GCT_connection_lost (struct CadetTConnection *ct) | ||
2169 | { | ||
2170 | struct CadetTunnel *t = ct->t; | ||
2171 | |||
2172 | if (GNUNET_YES == ct->is_ready) | ||
2173 | { | ||
2174 | GNUNET_CONTAINER_DLL_remove (t->connection_ready_head, | ||
2175 | t->connection_ready_tail, | ||
2176 | ct); | ||
2177 | t->num_ready_connections--; | ||
2178 | } | ||
2179 | else | ||
2180 | { | ||
2181 | GNUNET_CONTAINER_DLL_remove (t->connection_busy_head, | ||
2182 | t->connection_busy_tail, | ||
2183 | ct); | ||
2184 | t->num_busy_connections--; | ||
2185 | } | ||
2186 | GNUNET_free (ct); | ||
2187 | } | ||
2188 | |||
2189 | |||
2190 | /** | ||
2191 | * Clean up connection @a ct of a tunnel. | ||
2192 | * | ||
2193 | * @param cls the `struct CadetTunnel` | ||
2194 | * @param ct connection to clean up | ||
2195 | */ | ||
2196 | static void | ||
2197 | destroy_t_connection (void *cls, | ||
2198 | struct CadetTConnection *ct) | ||
2199 | { | ||
2200 | struct CadetTunnel *t = cls; | ||
2201 | struct CadetConnection *cc = ct->cc; | ||
2202 | |||
2203 | GNUNET_assert (ct->t == t); | ||
2204 | GCT_connection_lost (ct); | ||
2205 | GCC_destroy_without_tunnel (cc); | ||
2206 | } | ||
2207 | |||
2208 | |||
2209 | /** | ||
2210 | * This tunnel is no longer used, destroy it. | ||
2211 | * | ||
2212 | * @param cls the idle tunnel | ||
2213 | */ | ||
2214 | static void | ||
2215 | destroy_tunnel (void *cls) | ||
2216 | { | ||
2217 | struct CadetTunnel *t = cls; | ||
2218 | struct CadetTunnelQueueEntry *tq; | ||
2219 | |||
2220 | t->destroy_task = NULL; | ||
2221 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2222 | "Destroying idle %s\n", | ||
2223 | GCT_2s (t)); | ||
2224 | GNUNET_assert (0 == GCT_count_channels (t)); | ||
2225 | GCT_iterate_connections (t, | ||
2226 | &destroy_t_connection, | ||
2227 | t); | ||
2228 | GNUNET_assert (NULL == t->connection_ready_head); | ||
2229 | GNUNET_assert (NULL == t->connection_busy_head); | ||
2230 | while (NULL != (tq = t->tq_head)) | ||
2231 | { | ||
2232 | if (NULL != tq->cont) | ||
2233 | tq->cont (tq->cont_cls, | ||
2234 | NULL); | ||
2235 | GCT_send_cancel (tq); | ||
2236 | } | ||
2237 | GCP_drop_tunnel (t->destination, | ||
2238 | t); | ||
2239 | GNUNET_CONTAINER_multihashmap32_destroy (t->channels); | ||
2240 | if (NULL != t->maintain_connections_task) | ||
2241 | { | ||
2242 | GNUNET_SCHEDULER_cancel (t->maintain_connections_task); | ||
2243 | t->maintain_connections_task = NULL; | ||
2244 | } | ||
2245 | if (NULL != t->send_task) | ||
2246 | { | ||
2247 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
2248 | t->send_task = NULL; | ||
2249 | } | ||
2250 | if (NULL != t->kx_task) | ||
2251 | { | ||
2252 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
2253 | t->kx_task = NULL; | ||
2254 | } | ||
2255 | GNUNET_MST_destroy (t->mst); | ||
2256 | GNUNET_MQ_destroy (t->mq); | ||
2257 | if (NULL != t->unverified_ax) | ||
2258 | { | ||
2259 | cleanup_ax (t->unverified_ax); | ||
2260 | GNUNET_free (t->unverified_ax); | ||
2261 | } | ||
2262 | cleanup_ax (&t->ax); | ||
2263 | GNUNET_assert (NULL == t->destroy_task); | ||
2264 | GNUNET_free (t); | ||
2265 | } | ||
2266 | |||
2267 | |||
2268 | /** | ||
2269 | * Remove a channel from a tunnel. | ||
2270 | * | ||
2271 | * @param t Tunnel. | ||
2272 | * @param ch Channel | ||
2273 | * @param ctn unique number identifying @a ch within @a t | ||
2274 | */ | ||
2275 | void | ||
2276 | GCT_remove_channel (struct CadetTunnel *t, | ||
2277 | struct CadetChannel *ch, | ||
2278 | struct GNUNET_CADET_ChannelTunnelNumber ctn) | ||
2279 | { | ||
2280 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2281 | "Removing %s from %s\n", | ||
2282 | GCCH_2s (ch), | ||
2283 | GCT_2s (t)); | ||
2284 | GNUNET_assert (GNUNET_YES == | ||
2285 | GNUNET_CONTAINER_multihashmap32_remove (t->channels, | ||
2286 | ntohl (ctn.cn), | ||
2287 | ch)); | ||
2288 | if ((0 == | ||
2289 | GCT_count_channels (t)) && | ||
2290 | (NULL == t->destroy_task)) | ||
2291 | { | ||
2292 | t->destroy_task | ||
2293 | = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, | ||
2294 | &destroy_tunnel, | ||
2295 | t); | ||
2296 | } | ||
2297 | } | ||
2298 | |||
2299 | |||
2300 | /** | ||
2301 | * Destroy remaining channels during shutdown. | ||
2302 | * | ||
2303 | * @param cls the `struct CadetTunnel` of the channel | ||
2304 | * @param key key of the channel | ||
2305 | * @param value the `struct CadetChannel` | ||
2306 | * @return #GNUNET_OK (continue to iterate) | ||
2307 | */ | ||
2308 | static int | ||
2309 | destroy_remaining_channels (void *cls, | ||
2310 | uint32_t key, | ||
2311 | void *value) | ||
2312 | { | ||
2313 | struct CadetChannel *ch = value; | ||
2314 | |||
2315 | GCCH_handle_remote_destroy (ch, | ||
2316 | NULL); | ||
2317 | return GNUNET_OK; | ||
2318 | } | ||
2319 | |||
2320 | |||
2321 | /** | ||
2322 | * Destroys the tunnel @a t now, without delay. Used during shutdown. | ||
2323 | * | ||
2324 | * @param t tunnel to destroy | ||
2325 | */ | ||
2326 | void | ||
2327 | GCT_destroy_tunnel_now (struct CadetTunnel *t) | ||
2328 | { | ||
2329 | GNUNET_assert (GNUNET_YES == shutting_down); | ||
2330 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
2331 | &destroy_remaining_channels, | ||
2332 | t); | ||
2333 | GNUNET_assert (0 == | ||
2334 | GCT_count_channels (t)); | ||
2335 | if (NULL != t->destroy_task) | ||
2336 | { | ||
2337 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
2338 | t->destroy_task = NULL; | ||
2339 | } | ||
2340 | destroy_tunnel (t); | ||
2341 | } | ||
2342 | |||
2343 | |||
2344 | /** | ||
2345 | * Send normal payload from queue in @a t via connection @a ct. | ||
2346 | * Does nothing if our payload queue is empty. | ||
2347 | * | ||
2348 | * @param t tunnel to send data from | ||
2349 | * @param ct connection to use for transmission (is ready) | ||
2350 | */ | ||
2351 | static void | ||
2352 | try_send_normal_payload (struct CadetTunnel *t, | ||
2353 | struct CadetTConnection *ct) | ||
2354 | { | ||
2355 | struct CadetTunnelQueueEntry *tq; | ||
2356 | |||
2357 | GNUNET_assert (GNUNET_YES == ct->is_ready); | ||
2358 | tq = t->tq_head; | ||
2359 | if (NULL == tq) | ||
2360 | { | ||
2361 | /* no messages pending right now */ | ||
2362 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2363 | "Not sending payload of %s on ready %s (nothing pending)\n", | ||
2364 | GCT_2s (t), | ||
2365 | GCC_2s (ct->cc)); | ||
2366 | return; | ||
2367 | } | ||
2368 | /* ready to send message 'tq' on tunnel 'ct' */ | ||
2369 | GNUNET_assert (t == tq->t); | ||
2370 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | ||
2371 | t->tq_tail, | ||
2372 | tq); | ||
2373 | if (NULL != tq->cid) | ||
2374 | *tq->cid = *GCC_get_id (ct->cc); | ||
2375 | mark_connection_unready (ct); | ||
2376 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2377 | "Sending payload of %s on %s\n", | ||
2378 | GCT_2s (t), | ||
2379 | GCC_2s (ct->cc)); | ||
2380 | GCC_transmit (ct->cc, | ||
2381 | tq->env); | ||
2382 | if (NULL != tq->cont) | ||
2383 | tq->cont (tq->cont_cls, | ||
2384 | GCC_get_id (ct->cc)); | ||
2385 | GNUNET_free (tq); | ||
2386 | } | ||
2387 | |||
2388 | |||
2389 | /** | ||
2390 | * A connection is @a is_ready for transmission. Looks at our message | ||
2391 | * queue and if there is a message, sends it out via the connection. | ||
2392 | * | ||
2393 | * @param cls the `struct CadetTConnection` that is @a is_ready | ||
2394 | * @param is_ready #GNUNET_YES if connection are now ready, | ||
2395 | * #GNUNET_NO if connection are no longer ready | ||
2396 | */ | ||
2397 | static void | ||
2398 | connection_ready_cb (void *cls, | ||
2399 | int is_ready) | ||
2400 | { | ||
2401 | struct CadetTConnection *ct = cls; | ||
2402 | struct CadetTunnel *t = ct->t; | ||
2403 | |||
2404 | if (GNUNET_NO == is_ready) | ||
2405 | { | ||
2406 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2407 | "%s no longer ready for %s\n", | ||
2408 | GCC_2s (ct->cc), | ||
2409 | GCT_2s (t)); | ||
2410 | mark_connection_unready (ct); | ||
2411 | return; | ||
2412 | } | ||
2413 | GNUNET_assert (GNUNET_NO == ct->is_ready); | ||
2414 | GNUNET_CONTAINER_DLL_remove (t->connection_busy_head, | ||
2415 | t->connection_busy_tail, | ||
2416 | ct); | ||
2417 | GNUNET_assert (0 < t->num_busy_connections); | ||
2418 | t->num_busy_connections--; | ||
2419 | ct->is_ready = GNUNET_YES; | ||
2420 | GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head, | ||
2421 | t->connection_ready_tail, | ||
2422 | ct); | ||
2423 | t->num_ready_connections++; | ||
2424 | |||
2425 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2426 | "%s now ready for %s in state %s\n", | ||
2427 | GCC_2s (ct->cc), | ||
2428 | GCT_2s (t), | ||
2429 | estate2s (t->estate)); | ||
2430 | switch (t->estate) | ||
2431 | { | ||
2432 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
2433 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2434 | "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n", | ||
2435 | GCT_2s (t), | ||
2436 | (unsigned long long) GNUNET_TIME_absolute_get_remaining ( | ||
2437 | t->next_kx_attempt).rel_value_us); | ||
2438 | /* Do not begin KX if WE have no channels waiting! */ | ||
2439 | if (0 != GNUNET_TIME_absolute_get_remaining ( | ||
2440 | t->next_kx_attempt).rel_value_us) | ||
2441 | return; /* wait for timeout before retrying */ | ||
2442 | /* We are uninitialized, just transmit immediately, | ||
2443 | without undue delay. */ | ||
2444 | |||
2445 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2446 | "Why for %s \n", | ||
2447 | GCT_2s (t)); | ||
2448 | |||
2449 | if (NULL != t->kx_task) | ||
2450 | { | ||
2451 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
2452 | t->kx_task = NULL; | ||
2453 | } | ||
2454 | send_kx (t, | ||
2455 | ct, | ||
2456 | &t->ax); | ||
2457 | if ((0 == | ||
2458 | GCT_count_channels (t)) && | ||
2459 | (NULL == t->destroy_task)) | ||
2460 | { | ||
2461 | t->destroy_task | ||
2462 | = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, | ||
2463 | &destroy_tunnel, | ||
2464 | t); | ||
2465 | } | ||
2466 | break; | ||
2467 | |||
2468 | case CADET_TUNNEL_KEY_AX_RECV: | ||
2469 | case CADET_TUNNEL_KEY_AX_SENT: | ||
2470 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: | ||
2471 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
2472 | /* we're currently waiting for KX to complete, schedule job */ | ||
2473 | if (NULL == t->kx_task) | ||
2474 | t->kx_task | ||
2475 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, | ||
2476 | &retry_kx, | ||
2477 | t); | ||
2478 | break; | ||
2479 | |||
2480 | case CADET_TUNNEL_KEY_OK: | ||
2481 | if (GNUNET_YES == t->kx_auth_requested) | ||
2482 | { | ||
2483 | if (0 != GNUNET_TIME_absolute_get_remaining ( | ||
2484 | t->next_kx_attempt).rel_value_us) | ||
2485 | return; /* wait for timeout */ | ||
2486 | if (NULL != t->kx_task) | ||
2487 | { | ||
2488 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
2489 | t->kx_task = NULL; | ||
2490 | } | ||
2491 | send_kx_auth (t, | ||
2492 | ct, | ||
2493 | &t->ax, | ||
2494 | GNUNET_NO); | ||
2495 | return; | ||
2496 | } | ||
2497 | try_send_normal_payload (t, | ||
2498 | ct); | ||
2499 | break; | ||
2500 | } | ||
2501 | } | ||
2502 | |||
2503 | |||
2504 | /** | ||
2505 | * Called when either we have a new connection, or a new message in the | ||
2506 | * queue, or some existing connection has transmission capacity. Looks | ||
2507 | * at our message queue and if there is a message, picks a connection | ||
2508 | * to send it on. | ||
2509 | * | ||
2510 | * @param cls the `struct CadetTunnel` to process messages on | ||
2511 | */ | ||
2512 | static void | ||
2513 | trigger_transmissions (void *cls) | ||
2514 | { | ||
2515 | struct CadetTunnel *t = cls; | ||
2516 | struct CadetTConnection *ct; | ||
2517 | |||
2518 | t->send_task = NULL; | ||
2519 | if (NULL == t->tq_head) | ||
2520 | return; /* no messages pending right now */ | ||
2521 | ct = get_ready_connection (t); | ||
2522 | if (NULL == ct) | ||
2523 | return; /* no connections ready */ | ||
2524 | try_send_normal_payload (t, | ||
2525 | ct); | ||
2526 | } | ||
2527 | |||
2528 | |||
2529 | /** | ||
2530 | * Closure for #evaluate_connection. Used to assemble summary information | ||
2531 | * about the existing connections so we can evaluate a new path. | ||
2532 | */ | ||
2533 | struct EvaluationSummary | ||
2534 | { | ||
2535 | /** | ||
2536 | * Minimum length of any of our connections, `UINT_MAX` if we have none. | ||
2537 | */ | ||
2538 | unsigned int min_length; | ||
2539 | |||
2540 | /** | ||
2541 | * Maximum length of any of our connections, 0 if we have none. | ||
2542 | */ | ||
2543 | unsigned int max_length; | ||
2544 | |||
2545 | /** | ||
2546 | * Minimum desirability of any of our connections, UINT64_MAX if we have none. | ||
2547 | */ | ||
2548 | GNUNET_CONTAINER_HeapCostType min_desire; | ||
2549 | |||
2550 | /** | ||
2551 | * Maximum desirability of any of our connections, 0 if we have none. | ||
2552 | */ | ||
2553 | GNUNET_CONTAINER_HeapCostType max_desire; | ||
2554 | |||
2555 | /** | ||
2556 | * Path we are comparing against for #evaluate_connection, can be NULL. | ||
2557 | */ | ||
2558 | struct CadetPeerPath *path; | ||
2559 | |||
2560 | /** | ||
2561 | * Connection deemed the "worst" so far encountered by #evaluate_connection, | ||
2562 | * NULL if we did not yet encounter any connections. | ||
2563 | */ | ||
2564 | struct CadetTConnection *worst; | ||
2565 | |||
2566 | /** | ||
2567 | * Numeric score of @e worst, only set if @e worst is non-NULL. | ||
2568 | */ | ||
2569 | double worst_score; | ||
2570 | |||
2571 | /** | ||
2572 | * Set to #GNUNET_YES if we have a connection over @e path already. | ||
2573 | */ | ||
2574 | int duplicate; | ||
2575 | }; | ||
2576 | |||
2577 | |||
2578 | /** | ||
2579 | * Evaluate a connection, updating our summary information in @a cls about | ||
2580 | * what kinds of connections we have. | ||
2581 | * | ||
2582 | * @param cls the `struct EvaluationSummary *` to update | ||
2583 | * @param ct a connection to include in the summary | ||
2584 | */ | ||
2585 | static void | ||
2586 | evaluate_connection (void *cls, | ||
2587 | struct CadetTConnection *ct) | ||
2588 | { | ||
2589 | struct EvaluationSummary *es = cls; | ||
2590 | struct CadetConnection *cc = ct->cc; | ||
2591 | unsigned int ct_length; | ||
2592 | struct CadetPeerPath *ps; | ||
2593 | const struct CadetConnectionMetrics *metrics; | ||
2594 | GNUNET_CONTAINER_HeapCostType ct_desirability; | ||
2595 | struct GNUNET_TIME_Relative uptime; | ||
2596 | struct GNUNET_TIME_Relative last_use; | ||
2597 | double score; | ||
2598 | double success_rate; | ||
2599 | |||
2600 | ps = GCC_get_path (cc, | ||
2601 | &ct_length); | ||
2602 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2603 | "Evaluating path %s of existing %s\n", | ||
2604 | GCPP_2s (ps), | ||
2605 | GCC_2s (cc)); | ||
2606 | if (ps == es->path) | ||
2607 | { | ||
2608 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2609 | "Ignoring duplicate path %s.\n", | ||
2610 | GCPP_2s (es->path)); | ||
2611 | es->duplicate = GNUNET_YES; | ||
2612 | return; | ||
2613 | } | ||
2614 | if (NULL != es->path) | ||
2615 | { | ||
2616 | int duplicate = GNUNET_YES; | ||
2617 | |||
2618 | for (unsigned int i = 0; i < ct_length; i++) | ||
2619 | { | ||
2620 | GNUNET_assert (GCPP_get_length (es->path) > i); | ||
2621 | if (GCPP_get_peer_at_offset (es->path, | ||
2622 | i) != | ||
2623 | GCPP_get_peer_at_offset (ps, | ||
2624 | i)) | ||
2625 | { | ||
2626 | duplicate = GNUNET_NO; | ||
2627 | break; | ||
2628 | } | ||
2629 | } | ||
2630 | if (GNUNET_YES == duplicate) | ||
2631 | { | ||
2632 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2633 | "Ignoring overlapping path %s.\n", | ||
2634 | GCPP_2s (es->path)); | ||
2635 | es->duplicate = GNUNET_YES; | ||
2636 | return; | ||
2637 | } | ||
2638 | else | ||
2639 | { | ||
2640 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2641 | "Known path %s differs from proposed path\n", | ||
2642 | GCPP_2s (ps)); | ||
2643 | } | ||
2644 | } | ||
2645 | |||
2646 | ct_desirability = GCPP_get_desirability (ps); | ||
2647 | metrics = GCC_get_metrics (cc); | ||
2648 | uptime = GNUNET_TIME_absolute_get_duration (metrics->age); | ||
2649 | last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use); | ||
2650 | /* We add 1.0 here to avoid division by zero. */ | ||
2651 | success_rate = (metrics->num_acked_transmissions + 1.0) | ||
2652 | / (metrics->num_successes + 1.0); | ||
2653 | score | ||
2654 | = ct_desirability | ||
2655 | + 100.0 / (1.0 + ct_length) /* longer paths = better */ | ||
2656 | + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */ | ||
2657 | - last_use.rel_value_us / 1000L; /* longer idle = worse */ | ||
2658 | score *= success_rate; /* weigh overall by success rate */ | ||
2659 | |||
2660 | if ((NULL == es->worst) || | ||
2661 | (score < es->worst_score)) | ||
2662 | { | ||
2663 | es->worst = ct; | ||
2664 | es->worst_score = score; | ||
2665 | } | ||
2666 | es->min_length = GNUNET_MIN (es->min_length, | ||
2667 | ct_length); | ||
2668 | es->max_length = GNUNET_MAX (es->max_length, | ||
2669 | ct_length); | ||
2670 | es->min_desire = GNUNET_MIN (es->min_desire, | ||
2671 | ct_desirability); | ||
2672 | es->max_desire = GNUNET_MAX (es->max_desire, | ||
2673 | ct_desirability); | ||
2674 | } | ||
2675 | |||
2676 | |||
2677 | /** | ||
2678 | * Consider using the path @a p for the tunnel @a t. | ||
2679 | * The tunnel destination is at offset @a off in path @a p. | ||
2680 | * | ||
2681 | * @param cls our tunnel | ||
2682 | * @param path a path to our destination | ||
2683 | * @param off offset of the destination on path @a path | ||
2684 | * @return #GNUNET_YES (should keep iterating) | ||
2685 | */ | ||
2686 | static int | ||
2687 | consider_path_cb (void *cls, | ||
2688 | struct CadetPeerPath *path, | ||
2689 | unsigned int off) | ||
2690 | { | ||
2691 | struct CadetTunnel *t = cls; | ||
2692 | struct EvaluationSummary es; | ||
2693 | struct CadetTConnection *ct; | ||
2694 | |||
2695 | GNUNET_assert (off < GCPP_get_length (path)); | ||
2696 | GNUNET_assert (GCPP_get_peer_at_offset (path, | ||
2697 | off) == t->destination); | ||
2698 | es.min_length = UINT_MAX; | ||
2699 | es.max_length = 0; | ||
2700 | es.max_desire = 0; | ||
2701 | es.min_desire = UINT64_MAX; | ||
2702 | es.path = path; | ||
2703 | es.duplicate = GNUNET_NO; | ||
2704 | es.worst = NULL; | ||
2705 | |||
2706 | /* Compute evaluation summary over existing connections. */ | ||
2707 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2708 | "Evaluating proposed path %s for target %s\n", | ||
2709 | GCPP_2s (path), | ||
2710 | GCT_2s (t)); | ||
2711 | /* FIXME: suspect this does not ACTUALLY iterate | ||
2712 | over all existing paths, otherwise dup detection | ||
2713 | should work!!! */ | ||
2714 | GCT_iterate_connections (t, | ||
2715 | &evaluate_connection, | ||
2716 | &es); | ||
2717 | if (GNUNET_YES == es.duplicate) | ||
2718 | return GNUNET_YES; | ||
2719 | |||
2720 | /* FIXME: not sure we should really just count | ||
2721 | 'num_connections' here, as they may all have | ||
2722 | consistently failed to connect. */ | ||
2723 | |||
2724 | /* We iterate by increasing path length; if we have enough paths and | ||
2725 | this one is more than twice as long than what we are currently | ||
2726 | using, then ignore all of these super-long ones! */ | ||
2727 | if ((GCT_count_any_connections (t) > DESIRED_CONNECTIONS_PER_TUNNEL) && | ||
2728 | (es.min_length * 2 < off) && | ||
2729 | (es.max_length < off)) | ||
2730 | { | ||
2731 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2732 | "Ignoring paths of length %u, they are way too long.\n", | ||
2733 | es.min_length * 2); | ||
2734 | return GNUNET_NO; | ||
2735 | } | ||
2736 | /* If we have enough paths and this one looks no better, ignore it. */ | ||
2737 | if ((GCT_count_any_connections (t) >= DESIRED_CONNECTIONS_PER_TUNNEL) && | ||
2738 | (es.min_length < GCPP_get_length (path)) && | ||
2739 | (es.min_desire > GCPP_get_desirability (path)) && | ||
2740 | (es.max_length < off)) | ||
2741 | { | ||
2742 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2743 | "Ignoring path (%u/%llu) to %s, got something better already.\n", | ||
2744 | GCPP_get_length (path), | ||
2745 | (unsigned long long) GCPP_get_desirability (path), | ||
2746 | GCP_2s (t->destination)); | ||
2747 | return GNUNET_YES; | ||
2748 | } | ||
2749 | |||
2750 | /* Path is interesting (better by some metric, or we don't have | ||
2751 | enough paths yet). */ | ||
2752 | ct = GNUNET_new (struct CadetTConnection); | ||
2753 | ct->created = GNUNET_TIME_absolute_get (); | ||
2754 | ct->t = t; | ||
2755 | ct->cc = GCC_create (t->destination, | ||
2756 | path, | ||
2757 | off, | ||
2758 | ct, | ||
2759 | &connection_ready_cb, | ||
2760 | ct); | ||
2761 | |||
2762 | /* FIXME: schedule job to kill connection (and path?) if it takes | ||
2763 | too long to get ready! (And track performance data on how long | ||
2764 | other connections took with the tunnel!) | ||
2765 | => Note: to be done within 'connection'-logic! */ | ||
2766 | GNUNET_CONTAINER_DLL_insert (t->connection_busy_head, | ||
2767 | t->connection_busy_tail, | ||
2768 | ct); | ||
2769 | t->num_busy_connections++; | ||
2770 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2771 | "Found interesting path %s for %s, created %s\n", | ||
2772 | GCPP_2s (path), | ||
2773 | GCT_2s (t), | ||
2774 | GCC_2s (ct->cc)); | ||
2775 | return GNUNET_YES; | ||
2776 | } | ||
2777 | |||
2778 | |||
2779 | /** | ||
2780 | * Function called to maintain the connections underlying our tunnel. | ||
2781 | * Tries to maintain (incl. tear down) connections for the tunnel, and | ||
2782 | * if there is a significant change, may trigger transmissions. | ||
2783 | * | ||
2784 | * Basically, needs to check if there are connections that perform | ||
2785 | * badly, and if so eventually kill them and trigger a replacement. | ||
2786 | * The strategy is to open one more connection than | ||
2787 | * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the | ||
2788 | * least-performing one, and then inquire for new ones. | ||
2789 | * | ||
2790 | * @param cls the `struct CadetTunnel` | ||
2791 | */ | ||
2792 | static void | ||
2793 | maintain_connections_cb (void *cls) | ||
2794 | { | ||
2795 | struct CadetTunnel *t = cls; | ||
2796 | struct GNUNET_TIME_Relative delay; | ||
2797 | struct EvaluationSummary es; | ||
2798 | |||
2799 | t->maintain_connections_task = NULL; | ||
2800 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2801 | "Performing connection maintenance for %s.\n", | ||
2802 | GCT_2s (t)); | ||
2803 | |||
2804 | es.min_length = UINT_MAX; | ||
2805 | es.max_length = 0; | ||
2806 | es.max_desire = 0; | ||
2807 | es.min_desire = UINT64_MAX; | ||
2808 | es.path = NULL; | ||
2809 | es.worst = NULL; | ||
2810 | es.duplicate = GNUNET_NO; | ||
2811 | GCT_iterate_connections (t, | ||
2812 | &evaluate_connection, | ||
2813 | &es); | ||
2814 | if ((NULL != es.worst) && | ||
2815 | (GCT_count_any_connections (t) > DESIRED_CONNECTIONS_PER_TUNNEL)) | ||
2816 | { | ||
2817 | /* Clear out worst-performing connection 'es.worst'. */ | ||
2818 | destroy_t_connection (t, | ||
2819 | es.worst); | ||
2820 | } | ||
2821 | |||
2822 | /* Consider additional paths */ | ||
2823 | (void) GCP_iterate_paths (t->destination, | ||
2824 | &consider_path_cb, | ||
2825 | t); | ||
2826 | |||
2827 | /* FIXME: calculate when to try again based on how well we are doing; | ||
2828 | in particular, if we have to few connections, we might be able | ||
2829 | to do without this (as PATHS should tell us whenever a new path | ||
2830 | is available instantly; however, need to make sure this job is | ||
2831 | restarted after that happens). | ||
2832 | Furthermore, if the paths we do know are in a reasonably narrow | ||
2833 | quality band and are plentyful, we might also consider us stabilized | ||
2834 | and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES; | ||
2835 | t->maintain_connections_task | ||
2836 | = GNUNET_SCHEDULER_add_delayed (delay, | ||
2837 | &maintain_connections_cb, | ||
2838 | t); | ||
2839 | } | ||
2840 | |||
2841 | |||
2842 | /** | ||
2843 | * Consider using the path @a p for the tunnel @a t. | ||
2844 | * The tunnel destination is at offset @a off in path @a p. | ||
2845 | * | ||
2846 | * @param cls our tunnel | ||
2847 | * @param path a path to our destination | ||
2848 | * @param off offset of the destination on path @a path | ||
2849 | */ | ||
2850 | void | ||
2851 | GCT_consider_path (struct CadetTunnel *t, | ||
2852 | struct CadetPeerPath *p, | ||
2853 | unsigned int off) | ||
2854 | { | ||
2855 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2856 | "Considering %s for %s (offset %u)\n", | ||
2857 | GCPP_2s (p), | ||
2858 | GCT_2s (t), | ||
2859 | off); | ||
2860 | (void) consider_path_cb (t, | ||
2861 | p, | ||
2862 | off); | ||
2863 | } | ||
2864 | |||
2865 | |||
2866 | /** | ||
2867 | * We got a keepalive. Track in statistics. | ||
2868 | * | ||
2869 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
2870 | * @param msg the message we received on the tunnel | ||
2871 | */ | ||
2872 | static void | ||
2873 | handle_plaintext_keepalive (void *cls, | ||
2874 | const struct GNUNET_MessageHeader *msg) | ||
2875 | { | ||
2876 | struct CadetTunnel *t = cls; | ||
2877 | |||
2878 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2879 | "Received KEEPALIVE on %s\n", | ||
2880 | GCT_2s (t)); | ||
2881 | GNUNET_STATISTICS_update (stats, | ||
2882 | "# keepalives received", | ||
2883 | 1, | ||
2884 | GNUNET_NO); | ||
2885 | } | ||
2886 | |||
2887 | |||
2888 | /** | ||
2889 | * Check that @a msg is well-formed. | ||
2890 | * | ||
2891 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
2892 | * @param msg the message we received on the tunnel | ||
2893 | * @return #GNUNET_OK (any variable-size payload goes) | ||
2894 | */ | ||
2895 | static int | ||
2896 | check_plaintext_data (void *cls, | ||
2897 | const struct GNUNET_CADET_ChannelAppDataMessage *msg) | ||
2898 | { | ||
2899 | return GNUNET_OK; | ||
2900 | } | ||
2901 | |||
2902 | |||
2903 | /** | ||
2904 | * We received payload data for a channel. Locate the channel | ||
2905 | * and process the data, or return an error if the channel is unknown. | ||
2906 | * | ||
2907 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
2908 | * @param msg the message we received on the tunnel | ||
2909 | */ | ||
2910 | static void | ||
2911 | handle_plaintext_data (void *cls, | ||
2912 | const struct GNUNET_CADET_ChannelAppDataMessage *msg) | ||
2913 | { | ||
2914 | struct CadetTunnel *t = cls; | ||
2915 | struct CadetChannel *ch; | ||
2916 | |||
2917 | ch = lookup_channel (t, | ||
2918 | msg->ctn); | ||
2919 | if (NULL == ch) | ||
2920 | { | ||
2921 | /* We don't know about such a channel, might have been destroyed on our | ||
2922 | end in the meantime, or never existed. Send back a DESTROY. */ | ||
2923 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2924 | "Received %u bytes of application data for unknown channel %u, sending DESTROY\n", | ||
2925 | (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)), | ||
2926 | ntohl (msg->ctn.cn)); | ||
2927 | GCT_send_channel_destroy (t, | ||
2928 | msg->ctn); | ||
2929 | return; | ||
2930 | } | ||
2931 | GCCH_handle_channel_plaintext_data (ch, | ||
2932 | GCC_get_id (t->current_ct->cc), | ||
2933 | msg); | ||
2934 | } | ||
2935 | |||
2936 | |||
2937 | /** | ||
2938 | * We received an acknowledgement for data we sent on a channel. | ||
2939 | * Locate the channel and process it, or return an error if the | ||
2940 | * channel is unknown. | ||
2941 | * | ||
2942 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
2943 | * @param ack the message we received on the tunnel | ||
2944 | */ | ||
2945 | static void | ||
2946 | handle_plaintext_data_ack (void *cls, | ||
2947 | const struct GNUNET_CADET_ChannelDataAckMessage *ack) | ||
2948 | { | ||
2949 | struct CadetTunnel *t = cls; | ||
2950 | struct CadetChannel *ch; | ||
2951 | |||
2952 | ch = lookup_channel (t, | ||
2953 | ack->ctn); | ||
2954 | if (NULL == ch) | ||
2955 | { | ||
2956 | /* We don't know about such a channel, might have been destroyed on our | ||
2957 | end in the meantime, or never existed. Send back a DESTROY. */ | ||
2958 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2959 | "Received DATA_ACK for unknown channel %u, sending DESTROY\n", | ||
2960 | ntohl (ack->ctn.cn)); | ||
2961 | GCT_send_channel_destroy (t, | ||
2962 | ack->ctn); | ||
2963 | return; | ||
2964 | } | ||
2965 | GCCH_handle_channel_plaintext_data_ack (ch, | ||
2966 | GCC_get_id (t->current_ct->cc), | ||
2967 | ack); | ||
2968 | } | ||
2969 | |||
2970 | |||
2971 | /** | ||
2972 | * We have received a request to open a channel to a port from | ||
2973 | * another peer. Creates the incoming channel. | ||
2974 | * | ||
2975 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
2976 | * @param copen the message we received on the tunnel | ||
2977 | */ | ||
2978 | static void | ||
2979 | handle_plaintext_channel_open (void *cls, | ||
2980 | const struct | ||
2981 | GNUNET_CADET_ChannelOpenMessage *copen) | ||
2982 | { | ||
2983 | struct CadetTunnel *t = cls; | ||
2984 | struct CadetChannel *ch; | ||
2985 | |||
2986 | ch = GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
2987 | ntohl (copen->ctn.cn)); | ||
2988 | if (NULL != ch) | ||
2989 | { | ||
2990 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2991 | "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n", | ||
2992 | GNUNET_h2s (&copen->h_port), | ||
2993 | GCT_2s (t), | ||
2994 | GCCH_2s (ch)); | ||
2995 | GCCH_handle_duplicate_open (ch, | ||
2996 | GCC_get_id (t->current_ct->cc)); | ||
2997 | return; | ||
2998 | } | ||
2999 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3000 | "Received CHANNEL_OPEN on h_port %s from %s\n", | ||
3001 | GNUNET_h2s (&copen->h_port), | ||
3002 | GCT_2s (t)); | ||
3003 | ch = GCCH_channel_incoming_new (t, | ||
3004 | copen->ctn, | ||
3005 | &copen->h_port, | ||
3006 | ntohl (copen->opt)); | ||
3007 | if (NULL != t->destroy_task) | ||
3008 | { | ||
3009 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
3010 | t->destroy_task = NULL; | ||
3011 | } | ||
3012 | GNUNET_assert (GNUNET_OK == | ||
3013 | GNUNET_CONTAINER_multihashmap32_put (t->channels, | ||
3014 | ntohl (copen->ctn.cn), | ||
3015 | ch, | ||
3016 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
3017 | } | ||
3018 | |||
3019 | |||
3020 | /** | ||
3021 | * Send a DESTROY message via the tunnel. | ||
3022 | * | ||
3023 | * @param t the tunnel to transmit over | ||
3024 | * @param ctn ID of the channel to destroy | ||
3025 | */ | ||
3026 | void | ||
3027 | GCT_send_channel_destroy (struct CadetTunnel *t, | ||
3028 | struct GNUNET_CADET_ChannelTunnelNumber ctn) | ||
3029 | { | ||
3030 | struct GNUNET_CADET_ChannelDestroyMessage msg; | ||
3031 | |||
3032 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3033 | "Sending DESTROY message for channel ID %u\n", | ||
3034 | ntohl (ctn.cn)); | ||
3035 | msg.header.size = htons (sizeof(msg)); | ||
3036 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | ||
3037 | msg.reserved = htonl (0); | ||
3038 | msg.ctn = ctn; | ||
3039 | GCT_send (t, | ||
3040 | &msg.header, | ||
3041 | NULL, | ||
3042 | NULL, | ||
3043 | &ctn); | ||
3044 | } | ||
3045 | |||
3046 | |||
3047 | /** | ||
3048 | * We have received confirmation from the target peer that the | ||
3049 | * given channel could be established (the port is open). | ||
3050 | * Tell the client. | ||
3051 | * | ||
3052 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
3053 | * @param cm the message we received on the tunnel | ||
3054 | */ | ||
3055 | static void | ||
3056 | handle_plaintext_channel_open_ack (void *cls, | ||
3057 | const struct | ||
3058 | GNUNET_CADET_ChannelOpenAckMessage *cm) | ||
3059 | { | ||
3060 | struct CadetTunnel *t = cls; | ||
3061 | struct CadetChannel *ch; | ||
3062 | |||
3063 | ch = lookup_channel (t, | ||
3064 | cm->ctn); | ||
3065 | if (NULL == ch) | ||
3066 | { | ||
3067 | /* We don't know about such a channel, might have been destroyed on our | ||
3068 | end in the meantime, or never existed. Send back a DESTROY. */ | ||
3069 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3070 | "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n", | ||
3071 | ntohl (cm->ctn.cn)); | ||
3072 | GCT_send_channel_destroy (t, | ||
3073 | cm->ctn); | ||
3074 | return; | ||
3075 | } | ||
3076 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3077 | "Received channel OPEN_ACK on channel %s from %s\n", | ||
3078 | GCCH_2s (ch), | ||
3079 | GCT_2s (t)); | ||
3080 | GCCH_handle_channel_open_ack (ch, | ||
3081 | GCC_get_id (t->current_ct->cc), | ||
3082 | &cm->port); | ||
3083 | } | ||
3084 | |||
3085 | |||
3086 | /** | ||
3087 | * We received a message saying that a channel should be destroyed. | ||
3088 | * Pass it on to the correct channel. | ||
3089 | * | ||
3090 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
3091 | * @param cm the message we received on the tunnel | ||
3092 | */ | ||
3093 | static void | ||
3094 | handle_plaintext_channel_destroy (void *cls, | ||
3095 | const struct | ||
3096 | GNUNET_CADET_ChannelDestroyMessage *cm) | ||
3097 | { | ||
3098 | struct CadetTunnel *t = cls; | ||
3099 | struct CadetChannel *ch; | ||
3100 | |||
3101 | ch = lookup_channel (t, | ||
3102 | cm->ctn); | ||
3103 | if (NULL == ch) | ||
3104 | { | ||
3105 | /* We don't know about such a channel, might have been destroyed on our | ||
3106 | end in the meantime, or never existed. */ | ||
3107 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3108 | "Received channel DESTROY for unknown channel %u. Ignoring.\n", | ||
3109 | ntohl (cm->ctn.cn)); | ||
3110 | return; | ||
3111 | } | ||
3112 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3113 | "Received channel DESTROY on %s from %s\n", | ||
3114 | GCCH_2s (ch), | ||
3115 | GCT_2s (t)); | ||
3116 | GCCH_handle_remote_destroy (ch, | ||
3117 | GCC_get_id (t->current_ct->cc)); | ||
3118 | } | ||
3119 | |||
3120 | |||
3121 | /** | ||
3122 | * Handles a message we decrypted, by injecting it into | ||
3123 | * our message queue (which will do the dispatching). | ||
3124 | * | ||
3125 | * @param cls the `struct CadetTunnel` that got the message | ||
3126 | * @param msg the message | ||
3127 | * @return #GNUNET_OK on success (always) | ||
3128 | * #GNUNET_NO to stop further processing (no error) | ||
3129 | * #GNUNET_SYSERR to stop further processing with error | ||
3130 | */ | ||
3131 | static int | ||
3132 | handle_decrypted (void *cls, | ||
3133 | const struct GNUNET_MessageHeader *msg) | ||
3134 | { | ||
3135 | struct CadetTunnel *t = cls; | ||
3136 | |||
3137 | GNUNET_assert (NULL != t->current_ct); | ||
3138 | GNUNET_MQ_inject_message (t->mq, | ||
3139 | msg); | ||
3140 | return GNUNET_OK; | ||
3141 | } | ||
3142 | |||
3143 | |||
3144 | /** | ||
3145 | * Function called if we had an error processing | ||
3146 | * an incoming decrypted message. | ||
3147 | * | ||
3148 | * @param cls the `struct CadetTunnel` | ||
3149 | * @param error error code | ||
3150 | */ | ||
3151 | static void | ||
3152 | decrypted_error_cb (void *cls, | ||
3153 | enum GNUNET_MQ_Error error) | ||
3154 | { | ||
3155 | GNUNET_break_op (0); | ||
3156 | } | ||
3157 | |||
3158 | |||
3159 | /** | ||
3160 | * Create a tunnel to @a destination. Must only be called | ||
3161 | * from within #GCP_get_tunnel(). | ||
3162 | * | ||
3163 | * @param destination where to create the tunnel to | ||
3164 | * @return new tunnel to @a destination | ||
3165 | */ | ||
3166 | struct CadetTunnel * | ||
3167 | GCT_create_tunnel (struct CadetPeer *destination) | ||
3168 | { | ||
3169 | struct CadetTunnel *t = GNUNET_new (struct CadetTunnel); | ||
3170 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
3171 | GNUNET_MQ_hd_fixed_size (plaintext_keepalive, | ||
3172 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE, | ||
3173 | struct GNUNET_MessageHeader, | ||
3174 | t), | ||
3175 | GNUNET_MQ_hd_var_size (plaintext_data, | ||
3176 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA, | ||
3177 | struct GNUNET_CADET_ChannelAppDataMessage, | ||
3178 | t), | ||
3179 | GNUNET_MQ_hd_fixed_size (plaintext_data_ack, | ||
3180 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK, | ||
3181 | struct GNUNET_CADET_ChannelDataAckMessage, | ||
3182 | t), | ||
3183 | GNUNET_MQ_hd_fixed_size (plaintext_channel_open, | ||
3184 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, | ||
3185 | struct GNUNET_CADET_ChannelOpenMessage, | ||
3186 | t), | ||
3187 | GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack, | ||
3188 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, | ||
3189 | struct GNUNET_CADET_ChannelOpenAckMessage, | ||
3190 | t), | ||
3191 | GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy, | ||
3192 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, | ||
3193 | struct GNUNET_CADET_ChannelDestroyMessage, | ||
3194 | t), | ||
3195 | GNUNET_MQ_handler_end () | ||
3196 | }; | ||
3197 | |||
3198 | t->kx_retry_delay = INITIAL_KX_RETRY_DELAY; | ||
3199 | new_ephemeral (&t->ax); | ||
3200 | GNUNET_CRYPTO_ecdhe_key_create (&t->ax.kx_0); | ||
3201 | t->destination = destination; | ||
3202 | t->channels = GNUNET_CONTAINER_multihashmap32_create (8); | ||
3203 | t->maintain_connections_task | ||
3204 | = GNUNET_SCHEDULER_add_now (&maintain_connections_cb, | ||
3205 | t); | ||
3206 | t->mq = GNUNET_MQ_queue_for_callbacks (NULL, | ||
3207 | NULL, | ||
3208 | NULL, | ||
3209 | NULL, | ||
3210 | handlers, | ||
3211 | &decrypted_error_cb, | ||
3212 | t); | ||
3213 | t->mst = GNUNET_MST_create (&handle_decrypted, | ||
3214 | t); | ||
3215 | return t; | ||
3216 | } | ||
3217 | |||
3218 | |||
3219 | /** | ||
3220 | * Add a @a connection to the @a tunnel. | ||
3221 | * | ||
3222 | * @param t a tunnel | ||
3223 | * @param cid connection identifier to use for the connection | ||
3224 | * @param options options for the connection | ||
3225 | * @param path path to use for the connection | ||
3226 | * @return #GNUNET_OK on success, | ||
3227 | * #GNUNET_SYSERR on failure (duplicate connection) | ||
3228 | */ | ||
3229 | int | ||
3230 | GCT_add_inbound_connection (struct CadetTunnel *t, | ||
3231 | const struct | ||
3232 | GNUNET_CADET_ConnectionTunnelIdentifier *cid, | ||
3233 | struct CadetPeerPath *path) | ||
3234 | { | ||
3235 | struct CadetTConnection *ct; | ||
3236 | |||
3237 | ct = GNUNET_new (struct CadetTConnection); | ||
3238 | ct->created = GNUNET_TIME_absolute_get (); | ||
3239 | ct->t = t; | ||
3240 | ct->cc = GCC_create_inbound (t->destination, | ||
3241 | path, | ||
3242 | ct, | ||
3243 | cid, | ||
3244 | &connection_ready_cb, | ||
3245 | ct); | ||
3246 | if (NULL == ct->cc) | ||
3247 | { | ||
3248 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3249 | "%s refused inbound %s (duplicate)\n", | ||
3250 | GCT_2s (t), | ||
3251 | GCC_2s (ct->cc)); | ||
3252 | GNUNET_free (ct); | ||
3253 | return GNUNET_SYSERR; | ||
3254 | } | ||
3255 | /* FIXME: schedule job to kill connection (and path?) if it takes | ||
3256 | too long to get ready! (And track performance data on how long | ||
3257 | other connections took with the tunnel!) | ||
3258 | => Note: to be done within 'connection'-logic! */ | ||
3259 | GNUNET_CONTAINER_DLL_insert (t->connection_busy_head, | ||
3260 | t->connection_busy_tail, | ||
3261 | ct); | ||
3262 | t->num_busy_connections++; | ||
3263 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3264 | "%s has new %s\n", | ||
3265 | GCT_2s (t), | ||
3266 | GCC_2s (ct->cc)); | ||
3267 | return GNUNET_OK; | ||
3268 | } | ||
3269 | |||
3270 | |||
3271 | /** | ||
3272 | * Handle encrypted message. | ||
3273 | * | ||
3274 | * @param ct connection/tunnel combo that received encrypted message | ||
3275 | * @param msg the encrypted message to decrypt | ||
3276 | */ | ||
3277 | void | ||
3278 | GCT_handle_encrypted (struct CadetTConnection *ct, | ||
3279 | const struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
3280 | { | ||
3281 | struct CadetTunnel *t = ct->t; | ||
3282 | uint16_t size = ntohs (msg->header.size); | ||
3283 | char cbuf[size] GNUNET_ALIGN; | ||
3284 | ssize_t decrypted_size; | ||
3285 | |||
3286 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3287 | "%s received %u bytes of encrypted data in state %d\n", | ||
3288 | GCT_2s (t), | ||
3289 | (unsigned int) size, | ||
3290 | t->estate); | ||
3291 | |||
3292 | switch (t->estate) | ||
3293 | { | ||
3294 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
3295 | case CADET_TUNNEL_KEY_AX_RECV: | ||
3296 | /* We did not even SEND our KX, how can the other peer | ||
3297 | send us encrypted data? Must have been that we went | ||
3298 | down and the other peer still things we are up. | ||
3299 | Let's send it KX back. */ | ||
3300 | GNUNET_STATISTICS_update (stats, | ||
3301 | "# received encrypted without any KX", | ||
3302 | 1, | ||
3303 | GNUNET_NO); | ||
3304 | if (NULL != t->kx_task) | ||
3305 | { | ||
3306 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
3307 | t->kx_task = NULL; | ||
3308 | } | ||
3309 | send_kx (t, | ||
3310 | ct, | ||
3311 | &t->ax); | ||
3312 | return; | ||
3313 | |||
3314 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: | ||
3315 | /* We send KX, and other peer send KX to us at the same time. | ||
3316 | Neither KX is AUTH'ed, so let's try KX_AUTH this time. */ | ||
3317 | GNUNET_STATISTICS_update (stats, | ||
3318 | "# received encrypted without KX_AUTH", | ||
3319 | 1, | ||
3320 | GNUNET_NO); | ||
3321 | if (NULL != t->kx_task) | ||
3322 | { | ||
3323 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
3324 | t->kx_task = NULL; | ||
3325 | } | ||
3326 | send_kx_auth (t, | ||
3327 | ct, | ||
3328 | &t->ax, | ||
3329 | GNUNET_YES); | ||
3330 | return; | ||
3331 | |||
3332 | case CADET_TUNNEL_KEY_AX_SENT: | ||
3333 | /* We did not get the KX of the other peer, but that | ||
3334 | might have been lost. Send our KX again immediately. */ | ||
3335 | GNUNET_STATISTICS_update (stats, | ||
3336 | "# received encrypted without KX", | ||
3337 | 1, | ||
3338 | GNUNET_NO); | ||
3339 | if (NULL != t->kx_task) | ||
3340 | { | ||
3341 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
3342 | t->kx_task = NULL; | ||
3343 | } | ||
3344 | send_kx (t, | ||
3345 | ct, | ||
3346 | &t->ax); | ||
3347 | return; | ||
3348 | |||
3349 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
3350 | /* Great, first payload, we might graduate to OK! */ | ||
3351 | case CADET_TUNNEL_KEY_OK: | ||
3352 | /* We are up and running, all good. */ | ||
3353 | break; | ||
3354 | } | ||
3355 | |||
3356 | decrypted_size = -1; | ||
3357 | if (CADET_TUNNEL_KEY_OK == t->estate) | ||
3358 | { | ||
3359 | /* We have well-established key material available, | ||
3360 | try that. (This is the common case.) */ | ||
3361 | decrypted_size = t_ax_decrypt_and_validate (&t->ax, | ||
3362 | cbuf, | ||
3363 | msg, | ||
3364 | size); | ||
3365 | } | ||
3366 | |||
3367 | if ((-1 == decrypted_size) && | ||
3368 | (NULL != t->unverified_ax)) | ||
3369 | { | ||
3370 | /* We have un-authenticated KX material available. We should try | ||
3371 | this as a back-up option, in case the sender crashed and | ||
3372 | switched keys. */ | ||
3373 | decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax, | ||
3374 | cbuf, | ||
3375 | msg, | ||
3376 | size); | ||
3377 | if (-1 != decrypted_size) | ||
3378 | { | ||
3379 | /* It worked! Treat this as authentication of the AX data! */ | ||
3380 | cleanup_ax (&t->ax); | ||
3381 | t->ax = *t->unverified_ax; | ||
3382 | GNUNET_free (t->unverified_ax); | ||
3383 | t->unverified_ax = NULL; | ||
3384 | } | ||
3385 | if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate) | ||
3386 | { | ||
3387 | /* First time it worked, move tunnel into production! */ | ||
3388 | GCT_change_estate (t, | ||
3389 | CADET_TUNNEL_KEY_OK); | ||
3390 | if (NULL != t->send_task) | ||
3391 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
3392 | t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
3393 | t); | ||
3394 | } | ||
3395 | } | ||
3396 | if (NULL != t->unverified_ax) | ||
3397 | { | ||
3398 | /* We had unverified KX material that was useless; so increment | ||
3399 | counter and eventually move to ignore it. Note that we even do | ||
3400 | this increment if we successfully decrypted with the old KX | ||
3401 | material and thus didn't even both with the new one. This is | ||
3402 | the ideal case, as a malicious injection of bogus KX data | ||
3403 | basically only causes us to increment a counter a few times. */t->unverified_attempts++; | ||
3404 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3405 | "Failed to decrypt message with unverified KX data %u times\n", | ||
3406 | t->unverified_attempts); | ||
3407 | if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS) | ||
3408 | { | ||
3409 | cleanup_ax (t->unverified_ax); | ||
3410 | GNUNET_free (t->unverified_ax); | ||
3411 | t->unverified_ax = NULL; | ||
3412 | } | ||
3413 | } | ||
3414 | |||
3415 | if (-1 == decrypted_size) | ||
3416 | { | ||
3417 | /* Decryption failed for good, complain. */ | ||
3418 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
3419 | "%s failed to decrypt and validate encrypted data, retrying KX\n", | ||
3420 | GCT_2s (t)); | ||
3421 | GNUNET_STATISTICS_update (stats, | ||
3422 | "# unable to decrypt", | ||
3423 | 1, | ||
3424 | GNUNET_NO); | ||
3425 | if (NULL != t->kx_task) | ||
3426 | { | ||
3427 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
3428 | t->kx_task = NULL; | ||
3429 | } | ||
3430 | send_kx (t, | ||
3431 | ct, | ||
3432 | &t->ax); | ||
3433 | return; | ||
3434 | } | ||
3435 | GNUNET_STATISTICS_update (stats, | ||
3436 | "# decrypted bytes", | ||
3437 | decrypted_size, | ||
3438 | GNUNET_NO); | ||
3439 | |||
3440 | /* The MST will ultimately call #handle_decrypted() on each message. */ | ||
3441 | t->current_ct = ct; | ||
3442 | GNUNET_break_op (GNUNET_OK == | ||
3443 | GNUNET_MST_from_buffer (t->mst, | ||
3444 | cbuf, | ||
3445 | decrypted_size, | ||
3446 | GNUNET_YES, | ||
3447 | GNUNET_NO)); | ||
3448 | t->current_ct = NULL; | ||
3449 | } | ||
3450 | |||
3451 | |||
3452 | /** | ||
3453 | * Sends an already built message on a tunnel, encrypting it and | ||
3454 | * choosing the best connection if not provided. | ||
3455 | * | ||
3456 | * @param message Message to send. Function modifies it. | ||
3457 | * @param t Tunnel on which this message is transmitted. | ||
3458 | * @param cont Continuation to call once message is really sent. | ||
3459 | * @param cont_cls Closure for @c cont. | ||
3460 | * @param The ID of the channel we are using for sending. | ||
3461 | * @return Handle to cancel message | ||
3462 | */ | ||
3463 | struct CadetTunnelQueueEntry * | ||
3464 | GCT_send (struct CadetTunnel *t, | ||
3465 | const struct GNUNET_MessageHeader *message, | ||
3466 | GCT_SendContinuation cont, | ||
3467 | void *cont_cls, | ||
3468 | struct GNUNET_CADET_ChannelTunnelNumber *ctn) | ||
3469 | { | ||
3470 | struct CadetTunnelQueueEntry *tq; | ||
3471 | uint16_t payload_size; | ||
3472 | struct GNUNET_MQ_Envelope *env; | ||
3473 | struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg; | ||
3474 | struct CadetChannel *ch; | ||
3475 | |||
3476 | if (NULL != ctn) | ||
3477 | { | ||
3478 | ch = lookup_channel (t, | ||
3479 | *ctn); | ||
3480 | if ((NULL != ch) && GCCH_is_type_to_drop (ch, message)) | ||
3481 | { | ||
3482 | GNUNET_break (0); | ||
3483 | return NULL; | ||
3484 | } | ||
3485 | } | ||
3486 | |||
3487 | if (CADET_TUNNEL_KEY_OK != t->estate) | ||
3488 | { | ||
3489 | GNUNET_break (0); | ||
3490 | return NULL; | ||
3491 | } | ||
3492 | payload_size = ntohs (message->size); | ||
3493 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3494 | "Encrypting %u bytes for %s\n", | ||
3495 | (unsigned int) payload_size, | ||
3496 | GCT_2s (t)); | ||
3497 | env = GNUNET_MQ_msg_extra (ax_msg, | ||
3498 | payload_size, | ||
3499 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED); | ||
3500 | t_ax_encrypt (&t->ax, | ||
3501 | &ax_msg[1], | ||
3502 | message, | ||
3503 | payload_size); | ||
3504 | GNUNET_STATISTICS_update (stats, | ||
3505 | "# encrypted bytes", | ||
3506 | payload_size, | ||
3507 | GNUNET_NO); | ||
3508 | ax_msg->ax_header.Ns = htonl (t->ax.Ns++); | ||
3509 | ax_msg->ax_header.PNs = htonl (t->ax.PNs); | ||
3510 | /* FIXME: we should do this once, not once per message; | ||
3511 | this is a point multiplication, and DHRs does not | ||
3512 | change all the time. */ | ||
3513 | GNUNET_CRYPTO_ecdhe_key_get_public (&t->ax.DHRs, | ||
3514 | &ax_msg->ax_header.DHRs); | ||
3515 | t_h_encrypt (&t->ax, | ||
3516 | ax_msg); | ||
3517 | t_hmac (&ax_msg->ax_header, | ||
3518 | sizeof(struct GNUNET_CADET_AxHeader) + payload_size, | ||
3519 | 0, | ||
3520 | &t->ax.HKs, | ||
3521 | &ax_msg->hmac); | ||
3522 | |||
3523 | tq = GNUNET_malloc (sizeof(*tq)); | ||
3524 | tq->t = t; | ||
3525 | tq->env = env; | ||
3526 | tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */ | ||
3527 | tq->cont = cont; | ||
3528 | tq->cont_cls = cont_cls; | ||
3529 | GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, | ||
3530 | t->tq_tail, | ||
3531 | tq); | ||
3532 | if (NULL != t->send_task) | ||
3533 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
3534 | t->send_task | ||
3535 | = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
3536 | t); | ||
3537 | return tq; | ||
3538 | } | ||
3539 | |||
3540 | |||
3541 | /** | ||
3542 | * Cancel a previously sent message while it's in the queue. | ||
3543 | * | ||
3544 | * ONLY can be called before the continuation given to the send | ||
3545 | * function is called. Once the continuation is called, the message is | ||
3546 | * no longer in the queue! | ||
3547 | * | ||
3548 | * @param tq Handle to the queue entry to cancel. | ||
3549 | */ | ||
3550 | void | ||
3551 | GCT_send_cancel (struct CadetTunnelQueueEntry *tq) | ||
3552 | { | ||
3553 | struct CadetTunnel *t = tq->t; | ||
3554 | |||
3555 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | ||
3556 | t->tq_tail, | ||
3557 | tq); | ||
3558 | GNUNET_MQ_discard (tq->env); | ||
3559 | GNUNET_free (tq); | ||
3560 | } | ||
3561 | |||
3562 | |||
3563 | /** | ||
3564 | * Iterate over all connections of a tunnel. | ||
3565 | * | ||
3566 | * @param t Tunnel whose connections to iterate. | ||
3567 | * @param iter Iterator. | ||
3568 | * @param iter_cls Closure for @c iter. | ||
3569 | */ | ||
3570 | void | ||
3571 | GCT_iterate_connections (struct CadetTunnel *t, | ||
3572 | GCT_ConnectionIterator iter, | ||
3573 | void *iter_cls) | ||
3574 | { | ||
3575 | struct CadetTConnection *n; | ||
3576 | |||
3577 | for (struct CadetTConnection *ct = t->connection_ready_head; | ||
3578 | NULL != ct; | ||
3579 | ct = n) | ||
3580 | { | ||
3581 | n = ct->next; | ||
3582 | iter (iter_cls, | ||
3583 | ct); | ||
3584 | } | ||
3585 | for (struct CadetTConnection *ct = t->connection_busy_head; | ||
3586 | NULL != ct; | ||
3587 | ct = n) | ||
3588 | { | ||
3589 | n = ct->next; | ||
3590 | iter (iter_cls, | ||
3591 | ct); | ||
3592 | } | ||
3593 | } | ||
3594 | |||
3595 | |||
3596 | /** | ||
3597 | * Closure for #iterate_channels_cb. | ||
3598 | */ | ||
3599 | struct ChanIterCls | ||
3600 | { | ||
3601 | /** | ||
3602 | * Function to call. | ||
3603 | */ | ||
3604 | GCT_ChannelIterator iter; | ||
3605 | |||
3606 | /** | ||
3607 | * Closure for @e iter. | ||
3608 | */ | ||
3609 | void *iter_cls; | ||
3610 | }; | ||
3611 | |||
3612 | |||
3613 | /** | ||
3614 | * Helper function for #GCT_iterate_channels. | ||
3615 | * | ||
3616 | * @param cls the `struct ChanIterCls` | ||
3617 | * @param key unused | ||
3618 | * @param value a `struct CadetChannel` | ||
3619 | * @return #GNUNET_OK | ||
3620 | */ | ||
3621 | static int | ||
3622 | iterate_channels_cb (void *cls, | ||
3623 | uint32_t key, | ||
3624 | void *value) | ||
3625 | { | ||
3626 | struct ChanIterCls *ctx = cls; | ||
3627 | struct CadetChannel *ch = value; | ||
3628 | |||
3629 | ctx->iter (ctx->iter_cls, | ||
3630 | ch); | ||
3631 | return GNUNET_OK; | ||
3632 | } | ||
3633 | |||
3634 | |||
3635 | /** | ||
3636 | * Iterate over all channels of a tunnel. | ||
3637 | * | ||
3638 | * @param t Tunnel whose channels to iterate. | ||
3639 | * @param iter Iterator. | ||
3640 | * @param iter_cls Closure for @c iter. | ||
3641 | */ | ||
3642 | void | ||
3643 | GCT_iterate_channels (struct CadetTunnel *t, | ||
3644 | GCT_ChannelIterator iter, | ||
3645 | void *iter_cls) | ||
3646 | { | ||
3647 | struct ChanIterCls ctx; | ||
3648 | |||
3649 | ctx.iter = iter; | ||
3650 | ctx.iter_cls = iter_cls; | ||
3651 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
3652 | &iterate_channels_cb, | ||
3653 | &ctx); | ||
3654 | } | ||
3655 | |||
3656 | |||
3657 | /** | ||
3658 | * Call #GCCH_debug() on a channel. | ||
3659 | * | ||
3660 | * @param cls points to the log level to use | ||
3661 | * @param key unused | ||
3662 | * @param value the `struct CadetChannel` to dump | ||
3663 | * @return #GNUNET_OK (continue iteration) | ||
3664 | */ | ||
3665 | static int | ||
3666 | debug_channel (void *cls, | ||
3667 | uint32_t key, | ||
3668 | void *value) | ||
3669 | { | ||
3670 | const enum GNUNET_ErrorType *level = cls; | ||
3671 | struct CadetChannel *ch = value; | ||
3672 | |||
3673 | GCCH_debug (ch, *level); | ||
3674 | return GNUNET_OK; | ||
3675 | } | ||
3676 | |||
3677 | |||
3678 | #define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \ | ||
3679 | __VA_ARGS__) | ||
3680 | |||
3681 | |||
3682 | /** | ||
3683 | * Log all possible info about the tunnel state. | ||
3684 | * | ||
3685 | * @param t Tunnel to debug. | ||
3686 | * @param level Debug level to use. | ||
3687 | */ | ||
3688 | void | ||
3689 | GCT_debug (const struct CadetTunnel *t, | ||
3690 | enum GNUNET_ErrorType level) | ||
3691 | { | ||
3692 | #if ! defined(GNUNET_CULL_LOGGING) | ||
3693 | struct CadetTConnection *iter_c; | ||
3694 | int do_log; | ||
3695 | |||
3696 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), | ||
3697 | "cadet-tun", | ||
3698 | __FILE__, __FUNCTION__, __LINE__); | ||
3699 | if (0 == do_log) | ||
3700 | return; | ||
3701 | |||
3702 | LOG2 (level, | ||
3703 | "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n", | ||
3704 | GCT_2s (t), | ||
3705 | estate2s (t->estate), | ||
3706 | t->tq_len, | ||
3707 | GCT_count_any_connections (t)); | ||
3708 | LOG2 (level, | ||
3709 | "TTT channels:\n"); | ||
3710 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
3711 | &debug_channel, | ||
3712 | &level); | ||
3713 | LOG2 (level, | ||
3714 | "TTT connections:\n"); | ||
3715 | for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next) | ||
3716 | GCC_debug (iter_c->cc, | ||
3717 | level); | ||
3718 | for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next) | ||
3719 | GCC_debug (iter_c->cc, | ||
3720 | level); | ||
3721 | |||
3722 | LOG2 (level, | ||
3723 | "TTT TUNNEL END\n"); | ||
3724 | #endif | ||
3725 | } | ||
3726 | |||
3727 | |||
3728 | /* end of gnunet-service-cadet_tunnels.c */ | ||