diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet_tunnel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnel.c | 3501 |
1 files changed, 0 insertions, 3501 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c deleted file mode 100644 index a94e8f4ff..000000000 --- a/src/cadet/gnunet-service-cadet_tunnel.c +++ /dev/null | |||
@@ -1,3501 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013, 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file cadet/gnunet-service-cadet_tunnel.c | ||
22 | * @brief logical links between CADET clients | ||
23 | * @author Bartlomiej Polot | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_signatures.h" | ||
28 | #include "gnunet_statistics_service.h" | ||
29 | #include "cadet_protocol.h" | ||
30 | #include "cadet_path.h" | ||
31 | #include "gnunet-service-cadet_tunnel.h" | ||
32 | #include "gnunet-service-cadet_connection.h" | ||
33 | #include "gnunet-service-cadet_channel.h" | ||
34 | #include "gnunet-service-cadet_peer.h" | ||
35 | |||
36 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-tun",__VA_ARGS__) | ||
37 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-tun",__VA_ARGS__) | ||
38 | |||
39 | #define REKEY_WAIT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5) | ||
40 | |||
41 | #if !defined(GNUNET_CULL_LOGGING) | ||
42 | #define DUMP_KEYS_TO_STDERR GNUNET_YES | ||
43 | #else | ||
44 | #define DUMP_KEYS_TO_STDERR GNUNET_NO | ||
45 | #endif | ||
46 | |||
47 | #define MIN_TUNNEL_BUFFER 8 | ||
48 | #define MAX_TUNNEL_BUFFER 64 | ||
49 | #define MAX_SKIPPED_KEYS 64 | ||
50 | #define MAX_KEY_GAP 256 | ||
51 | #define AX_HEADER_SIZE (sizeof (uint32_t) * 2\ | ||
52 | + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)) | ||
53 | |||
54 | /******************************************************************************/ | ||
55 | /******************************** STRUCTS **********************************/ | ||
56 | /******************************************************************************/ | ||
57 | |||
58 | struct CadetTChannel | ||
59 | { | ||
60 | struct CadetTChannel *next; | ||
61 | struct CadetTChannel *prev; | ||
62 | struct CadetChannel *ch; | ||
63 | }; | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Entry in list of connections used by tunnel, with metadata. | ||
68 | */ | ||
69 | struct CadetTConnection | ||
70 | { | ||
71 | /** | ||
72 | * Next in DLL. | ||
73 | */ | ||
74 | struct CadetTConnection *next; | ||
75 | |||
76 | /** | ||
77 | * Prev in DLL. | ||
78 | */ | ||
79 | struct CadetTConnection *prev; | ||
80 | |||
81 | /** | ||
82 | * Connection handle. | ||
83 | */ | ||
84 | struct CadetConnection *c; | ||
85 | |||
86 | /** | ||
87 | * Creation time, to keep oldest connection alive. | ||
88 | */ | ||
89 | struct GNUNET_TIME_Absolute created; | ||
90 | |||
91 | /** | ||
92 | * Connection throughput, to keep fastest connection alive. | ||
93 | */ | ||
94 | uint32_t throughput; | ||
95 | }; | ||
96 | |||
97 | |||
98 | /** | ||
99 | * Struct to old keys for skipped messages while advancing the Axolotl ratchet. | ||
100 | */ | ||
101 | struct CadetTunnelSkippedKey | ||
102 | { | ||
103 | /** | ||
104 | * DLL next. | ||
105 | */ | ||
106 | struct CadetTunnelSkippedKey *next; | ||
107 | |||
108 | /** | ||
109 | * DLL prev. | ||
110 | */ | ||
111 | struct CadetTunnelSkippedKey *prev; | ||
112 | |||
113 | /** | ||
114 | * When was this key stored (for timeout). | ||
115 | */ | ||
116 | struct GNUNET_TIME_Absolute timestamp; | ||
117 | |||
118 | /** | ||
119 | * Header key. | ||
120 | */ | ||
121 | struct GNUNET_CRYPTO_SymmetricSessionKey HK; | ||
122 | |||
123 | /** | ||
124 | * Message key. | ||
125 | */ | ||
126 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
127 | |||
128 | /** | ||
129 | * Key number for a given HK. | ||
130 | */ | ||
131 | unsigned int Kn; | ||
132 | }; | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Axolotl data, according to https://github.com/trevp/axolotl/wiki . | ||
137 | */ | ||
138 | struct CadetTunnelAxolotl | ||
139 | { | ||
140 | /** | ||
141 | * A (double linked) list of stored message keys and associated header keys | ||
142 | * for "skipped" messages, i.e. messages that have not been | ||
143 | * received despite the reception of more recent messages, (head). | ||
144 | */ | ||
145 | struct CadetTunnelSkippedKey *skipped_head; | ||
146 | |||
147 | /** | ||
148 | * Skipped messages' keys DLL, tail. | ||
149 | */ | ||
150 | struct CadetTunnelSkippedKey *skipped_tail; | ||
151 | |||
152 | /** | ||
153 | * Elements in @a skipped_head <-> @a skipped_tail. | ||
154 | */ | ||
155 | unsigned int skipped; | ||
156 | |||
157 | /** | ||
158 | * 32-byte root key which gets updated by DH ratchet. | ||
159 | */ | ||
160 | struct GNUNET_CRYPTO_SymmetricSessionKey RK; | ||
161 | |||
162 | /** | ||
163 | * 32-byte header key (send). | ||
164 | */ | ||
165 | struct GNUNET_CRYPTO_SymmetricSessionKey HKs; | ||
166 | |||
167 | /** | ||
168 | * 32-byte header key (recv) | ||
169 | */ | ||
170 | struct GNUNET_CRYPTO_SymmetricSessionKey HKr; | ||
171 | |||
172 | /** | ||
173 | * 32-byte next header key (send). | ||
174 | */ | ||
175 | struct GNUNET_CRYPTO_SymmetricSessionKey NHKs; | ||
176 | |||
177 | /** | ||
178 | * 32-byte next header key (recv). | ||
179 | */ | ||
180 | struct GNUNET_CRYPTO_SymmetricSessionKey NHKr; | ||
181 | |||
182 | /** | ||
183 | * 32-byte chain keys (used for forward-secrecy updating, send). | ||
184 | */ | ||
185 | struct GNUNET_CRYPTO_SymmetricSessionKey CKs; | ||
186 | |||
187 | /** | ||
188 | * 32-byte chain keys (used for forward-secrecy updating, recv). | ||
189 | */ | ||
190 | struct GNUNET_CRYPTO_SymmetricSessionKey CKr; | ||
191 | |||
192 | /** | ||
193 | * ECDH for key exchange (A0 / B0). | ||
194 | */ | ||
195 | struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0; | ||
196 | |||
197 | /** | ||
198 | * ECDH Ratchet key (send). | ||
199 | */ | ||
200 | struct GNUNET_CRYPTO_EcdhePrivateKey *DHRs; | ||
201 | |||
202 | /** | ||
203 | * ECDH Ratchet key (recv). | ||
204 | */ | ||
205 | struct GNUNET_CRYPTO_EcdhePublicKey DHRr; | ||
206 | |||
207 | /** | ||
208 | * Message number (reset to 0 with each new ratchet, next message to send). | ||
209 | */ | ||
210 | uint32_t Ns; | ||
211 | |||
212 | /** | ||
213 | * Message number (reset to 0 with each new ratchet, next message to recv). | ||
214 | */ | ||
215 | uint32_t Nr; | ||
216 | |||
217 | /** | ||
218 | * Previous message numbers (# of msgs sent under prev ratchet) | ||
219 | */ | ||
220 | uint32_t PNs; | ||
221 | |||
222 | /** | ||
223 | * True (#GNUNET_YES) if we have to send a new ratchet key in next msg. | ||
224 | */ | ||
225 | int ratchet_flag; | ||
226 | |||
227 | /** | ||
228 | * Number of messages recieved since our last ratchet advance. | ||
229 | * - If this counter = 0, we cannot send a new ratchet key in next msg. | ||
230 | * - If this counter > 0, we can (but don't yet have to) send a new key. | ||
231 | */ | ||
232 | unsigned int ratchet_allowed; | ||
233 | |||
234 | /** | ||
235 | * Number of messages recieved since our last ratchet advance. | ||
236 | * - If this counter = 0, we cannot send a new ratchet key in next msg. | ||
237 | * - If this counter > 0, we can (but don't yet have to) send a new key. | ||
238 | */ | ||
239 | unsigned int ratchet_counter; | ||
240 | |||
241 | /** | ||
242 | * When does this ratchet expire and a new one is triggered. | ||
243 | */ | ||
244 | struct GNUNET_TIME_Absolute ratchet_expiration; | ||
245 | }; | ||
246 | |||
247 | |||
248 | /** | ||
249 | * Struct containing all information regarding a tunnel to a peer. | ||
250 | */ | ||
251 | struct CadetTunnel | ||
252 | { | ||
253 | /** | ||
254 | * Endpoint of the tunnel. | ||
255 | */ | ||
256 | struct CadetPeer *peer; | ||
257 | |||
258 | /** | ||
259 | * Axolotl info. | ||
260 | */ | ||
261 | struct CadetTunnelAxolotl *ax; | ||
262 | |||
263 | /** | ||
264 | * State of the tunnel connectivity. | ||
265 | */ | ||
266 | enum CadetTunnelCState cstate; | ||
267 | |||
268 | /** | ||
269 | * State of the tunnel encryption. | ||
270 | */ | ||
271 | enum CadetTunnelEState estate; | ||
272 | |||
273 | /** | ||
274 | * Peer's ephemeral key, to recreate @c e_key and @c d_key when own ephemeral | ||
275 | * key changes. | ||
276 | */ | ||
277 | struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key; | ||
278 | |||
279 | /** | ||
280 | * Encryption ("our") key. It is only "confirmed" if kx_ctx is NULL. | ||
281 | */ | ||
282 | struct GNUNET_CRYPTO_SymmetricSessionKey e_key; | ||
283 | |||
284 | /** | ||
285 | * Decryption ("their") key. It is only "confirmed" if kx_ctx is NULL. | ||
286 | */ | ||
287 | struct GNUNET_CRYPTO_SymmetricSessionKey d_key; | ||
288 | |||
289 | /** | ||
290 | * Task to start the rekey process. | ||
291 | */ | ||
292 | struct GNUNET_SCHEDULER_Task *rekey_task; | ||
293 | |||
294 | /** | ||
295 | * Paths that are actively used to reach the destination peer. | ||
296 | */ | ||
297 | struct CadetTConnection *connection_head; | ||
298 | struct CadetTConnection *connection_tail; | ||
299 | |||
300 | /** | ||
301 | * Next connection number. | ||
302 | */ | ||
303 | uint32_t next_cid; | ||
304 | |||
305 | /** | ||
306 | * Channels inside this tunnel. | ||
307 | */ | ||
308 | struct CadetTChannel *channel_head; | ||
309 | struct CadetTChannel *channel_tail; | ||
310 | |||
311 | /** | ||
312 | * Channel ID for the next created channel. | ||
313 | */ | ||
314 | struct GNUNET_CADET_ChannelTunnelNumber next_ctn; | ||
315 | |||
316 | /** | ||
317 | * Destroy flag: if true, destroy on last message. | ||
318 | */ | ||
319 | struct GNUNET_SCHEDULER_Task * destroy_task; | ||
320 | |||
321 | /** | ||
322 | * Queued messages, to transmit once tunnel gets connected. | ||
323 | */ | ||
324 | struct CadetTunnelDelayed *tq_head; | ||
325 | struct CadetTunnelDelayed *tq_tail; | ||
326 | |||
327 | /** | ||
328 | * Task to trim connections if too many are present. | ||
329 | */ | ||
330 | struct GNUNET_SCHEDULER_Task * trim_connections_task; | ||
331 | |||
332 | /** | ||
333 | * Ephemeral message in the queue (to avoid queueing more than one). | ||
334 | */ | ||
335 | struct CadetConnectionQueue *ephm_h; | ||
336 | |||
337 | /** | ||
338 | * Pong message in the queue. | ||
339 | */ | ||
340 | struct CadetConnectionQueue *pong_h; | ||
341 | }; | ||
342 | |||
343 | |||
344 | /** | ||
345 | * Struct used to save messages in a non-ready tunnel to send once connected. | ||
346 | */ | ||
347 | struct CadetTunnelDelayed | ||
348 | { | ||
349 | /** | ||
350 | * DLL | ||
351 | */ | ||
352 | struct CadetTunnelDelayed *next; | ||
353 | struct CadetTunnelDelayed *prev; | ||
354 | |||
355 | /** | ||
356 | * Tunnel. | ||
357 | */ | ||
358 | struct CadetTunnel *t; | ||
359 | |||
360 | /** | ||
361 | * Tunnel queue given to the channel to cancel request. Update on send_queued. | ||
362 | */ | ||
363 | struct CadetTunnelQueue *tq; | ||
364 | |||
365 | /** | ||
366 | * Message to send. | ||
367 | */ | ||
368 | /* struct GNUNET_MessageHeader *msg; */ | ||
369 | }; | ||
370 | |||
371 | |||
372 | /** | ||
373 | * Handle for messages queued but not yet sent. | ||
374 | */ | ||
375 | struct CadetTunnelQueue | ||
376 | { | ||
377 | /** | ||
378 | * Connection queue handle, to cancel if necessary. | ||
379 | */ | ||
380 | struct CadetConnectionQueue *cq; | ||
381 | |||
382 | /** | ||
383 | * Handle in case message hasn't been given to a connection yet. | ||
384 | */ | ||
385 | struct CadetTunnelDelayed *tqd; | ||
386 | |||
387 | /** | ||
388 | * Continuation to call once sent. | ||
389 | */ | ||
390 | GCT_sent cont; | ||
391 | |||
392 | /** | ||
393 | * Closure for @c cont. | ||
394 | */ | ||
395 | void *cont_cls; | ||
396 | }; | ||
397 | |||
398 | |||
399 | /******************************************************************************/ | ||
400 | /******************************* GLOBALS ***********************************/ | ||
401 | /******************************************************************************/ | ||
402 | |||
403 | /** | ||
404 | * Global handle to the statistics service. | ||
405 | */ | ||
406 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
407 | |||
408 | /** | ||
409 | * Local peer own ID (memory efficient handle). | ||
410 | */ | ||
411 | extern GNUNET_PEER_Id myid; | ||
412 | |||
413 | /** | ||
414 | * Local peer own ID (full value). | ||
415 | */ | ||
416 | extern struct GNUNET_PeerIdentity my_full_id; | ||
417 | |||
418 | |||
419 | /** | ||
420 | * Don't try to recover tunnels if shutting down. | ||
421 | */ | ||
422 | extern int shutting_down; | ||
423 | |||
424 | |||
425 | /** | ||
426 | * Set of all tunnels, in order to trigger a new exchange on rekey. | ||
427 | * Indexed by peer's ID. | ||
428 | */ | ||
429 | static struct GNUNET_CONTAINER_MultiPeerMap *tunnels; | ||
430 | |||
431 | /** | ||
432 | * Own Peer ID private key. | ||
433 | */ | ||
434 | const static struct GNUNET_CRYPTO_EddsaPrivateKey *id_key; | ||
435 | |||
436 | |||
437 | /******************************** AXOLOTL ************************************/ | ||
438 | |||
439 | /** | ||
440 | * How many messages are needed to trigger a ratchet advance. | ||
441 | */ | ||
442 | static unsigned long long ratchet_messages; | ||
443 | |||
444 | /** | ||
445 | * How long until we trigger a ratched advance. | ||
446 | */ | ||
447 | static struct GNUNET_TIME_Relative ratchet_time; | ||
448 | |||
449 | |||
450 | /******************************************************************************/ | ||
451 | /******************************** STATIC ***********************************/ | ||
452 | /******************************************************************************/ | ||
453 | |||
454 | /** | ||
455 | * Get string description for tunnel connectivity state. | ||
456 | * | ||
457 | * @param cs Tunnel state. | ||
458 | * | ||
459 | * @return String representation. | ||
460 | */ | ||
461 | static const char * | ||
462 | cstate2s (enum CadetTunnelCState cs) | ||
463 | { | ||
464 | static char buf[32]; | ||
465 | |||
466 | switch (cs) | ||
467 | { | ||
468 | case CADET_TUNNEL_NEW: | ||
469 | return "CADET_TUNNEL_NEW"; | ||
470 | case CADET_TUNNEL_SEARCHING: | ||
471 | return "CADET_TUNNEL_SEARCHING"; | ||
472 | case CADET_TUNNEL_WAITING: | ||
473 | return "CADET_TUNNEL_WAITING"; | ||
474 | case CADET_TUNNEL_READY: | ||
475 | return "CADET_TUNNEL_READY"; | ||
476 | case CADET_TUNNEL_SHUTDOWN: | ||
477 | return "CADET_TUNNEL_SHUTDOWN"; | ||
478 | default: | ||
479 | SPRINTF (buf, "%u (UNKNOWN STATE)", cs); | ||
480 | return buf; | ||
481 | } | ||
482 | return ""; | ||
483 | } | ||
484 | |||
485 | |||
486 | /** | ||
487 | * Get string description for tunnel encryption state. | ||
488 | * | ||
489 | * @param es Tunnel state. | ||
490 | * | ||
491 | * @return String representation. | ||
492 | */ | ||
493 | static const char * | ||
494 | estate2s (enum CadetTunnelEState es) | ||
495 | { | ||
496 | static char buf[32]; | ||
497 | |||
498 | switch (es) | ||
499 | { | ||
500 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
501 | return "CADET_TUNNEL_KEY_UNINITIALIZED"; | ||
502 | case CADET_TUNNEL_KEY_AX_SENT: | ||
503 | return "CADET_TUNNEL_KEY_AX_SENT"; | ||
504 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
505 | return "CADET_TUNNEL_KEY_AX_AUTH_SENT"; | ||
506 | case CADET_TUNNEL_KEY_OK: | ||
507 | return "CADET_TUNNEL_KEY_OK"; | ||
508 | case CADET_TUNNEL_KEY_REKEY: | ||
509 | return "CADET_TUNNEL_KEY_REKEY"; | ||
510 | default: | ||
511 | SPRINTF (buf, "%u (UNKNOWN STATE)", es); | ||
512 | return buf; | ||
513 | } | ||
514 | return ""; | ||
515 | } | ||
516 | |||
517 | |||
518 | /** | ||
519 | * @brief Check if tunnel is ready to send traffic. | ||
520 | * | ||
521 | * Tunnel must be connected and with encryption correctly set up. | ||
522 | * | ||
523 | * @param t Tunnel to check. | ||
524 | * | ||
525 | * @return #GNUNET_YES if ready, #GNUNET_NO otherwise | ||
526 | */ | ||
527 | static int | ||
528 | is_ready (struct CadetTunnel *t) | ||
529 | { | ||
530 | int ready; | ||
531 | int conn_ok; | ||
532 | int enc_ok; | ||
533 | |||
534 | conn_ok = CADET_TUNNEL_READY == t->cstate; | ||
535 | enc_ok = CADET_TUNNEL_KEY_OK == t->estate | ||
536 | || CADET_TUNNEL_KEY_REKEY == t->estate | ||
537 | || CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate; | ||
538 | ready = conn_ok && enc_ok; | ||
539 | ready = ready || GCT_is_loopback (t); | ||
540 | return ready; | ||
541 | } | ||
542 | |||
543 | |||
544 | /** | ||
545 | * Get the channel's buffer. ONLY FOR NON-LOOPBACK CHANNELS!! | ||
546 | * | ||
547 | * @param tch Tunnel's channel handle. | ||
548 | * | ||
549 | * @return Amount of messages the channel can still buffer towards the client. | ||
550 | */ | ||
551 | static unsigned int | ||
552 | get_channel_buffer (const struct CadetTChannel *tch) | ||
553 | { | ||
554 | int fwd; | ||
555 | |||
556 | /* If channel is incoming, is terminal in the FWD direction and fwd is YES */ | ||
557 | fwd = GCCH_is_terminal (tch->ch, GNUNET_YES); | ||
558 | |||
559 | return GCCH_get_buffer (tch->ch, fwd); | ||
560 | } | ||
561 | |||
562 | |||
563 | /** | ||
564 | * Get the channel's allowance status. | ||
565 | * | ||
566 | * @param tch Tunnel's channel handle. | ||
567 | * | ||
568 | * @return #GNUNET_YES if we allowed the client to send data to us. | ||
569 | */ | ||
570 | static int | ||
571 | get_channel_allowed (const struct CadetTChannel *tch) | ||
572 | { | ||
573 | int fwd; | ||
574 | |||
575 | /* If channel is outgoing, is origin in the FWD direction and fwd is YES */ | ||
576 | fwd = GCCH_is_origin (tch->ch, GNUNET_YES); | ||
577 | |||
578 | return GCCH_get_allowed (tch->ch, fwd); | ||
579 | } | ||
580 | |||
581 | |||
582 | /** | ||
583 | * Get the connection's buffer. | ||
584 | * | ||
585 | * @param tc Tunnel's connection handle. | ||
586 | * | ||
587 | * @return Amount of messages the connection can still buffer. | ||
588 | */ | ||
589 | static unsigned int | ||
590 | get_connection_buffer (const struct CadetTConnection *tc) | ||
591 | { | ||
592 | int fwd; | ||
593 | |||
594 | /* If connection is outgoing, is origin in the FWD direction and fwd is YES */ | ||
595 | fwd = GCC_is_origin (tc->c, GNUNET_YES); | ||
596 | |||
597 | return GCC_get_buffer (tc->c, fwd); | ||
598 | } | ||
599 | |||
600 | |||
601 | /** | ||
602 | * Get the connection's allowance. | ||
603 | * | ||
604 | * @param tc Tunnel's connection handle. | ||
605 | * | ||
606 | * @return Amount of messages we have allowed the next peer to send us. | ||
607 | */ | ||
608 | static unsigned int | ||
609 | get_connection_allowed (const struct CadetTConnection *tc) | ||
610 | { | ||
611 | int fwd; | ||
612 | |||
613 | /* If connection is outgoing, is origin in the FWD direction and fwd is YES */ | ||
614 | fwd = GCC_is_origin (tc->c, GNUNET_YES); | ||
615 | |||
616 | return GCC_get_allowed (tc->c, fwd); | ||
617 | } | ||
618 | |||
619 | |||
620 | /** | ||
621 | * Create a new Axolotl ephemeral (ratchet) key. | ||
622 | * | ||
623 | * @param t Tunnel. | ||
624 | */ | ||
625 | static void | ||
626 | new_ephemeral (struct CadetTunnel *t) | ||
627 | { | ||
628 | GNUNET_free_non_null (t->ax->DHRs); | ||
629 | t->ax->DHRs = GNUNET_CRYPTO_ecdhe_key_create(); | ||
630 | #if DUMP_KEYS_TO_STDERR | ||
631 | { | ||
632 | struct GNUNET_CRYPTO_EcdhePublicKey pub; | ||
633 | GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->DHRs, &pub); | ||
634 | LOG (GNUNET_ERROR_TYPE_DEBUG, " new DHRs generated: pub %s\n", | ||
635 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &pub)); | ||
636 | } | ||
637 | #endif | ||
638 | } | ||
639 | |||
640 | |||
641 | /** | ||
642 | * Calculate HMAC. | ||
643 | * | ||
644 | * @param plaintext Content to HMAC. | ||
645 | * @param size Size of @c plaintext. | ||
646 | * @param iv Initialization vector for the message. | ||
647 | * @param key Key to use. | ||
648 | * @param hmac[out] Destination to store the HMAC. | ||
649 | */ | ||
650 | static void | ||
651 | t_hmac (const void *plaintext, size_t size, | ||
652 | uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
653 | struct GNUNET_ShortHashCode *hmac) | ||
654 | { | ||
655 | static const char ctx[] = "cadet authentication key"; | ||
656 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
657 | struct GNUNET_HashCode hash; | ||
658 | |||
659 | #if DUMP_KEYS_TO_STDERR | ||
660 | LOG (GNUNET_ERROR_TYPE_INFO, " HMAC %u bytes with key %s\n", size, | ||
661 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) key)); | ||
662 | #endif | ||
663 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, key, | ||
664 | &iv, sizeof (iv), | ||
665 | key, sizeof (*key), | ||
666 | ctx, sizeof (ctx), | ||
667 | NULL); | ||
668 | /* Two step: CADET_Hash is only 256 bits, HashCode is 512. */ | ||
669 | GNUNET_CRYPTO_hmac (&auth_key, plaintext, size, &hash); | ||
670 | GNUNET_memcpy (hmac, &hash, sizeof (*hmac)); | ||
671 | } | ||
672 | |||
673 | |||
674 | /** | ||
675 | * Perform a HMAC. | ||
676 | * | ||
677 | * @param key Key to use. | ||
678 | * @param hash[out] Resulting HMAC. | ||
679 | * @param source Source key material (data to HMAC). | ||
680 | * @param len Length of @a source. | ||
681 | */ | ||
682 | static void | ||
683 | t_ax_hmac_hash (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
684 | struct GNUNET_HashCode *hash, | ||
685 | void *source, unsigned int len) | ||
686 | { | ||
687 | static const char ctx[] = "axolotl HMAC-HASH"; | ||
688 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
689 | |||
690 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, key, | ||
691 | ctx, sizeof (ctx), | ||
692 | NULL); | ||
693 | GNUNET_CRYPTO_hmac (&auth_key, source, len, hash); | ||
694 | } | ||
695 | |||
696 | |||
697 | /** | ||
698 | * Derive a key from a HMAC-HASH. | ||
699 | * | ||
700 | * @param key Key to use for the HMAC. | ||
701 | * @param out Key to generate. | ||
702 | * @param source Source key material (data to HMAC). | ||
703 | * @param len Length of @a source. | ||
704 | */ | ||
705 | static void | ||
706 | t_hmac_derive_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
707 | struct GNUNET_CRYPTO_SymmetricSessionKey *out, | ||
708 | void *source, unsigned int len) | ||
709 | { | ||
710 | static const char ctx[] = "axolotl derive key"; | ||
711 | struct GNUNET_HashCode h; | ||
712 | |||
713 | t_ax_hmac_hash (key, &h, source, len); | ||
714 | GNUNET_CRYPTO_kdf (out, sizeof (*out), ctx, sizeof (ctx), | ||
715 | &h, sizeof (h), NULL); | ||
716 | } | ||
717 | |||
718 | |||
719 | /** | ||
720 | * Encrypt data with the axolotl tunnel key. | ||
721 | * | ||
722 | * @param t Tunnel whose key to use. | ||
723 | * @param dst Destination for the encrypted data. | ||
724 | * @param src Source of the plaintext. Can overlap with @c dst. | ||
725 | * @param size Size of the plaintext. | ||
726 | * | ||
727 | * @return Size of the encrypted data. | ||
728 | */ | ||
729 | static int | ||
730 | t_ax_encrypt (struct CadetTunnel *t, void *dst, const void *src, size_t size) | ||
731 | { | ||
732 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
733 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
734 | struct CadetTunnelAxolotl *ax; | ||
735 | size_t out_size; | ||
736 | |||
737 | CADET_TIMING_START; | ||
738 | |||
739 | ax = t->ax; | ||
740 | ax->ratchet_counter++; | ||
741 | if (GNUNET_YES == ax->ratchet_allowed | ||
742 | && (ratchet_messages <= ax->ratchet_counter | ||
743 | || 0 == GNUNET_TIME_absolute_get_remaining (ax->ratchet_expiration).rel_value_us)) | ||
744 | { | ||
745 | ax->ratchet_flag = GNUNET_YES; | ||
746 | } | ||
747 | |||
748 | if (GNUNET_YES == ax->ratchet_flag) | ||
749 | { | ||
750 | /* Advance ratchet */ | ||
751 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; | ||
752 | struct GNUNET_HashCode dh; | ||
753 | struct GNUNET_HashCode hmac; | ||
754 | static const char ctx[] = "axolotl ratchet"; | ||
755 | |||
756 | new_ephemeral (t); | ||
757 | ax->HKs = ax->NHKs; | ||
758 | |||
759 | /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */ | ||
760 | GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, &ax->DHRr, &dh); | ||
761 | t_ax_hmac_hash (&ax->RK, &hmac, &dh, sizeof (dh)); | ||
762 | GNUNET_CRYPTO_kdf (keys, sizeof (keys), ctx, sizeof (ctx), | ||
763 | &hmac, sizeof (hmac), NULL); | ||
764 | ax->RK = keys[0]; | ||
765 | ax->NHKs = keys[1]; | ||
766 | ax->CKs = keys[2]; | ||
767 | |||
768 | ax->PNs = ax->Ns; | ||
769 | ax->Ns = 0; | ||
770 | ax->ratchet_flag = GNUNET_NO; | ||
771 | ax->ratchet_allowed = GNUNET_NO; | ||
772 | ax->ratchet_counter = 0; | ||
773 | ax->ratchet_expiration = | ||
774 | GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), ratchet_time); | ||
775 | } | ||
776 | |||
777 | t_hmac_derive_key (&ax->CKs, &MK, "0", 1); | ||
778 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, &MK, NULL, 0, NULL); | ||
779 | |||
780 | #if DUMP_KEYS_TO_STDERR | ||
781 | LOG (GNUNET_ERROR_TYPE_DEBUG, " CKs: %s\n", | ||
782 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKs)); | ||
783 | LOG (GNUNET_ERROR_TYPE_INFO, " AX_ENC with key %u: %s\n", ax->Ns, | ||
784 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &MK)); | ||
785 | #endif | ||
786 | |||
787 | out_size = GNUNET_CRYPTO_symmetric_encrypt (src, size, &MK, &iv, dst); | ||
788 | t_hmac_derive_key (&ax->CKs, &ax->CKs, "1", 1); | ||
789 | |||
790 | CADET_TIMING_END; | ||
791 | |||
792 | return out_size; | ||
793 | } | ||
794 | |||
795 | |||
796 | /** | ||
797 | * Decrypt data with the axolotl tunnel key. | ||
798 | * | ||
799 | * @param t Tunnel whose key to use. | ||
800 | * @param dst Destination for the decrypted data. | ||
801 | * @param src Source of the ciphertext. Can overlap with @c dst. | ||
802 | * @param size Size of the ciphertext. | ||
803 | * | ||
804 | * @return Size of the decrypted data. | ||
805 | */ | ||
806 | static int | ||
807 | t_ax_decrypt (struct CadetTunnel *t, void *dst, const void *src, size_t size) | ||
808 | { | ||
809 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
810 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
811 | struct CadetTunnelAxolotl *ax; | ||
812 | size_t out_size; | ||
813 | |||
814 | CADET_TIMING_START; | ||
815 | |||
816 | ax = t->ax; | ||
817 | |||
818 | t_hmac_derive_key (&ax->CKr, &MK, "0", 1); | ||
819 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, &MK, NULL, 0, NULL); | ||
820 | |||
821 | #if DUMP_KEYS_TO_STDERR | ||
822 | LOG (GNUNET_ERROR_TYPE_DEBUG, " CKr: %s\n", | ||
823 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKr)); | ||
824 | LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC with key %u: %s\n", ax->Nr, | ||
825 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &MK)); | ||
826 | #endif | ||
827 | |||
828 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | ||
829 | out_size = GNUNET_CRYPTO_symmetric_decrypt (src, size, &MK, &iv, dst); | ||
830 | GNUNET_assert (out_size == size); | ||
831 | |||
832 | t_hmac_derive_key (&ax->CKr, &ax->CKr, "1", 1); | ||
833 | |||
834 | CADET_TIMING_END; | ||
835 | |||
836 | return out_size; | ||
837 | } | ||
838 | |||
839 | |||
840 | /** | ||
841 | * Encrypt header with the axolotl header key. | ||
842 | * | ||
843 | * @param t Tunnel whose key to use. | ||
844 | * @param msg Message whose header to encrypt. | ||
845 | */ | ||
846 | static void | ||
847 | t_h_encrypt (struct CadetTunnel *t, struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
848 | { | ||
849 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
850 | struct CadetTunnelAxolotl *ax; | ||
851 | size_t out_size; | ||
852 | |||
853 | CADET_TIMING_START; | ||
854 | ax = t->ax; | ||
855 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, &ax->HKs, NULL, 0, NULL); | ||
856 | |||
857 | #if DUMP_KEYS_TO_STDERR | ||
858 | LOG (GNUNET_ERROR_TYPE_INFO, " AX_ENC_H with key %s\n", | ||
859 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKs)); | ||
860 | #endif | ||
861 | |||
862 | out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->Ns, AX_HEADER_SIZE, | ||
863 | &ax->HKs, &iv, &msg->Ns); | ||
864 | |||
865 | GNUNET_assert (AX_HEADER_SIZE == out_size); | ||
866 | CADET_TIMING_END; | ||
867 | } | ||
868 | |||
869 | |||
870 | /** | ||
871 | * Decrypt header with the current axolotl header key. | ||
872 | * | ||
873 | * @param t Tunnel whose current ax HK to use. | ||
874 | * @param src Message whose header to decrypt. | ||
875 | * @param dst Where to decrypt header to. | ||
876 | */ | ||
877 | static void | ||
878 | t_h_decrypt (struct CadetTunnel *t, const struct GNUNET_CADET_TunnelEncryptedMessage *src, | ||
879 | struct GNUNET_CADET_TunnelEncryptedMessage *dst) | ||
880 | { | ||
881 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
882 | struct CadetTunnelAxolotl *ax; | ||
883 | size_t out_size; | ||
884 | |||
885 | CADET_TIMING_START; | ||
886 | |||
887 | ax = t->ax; | ||
888 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, &ax->HKr, NULL, 0, NULL); | ||
889 | |||
890 | #if DUMP_KEYS_TO_STDERR | ||
891 | LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC_H with key %s\n", | ||
892 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKr)); | ||
893 | #endif | ||
894 | |||
895 | out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, AX_HEADER_SIZE, | ||
896 | &ax->HKr, &iv, &dst->Ns); | ||
897 | |||
898 | GNUNET_assert (AX_HEADER_SIZE == out_size); | ||
899 | |||
900 | CADET_TIMING_END; | ||
901 | } | ||
902 | |||
903 | |||
904 | /** | ||
905 | * Decrypt and verify data with the appropriate tunnel key and verify that the | ||
906 | * data has not been altered since it was sent by the remote peer. | ||
907 | * | ||
908 | * @param t Tunnel whose key to use. | ||
909 | * @param dst Destination for the plaintext. | ||
910 | * @param src Source of the message. Can overlap with @c dst. | ||
911 | * @param size Size of the message. | ||
912 | * | ||
913 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
914 | */ | ||
915 | static int | ||
916 | try_old_ax_keys (struct CadetTunnel *t, void *dst, | ||
917 | const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size) | ||
918 | { | ||
919 | struct CadetTunnelSkippedKey *key; | ||
920 | struct GNUNET_ShortHashCode *hmac; | ||
921 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
922 | struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header; | ||
923 | struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK; | ||
924 | size_t esize; | ||
925 | size_t res; | ||
926 | size_t len; | ||
927 | unsigned int N; | ||
928 | |||
929 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying old keys\n"); | ||
930 | hmac = &plaintext_header.hmac; | ||
931 | esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); | ||
932 | |||
933 | /* Find a correct Header Key */ | ||
934 | for (key = t->ax->skipped_head; NULL != key; key = key->next) | ||
935 | { | ||
936 | #if DUMP_KEYS_TO_STDERR | ||
937 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Trying hmac with key %s\n", | ||
938 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->HK)); | ||
939 | #endif | ||
940 | t_hmac (&src->Ns, AX_HEADER_SIZE + esize, 0, &key->HK, hmac); | ||
941 | if (0 == memcmp (hmac, &src->hmac, sizeof (*hmac))) | ||
942 | { | ||
943 | LOG (GNUNET_ERROR_TYPE_DEBUG, " hmac correct\n"); | ||
944 | valid_HK = &key->HK; | ||
945 | break; | ||
946 | } | ||
947 | } | ||
948 | if (NULL == key) | ||
949 | return -1; | ||
950 | |||
951 | /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */ | ||
952 | GNUNET_assert (size > sizeof (struct GNUNET_CADET_TunnelEncryptedMessage)); | ||
953 | len = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); | ||
954 | GNUNET_assert (len >= sizeof (struct GNUNET_MessageHeader)); | ||
955 | |||
956 | /* Decrypt header */ | ||
957 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, &key->HK, NULL, 0, NULL); | ||
958 | res = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, AX_HEADER_SIZE, | ||
959 | &key->HK, &iv, &plaintext_header.Ns); | ||
960 | GNUNET_assert (AX_HEADER_SIZE == res); | ||
961 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Message %u, previous: %u\n", | ||
962 | ntohl (plaintext_header.Ns), ntohl (plaintext_header.PNs)); | ||
963 | |||
964 | /* Find the correct Message Key */ | ||
965 | N = ntohl (plaintext_header.Ns); | ||
966 | while (NULL != key && N != key->Kn) | ||
967 | key = key->next; | ||
968 | if (NULL == key || 0 != memcmp (&key->HK, valid_HK, sizeof (*valid_HK))) | ||
969 | return -1; | ||
970 | |||
971 | #if DUMP_KEYS_TO_STDERR | ||
972 | LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC_H with skipped key %s\n", | ||
973 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->HK)); | ||
974 | LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC with skipped key %u: %s\n", | ||
975 | key->Kn, GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK)); | ||
976 | #endif | ||
977 | |||
978 | /* Decrypt payload */ | ||
979 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, &key->MK, NULL, 0, NULL); | ||
980 | res = GNUNET_CRYPTO_symmetric_decrypt (&src[1], len, &key->MK, &iv, dst); | ||
981 | |||
982 | /* Remove key */ | ||
983 | GNUNET_CONTAINER_DLL_remove (t->ax->skipped_head, t->ax->skipped_tail, key); | ||
984 | t->ax->skipped--; | ||
985 | GNUNET_free (key); /* GNUNET_free overwrites memory with 0xbaadf00d */ | ||
986 | |||
987 | return res; | ||
988 | } | ||
989 | |||
990 | |||
991 | /** | ||
992 | * Delete a key from the list of skipped keys. | ||
993 | * | ||
994 | * @param t Tunnel to delete from. | ||
995 | * @param HKr Header Key to use. | ||
996 | */ | ||
997 | static void | ||
998 | store_skipped_key (struct CadetTunnel *t, | ||
999 | const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr) | ||
1000 | { | ||
1001 | struct CadetTunnelSkippedKey *key; | ||
1002 | |||
1003 | key = GNUNET_new (struct CadetTunnelSkippedKey); | ||
1004 | key->timestamp = GNUNET_TIME_absolute_get (); | ||
1005 | key->Kn = t->ax->Nr; | ||
1006 | key->HK = t->ax->HKr; | ||
1007 | t_hmac_derive_key (&t->ax->CKr, &key->MK, "0", 1); | ||
1008 | #if DUMP_KEYS_TO_STDERR | ||
1009 | LOG (GNUNET_ERROR_TYPE_DEBUG, " storing MK for Nr %u: %s\n", | ||
1010 | key->Kn, GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK)); | ||
1011 | LOG (GNUNET_ERROR_TYPE_DEBUG, " for CKr: %s\n", | ||
1012 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &t->ax->CKr)); | ||
1013 | #endif | ||
1014 | t_hmac_derive_key (&t->ax->CKr, &t->ax->CKr, "1", 1); | ||
1015 | GNUNET_CONTAINER_DLL_insert (t->ax->skipped_head, t->ax->skipped_tail, key); | ||
1016 | t->ax->Nr++; | ||
1017 | t->ax->skipped++; | ||
1018 | } | ||
1019 | |||
1020 | |||
1021 | /** | ||
1022 | * Delete a key from the list of skipped keys. | ||
1023 | * | ||
1024 | * @param t Tunnel to delete from. | ||
1025 | * @param key Key to delete. | ||
1026 | */ | ||
1027 | static void | ||
1028 | delete_skipped_key (struct CadetTunnel *t, struct CadetTunnelSkippedKey *key) | ||
1029 | { | ||
1030 | GNUNET_CONTAINER_DLL_remove (t->ax->skipped_head, t->ax->skipped_tail, key); | ||
1031 | GNUNET_free (key); | ||
1032 | t->ax->skipped--; | ||
1033 | } | ||
1034 | |||
1035 | |||
1036 | /** | ||
1037 | * Stage skipped AX keys and calculate the message key. | ||
1038 | * | ||
1039 | * Stores each HK and MK for skipped messages. | ||
1040 | * | ||
1041 | * @param t Tunnel where to stage the keys. | ||
1042 | * @param HKr Header key. | ||
1043 | * @param Np Received meesage number. | ||
1044 | * | ||
1045 | * @return GNUNET_OK if keys were stored. | ||
1046 | * GNUNET_SYSERR if an error ocurred (Np not expected). | ||
1047 | */ | ||
1048 | static int | ||
1049 | store_ax_keys (struct CadetTunnel *t, | ||
1050 | const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, | ||
1051 | uint32_t Np) | ||
1052 | { | ||
1053 | int gap; | ||
1054 | |||
1055 | |||
1056 | gap = Np - t->ax->Nr; | ||
1057 | LOG (GNUNET_ERROR_TYPE_INFO, "Storing keys [%u, %u)\n", t->ax->Nr, Np); | ||
1058 | if (MAX_KEY_GAP < gap) | ||
1059 | { | ||
1060 | /* Avoid DoS (forcing peer to do 2*33 chain HMAC operations) */ | ||
1061 | /* TODO: start new key exchange on return */ | ||
1062 | GNUNET_break_op (0); | ||
1063 | LOG (GNUNET_ERROR_TYPE_WARNING, "Got message %u, expected %u+\n", | ||
1064 | Np, t->ax->Nr); | ||
1065 | return GNUNET_SYSERR; | ||
1066 | } | ||
1067 | if (0 > gap) | ||
1068 | { | ||
1069 | /* Delayed message: don't store keys, flag to try old keys. */ | ||
1070 | return GNUNET_SYSERR; | ||
1071 | } | ||
1072 | |||
1073 | while (t->ax->Nr < Np) | ||
1074 | store_skipped_key (t, HKr); | ||
1075 | |||
1076 | while (t->ax->skipped > MAX_SKIPPED_KEYS) | ||
1077 | delete_skipped_key (t, t->ax->skipped_tail); | ||
1078 | |||
1079 | return GNUNET_OK; | ||
1080 | } | ||
1081 | |||
1082 | |||
1083 | /** | ||
1084 | * Decrypt and verify data with the appropriate tunnel key and verify that the | ||
1085 | * data has not been altered since it was sent by the remote peer. | ||
1086 | * | ||
1087 | * @param t Tunnel whose key to use. | ||
1088 | * @param dst Destination for the plaintext. | ||
1089 | * @param src Source of the message. Can overlap with @c dst. | ||
1090 | * @param size Size of the message. | ||
1091 | * | ||
1092 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
1093 | */ | ||
1094 | static int | ||
1095 | t_ax_decrypt_and_validate (struct CadetTunnel *t, void *dst, | ||
1096 | const struct GNUNET_CADET_TunnelEncryptedMessage *src, | ||
1097 | size_t size) | ||
1098 | { | ||
1099 | struct CadetTunnelAxolotl *ax; | ||
1100 | struct GNUNET_ShortHashCode msg_hmac; | ||
1101 | struct GNUNET_HashCode hmac; | ||
1102 | struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header; | ||
1103 | uint32_t Np; | ||
1104 | uint32_t PNp; | ||
1105 | size_t esize; /* Size of encryped payload */ | ||
1106 | size_t osize; /* Size of output (decrypted payload) */ | ||
1107 | |||
1108 | esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); | ||
1109 | ax = t->ax; | ||
1110 | if (NULL == ax) | ||
1111 | return -1; | ||
1112 | |||
1113 | /* Try current HK */ | ||
1114 | t_hmac (&src->Ns, AX_HEADER_SIZE + esize, 0, &ax->HKr, &msg_hmac); | ||
1115 | if (0 != memcmp (&msg_hmac, &src->hmac, sizeof (msg_hmac))) | ||
1116 | { | ||
1117 | static const char ctx[] = "axolotl ratchet"; | ||
1118 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */ | ||
1119 | struct GNUNET_CRYPTO_SymmetricSessionKey HK; | ||
1120 | struct GNUNET_HashCode dh; | ||
1121 | struct GNUNET_CRYPTO_EcdhePublicKey *DHRp; | ||
1122 | |||
1123 | /* Try Next HK */ | ||
1124 | LOG (GNUNET_ERROR_TYPE_DEBUG, " trying next HK\n"); | ||
1125 | t_hmac (&src->Ns, AX_HEADER_SIZE + esize, 0, &ax->NHKr, &msg_hmac); | ||
1126 | if (0 != memcmp (&msg_hmac, &src->hmac, sizeof (msg_hmac))) | ||
1127 | { | ||
1128 | /* Try the skipped keys, if that fails, we're out of luck. */ | ||
1129 | return try_old_ax_keys (t, dst, src, size); | ||
1130 | } | ||
1131 | LOG (GNUNET_ERROR_TYPE_INFO, "next HK worked\n"); | ||
1132 | |||
1133 | HK = ax->HKr; | ||
1134 | ax->HKr = ax->NHKr; | ||
1135 | t_h_decrypt (t, src, &plaintext_header); | ||
1136 | Np = ntohl (plaintext_header.Ns); | ||
1137 | PNp = ntohl (plaintext_header.PNs); | ||
1138 | DHRp = &plaintext_header.DHRs; | ||
1139 | store_ax_keys (t, &HK, PNp); | ||
1140 | |||
1141 | /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */ | ||
1142 | GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, DHRp, &dh); | ||
1143 | t_ax_hmac_hash (&ax->RK, &hmac, &dh, sizeof (dh)); | ||
1144 | GNUNET_CRYPTO_kdf (keys, sizeof (keys), ctx, sizeof (ctx), | ||
1145 | &hmac, sizeof (hmac), NULL); | ||
1146 | |||
1147 | /* Commit "purported" keys */ | ||
1148 | ax->RK = keys[0]; | ||
1149 | ax->NHKr = keys[1]; | ||
1150 | ax->CKr = keys[2]; | ||
1151 | ax->DHRr = *DHRp; | ||
1152 | ax->Nr = 0; | ||
1153 | ax->ratchet_allowed = GNUNET_YES; | ||
1154 | } | ||
1155 | else | ||
1156 | { | ||
1157 | LOG (GNUNET_ERROR_TYPE_DEBUG, "current HK\n"); | ||
1158 | t_h_decrypt (t, src, &plaintext_header); | ||
1159 | Np = ntohl (plaintext_header.Ns); | ||
1160 | PNp = ntohl (plaintext_header.PNs); | ||
1161 | } | ||
1162 | LOG (GNUNET_ERROR_TYPE_INFO, " got AX Nr %u\n", Np); | ||
1163 | if (Np != ax->Nr) | ||
1164 | if (GNUNET_OK != store_ax_keys (t, &ax->HKr, Np)) | ||
1165 | /* Try the skipped keys, if that fails, we're out of luck. */ | ||
1166 | return try_old_ax_keys (t, dst, src, size); | ||
1167 | |||
1168 | osize = t_ax_decrypt (t, dst, &src[1], esize); | ||
1169 | ax->Nr = Np + 1; | ||
1170 | |||
1171 | if (osize != esize) | ||
1172 | { | ||
1173 | GNUNET_break_op (0); | ||
1174 | return -1; | ||
1175 | } | ||
1176 | |||
1177 | return osize; | ||
1178 | } | ||
1179 | |||
1180 | |||
1181 | /** | ||
1182 | * Pick a connection on which send the next data message. | ||
1183 | * | ||
1184 | * @param t Tunnel on which to send the message. | ||
1185 | * | ||
1186 | * @return The connection on which to send the next message. | ||
1187 | */ | ||
1188 | static struct CadetConnection * | ||
1189 | tunnel_get_connection (struct CadetTunnel *t) | ||
1190 | { | ||
1191 | struct CadetTConnection *iter; | ||
1192 | struct CadetConnection *best; | ||
1193 | unsigned int qn; | ||
1194 | unsigned int lowest_q; | ||
1195 | |||
1196 | LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GCT_2s (t)); | ||
1197 | best = NULL; | ||
1198 | lowest_q = UINT_MAX; | ||
1199 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
1200 | { | ||
1201 | LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n", | ||
1202 | GCC_2s (iter->c), GCC_get_state (iter->c)); | ||
1203 | if (CADET_CONNECTION_READY == GCC_get_state (iter->c)) | ||
1204 | { | ||
1205 | qn = GCC_get_qn (iter->c, GCC_is_origin (iter->c, GNUNET_YES)); | ||
1206 | LOG (GNUNET_ERROR_TYPE_DEBUG, " q_n %u, \n", qn); | ||
1207 | if (qn < lowest_q) | ||
1208 | { | ||
1209 | best = iter->c; | ||
1210 | lowest_q = qn; | ||
1211 | } | ||
1212 | } | ||
1213 | } | ||
1214 | LOG (GNUNET_ERROR_TYPE_DEBUG, " selected: connection %s\n", GCC_2s (best)); | ||
1215 | return best; | ||
1216 | } | ||
1217 | |||
1218 | |||
1219 | /** | ||
1220 | * Callback called when a queued message is sent. | ||
1221 | * | ||
1222 | * Calculates the average time and connection packet tracking. | ||
1223 | * | ||
1224 | * @param cls Closure (TunnelQueue handle). | ||
1225 | * @param c Connection this message was on. | ||
1226 | * @param q Connection queue handle (unused). | ||
1227 | * @param type Type of message sent. | ||
1228 | * @param fwd Was this a FWD going message? | ||
1229 | * @param size Size of the message. | ||
1230 | */ | ||
1231 | static void | ||
1232 | tun_message_sent (void *cls, | ||
1233 | struct CadetConnection *c, | ||
1234 | struct CadetConnectionQueue *q, | ||
1235 | uint16_t type, int fwd, size_t size) | ||
1236 | { | ||
1237 | struct CadetTunnelQueue *qt = cls; | ||
1238 | struct CadetTunnel *t; | ||
1239 | |||
1240 | LOG (GNUNET_ERROR_TYPE_DEBUG, "tun_message_sent\n"); | ||
1241 | |||
1242 | GNUNET_assert (NULL != qt->cont); | ||
1243 | t = NULL == c ? NULL : GCC_get_tunnel (c); | ||
1244 | qt->cont (qt->cont_cls, t, qt, type, size); | ||
1245 | GNUNET_free (qt); | ||
1246 | } | ||
1247 | |||
1248 | |||
1249 | static unsigned int | ||
1250 | count_queued_data (const struct CadetTunnel *t) | ||
1251 | { | ||
1252 | struct CadetTunnelDelayed *iter; | ||
1253 | unsigned int count; | ||
1254 | |||
1255 | for (count = 0, iter = t->tq_head; iter != NULL; iter = iter->next) | ||
1256 | count++; | ||
1257 | |||
1258 | return count; | ||
1259 | } | ||
1260 | |||
1261 | /** | ||
1262 | * Delete a queued message: either was sent or the channel was destroyed | ||
1263 | * before the tunnel's key exchange had a chance to finish. | ||
1264 | * | ||
1265 | * @param tqd Delayed queue handle. | ||
1266 | */ | ||
1267 | static void | ||
1268 | unqueue_data (struct CadetTunnelDelayed *tqd) | ||
1269 | { | ||
1270 | GNUNET_CONTAINER_DLL_remove (tqd->t->tq_head, tqd->t->tq_tail, tqd); | ||
1271 | GNUNET_free (tqd); | ||
1272 | } | ||
1273 | |||
1274 | |||
1275 | /** | ||
1276 | * Cache a message to be sent once tunnel is online. | ||
1277 | * | ||
1278 | * @param t Tunnel to hold the message. | ||
1279 | * @param msg Message itself (copy will be made). | ||
1280 | */ | ||
1281 | static struct CadetTunnelDelayed * | ||
1282 | queue_data (struct CadetTunnel *t, const struct GNUNET_MessageHeader *msg) | ||
1283 | { | ||
1284 | struct CadetTunnelDelayed *tqd; | ||
1285 | uint16_t size = ntohs (msg->size); | ||
1286 | |||
1287 | LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GCT_2s (t)); | ||
1288 | |||
1289 | GNUNET_assert (GNUNET_NO == is_ready (t)); | ||
1290 | |||
1291 | tqd = GNUNET_malloc (sizeof (struct CadetTunnelDelayed) + size); | ||
1292 | |||
1293 | tqd->t = t; | ||
1294 | GNUNET_memcpy (&tqd[1], msg, size); | ||
1295 | GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tqd); | ||
1296 | return tqd; | ||
1297 | } | ||
1298 | |||
1299 | |||
1300 | /** | ||
1301 | * Sends an already built message on a tunnel, encrypting it and | ||
1302 | * choosing the best connection. | ||
1303 | * | ||
1304 | * @param message Message to send. Function modifies it. | ||
1305 | * @param t Tunnel on which this message is transmitted. | ||
1306 | * @param c Connection to use (autoselect if NULL). | ||
1307 | * @param force Force the tunnel to take the message (buffer overfill). | ||
1308 | * @param cont Continuation to call once message is really sent. | ||
1309 | * @param cont_cls Closure for @c cont. | ||
1310 | * @param existing_q In case this a transmission of previously queued data, | ||
1311 | * this should be TunnelQueue given to the client. | ||
1312 | * Otherwise, NULL. | ||
1313 | * @return Handle to cancel message. | ||
1314 | * NULL if @c cont is NULL or an error happens and message is dropped. | ||
1315 | */ | ||
1316 | static struct CadetTunnelQueue * | ||
1317 | send_prebuilt_message (const struct GNUNET_MessageHeader *message, | ||
1318 | struct CadetTunnel *t, | ||
1319 | struct CadetConnection *c, | ||
1320 | int force, | ||
1321 | GCT_sent cont, | ||
1322 | void *cont_cls, | ||
1323 | struct CadetTunnelQueue *existing_q) | ||
1324 | { | ||
1325 | struct GNUNET_MessageHeader *msg; | ||
1326 | struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg; | ||
1327 | struct CadetTunnelQueue *tq; | ||
1328 | size_t size = ntohs (message->size); | ||
1329 | char cbuf[sizeof (struct GNUNET_CADET_TunnelEncryptedMessage) + size] GNUNET_ALIGN; | ||
1330 | size_t esize; | ||
1331 | uint16_t type; | ||
1332 | int fwd; | ||
1333 | |||
1334 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GCT_2s (t)); | ||
1335 | |||
1336 | if (GNUNET_NO == is_ready (t)) | ||
1337 | { | ||
1338 | struct CadetTunnelDelayed *tqd; | ||
1339 | /* A non null existing_q indicates sending of queued data. | ||
1340 | * Should only happen after tunnel becomes ready. | ||
1341 | */ | ||
1342 | GNUNET_assert (NULL == existing_q); | ||
1343 | tqd = queue_data (t, message); | ||
1344 | if (NULL == cont) | ||
1345 | return NULL; | ||
1346 | tq = GNUNET_new (struct CadetTunnelQueue); | ||
1347 | tq->tqd = tqd; | ||
1348 | tqd->tq = tq; | ||
1349 | tq->cont = cont; | ||
1350 | tq->cont_cls = cont_cls; | ||
1351 | return tq; | ||
1352 | } | ||
1353 | |||
1354 | GNUNET_assert (GNUNET_NO == GCT_is_loopback (t)); | ||
1355 | |||
1356 | ax_msg = (struct GNUNET_CADET_TunnelEncryptedMessage *) cbuf; | ||
1357 | msg = &ax_msg->header; | ||
1358 | msg->size = htons (sizeof (struct GNUNET_CADET_TunnelEncryptedMessage) + size); | ||
1359 | msg->type = htons (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED); | ||
1360 | esize = t_ax_encrypt (t, &ax_msg[1], message, size); | ||
1361 | ax_msg->Ns = htonl (t->ax->Ns++); | ||
1362 | ax_msg->PNs = htonl (t->ax->PNs); | ||
1363 | GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->DHRs, &ax_msg->DHRs); | ||
1364 | t_h_encrypt (t, ax_msg); | ||
1365 | t_hmac (&ax_msg->Ns, AX_HEADER_SIZE + esize, 0, &t->ax->HKs, &ax_msg->hmac); | ||
1366 | GNUNET_assert (esize == size); | ||
1367 | |||
1368 | if (NULL == c) | ||
1369 | c = tunnel_get_connection (t); | ||
1370 | if (NULL == c) | ||
1371 | { | ||
1372 | /* Why is tunnel 'ready'? Should have been queued! */ | ||
1373 | if (NULL != t->destroy_task) | ||
1374 | { | ||
1375 | GNUNET_break (0); | ||
1376 | GCT_debug (t, GNUNET_ERROR_TYPE_WARNING); | ||
1377 | } | ||
1378 | return NULL; /* Drop... */ | ||
1379 | } | ||
1380 | fwd = GCC_is_origin (c, GNUNET_YES); | ||
1381 | ax_msg->cid = *GCC_get_id (c); | ||
1382 | ax_msg->cemi = GCC_get_pid (c, fwd); | ||
1383 | |||
1384 | type = htons (message->type); | ||
1385 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1386 | "Sending message of type %s with CEMI %u and CID %s\n", | ||
1387 | GC_m2s (type), | ||
1388 | htonl (ax_msg->cemi.pid), | ||
1389 | GNUNET_sh2s (&ax_msg->cid.connection_of_tunnel)); | ||
1390 | |||
1391 | if (NULL == cont) | ||
1392 | { | ||
1393 | (void) GCC_send_prebuilt_message (msg, | ||
1394 | type, | ||
1395 | ax_msg->cemi, | ||
1396 | c, | ||
1397 | fwd, | ||
1398 | force, NULL, NULL); | ||
1399 | return NULL; | ||
1400 | } | ||
1401 | if (NULL == existing_q) | ||
1402 | { | ||
1403 | tq = GNUNET_new (struct CadetTunnelQueue); /* FIXME valgrind: leak*/ | ||
1404 | } | ||
1405 | else | ||
1406 | { | ||
1407 | tq = existing_q; | ||
1408 | tq->tqd = NULL; | ||
1409 | } | ||
1410 | tq->cont = cont; | ||
1411 | tq->cont_cls = cont_cls; | ||
1412 | tq->cq = GCC_send_prebuilt_message (msg, | ||
1413 | type, | ||
1414 | ax_msg->cemi, | ||
1415 | c, | ||
1416 | fwd, | ||
1417 | force, | ||
1418 | &tun_message_sent, tq); | ||
1419 | GNUNET_assert (NULL != tq->cq); | ||
1420 | |||
1421 | return tq; | ||
1422 | } | ||
1423 | |||
1424 | |||
1425 | /** | ||
1426 | * Send all cached messages that we can, tunnel is online. | ||
1427 | * | ||
1428 | * @param t Tunnel that holds the messages. Cannot be loopback. | ||
1429 | */ | ||
1430 | static void | ||
1431 | send_queued_data (struct CadetTunnel *t) | ||
1432 | { | ||
1433 | struct CadetTunnelDelayed *tqd; | ||
1434 | struct CadetTunnelDelayed *next; | ||
1435 | unsigned int room; | ||
1436 | |||
1437 | LOG (GNUNET_ERROR_TYPE_INFO, "Send queued data, tunnel %s\n", GCT_2s (t)); | ||
1438 | |||
1439 | if (GCT_is_loopback (t)) | ||
1440 | { | ||
1441 | GNUNET_break (0); | ||
1442 | return; | ||
1443 | } | ||
1444 | |||
1445 | if (GNUNET_NO == is_ready (t)) | ||
1446 | { | ||
1447 | LOG (GNUNET_ERROR_TYPE_WARNING, " not ready yet: %s/%s\n", | ||
1448 | estate2s (t->estate), cstate2s (t->cstate)); | ||
1449 | return; | ||
1450 | } | ||
1451 | |||
1452 | room = GCT_get_connections_buffer (t); | ||
1453 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room); | ||
1454 | LOG (GNUNET_ERROR_TYPE_DEBUG, " tq head: %p\n", t->tq_head); | ||
1455 | for (tqd = t->tq_head; NULL != tqd && room > 0; tqd = next) | ||
1456 | { | ||
1457 | LOG (GNUNET_ERROR_TYPE_DEBUG, " sending queued data\n"); | ||
1458 | next = tqd->next; | ||
1459 | room--; | ||
1460 | send_prebuilt_message ((struct GNUNET_MessageHeader *) &tqd[1], | ||
1461 | tqd->t, NULL, GNUNET_YES, | ||
1462 | NULL != tqd->tq ? tqd->tq->cont : NULL, | ||
1463 | NULL != tqd->tq ? tqd->tq->cont_cls : NULL, | ||
1464 | tqd->tq); | ||
1465 | unqueue_data (tqd); | ||
1466 | } | ||
1467 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GCT_send_queued_data end\n", GCP_2s (t->peer)); | ||
1468 | } | ||
1469 | |||
1470 | |||
1471 | /** | ||
1472 | * @brief Resend the KX until we complete the handshake. | ||
1473 | * | ||
1474 | * @param cls Closure (tunnel). | ||
1475 | */ | ||
1476 | static void | ||
1477 | kx_resend (void *cls) | ||
1478 | { | ||
1479 | struct CadetTunnel *t = cls; | ||
1480 | |||
1481 | t->rekey_task = NULL; | ||
1482 | if (CADET_TUNNEL_KEY_OK == t->estate) | ||
1483 | { | ||
1484 | /* Should have been canceled on estate change */ | ||
1485 | GNUNET_break (0); | ||
1486 | return; | ||
1487 | } | ||
1488 | |||
1489 | GCT_send_kx (t, CADET_TUNNEL_KEY_AX_SENT >= t->estate); | ||
1490 | } | ||
1491 | |||
1492 | |||
1493 | /** | ||
1494 | * Callback called when a queued message is sent. | ||
1495 | * | ||
1496 | * @param cls Closure. | ||
1497 | * @param c Connection this message was on. | ||
1498 | * @param type Type of message sent. | ||
1499 | * @param fwd Was this a FWD going message? | ||
1500 | * @param size Size of the message. | ||
1501 | */ | ||
1502 | static void | ||
1503 | ephm_sent (void *cls, | ||
1504 | struct CadetConnection *c, | ||
1505 | struct CadetConnectionQueue *q, | ||
1506 | uint16_t type, int fwd, size_t size) | ||
1507 | { | ||
1508 | struct CadetTunnel *t = cls; | ||
1509 | LOG (GNUNET_ERROR_TYPE_DEBUG, "ephemeral sent %s\n", GC_m2s (type)); | ||
1510 | |||
1511 | t->ephm_h = NULL; | ||
1512 | |||
1513 | if (CADET_TUNNEL_KEY_OK == t->estate) | ||
1514 | return; | ||
1515 | |||
1516 | if (NULL != t->rekey_task) | ||
1517 | { | ||
1518 | GNUNET_break (0); | ||
1519 | GCT_debug (t, GNUNET_ERROR_TYPE_WARNING); | ||
1520 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
1521 | } | ||
1522 | t->rekey_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
1523 | &kx_resend, t); | ||
1524 | |||
1525 | } | ||
1526 | |||
1527 | |||
1528 | /** | ||
1529 | * Called only on shutdown, destroy every tunnel. | ||
1530 | * | ||
1531 | * @param cls Closure (unused). | ||
1532 | * @param key Current public key. | ||
1533 | * @param value Value in the hash map (tunnel). | ||
1534 | * | ||
1535 | * @return #GNUNET_YES, so we should continue to iterate, | ||
1536 | */ | ||
1537 | static int | ||
1538 | destroy_iterator (void *cls, | ||
1539 | const struct GNUNET_PeerIdentity *key, | ||
1540 | void *value) | ||
1541 | { | ||
1542 | struct CadetTunnel *t = value; | ||
1543 | |||
1544 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1545 | "GCT_shutdown destroying tunnel at %p\n", t); | ||
1546 | GCT_destroy (t); | ||
1547 | return GNUNET_YES; | ||
1548 | } | ||
1549 | |||
1550 | |||
1551 | /** | ||
1552 | * Notify remote peer that we don't know a channel he is talking about, | ||
1553 | * probably CHANNEL_DESTROY was missed. | ||
1554 | * | ||
1555 | * @param t Tunnel on which to notify. | ||
1556 | * @param gid ID of the channel. | ||
1557 | */ | ||
1558 | static void | ||
1559 | send_channel_destroy (struct CadetTunnel *t, | ||
1560 | struct GNUNET_CADET_ChannelTunnelNumber gid) | ||
1561 | { | ||
1562 | struct GNUNET_CADET_ChannelManageMessage msg; | ||
1563 | |||
1564 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | ||
1565 | msg.header.size = htons (sizeof (msg)); | ||
1566 | msg.ctn = gid; | ||
1567 | |||
1568 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1569 | "WARNING destroying unknown channel %u on tunnel %s\n", | ||
1570 | ntohl (gid.cn), | ||
1571 | GCT_2s (t)); | ||
1572 | send_prebuilt_message (&msg.header, t, NULL, GNUNET_YES, NULL, NULL, NULL); | ||
1573 | } | ||
1574 | |||
1575 | |||
1576 | /** | ||
1577 | * Demultiplex data per channel and call appropriate channel handler. | ||
1578 | * | ||
1579 | * @param t Tunnel on which the data came. | ||
1580 | * @param msg Data message. | ||
1581 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1582 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1583 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1584 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1585 | */ | ||
1586 | static void | ||
1587 | handle_data (struct CadetTunnel *t, | ||
1588 | const struct GNUNET_CADET_ChannelAppDataMessage *msg, | ||
1589 | int fwd) | ||
1590 | { | ||
1591 | struct CadetChannel *ch; | ||
1592 | char buf[128]; | ||
1593 | size_t size; | ||
1594 | uint16_t type; | ||
1595 | |||
1596 | /* Check size */ | ||
1597 | size = ntohs (msg->header.size); | ||
1598 | if (size < | ||
1599 | sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + | ||
1600 | sizeof (struct GNUNET_MessageHeader)) | ||
1601 | { | ||
1602 | GNUNET_break (0); | ||
1603 | return; | ||
1604 | } | ||
1605 | type = ntohs (msg[1].header.type); | ||
1606 | LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n", GC_m2s (type)); | ||
1607 | SPRINTF (buf, "# received payload of type %hu", type); | ||
1608 | GNUNET_STATISTICS_update (stats, buf, 1, GNUNET_NO); | ||
1609 | |||
1610 | |||
1611 | /* Check channel */ | ||
1612 | ch = GCT_get_channel (t, msg->ctn); | ||
1613 | if (NULL == ch) | ||
1614 | { | ||
1615 | GNUNET_STATISTICS_update (stats, | ||
1616 | "# data on unknown channel", | ||
1617 | 1, | ||
1618 | GNUNET_NO); | ||
1619 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1620 | "channel 0x%X unknown\n", | ||
1621 | ntohl (msg->ctn.cn)); | ||
1622 | send_channel_destroy (t, msg->ctn); | ||
1623 | return; | ||
1624 | } | ||
1625 | |||
1626 | GCCH_handle_data (ch, msg, fwd); | ||
1627 | } | ||
1628 | |||
1629 | |||
1630 | /** | ||
1631 | * Demultiplex data ACKs per channel and update appropriate channel buffer info. | ||
1632 | * | ||
1633 | * @param t Tunnel on which the DATA ACK came. | ||
1634 | * @param msg DATA ACK message. | ||
1635 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1636 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1637 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1638 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1639 | */ | ||
1640 | static void | ||
1641 | handle_data_ack (struct CadetTunnel *t, | ||
1642 | const struct GNUNET_CADET_ChannelDataAckMessage *msg, | ||
1643 | int fwd) | ||
1644 | { | ||
1645 | struct CadetChannel *ch; | ||
1646 | size_t size; | ||
1647 | |||
1648 | /* Check size */ | ||
1649 | size = ntohs (msg->header.size); | ||
1650 | if (size != sizeof (struct GNUNET_CADET_ChannelDataAckMessage)) | ||
1651 | { | ||
1652 | GNUNET_break (0); | ||
1653 | return; | ||
1654 | } | ||
1655 | |||
1656 | /* Check channel */ | ||
1657 | ch = GCT_get_channel (t, msg->ctn); | ||
1658 | if (NULL == ch) | ||
1659 | { | ||
1660 | GNUNET_STATISTICS_update (stats, "# data ack on unknown channel", | ||
1661 | 1, GNUNET_NO); | ||
1662 | LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", | ||
1663 | ntohl (msg->ctn.cn)); | ||
1664 | return; | ||
1665 | } | ||
1666 | |||
1667 | GCCH_handle_data_ack (ch, msg, fwd); | ||
1668 | } | ||
1669 | |||
1670 | |||
1671 | /** | ||
1672 | * Handle channel create. | ||
1673 | * | ||
1674 | * @param t Tunnel on which the message came. | ||
1675 | * @param msg ChannelCreate message. | ||
1676 | */ | ||
1677 | static void | ||
1678 | handle_ch_create (struct CadetTunnel *t, | ||
1679 | const struct GNUNET_CADET_ChannelOpenMessage *msg) | ||
1680 | { | ||
1681 | struct CadetChannel *ch; | ||
1682 | size_t size; | ||
1683 | |||
1684 | /* Check size */ | ||
1685 | size = ntohs (msg->header.size); | ||
1686 | if (size != sizeof (struct GNUNET_CADET_ChannelOpenMessage)) | ||
1687 | { | ||
1688 | GNUNET_break_op (0); | ||
1689 | return; | ||
1690 | } | ||
1691 | |||
1692 | /* Check channel */ | ||
1693 | ch = GCT_get_channel (t, msg->ctn); | ||
1694 | if (NULL != ch && ! GCT_is_loopback (t)) | ||
1695 | { | ||
1696 | /* Probably a retransmission, safe to ignore */ | ||
1697 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n"); | ||
1698 | } | ||
1699 | ch = GCCH_handle_create (t, msg); | ||
1700 | if (NULL != ch) | ||
1701 | GCT_add_channel (t, ch); | ||
1702 | } | ||
1703 | |||
1704 | |||
1705 | |||
1706 | /** | ||
1707 | * Handle channel NACK: check correctness and call channel handler for NACKs. | ||
1708 | * | ||
1709 | * @param t Tunnel on which the NACK came. | ||
1710 | * @param msg NACK message. | ||
1711 | */ | ||
1712 | static void | ||
1713 | handle_ch_nack (struct CadetTunnel *t, | ||
1714 | const struct GNUNET_CADET_ChannelManageMessage *msg) | ||
1715 | { | ||
1716 | struct CadetChannel *ch; | ||
1717 | size_t size; | ||
1718 | |||
1719 | /* Check size */ | ||
1720 | size = ntohs (msg->header.size); | ||
1721 | if (size != sizeof (struct GNUNET_CADET_ChannelManageMessage)) | ||
1722 | { | ||
1723 | GNUNET_break (0); | ||
1724 | return; | ||
1725 | } | ||
1726 | |||
1727 | /* Check channel */ | ||
1728 | ch = GCT_get_channel (t, msg->ctn); | ||
1729 | if (NULL == ch) | ||
1730 | { | ||
1731 | GNUNET_STATISTICS_update (stats, "# channel NACK on unknown channel", | ||
1732 | 1, GNUNET_NO); | ||
1733 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1734 | "WARNING channel %u unknown\n", | ||
1735 | ntohl (msg->ctn.cn)); | ||
1736 | return; | ||
1737 | } | ||
1738 | |||
1739 | GCCH_handle_nack (ch); | ||
1740 | } | ||
1741 | |||
1742 | |||
1743 | /** | ||
1744 | * Handle a CHANNEL ACK (SYNACK/ACK). | ||
1745 | * | ||
1746 | * @param t Tunnel on which the CHANNEL ACK came. | ||
1747 | * @param msg CHANNEL ACK message. | ||
1748 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1749 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1750 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1751 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1752 | */ | ||
1753 | static void | ||
1754 | handle_ch_ack (struct CadetTunnel *t, | ||
1755 | const struct GNUNET_CADET_ChannelManageMessage *msg, | ||
1756 | int fwd) | ||
1757 | { | ||
1758 | struct CadetChannel *ch; | ||
1759 | size_t size; | ||
1760 | |||
1761 | /* Check size */ | ||
1762 | size = ntohs (msg->header.size); | ||
1763 | if (size != sizeof (struct GNUNET_CADET_ChannelManageMessage)) | ||
1764 | { | ||
1765 | GNUNET_break (0); | ||
1766 | return; | ||
1767 | } | ||
1768 | |||
1769 | /* Check channel */ | ||
1770 | ch = GCT_get_channel (t, msg->ctn); | ||
1771 | if (NULL == ch) | ||
1772 | { | ||
1773 | GNUNET_STATISTICS_update (stats, | ||
1774 | "# channel ack on unknown channel", | ||
1775 | 1, | ||
1776 | GNUNET_NO); | ||
1777 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1778 | "WARNING channel %u unknown\n", | ||
1779 | ntohl (msg->ctn.cn)); | ||
1780 | return; | ||
1781 | } | ||
1782 | |||
1783 | GCCH_handle_ack (ch, msg, fwd); | ||
1784 | } | ||
1785 | |||
1786 | |||
1787 | /** | ||
1788 | * Handle a channel destruction message. | ||
1789 | * | ||
1790 | * @param t Tunnel on which the message came. | ||
1791 | * @param msg Channel destroy message. | ||
1792 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1793 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1794 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1795 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1796 | */ | ||
1797 | static void | ||
1798 | handle_ch_destroy (struct CadetTunnel *t, | ||
1799 | const struct GNUNET_CADET_ChannelManageMessage *msg, | ||
1800 | int fwd) | ||
1801 | { | ||
1802 | struct CadetChannel *ch; | ||
1803 | size_t size; | ||
1804 | |||
1805 | /* Check size */ | ||
1806 | size = ntohs (msg->header.size); | ||
1807 | if (size != sizeof (struct GNUNET_CADET_ChannelManageMessage)) | ||
1808 | { | ||
1809 | GNUNET_break (0); | ||
1810 | return; | ||
1811 | } | ||
1812 | |||
1813 | /* Check channel */ | ||
1814 | ch = GCT_get_channel (t, msg->ctn); | ||
1815 | if (NULL == ch) | ||
1816 | { | ||
1817 | /* Probably a retransmission, safe to ignore */ | ||
1818 | return; | ||
1819 | } | ||
1820 | |||
1821 | GCCH_handle_destroy (ch, msg, fwd); | ||
1822 | } | ||
1823 | |||
1824 | |||
1825 | /** | ||
1826 | * Free Axolotl data. | ||
1827 | * | ||
1828 | * @param t Tunnel. | ||
1829 | */ | ||
1830 | static void | ||
1831 | destroy_ax (struct CadetTunnel *t) | ||
1832 | { | ||
1833 | if (NULL == t->ax) | ||
1834 | return; | ||
1835 | |||
1836 | GNUNET_free_non_null (t->ax->DHRs); | ||
1837 | GNUNET_free_non_null (t->ax->kx_0); | ||
1838 | while (NULL != t->ax->skipped_head) | ||
1839 | delete_skipped_key (t, t->ax->skipped_head); | ||
1840 | GNUNET_assert (0 == t->ax->skipped); | ||
1841 | |||
1842 | GNUNET_free (t->ax); | ||
1843 | t->ax = NULL; | ||
1844 | |||
1845 | if (NULL != t->rekey_task) | ||
1846 | { | ||
1847 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
1848 | t->rekey_task = NULL; | ||
1849 | } | ||
1850 | if (NULL != t->ephm_h) | ||
1851 | { | ||
1852 | GCC_cancel (t->ephm_h); | ||
1853 | t->ephm_h = NULL; | ||
1854 | } | ||
1855 | } | ||
1856 | |||
1857 | |||
1858 | /** | ||
1859 | * Demultiplex by message type and call appropriate handler for a message | ||
1860 | * towards a channel of a local tunnel. | ||
1861 | * | ||
1862 | * @param t Tunnel this message came on. | ||
1863 | * @param msgh Message header. | ||
1864 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1865 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1866 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1867 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1868 | */ | ||
1869 | static void | ||
1870 | handle_decrypted (struct CadetTunnel *t, | ||
1871 | const struct GNUNET_MessageHeader *msgh, | ||
1872 | int fwd) | ||
1873 | { | ||
1874 | uint16_t type; | ||
1875 | char buf[256]; | ||
1876 | |||
1877 | type = ntohs (msgh->type); | ||
1878 | LOG (GNUNET_ERROR_TYPE_DEBUG, "<-- %s on %s\n", GC_m2s (type), GCT_2s (t)); | ||
1879 | SPRINTF (buf, "# received encrypted of type %hu (%s)", type, GC_m2s (type)); | ||
1880 | GNUNET_STATISTICS_update (stats, buf, 1, GNUNET_NO); | ||
1881 | |||
1882 | switch (type) | ||
1883 | { | ||
1884 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE: | ||
1885 | /* Do nothing, connection aleady got updated. */ | ||
1886 | GNUNET_STATISTICS_update (stats, "# keepalives received", 1, GNUNET_NO); | ||
1887 | break; | ||
1888 | |||
1889 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
1890 | /* Don't send hop ACK, wait for client to ACK */ | ||
1891 | handle_data (t, (struct GNUNET_CADET_ChannelAppDataMessage *) msgh, fwd); | ||
1892 | break; | ||
1893 | |||
1894 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK: | ||
1895 | handle_data_ack (t, (struct GNUNET_CADET_ChannelDataAckMessage *) msgh, fwd); | ||
1896 | break; | ||
1897 | |||
1898 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN: | ||
1899 | handle_ch_create (t, (struct GNUNET_CADET_ChannelOpenMessage *) msgh); | ||
1900 | break; | ||
1901 | |||
1902 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED: | ||
1903 | handle_ch_nack (t, (struct GNUNET_CADET_ChannelManageMessage *) msgh); | ||
1904 | break; | ||
1905 | |||
1906 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: | ||
1907 | handle_ch_ack (t, (struct GNUNET_CADET_ChannelManageMessage *) msgh, fwd); | ||
1908 | break; | ||
1909 | |||
1910 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: | ||
1911 | handle_ch_destroy (t, (struct GNUNET_CADET_ChannelManageMessage *) msgh, fwd); | ||
1912 | break; | ||
1913 | |||
1914 | default: | ||
1915 | GNUNET_break_op (0); | ||
1916 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1917 | "end-to-end message not known (%u)\n", | ||
1918 | ntohs (msgh->type)); | ||
1919 | GCT_debug (t, GNUNET_ERROR_TYPE_WARNING); | ||
1920 | } | ||
1921 | } | ||
1922 | |||
1923 | |||
1924 | /******************************************************************************/ | ||
1925 | /******************************** API ***********************************/ | ||
1926 | /******************************************************************************/ | ||
1927 | |||
1928 | /** | ||
1929 | * Decrypt and process an encrypted message. | ||
1930 | * | ||
1931 | * Calls the appropriate handler for a message in a channel of a local tunnel. | ||
1932 | * | ||
1933 | * @param t Tunnel this message came on. | ||
1934 | * @param msg Message header. | ||
1935 | */ | ||
1936 | void | ||
1937 | GCT_handle_encrypted (struct CadetTunnel *t, | ||
1938 | const struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
1939 | { | ||
1940 | uint16_t size = ntohs (msg->header.size); | ||
1941 | char cbuf [size]; | ||
1942 | int decrypted_size; | ||
1943 | const struct GNUNET_MessageHeader *msgh; | ||
1944 | unsigned int off; | ||
1945 | |||
1946 | GNUNET_STATISTICS_update (stats, "# received encrypted", 1, GNUNET_NO); | ||
1947 | |||
1948 | decrypted_size = t_ax_decrypt_and_validate (t, cbuf, msg, size); | ||
1949 | |||
1950 | if (-1 == decrypted_size) | ||
1951 | { | ||
1952 | GNUNET_STATISTICS_update (stats, "# unable to decrypt", 1, GNUNET_NO); | ||
1953 | if (CADET_TUNNEL_KEY_AX_AUTH_SENT <= t->estate) | ||
1954 | { | ||
1955 | GNUNET_break_op (0); | ||
1956 | LOG (GNUNET_ERROR_TYPE_WARNING, "Wrong crypto, tunnel %s\n", GCT_2s (t)); | ||
1957 | GCT_debug (t, GNUNET_ERROR_TYPE_WARNING); | ||
1958 | } | ||
1959 | return; | ||
1960 | } | ||
1961 | GCT_change_estate (t, CADET_TUNNEL_KEY_OK); | ||
1962 | |||
1963 | /* FIXME: this is bad, as the structs returned from | ||
1964 | this loop may be unaligned, see util's MST for | ||
1965 | how to do this right. */ | ||
1966 | off = 0; | ||
1967 | while (off + sizeof (struct GNUNET_MessageHeader) <= decrypted_size) | ||
1968 | { | ||
1969 | uint16_t msize; | ||
1970 | |||
1971 | msgh = (const struct GNUNET_MessageHeader *) &cbuf[off]; | ||
1972 | msize = ntohs (msgh->size); | ||
1973 | if (msize < sizeof (struct GNUNET_MessageHeader)) | ||
1974 | { | ||
1975 | GNUNET_break_op (0); | ||
1976 | return; | ||
1977 | } | ||
1978 | if (off + msize < decrypted_size) | ||
1979 | { | ||
1980 | GNUNET_break_op (0); | ||
1981 | return; | ||
1982 | } | ||
1983 | handle_decrypted (t, msgh, GNUNET_SYSERR); | ||
1984 | off += msize; | ||
1985 | } | ||
1986 | } | ||
1987 | |||
1988 | |||
1989 | /** | ||
1990 | * Handle a Key eXchange message. | ||
1991 | * | ||
1992 | * @param t Tunnel on which the message came. | ||
1993 | * @param msg KX message itself. | ||
1994 | */ | ||
1995 | void | ||
1996 | GCT_handle_kx (struct CadetTunnel *t, | ||
1997 | const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) | ||
1998 | { | ||
1999 | struct CadetTunnelAxolotl *ax; | ||
2000 | struct GNUNET_HashCode key_material[3]; | ||
2001 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[5]; | ||
2002 | const char salt[] = "CADET Axolotl salt"; | ||
2003 | const struct GNUNET_PeerIdentity *pid; | ||
2004 | int am_I_alice; | ||
2005 | |||
2006 | CADET_TIMING_START; | ||
2007 | |||
2008 | LOG (GNUNET_ERROR_TYPE_INFO, "<== { KX} on %s\n", GCT_2s (t)); | ||
2009 | |||
2010 | if (NULL == t->ax) | ||
2011 | { | ||
2012 | /* Something is wrong if ax is NULL. Whose fault it is? */ | ||
2013 | return; | ||
2014 | } | ||
2015 | ax = t->ax; | ||
2016 | |||
2017 | pid = GCT_get_destination (t); | ||
2018 | if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, pid)) | ||
2019 | am_I_alice = GNUNET_YES; | ||
2020 | else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, pid)) | ||
2021 | am_I_alice = GNUNET_NO; | ||
2022 | else | ||
2023 | { | ||
2024 | GNUNET_break_op (0); | ||
2025 | return; | ||
2026 | } | ||
2027 | |||
2028 | if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags))) | ||
2029 | { | ||
2030 | if (NULL != t->rekey_task) | ||
2031 | { | ||
2032 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
2033 | t->rekey_task = NULL; | ||
2034 | } | ||
2035 | GCT_send_kx (t, GNUNET_NO); | ||
2036 | } | ||
2037 | |||
2038 | if (0 == memcmp (&ax->DHRr, &msg->ratchet_key, sizeof(msg->ratchet_key))) | ||
2039 | { | ||
2040 | LOG (GNUNET_ERROR_TYPE_INFO, " known ratchet key, exit\n"); | ||
2041 | return; | ||
2042 | } | ||
2043 | |||
2044 | LOG (GNUNET_ERROR_TYPE_INFO, " is Alice? %s\n", am_I_alice ? "YES" : "NO"); | ||
2045 | |||
2046 | ax->DHRr = msg->ratchet_key; | ||
2047 | |||
2048 | /* ECDH A B0 */ | ||
2049 | if (GNUNET_YES == am_I_alice) | ||
2050 | { | ||
2051 | GNUNET_CRYPTO_eddsa_ecdh (id_key, /* A */ | ||
2052 | &msg->ephemeral_key, /* B0 */ | ||
2053 | &key_material[0]); | ||
2054 | } | ||
2055 | else | ||
2056 | { | ||
2057 | GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* B0 */ | ||
2058 | &pid->public_key, /* A */ | ||
2059 | &key_material[0]); | ||
2060 | } | ||
2061 | |||
2062 | /* ECDH A0 B */ | ||
2063 | if (GNUNET_YES == am_I_alice) | ||
2064 | { | ||
2065 | GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* A0 */ | ||
2066 | &pid->public_key, /* B */ | ||
2067 | &key_material[1]); | ||
2068 | } | ||
2069 | else | ||
2070 | { | ||
2071 | GNUNET_CRYPTO_eddsa_ecdh (id_key, /* A */ | ||
2072 | &msg->ephemeral_key, /* B0 */ | ||
2073 | &key_material[1]); | ||
2074 | |||
2075 | |||
2076 | } | ||
2077 | |||
2078 | /* ECDH A0 B0 */ | ||
2079 | /* (This is the triple-DH, we could probably safely skip this, | ||
2080 | as A0/B0 are already in the key material.) */ | ||
2081 | GNUNET_CRYPTO_ecc_ecdh (ax->kx_0, /* A0 or B0 */ | ||
2082 | &msg->ephemeral_key, /* B0 or A0 */ | ||
2083 | &key_material[2]); | ||
2084 | |||
2085 | #if DUMP_KEYS_TO_STDERR | ||
2086 | { | ||
2087 | unsigned int i; | ||
2088 | for (i = 0; i < 3; i++) | ||
2089 | LOG (GNUNET_ERROR_TYPE_INFO, "km[%u]: %s\n", | ||
2090 | i, GNUNET_h2s (&key_material[i])); | ||
2091 | } | ||
2092 | #endif | ||
2093 | |||
2094 | /* KDF */ | ||
2095 | GNUNET_CRYPTO_kdf (keys, sizeof (keys), | ||
2096 | salt, sizeof (salt), | ||
2097 | &key_material, sizeof (key_material), NULL); | ||
2098 | |||
2099 | if (0 == memcmp (&ax->RK, &keys[0], sizeof(ax->RK))) | ||
2100 | { | ||
2101 | LOG (GNUNET_ERROR_TYPE_INFO, " known handshake key, exit\n"); | ||
2102 | return; | ||
2103 | } | ||
2104 | ax->RK = keys[0]; | ||
2105 | if (GNUNET_YES == am_I_alice) | ||
2106 | { | ||
2107 | ax->HKr = keys[1]; | ||
2108 | ax->NHKs = keys[2]; | ||
2109 | ax->NHKr = keys[3]; | ||
2110 | ax->CKr = keys[4]; | ||
2111 | ax->ratchet_flag = GNUNET_YES; | ||
2112 | } | ||
2113 | else | ||
2114 | { | ||
2115 | ax->HKs = keys[1]; | ||
2116 | ax->NHKr = keys[2]; | ||
2117 | ax->NHKs = keys[3]; | ||
2118 | ax->CKs = keys[4]; | ||
2119 | ax->ratchet_flag = GNUNET_NO; | ||
2120 | ax->ratchet_allowed = GNUNET_NO; | ||
2121 | ax->ratchet_counter = 0; | ||
2122 | ax->ratchet_expiration = | ||
2123 | GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), ratchet_time); | ||
2124 | } | ||
2125 | ax->PNs = 0; | ||
2126 | ax->Nr = 0; | ||
2127 | ax->Ns = 0; | ||
2128 | |||
2129 | GCT_change_estate (t, CADET_TUNNEL_KEY_AX_AUTH_SENT); | ||
2130 | send_queued_data (t); | ||
2131 | |||
2132 | CADET_TIMING_END; | ||
2133 | } | ||
2134 | |||
2135 | /** | ||
2136 | * Initialize the tunnel subsystem. | ||
2137 | * | ||
2138 | * @param c Configuration handle. | ||
2139 | * @param key ECC private key, to derive all other keys and do crypto. | ||
2140 | */ | ||
2141 | void | ||
2142 | GCT_init (const struct GNUNET_CONFIGURATION_Handle *c, | ||
2143 | const struct GNUNET_CRYPTO_EddsaPrivateKey *key) | ||
2144 | { | ||
2145 | unsigned int expected_overhead; | ||
2146 | |||
2147 | LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); | ||
2148 | |||
2149 | expected_overhead = 0; | ||
2150 | expected_overhead += sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); | ||
2151 | expected_overhead += sizeof (struct GNUNET_CADET_ChannelAppDataMessage); | ||
2152 | expected_overhead += sizeof (struct GNUNET_CADET_ConnectionEncryptedAckMessage); | ||
2153 | GNUNET_assert (GNUNET_CONSTANTS_CADET_P2P_OVERHEAD == expected_overhead); | ||
2154 | |||
2155 | if (GNUNET_OK != | ||
2156 | GNUNET_CONFIGURATION_get_value_number (c, | ||
2157 | "CADET", | ||
2158 | "RATCHET_MESSAGES", | ||
2159 | &ratchet_messages)) | ||
2160 | { | ||
2161 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, | ||
2162 | "CADET", | ||
2163 | "RATCHET_MESSAGES", | ||
2164 | "USING DEFAULT"); | ||
2165 | ratchet_messages = 64; | ||
2166 | } | ||
2167 | if (GNUNET_OK != | ||
2168 | GNUNET_CONFIGURATION_get_value_time (c, | ||
2169 | "CADET", | ||
2170 | "RATCHET_TIME", | ||
2171 | &ratchet_time)) | ||
2172 | { | ||
2173 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, | ||
2174 | "CADET", "RATCHET_TIME", "USING DEFAULT"); | ||
2175 | ratchet_time = GNUNET_TIME_UNIT_HOURS; | ||
2176 | } | ||
2177 | |||
2178 | |||
2179 | id_key = key; | ||
2180 | tunnels = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES); | ||
2181 | } | ||
2182 | |||
2183 | |||
2184 | /** | ||
2185 | * Shut down the tunnel subsystem. | ||
2186 | */ | ||
2187 | void | ||
2188 | GCT_shutdown (void) | ||
2189 | { | ||
2190 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down tunnels\n"); | ||
2191 | GNUNET_CONTAINER_multipeermap_iterate (tunnels, &destroy_iterator, NULL); | ||
2192 | GNUNET_CONTAINER_multipeermap_destroy (tunnels); | ||
2193 | } | ||
2194 | |||
2195 | |||
2196 | /** | ||
2197 | * Create a tunnel. | ||
2198 | * | ||
2199 | * @param destination Peer this tunnel is towards. | ||
2200 | */ | ||
2201 | struct CadetTunnel * | ||
2202 | GCT_new (struct CadetPeer *destination) | ||
2203 | { | ||
2204 | struct CadetTunnel *t; | ||
2205 | |||
2206 | t = GNUNET_new (struct CadetTunnel); | ||
2207 | t->next_ctn.cn = 0; | ||
2208 | t->peer = destination; | ||
2209 | |||
2210 | if (GNUNET_OK != | ||
2211 | GNUNET_CONTAINER_multipeermap_put (tunnels, GCP_get_id (destination), t, | ||
2212 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
2213 | { | ||
2214 | GNUNET_break (0); | ||
2215 | GNUNET_free (t); | ||
2216 | return NULL; | ||
2217 | } | ||
2218 | t->ax = GNUNET_new (struct CadetTunnelAxolotl); | ||
2219 | new_ephemeral (t); | ||
2220 | t->ax->kx_0 = GNUNET_CRYPTO_ecdhe_key_create (); | ||
2221 | return t; | ||
2222 | } | ||
2223 | |||
2224 | |||
2225 | /** | ||
2226 | * Change the tunnel's connection state. | ||
2227 | * | ||
2228 | * @param t Tunnel whose connection state to change. | ||
2229 | * @param cstate New connection state. | ||
2230 | */ | ||
2231 | void | ||
2232 | GCT_change_cstate (struct CadetTunnel* t, enum CadetTunnelCState cstate) | ||
2233 | { | ||
2234 | if (NULL == t) | ||
2235 | return; | ||
2236 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s cstate %s => %s\n", | ||
2237 | GCP_2s (t->peer), cstate2s (t->cstate), cstate2s (cstate)); | ||
2238 | if (myid != GCP_get_short_id (t->peer) && | ||
2239 | CADET_TUNNEL_READY != t->cstate && | ||
2240 | CADET_TUNNEL_READY == cstate) | ||
2241 | { | ||
2242 | t->cstate = cstate; | ||
2243 | if (CADET_TUNNEL_KEY_OK == t->estate) | ||
2244 | { | ||
2245 | LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered send queued data\n"); | ||
2246 | send_queued_data (t); | ||
2247 | } | ||
2248 | else if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | ||
2249 | { | ||
2250 | LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered KX\n"); | ||
2251 | GCT_send_kx (t, GNUNET_NO); | ||
2252 | } | ||
2253 | else | ||
2254 | { | ||
2255 | LOG (GNUNET_ERROR_TYPE_DEBUG, "estate %s\n", estate2s (t->estate)); | ||
2256 | } | ||
2257 | } | ||
2258 | t->cstate = cstate; | ||
2259 | |||
2260 | if (CADET_TUNNEL_READY == cstate | ||
2261 | && CONNECTIONS_PER_TUNNEL <= GCT_count_connections (t)) | ||
2262 | { | ||
2263 | LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered stop dht\n"); | ||
2264 | GCP_stop_search (t->peer); | ||
2265 | } | ||
2266 | } | ||
2267 | |||
2268 | |||
2269 | /** | ||
2270 | * Change the tunnel encryption state. | ||
2271 | * | ||
2272 | * If the encryption state changes to OK, stop the rekey task. | ||
2273 | * | ||
2274 | * @param t Tunnel whose encryption state to change, or NULL. | ||
2275 | * @param state New encryption state. | ||
2276 | */ | ||
2277 | void | ||
2278 | GCT_change_estate (struct CadetTunnel* t, enum CadetTunnelEState state) | ||
2279 | { | ||
2280 | enum CadetTunnelEState old; | ||
2281 | |||
2282 | if (NULL == t) | ||
2283 | return; | ||
2284 | |||
2285 | old = t->estate; | ||
2286 | t->estate = state; | ||
2287 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s estate was %s\n", | ||
2288 | GCP_2s (t->peer), estate2s (old)); | ||
2289 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s estate is now %s\n", | ||
2290 | GCP_2s (t->peer), estate2s (t->estate)); | ||
2291 | |||
2292 | if (CADET_TUNNEL_KEY_OK != old && CADET_TUNNEL_KEY_OK == t->estate) | ||
2293 | { | ||
2294 | if (NULL != t->rekey_task) | ||
2295 | { | ||
2296 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
2297 | t->rekey_task = NULL; | ||
2298 | } | ||
2299 | /* Send queued data if tunnel is not loopback */ | ||
2300 | if (myid != GCP_get_short_id (t->peer)) | ||
2301 | send_queued_data (t); | ||
2302 | } | ||
2303 | } | ||
2304 | |||
2305 | |||
2306 | /** | ||
2307 | * @brief Check if tunnel has too many connections, and remove one if necessary. | ||
2308 | * | ||
2309 | * Currently this means the newest connection, unless it is a direct one. | ||
2310 | * Implemented as a task to avoid freeing a connection that is in the middle | ||
2311 | * of being created/processed. | ||
2312 | * | ||
2313 | * @param cls Closure (Tunnel to check). | ||
2314 | */ | ||
2315 | static void | ||
2316 | trim_connections (void *cls) | ||
2317 | { | ||
2318 | struct CadetTunnel *t = cls; | ||
2319 | |||
2320 | t->trim_connections_task = NULL; | ||
2321 | if (GCT_count_connections (t) > 2 * CONNECTIONS_PER_TUNNEL) | ||
2322 | { | ||
2323 | struct CadetTConnection *iter; | ||
2324 | struct CadetTConnection *c; | ||
2325 | |||
2326 | for (c = iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2327 | { | ||
2328 | if ((iter->created.abs_value_us > c->created.abs_value_us) | ||
2329 | && GNUNET_NO == GCC_is_direct (iter->c)) | ||
2330 | { | ||
2331 | c = iter; | ||
2332 | } | ||
2333 | } | ||
2334 | if (NULL != c) | ||
2335 | { | ||
2336 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Too many connections on tunnel %s\n", | ||
2337 | GCT_2s (t)); | ||
2338 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying connection %s\n", | ||
2339 | GCC_2s (c->c)); | ||
2340 | GCC_destroy (c->c); | ||
2341 | } | ||
2342 | else | ||
2343 | { | ||
2344 | GNUNET_break (0); | ||
2345 | } | ||
2346 | } | ||
2347 | } | ||
2348 | |||
2349 | |||
2350 | /** | ||
2351 | * Add a connection to a tunnel. | ||
2352 | * | ||
2353 | * @param t Tunnel. | ||
2354 | * @param c Connection. | ||
2355 | */ | ||
2356 | void | ||
2357 | GCT_add_connection (struct CadetTunnel *t, struct CadetConnection *c) | ||
2358 | { | ||
2359 | struct CadetTConnection *aux; | ||
2360 | |||
2361 | GNUNET_assert (NULL != c); | ||
2362 | |||
2363 | LOG (GNUNET_ERROR_TYPE_DEBUG, "add connection %s\n", GCC_2s (c)); | ||
2364 | LOG (GNUNET_ERROR_TYPE_DEBUG, " to tunnel %s\n", GCT_2s (t)); | ||
2365 | for (aux = t->connection_head; aux != NULL; aux = aux->next) | ||
2366 | if (aux->c == c) | ||
2367 | return; | ||
2368 | |||
2369 | aux = GNUNET_new (struct CadetTConnection); | ||
2370 | aux->c = c; | ||
2371 | aux->created = GNUNET_TIME_absolute_get (); | ||
2372 | |||
2373 | GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, aux); | ||
2374 | |||
2375 | if (CADET_TUNNEL_SEARCHING == t->cstate) | ||
2376 | GCT_change_cstate (t, CADET_TUNNEL_WAITING); | ||
2377 | |||
2378 | if (NULL != t->trim_connections_task) | ||
2379 | t->trim_connections_task = GNUNET_SCHEDULER_add_now (&trim_connections, t); | ||
2380 | } | ||
2381 | |||
2382 | |||
2383 | /** | ||
2384 | * Remove a connection from a tunnel. | ||
2385 | * | ||
2386 | * @param t Tunnel. | ||
2387 | * @param c Connection. | ||
2388 | */ | ||
2389 | void | ||
2390 | GCT_remove_connection (struct CadetTunnel *t, | ||
2391 | struct CadetConnection *c) | ||
2392 | { | ||
2393 | struct CadetTConnection *aux; | ||
2394 | struct CadetTConnection *next; | ||
2395 | unsigned int conns; | ||
2396 | |||
2397 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing connection %s from tunnel %s\n", | ||
2398 | GCC_2s (c), GCT_2s (t)); | ||
2399 | for (aux = t->connection_head; aux != NULL; aux = next) | ||
2400 | { | ||
2401 | next = aux->next; | ||
2402 | if (aux->c == c) | ||
2403 | { | ||
2404 | GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux); | ||
2405 | GNUNET_free (aux); | ||
2406 | } | ||
2407 | } | ||
2408 | |||
2409 | conns = GCT_count_connections (t); | ||
2410 | if (0 == conns | ||
2411 | && NULL == t->destroy_task | ||
2412 | && CADET_TUNNEL_SHUTDOWN != t->cstate | ||
2413 | && GNUNET_NO == shutting_down) | ||
2414 | { | ||
2415 | if (0 == GCT_count_any_connections (t)) | ||
2416 | GCT_change_cstate (t, CADET_TUNNEL_SEARCHING); | ||
2417 | else | ||
2418 | GCT_change_cstate (t, CADET_TUNNEL_WAITING); | ||
2419 | } | ||
2420 | |||
2421 | /* Start new connections if needed */ | ||
2422 | if (CONNECTIONS_PER_TUNNEL > conns | ||
2423 | && CADET_TUNNEL_SHUTDOWN != t->cstate | ||
2424 | && GNUNET_NO == shutting_down) | ||
2425 | { | ||
2426 | LOG (GNUNET_ERROR_TYPE_DEBUG, " too few connections, getting new ones\n"); | ||
2427 | GCP_connect (t->peer); /* Will change cstate to WAITING when possible */ | ||
2428 | return; | ||
2429 | } | ||
2430 | |||
2431 | /* If not marked as ready, no change is needed */ | ||
2432 | if (CADET_TUNNEL_READY != t->cstate) | ||
2433 | return; | ||
2434 | |||
2435 | /* Check if any connection is ready to maintain cstate */ | ||
2436 | for (aux = t->connection_head; aux != NULL; aux = aux->next) | ||
2437 | if (CADET_CONNECTION_READY == GCC_get_state (aux->c)) | ||
2438 | return; | ||
2439 | } | ||
2440 | |||
2441 | |||
2442 | /** | ||
2443 | * Add a channel to a tunnel. | ||
2444 | * | ||
2445 | * @param t Tunnel. | ||
2446 | * @param ch Channel. | ||
2447 | */ | ||
2448 | void | ||
2449 | GCT_add_channel (struct CadetTunnel *t, | ||
2450 | struct CadetChannel *ch) | ||
2451 | { | ||
2452 | struct CadetTChannel *aux; | ||
2453 | |||
2454 | GNUNET_assert (NULL != ch); | ||
2455 | |||
2456 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding channel %p to tunnel %p\n", ch, t); | ||
2457 | |||
2458 | for (aux = t->channel_head; aux != NULL; aux = aux->next) | ||
2459 | { | ||
2460 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already there %p\n", aux->ch); | ||
2461 | if (aux->ch == ch) | ||
2462 | return; | ||
2463 | } | ||
2464 | |||
2465 | aux = GNUNET_new (struct CadetTChannel); | ||
2466 | aux->ch = ch; | ||
2467 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2468 | " adding %p to %p\n", aux, t->channel_head); | ||
2469 | GNUNET_CONTAINER_DLL_insert_tail (t->channel_head, | ||
2470 | t->channel_tail, | ||
2471 | aux); | ||
2472 | |||
2473 | if (NULL != t->destroy_task) | ||
2474 | { | ||
2475 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
2476 | t->destroy_task = NULL; | ||
2477 | LOG (GNUNET_ERROR_TYPE_DEBUG, " undo destroy!\n"); | ||
2478 | } | ||
2479 | } | ||
2480 | |||
2481 | |||
2482 | /** | ||
2483 | * Remove a channel from a tunnel. | ||
2484 | * | ||
2485 | * @param t Tunnel. | ||
2486 | * @param ch Channel. | ||
2487 | */ | ||
2488 | void | ||
2489 | GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch) | ||
2490 | { | ||
2491 | struct CadetTChannel *aux; | ||
2492 | |||
2493 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing channel %p from tunnel %p\n", ch, t); | ||
2494 | for (aux = t->channel_head; aux != NULL; aux = aux->next) | ||
2495 | { | ||
2496 | if (aux->ch == ch) | ||
2497 | { | ||
2498 | LOG (GNUNET_ERROR_TYPE_DEBUG, " found! %s\n", GCCH_2s (ch)); | ||
2499 | GNUNET_CONTAINER_DLL_remove (t->channel_head, | ||
2500 | t->channel_tail, | ||
2501 | aux); | ||
2502 | GNUNET_free (aux); | ||
2503 | return; | ||
2504 | } | ||
2505 | } | ||
2506 | } | ||
2507 | |||
2508 | |||
2509 | /** | ||
2510 | * Search for a channel by global ID. | ||
2511 | * | ||
2512 | * @param t Tunnel containing the channel. | ||
2513 | * @param ctn Public channel number. | ||
2514 | * | ||
2515 | * @return channel handler, NULL if doesn't exist | ||
2516 | */ | ||
2517 | struct CadetChannel * | ||
2518 | GCT_get_channel (struct CadetTunnel *t, | ||
2519 | struct GNUNET_CADET_ChannelTunnelNumber ctn) | ||
2520 | { | ||
2521 | struct CadetTChannel *iter; | ||
2522 | |||
2523 | if (NULL == t) | ||
2524 | return NULL; | ||
2525 | |||
2526 | for (iter = t->channel_head; NULL != iter; iter = iter->next) | ||
2527 | { | ||
2528 | if (GCCH_get_id (iter->ch).cn == ctn.cn) | ||
2529 | break; | ||
2530 | } | ||
2531 | |||
2532 | return NULL == iter ? NULL : iter->ch; | ||
2533 | } | ||
2534 | |||
2535 | |||
2536 | /** | ||
2537 | * @brief Destroy a tunnel and free all resources. | ||
2538 | * | ||
2539 | * Should only be called a while after the tunnel has been marked as destroyed, | ||
2540 | * in case there is a new channel added to the same peer shortly after marking | ||
2541 | * the tunnel. This way we avoid a new public key handshake. | ||
2542 | * | ||
2543 | * @param cls Closure (tunnel to destroy). | ||
2544 | */ | ||
2545 | static void | ||
2546 | delayed_destroy (void *cls) | ||
2547 | { | ||
2548 | struct CadetTunnel *t = cls; | ||
2549 | struct CadetTConnection *iter; | ||
2550 | |||
2551 | t->destroy_task = NULL; | ||
2552 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2553 | "delayed destroying tunnel %p\n", | ||
2554 | t); | ||
2555 | t->cstate = CADET_TUNNEL_SHUTDOWN; | ||
2556 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2557 | { | ||
2558 | GCC_send_destroy (iter->c); | ||
2559 | } | ||
2560 | GCT_destroy (t); | ||
2561 | } | ||
2562 | |||
2563 | |||
2564 | /** | ||
2565 | * Tunnel is empty: destroy it. | ||
2566 | * | ||
2567 | * Notifies all connections about the destruction. | ||
2568 | * | ||
2569 | * @param t Tunnel to destroy. | ||
2570 | */ | ||
2571 | void | ||
2572 | GCT_destroy_empty (struct CadetTunnel *t) | ||
2573 | { | ||
2574 | if (GNUNET_YES == shutting_down) | ||
2575 | return; /* Will be destroyed immediately anyway */ | ||
2576 | |||
2577 | if (NULL != t->destroy_task) | ||
2578 | { | ||
2579 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2580 | "Tunnel %s is already scheduled for destruction. Tunnel debug dump:\n", | ||
2581 | GCT_2s (t)); | ||
2582 | GCT_debug (t, GNUNET_ERROR_TYPE_WARNING); | ||
2583 | GNUNET_break (0); | ||
2584 | /* should never happen, tunnel can only become empty once, and the | ||
2585 | * task identifier should be NO_TASK (cleaned when the tunnel was created | ||
2586 | * or became un-empty) | ||
2587 | */ | ||
2588 | return; | ||
2589 | } | ||
2590 | |||
2591 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s empty: scheduling destruction\n", | ||
2592 | GCT_2s (t)); | ||
2593 | |||
2594 | // FIXME make delay a config option | ||
2595 | t->destroy_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, | ||
2596 | &delayed_destroy, t); | ||
2597 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled destroy of %p as %p\n", | ||
2598 | t, t->destroy_task); | ||
2599 | } | ||
2600 | |||
2601 | |||
2602 | /** | ||
2603 | * Destroy tunnel if empty (no more channels). | ||
2604 | * | ||
2605 | * @param t Tunnel to destroy if empty. | ||
2606 | */ | ||
2607 | void | ||
2608 | GCT_destroy_if_empty (struct CadetTunnel *t) | ||
2609 | { | ||
2610 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s destroy if empty\n", GCT_2s (t)); | ||
2611 | if (0 < GCT_count_channels (t)) | ||
2612 | return; | ||
2613 | |||
2614 | GCT_destroy_empty (t); | ||
2615 | } | ||
2616 | |||
2617 | |||
2618 | /** | ||
2619 | * Destroy the tunnel. | ||
2620 | * | ||
2621 | * This function does not generate any warning traffic to clients or peers. | ||
2622 | * | ||
2623 | * Tasks: | ||
2624 | * Cancel messages belonging to this tunnel queued to neighbors. | ||
2625 | * Free any allocated resources linked to the tunnel. | ||
2626 | * | ||
2627 | * @param t The tunnel to destroy. | ||
2628 | */ | ||
2629 | void | ||
2630 | GCT_destroy (struct CadetTunnel *t) | ||
2631 | { | ||
2632 | struct CadetTConnection *iter_c; | ||
2633 | struct CadetTConnection *next_c; | ||
2634 | struct CadetTChannel *iter_ch; | ||
2635 | struct CadetTChannel *next_ch; | ||
2636 | unsigned int keepalives_queued; | ||
2637 | |||
2638 | if (NULL == t) | ||
2639 | return; | ||
2640 | |||
2641 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2642 | "destroying tunnel %s\n", | ||
2643 | GCP_2s (t->peer)); | ||
2644 | GNUNET_break (GNUNET_YES == | ||
2645 | GNUNET_CONTAINER_multipeermap_remove (tunnels, | ||
2646 | GCP_get_id (t->peer), t)); | ||
2647 | |||
2648 | for (iter_c = t->connection_head; NULL != iter_c; iter_c = next_c) | ||
2649 | { | ||
2650 | next_c = iter_c->next; | ||
2651 | GCC_destroy (iter_c->c); | ||
2652 | } | ||
2653 | for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = next_ch) | ||
2654 | { | ||
2655 | next_ch = iter_ch->next; | ||
2656 | GCCH_destroy (iter_ch->ch); | ||
2657 | /* Should only happen on shutdown, but it's ok. */ | ||
2658 | } | ||
2659 | keepalives_queued = 0; | ||
2660 | while (NULL != t->tq_head) | ||
2661 | { | ||
2662 | /* Should have been cleaned by destuction of channel. */ | ||
2663 | struct GNUNET_MessageHeader *mh; | ||
2664 | uint16_t type; | ||
2665 | |||
2666 | mh = (struct GNUNET_MessageHeader *) &t->tq_head[1]; | ||
2667 | type = ntohs (mh->type); | ||
2668 | if (0 == keepalives_queued && GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE == type) | ||
2669 | { | ||
2670 | keepalives_queued = 1; | ||
2671 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2672 | "one keepalive left behind on tunnel shutdown\n"); | ||
2673 | } | ||
2674 | else if (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY == type) | ||
2675 | { | ||
2676 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2677 | "tunnel destroyed before a CHANNEL_DESTROY was sent to peer\n"); | ||
2678 | } | ||
2679 | else | ||
2680 | { | ||
2681 | GNUNET_break (0); | ||
2682 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
2683 | "message left behind on tunnel shutdown: %s\n", | ||
2684 | GC_m2s (type)); | ||
2685 | } | ||
2686 | unqueue_data (t->tq_head); | ||
2687 | } | ||
2688 | |||
2689 | |||
2690 | if (NULL != t->destroy_task) | ||
2691 | { | ||
2692 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2693 | "cancelling dest: %p\n", | ||
2694 | t->destroy_task); | ||
2695 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
2696 | t->destroy_task = NULL; | ||
2697 | } | ||
2698 | |||
2699 | if (NULL != t->trim_connections_task) | ||
2700 | { | ||
2701 | LOG (GNUNET_ERROR_TYPE_DEBUG, "cancelling trim: %p\n", | ||
2702 | t->trim_connections_task); | ||
2703 | GNUNET_SCHEDULER_cancel (t->trim_connections_task); | ||
2704 | t->trim_connections_task = NULL; | ||
2705 | } | ||
2706 | |||
2707 | GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO); | ||
2708 | GCP_set_tunnel (t->peer, NULL); | ||
2709 | |||
2710 | if (NULL != t->rekey_task) | ||
2711 | { | ||
2712 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
2713 | t->rekey_task = NULL; | ||
2714 | } | ||
2715 | if (NULL != t->ax) | ||
2716 | destroy_ax (t); | ||
2717 | |||
2718 | GNUNET_free (t); | ||
2719 | } | ||
2720 | |||
2721 | |||
2722 | /** | ||
2723 | * @brief Use the given path for the tunnel. | ||
2724 | * Update the next and prev hops (and RCs). | ||
2725 | * (Re)start the path refresh in case the tunnel is locally owned. | ||
2726 | * | ||
2727 | * @param t Tunnel to update. | ||
2728 | * @param p Path to use. | ||
2729 | * | ||
2730 | * @return Connection created. | ||
2731 | */ | ||
2732 | struct CadetConnection * | ||
2733 | GCT_use_path (struct CadetTunnel *t, struct CadetPeerPath *path) | ||
2734 | { | ||
2735 | struct CadetConnection *c; | ||
2736 | struct GNUNET_CADET_ConnectionTunnelIdentifier cid; | ||
2737 | unsigned int own_pos; | ||
2738 | |||
2739 | if (NULL == t || NULL == path) | ||
2740 | { | ||
2741 | GNUNET_break (0); | ||
2742 | return NULL; | ||
2743 | } | ||
2744 | |||
2745 | if (CADET_TUNNEL_SHUTDOWN == t->cstate) | ||
2746 | { | ||
2747 | GNUNET_break (0); | ||
2748 | return NULL; | ||
2749 | } | ||
2750 | |||
2751 | for (own_pos = 0; own_pos < path->length; own_pos++) | ||
2752 | { | ||
2753 | if (path->peers[own_pos] == myid) | ||
2754 | break; | ||
2755 | } | ||
2756 | if (own_pos >= path->length) | ||
2757 | { | ||
2758 | GNUNET_break_op (0); | ||
2759 | return NULL; | ||
2760 | } | ||
2761 | |||
2762 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &cid, sizeof (cid)); | ||
2763 | c = GCC_new (&cid, t, path, own_pos); | ||
2764 | if (NULL == c) | ||
2765 | { | ||
2766 | /* Path was flawed */ | ||
2767 | return NULL; | ||
2768 | } | ||
2769 | GCT_add_connection (t, c); | ||
2770 | return c; | ||
2771 | } | ||
2772 | |||
2773 | |||
2774 | /** | ||
2775 | * Count all created connections of a tunnel. Not necessarily ready connections! | ||
2776 | * | ||
2777 | * @param t Tunnel on which to count. | ||
2778 | * | ||
2779 | * @return Number of connections created, either being established or ready. | ||
2780 | */ | ||
2781 | unsigned int | ||
2782 | GCT_count_any_connections (struct CadetTunnel *t) | ||
2783 | { | ||
2784 | struct CadetTConnection *iter; | ||
2785 | unsigned int count; | ||
2786 | |||
2787 | if (NULL == t) | ||
2788 | return 0; | ||
2789 | |||
2790 | for (count = 0, iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2791 | count++; | ||
2792 | |||
2793 | return count; | ||
2794 | } | ||
2795 | |||
2796 | |||
2797 | /** | ||
2798 | * Count established (ready) connections of a tunnel. | ||
2799 | * | ||
2800 | * @param t Tunnel on which to count. | ||
2801 | * | ||
2802 | * @return Number of connections. | ||
2803 | */ | ||
2804 | unsigned int | ||
2805 | GCT_count_connections (struct CadetTunnel *t) | ||
2806 | { | ||
2807 | struct CadetTConnection *iter; | ||
2808 | unsigned int count; | ||
2809 | |||
2810 | if (NULL == t) | ||
2811 | return 0; | ||
2812 | |||
2813 | for (count = 0, iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2814 | if (CADET_CONNECTION_READY == GCC_get_state (iter->c)) | ||
2815 | count++; | ||
2816 | |||
2817 | return count; | ||
2818 | } | ||
2819 | |||
2820 | |||
2821 | /** | ||
2822 | * Count channels of a tunnel. | ||
2823 | * | ||
2824 | * @param t Tunnel on which to count. | ||
2825 | * | ||
2826 | * @return Number of channels. | ||
2827 | */ | ||
2828 | unsigned int | ||
2829 | GCT_count_channels (struct CadetTunnel *t) | ||
2830 | { | ||
2831 | struct CadetTChannel *iter; | ||
2832 | unsigned int count; | ||
2833 | |||
2834 | for (count = 0, iter = t->channel_head; | ||
2835 | NULL != iter; | ||
2836 | iter = iter->next, count++) /* skip */; | ||
2837 | |||
2838 | return count; | ||
2839 | } | ||
2840 | |||
2841 | |||
2842 | /** | ||
2843 | * Get the connectivity state of a tunnel. | ||
2844 | * | ||
2845 | * @param t Tunnel. | ||
2846 | * | ||
2847 | * @return Tunnel's connectivity state. | ||
2848 | */ | ||
2849 | enum CadetTunnelCState | ||
2850 | GCT_get_cstate (struct CadetTunnel *t) | ||
2851 | { | ||
2852 | if (NULL == t) | ||
2853 | { | ||
2854 | GNUNET_assert (0); | ||
2855 | return (enum CadetTunnelCState) -1; | ||
2856 | } | ||
2857 | return t->cstate; | ||
2858 | } | ||
2859 | |||
2860 | |||
2861 | /** | ||
2862 | * Get the encryption state of a tunnel. | ||
2863 | * | ||
2864 | * @param t Tunnel. | ||
2865 | * | ||
2866 | * @return Tunnel's encryption state. | ||
2867 | */ | ||
2868 | enum CadetTunnelEState | ||
2869 | GCT_get_estate (struct CadetTunnel *t) | ||
2870 | { | ||
2871 | if (NULL == t) | ||
2872 | { | ||
2873 | GNUNET_break (0); | ||
2874 | return (enum CadetTunnelEState) -1; | ||
2875 | } | ||
2876 | return t->estate; | ||
2877 | } | ||
2878 | |||
2879 | /** | ||
2880 | * Get the maximum buffer space for a tunnel towards a local client. | ||
2881 | * | ||
2882 | * @param t Tunnel. | ||
2883 | * | ||
2884 | * @return Biggest buffer space offered by any channel in the tunnel. | ||
2885 | */ | ||
2886 | unsigned int | ||
2887 | GCT_get_channels_buffer (struct CadetTunnel *t) | ||
2888 | { | ||
2889 | struct CadetTChannel *iter; | ||
2890 | unsigned int buffer; | ||
2891 | unsigned int ch_buf; | ||
2892 | |||
2893 | if (NULL == t->channel_head) | ||
2894 | { | ||
2895 | /* Probably getting buffer for a channel create/handshake. */ | ||
2896 | LOG (GNUNET_ERROR_TYPE_DEBUG, " no channels, allow max\n"); | ||
2897 | return MIN_TUNNEL_BUFFER; | ||
2898 | } | ||
2899 | |||
2900 | buffer = 0; | ||
2901 | for (iter = t->channel_head; NULL != iter; iter = iter->next) | ||
2902 | { | ||
2903 | ch_buf = get_channel_buffer (iter); | ||
2904 | if (ch_buf > buffer) | ||
2905 | buffer = ch_buf; | ||
2906 | } | ||
2907 | if (MIN_TUNNEL_BUFFER > buffer) | ||
2908 | return MIN_TUNNEL_BUFFER; | ||
2909 | |||
2910 | if (MAX_TUNNEL_BUFFER < buffer) | ||
2911 | { | ||
2912 | GNUNET_break (0); | ||
2913 | return MAX_TUNNEL_BUFFER; | ||
2914 | } | ||
2915 | return buffer; | ||
2916 | } | ||
2917 | |||
2918 | |||
2919 | /** | ||
2920 | * Get the total buffer space for a tunnel for P2P traffic. | ||
2921 | * | ||
2922 | * @param t Tunnel. | ||
2923 | * | ||
2924 | * @return Buffer space offered by all connections in the tunnel. | ||
2925 | */ | ||
2926 | unsigned int | ||
2927 | GCT_get_connections_buffer (struct CadetTunnel *t) | ||
2928 | { | ||
2929 | struct CadetTConnection *iter; | ||
2930 | unsigned int buffer; | ||
2931 | |||
2932 | if (GNUNET_NO == is_ready (t)) | ||
2933 | { | ||
2934 | if (count_queued_data (t) >= 3) | ||
2935 | return 0; | ||
2936 | else | ||
2937 | return 1; | ||
2938 | } | ||
2939 | |||
2940 | buffer = 0; | ||
2941 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2942 | { | ||
2943 | if (GCC_get_state (iter->c) != CADET_CONNECTION_READY) | ||
2944 | { | ||
2945 | continue; | ||
2946 | } | ||
2947 | buffer += get_connection_buffer (iter); | ||
2948 | } | ||
2949 | |||
2950 | return buffer; | ||
2951 | } | ||
2952 | |||
2953 | |||
2954 | /** | ||
2955 | * Get the tunnel's destination. | ||
2956 | * | ||
2957 | * @param t Tunnel. | ||
2958 | * | ||
2959 | * @return ID of the destination peer. | ||
2960 | */ | ||
2961 | const struct GNUNET_PeerIdentity * | ||
2962 | GCT_get_destination (struct CadetTunnel *t) | ||
2963 | { | ||
2964 | return GCP_get_id (t->peer); | ||
2965 | } | ||
2966 | |||
2967 | |||
2968 | /** | ||
2969 | * Get the tunnel's next free global channel ID. | ||
2970 | * | ||
2971 | * @param t Tunnel. | ||
2972 | * | ||
2973 | * @return GID of a channel free to use. | ||
2974 | */ | ||
2975 | struct GNUNET_CADET_ChannelTunnelNumber | ||
2976 | GCT_get_next_ctn (struct CadetTunnel *t) | ||
2977 | { | ||
2978 | struct GNUNET_CADET_ChannelTunnelNumber ctn; | ||
2979 | struct GNUNET_CADET_ChannelTunnelNumber mask; | ||
2980 | int result; | ||
2981 | |||
2982 | /* Set bit 30 depending on the ID relationship. Bit 31 is always 0 for GID. | ||
2983 | * If our ID is bigger or loopback tunnel, start at 0, bit 30 = 0 | ||
2984 | * If peer's ID is bigger, start at 0x4... bit 30 = 1 | ||
2985 | */ | ||
2986 | result = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, GCP_get_id (t->peer)); | ||
2987 | if (0 > result) | ||
2988 | mask.cn = htonl (0x40000000); | ||
2989 | else | ||
2990 | mask.cn = 0x0; | ||
2991 | t->next_ctn.cn |= mask.cn; | ||
2992 | |||
2993 | while (NULL != GCT_get_channel (t, t->next_ctn)) | ||
2994 | { | ||
2995 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2996 | "Channel %u exists...\n", | ||
2997 | t->next_ctn.cn); | ||
2998 | t->next_ctn.cn = htonl ((ntohl (t->next_ctn.cn) + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | ||
2999 | t->next_ctn.cn |= mask.cn; | ||
3000 | } | ||
3001 | ctn = t->next_ctn; | ||
3002 | t->next_ctn.cn = (t->next_ctn.cn + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; | ||
3003 | t->next_ctn.cn |= mask.cn; | ||
3004 | |||
3005 | return ctn; | ||
3006 | } | ||
3007 | |||
3008 | |||
3009 | /** | ||
3010 | * Send ACK on one or more channels due to buffer in connections. | ||
3011 | * | ||
3012 | * @param t Channel which has some free buffer space. | ||
3013 | */ | ||
3014 | void | ||
3015 | GCT_unchoke_channels (struct CadetTunnel *t) | ||
3016 | { | ||
3017 | struct CadetTChannel *iter; | ||
3018 | unsigned int buffer; | ||
3019 | unsigned int channels = GCT_count_channels (t); | ||
3020 | unsigned int choked_n; | ||
3021 | struct CadetChannel *choked[channels]; | ||
3022 | |||
3023 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GCT_unchoke_channels on %s\n", GCT_2s (t)); | ||
3024 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head: %p\n", t->channel_head); | ||
3025 | if (NULL != t->channel_head) | ||
3026 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head ch: %p\n", t->channel_head->ch); | ||
3027 | |||
3028 | if (NULL != t->tq_head) | ||
3029 | send_queued_data (t); | ||
3030 | |||
3031 | /* Get buffer space */ | ||
3032 | buffer = GCT_get_connections_buffer (t); | ||
3033 | if (0 == buffer) | ||
3034 | { | ||
3035 | return; | ||
3036 | } | ||
3037 | |||
3038 | /* Count and remember choked channels */ | ||
3039 | choked_n = 0; | ||
3040 | for (iter = t->channel_head; NULL != iter; iter = iter->next) | ||
3041 | { | ||
3042 | if (GNUNET_NO == get_channel_allowed (iter)) | ||
3043 | { | ||
3044 | choked[choked_n++] = iter->ch; | ||
3045 | } | ||
3046 | } | ||
3047 | |||
3048 | /* Unchoke random channels */ | ||
3049 | while (0 < buffer && 0 < choked_n) | ||
3050 | { | ||
3051 | unsigned int r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
3052 | choked_n); | ||
3053 | GCCH_allow_client (choked[r], GCCH_is_origin (choked[r], GNUNET_YES)); | ||
3054 | choked_n--; | ||
3055 | buffer--; | ||
3056 | choked[r] = choked[choked_n]; | ||
3057 | } | ||
3058 | } | ||
3059 | |||
3060 | |||
3061 | /** | ||
3062 | * Send ACK on one or more connections due to buffer space to the client. | ||
3063 | * | ||
3064 | * Iterates all connections of the tunnel and sends ACKs appropriately. | ||
3065 | * | ||
3066 | * @param t Tunnel. | ||
3067 | */ | ||
3068 | void | ||
3069 | GCT_send_connection_acks (struct CadetTunnel *t) | ||
3070 | { | ||
3071 | struct CadetTConnection *iter; | ||
3072 | uint32_t allowed; | ||
3073 | uint32_t to_allow; | ||
3074 | uint32_t allow_per_connection; | ||
3075 | unsigned int cs; | ||
3076 | unsigned int buffer; | ||
3077 | |||
3078 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel send connection ACKs on %s\n", | ||
3079 | GCT_2s (t)); | ||
3080 | |||
3081 | if (NULL == t) | ||
3082 | { | ||
3083 | GNUNET_break (0); | ||
3084 | return; | ||
3085 | } | ||
3086 | |||
3087 | if (CADET_TUNNEL_READY != t->cstate) | ||
3088 | return; | ||
3089 | |||
3090 | buffer = GCT_get_channels_buffer (t); | ||
3091 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer %u\n", buffer); | ||
3092 | |||
3093 | /* Count connections, how many messages are already allowed */ | ||
3094 | cs = GCT_count_connections (t); | ||
3095 | for (allowed = 0, iter = t->connection_head; NULL != iter; iter = iter->next) | ||
3096 | { | ||
3097 | allowed += get_connection_allowed (iter); | ||
3098 | } | ||
3099 | LOG (GNUNET_ERROR_TYPE_DEBUG, " allowed %u\n", allowed); | ||
3100 | |||
3101 | /* Make sure there is no overflow */ | ||
3102 | if (allowed > buffer) | ||
3103 | return; | ||
3104 | |||
3105 | /* Authorize connections to send more data */ | ||
3106 | to_allow = buffer - allowed; | ||
3107 | |||
3108 | for (iter = t->connection_head; | ||
3109 | NULL != iter && to_allow > 0; | ||
3110 | iter = iter->next) | ||
3111 | { | ||
3112 | if (CADET_CONNECTION_READY != GCC_get_state (iter->c) | ||
3113 | || get_connection_allowed (iter) > 64 / 3) | ||
3114 | { | ||
3115 | continue; | ||
3116 | } | ||
3117 | GNUNET_assert(cs != 0); | ||
3118 | allow_per_connection = to_allow/cs; | ||
3119 | to_allow -= allow_per_connection; | ||
3120 | cs--; | ||
3121 | GCC_allow (iter->c, allow_per_connection, | ||
3122 | GCC_is_origin (iter->c, GNUNET_NO)); | ||
3123 | } | ||
3124 | |||
3125 | if (0 != to_allow) | ||
3126 | { | ||
3127 | /* Since we don't allow if it's allowed to send 64/3, this can happen. */ | ||
3128 | LOG (GNUNET_ERROR_TYPE_DEBUG, " reminding to_allow: %u\n", to_allow); | ||
3129 | } | ||
3130 | } | ||
3131 | |||
3132 | |||
3133 | /** | ||
3134 | * Cancel a previously sent message while it's in the queue. | ||
3135 | * | ||
3136 | * ONLY can be called before the continuation given to the send function | ||
3137 | * is called. Once the continuation is called, the message is no longer in the | ||
3138 | * queue. | ||
3139 | * | ||
3140 | * @param q Handle to the queue. | ||
3141 | */ | ||
3142 | void | ||
3143 | GCT_cancel (struct CadetTunnelQueue *q) | ||
3144 | { | ||
3145 | if (NULL != q->cq) | ||
3146 | { | ||
3147 | GNUNET_assert (NULL == q->tqd); | ||
3148 | GCC_cancel (q->cq); | ||
3149 | /* tun_message_sent() will be called and free q */ | ||
3150 | } | ||
3151 | else if (NULL != q->tqd) | ||
3152 | { | ||
3153 | unqueue_data (q->tqd); | ||
3154 | q->tqd = NULL; | ||
3155 | if (NULL != q->cont) | ||
3156 | q->cont (q->cont_cls, NULL, q, 0, 0); | ||
3157 | GNUNET_free (q); | ||
3158 | } | ||
3159 | else | ||
3160 | { | ||
3161 | GNUNET_break (0); | ||
3162 | } | ||
3163 | } | ||
3164 | |||
3165 | |||
3166 | /** | ||
3167 | * Check if the tunnel has queued traffic. | ||
3168 | * | ||
3169 | * @param t Tunnel to check. | ||
3170 | * | ||
3171 | * @return #GNUNET_YES if there is queued traffic | ||
3172 | * #GNUNET_NO otherwise | ||
3173 | */ | ||
3174 | int | ||
3175 | GCT_has_queued_traffic (struct CadetTunnel *t) | ||
3176 | { | ||
3177 | return (NULL != t->tq_head) ? GNUNET_YES : GNUNET_NO; | ||
3178 | } | ||
3179 | |||
3180 | |||
3181 | /** | ||
3182 | * Sends an already built message on a tunnel, encrypting it and | ||
3183 | * choosing the best connection if not provided. | ||
3184 | * | ||
3185 | * @param message Message to send. Function modifies it. | ||
3186 | * @param t Tunnel on which this message is transmitted. | ||
3187 | * @param c Connection to use (autoselect if NULL). | ||
3188 | * @param force Force the tunnel to take the message (buffer overfill). | ||
3189 | * @param cont Continuation to call once message is really sent. | ||
3190 | * @param cont_cls Closure for @c cont. | ||
3191 | * | ||
3192 | * @return Handle to cancel message. NULL if @c cont is NULL. | ||
3193 | */ | ||
3194 | struct CadetTunnelQueue * | ||
3195 | GCT_send_prebuilt_message (const struct GNUNET_MessageHeader *message, | ||
3196 | struct CadetTunnel *t, | ||
3197 | struct CadetConnection *c, | ||
3198 | int force, GCT_sent cont, void *cont_cls) | ||
3199 | { | ||
3200 | return send_prebuilt_message (message, t, c, force, cont, cont_cls, NULL); | ||
3201 | } | ||
3202 | |||
3203 | |||
3204 | /** | ||
3205 | * Send a KX message. | ||
3206 | * | ||
3207 | * @param t Tunnel on which to send it. | ||
3208 | * @param force_reply Force the other peer to reply with a KX message. | ||
3209 | */ | ||
3210 | void | ||
3211 | GCT_send_kx (struct CadetTunnel *t, int force_reply) | ||
3212 | { | ||
3213 | static struct CadetEncryptedMessageIdentifier zero; | ||
3214 | struct CadetConnection *c; | ||
3215 | struct GNUNET_CADET_TunnelKeyExchangeMessage msg; | ||
3216 | enum GNUNET_CADET_KX_Flags flags; | ||
3217 | |||
3218 | LOG (GNUNET_ERROR_TYPE_INFO, "==> { KX} on %s\n", GCT_2s (t)); | ||
3219 | if (NULL != t->ephm_h) | ||
3220 | { | ||
3221 | LOG (GNUNET_ERROR_TYPE_INFO, " already queued, nop\n"); | ||
3222 | return; | ||
3223 | } | ||
3224 | GNUNET_assert (GNUNET_NO == GCT_is_loopback (t)); | ||
3225 | |||
3226 | c = tunnel_get_connection (t); | ||
3227 | if (NULL == c) | ||
3228 | { | ||
3229 | if (NULL == t->destroy_task && CADET_TUNNEL_READY == t->cstate) | ||
3230 | { | ||
3231 | GNUNET_break (0); | ||
3232 | GCT_debug (t, GNUNET_ERROR_TYPE_ERROR); | ||
3233 | } | ||
3234 | return; | ||
3235 | } | ||
3236 | |||
3237 | msg.header.size = htons (sizeof (msg)); | ||
3238 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); | ||
3239 | flags = GNUNET_CADET_KX_FLAG_NONE; | ||
3240 | if (GNUNET_YES == force_reply) | ||
3241 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; | ||
3242 | msg.flags = htonl (flags); | ||
3243 | msg.cid = *GCC_get_id (c); | ||
3244 | GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->kx_0, &msg.ephemeral_key); | ||
3245 | GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->DHRs, &msg.ratchet_key); | ||
3246 | |||
3247 | t->ephm_h = GCC_send_prebuilt_message (&msg.header, | ||
3248 | UINT16_MAX, | ||
3249 | zero, | ||
3250 | c, | ||
3251 | GCC_is_origin (c, GNUNET_YES), | ||
3252 | GNUNET_YES, &ephm_sent, t); | ||
3253 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | ||
3254 | GCT_change_estate (t, CADET_TUNNEL_KEY_AX_SENT); | ||
3255 | } | ||
3256 | |||
3257 | |||
3258 | /** | ||
3259 | * Is the tunnel directed towards the local peer? | ||
3260 | * | ||
3261 | * @param t Tunnel. | ||
3262 | * | ||
3263 | * @return #GNUNET_YES if it is loopback. | ||
3264 | */ | ||
3265 | int | ||
3266 | GCT_is_loopback (const struct CadetTunnel *t) | ||
3267 | { | ||
3268 | return (myid == GCP_get_short_id (t->peer)); | ||
3269 | } | ||
3270 | |||
3271 | |||
3272 | /** | ||
3273 | * Is the tunnel this path already? | ||
3274 | * | ||
3275 | * @param t Tunnel. | ||
3276 | * @param p Path. | ||
3277 | * | ||
3278 | * @return #GNUNET_YES a connection uses this path. | ||
3279 | */ | ||
3280 | int | ||
3281 | GCT_is_path_used (const struct CadetTunnel *t, const struct CadetPeerPath *p) | ||
3282 | { | ||
3283 | struct CadetTConnection *iter; | ||
3284 | |||
3285 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
3286 | if (path_equivalent (GCC_get_path (iter->c), p)) | ||
3287 | return GNUNET_YES; | ||
3288 | |||
3289 | return GNUNET_NO; | ||
3290 | } | ||
3291 | |||
3292 | |||
3293 | /** | ||
3294 | * Get a cost of a path for a tunnel considering existing connections. | ||
3295 | * | ||
3296 | * @param t Tunnel. | ||
3297 | * @param path Candidate path. | ||
3298 | * | ||
3299 | * @return Cost of the path (path length + number of overlapping nodes) | ||
3300 | */ | ||
3301 | unsigned int | ||
3302 | GCT_get_path_cost (const struct CadetTunnel *t, | ||
3303 | const struct CadetPeerPath *path) | ||
3304 | { | ||
3305 | struct CadetTConnection *iter; | ||
3306 | const struct CadetPeerPath *aux; | ||
3307 | unsigned int overlap; | ||
3308 | unsigned int i; | ||
3309 | unsigned int j; | ||
3310 | |||
3311 | if (NULL == path) | ||
3312 | return 0; | ||
3313 | |||
3314 | overlap = 0; | ||
3315 | GNUNET_assert (NULL != t); | ||
3316 | |||
3317 | for (i = 0; i < path->length; i++) | ||
3318 | { | ||
3319 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
3320 | { | ||
3321 | aux = GCC_get_path (iter->c); | ||
3322 | if (NULL == aux) | ||
3323 | continue; | ||
3324 | |||
3325 | for (j = 0; j < aux->length; j++) | ||
3326 | { | ||
3327 | if (path->peers[i] == aux->peers[j]) | ||
3328 | { | ||
3329 | overlap++; | ||
3330 | break; | ||
3331 | } | ||
3332 | } | ||
3333 | } | ||
3334 | } | ||
3335 | return path->length + overlap; | ||
3336 | } | ||
3337 | |||
3338 | |||
3339 | /** | ||
3340 | * Get the static string for the peer this tunnel is directed. | ||
3341 | * | ||
3342 | * @param t Tunnel. | ||
3343 | * | ||
3344 | * @return Static string the destination peer's ID. | ||
3345 | */ | ||
3346 | const char * | ||
3347 | GCT_2s (const struct CadetTunnel *t) | ||
3348 | { | ||
3349 | if (NULL == t) | ||
3350 | return "(NULL)"; | ||
3351 | |||
3352 | return GCP_2s (t->peer); | ||
3353 | } | ||
3354 | |||
3355 | |||
3356 | /******************************************************************************/ | ||
3357 | /***************************** INFO/DEBUG *******************************/ | ||
3358 | /******************************************************************************/ | ||
3359 | |||
3360 | static void | ||
3361 | ax_debug (const struct CadetTunnelAxolotl *ax, enum GNUNET_ErrorType level) | ||
3362 | { | ||
3363 | struct GNUNET_CRYPTO_EcdhePublicKey pub; | ||
3364 | struct CadetTunnelSkippedKey *iter; | ||
3365 | |||
3366 | LOG2 (level, "TTT RK \t %s\n", | ||
3367 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->RK)); | ||
3368 | |||
3369 | LOG2 (level, "TTT HKs \t %s\n", | ||
3370 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKs)); | ||
3371 | LOG2 (level, "TTT HKr \t %s\n", | ||
3372 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKr)); | ||
3373 | LOG2 (level, "TTT NHKs\t %s\n", | ||
3374 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->NHKs)); | ||
3375 | LOG2 (level, "TTT NHKr\t %s\n", | ||
3376 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->NHKr)); | ||
3377 | |||
3378 | LOG2 (level, "TTT CKs \t %s\n", | ||
3379 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKs)); | ||
3380 | LOG2 (level, "TTT CKr \t %s\n", | ||
3381 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKr)); | ||
3382 | |||
3383 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, &pub); | ||
3384 | LOG2 (level, "TTT DHRs\t %s\n", | ||
3385 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &pub)); | ||
3386 | LOG2 (level, "TTT DHRr\t %s\n", | ||
3387 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->DHRr)); | ||
3388 | |||
3389 | LOG2 (level, "TTT Nr\t %u\tNs\t%u\n", ax->Nr, ax->Ns); | ||
3390 | LOG2 (level, "TTT PNs\t %u\tSkipped\t%u\n", ax->PNs, ax->skipped); | ||
3391 | LOG2 (level, "TTT Ratchet\t%u\n", ax->ratchet_flag); | ||
3392 | |||
3393 | for (iter = ax->skipped_head; NULL != iter; iter = iter->next) | ||
3394 | { | ||
3395 | LOG2 (level, "TTT HK\t %s\n", | ||
3396 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &iter->HK)); | ||
3397 | LOG2 (level, "TTT MK\t %s\n", | ||
3398 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) &iter->MK)); | ||
3399 | } | ||
3400 | } | ||
3401 | |||
3402 | /** | ||
3403 | * Log all possible info about the tunnel state. | ||
3404 | * | ||
3405 | * @param t Tunnel to debug. | ||
3406 | * @param level Debug level to use. | ||
3407 | */ | ||
3408 | void | ||
3409 | GCT_debug (const struct CadetTunnel *t, enum GNUNET_ErrorType level) | ||
3410 | { | ||
3411 | struct CadetTChannel *iter_ch; | ||
3412 | struct CadetTConnection *iter_c; | ||
3413 | int do_log; | ||
3414 | |||
3415 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), | ||
3416 | "cadet-tun", | ||
3417 | __FILE__, __FUNCTION__, __LINE__); | ||
3418 | if (0 == do_log) | ||
3419 | return; | ||
3420 | |||
3421 | LOG2 (level, "TTT DEBUG TUNNEL TOWARDS %s\n", GCT_2s (t)); | ||
3422 | LOG2 (level, "TTT cstate %s, estate %s\n", | ||
3423 | cstate2s (t->cstate), estate2s (t->estate)); | ||
3424 | #if DUMP_KEYS_TO_STDERR | ||
3425 | ax_debug (t->ax, level); | ||
3426 | #endif | ||
3427 | LOG2 (level, "TTT tq_head %p, tq_tail %p\n", t->tq_head, t->tq_tail); | ||
3428 | LOG2 (level, "TTT destroy %p\n", t->destroy_task); | ||
3429 | LOG2 (level, "TTT channels:\n"); | ||
3430 | for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next) | ||
3431 | { | ||
3432 | GCCH_debug (iter_ch->ch, level); | ||
3433 | } | ||
3434 | |||
3435 | LOG2 (level, "TTT connections:\n"); | ||
3436 | for (iter_c = t->connection_head; NULL != iter_c; iter_c = iter_c->next) | ||
3437 | { | ||
3438 | GCC_debug (iter_c->c, level); | ||
3439 | } | ||
3440 | |||
3441 | LOG2 (level, "TTT DEBUG TUNNEL END\n"); | ||
3442 | } | ||
3443 | |||
3444 | |||
3445 | /** | ||
3446 | * Iterate all tunnels. | ||
3447 | * | ||
3448 | * @param iter Iterator. | ||
3449 | * @param cls Closure for @c iter. | ||
3450 | */ | ||
3451 | void | ||
3452 | GCT_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls) | ||
3453 | { | ||
3454 | GNUNET_CONTAINER_multipeermap_iterate (tunnels, iter, cls); | ||
3455 | } | ||
3456 | |||
3457 | |||
3458 | /** | ||
3459 | * Count all tunnels. | ||
3460 | * | ||
3461 | * @return Number of tunnels to remote peers kept by this peer. | ||
3462 | */ | ||
3463 | unsigned int | ||
3464 | GCT_count_all (void) | ||
3465 | { | ||
3466 | return GNUNET_CONTAINER_multipeermap_size (tunnels); | ||
3467 | } | ||
3468 | |||
3469 | |||
3470 | /** | ||
3471 | * Iterate all connections of a tunnel. | ||
3472 | * | ||
3473 | * @param t Tunnel whose connections to iterate. | ||
3474 | * @param iter Iterator. | ||
3475 | * @param cls Closure for @c iter. | ||
3476 | */ | ||
3477 | void | ||
3478 | GCT_iterate_connections (struct CadetTunnel *t, GCT_conn_iter iter, void *cls) | ||
3479 | { | ||
3480 | struct CadetTConnection *ct; | ||
3481 | |||
3482 | for (ct = t->connection_head; NULL != ct; ct = ct->next) | ||
3483 | iter (cls, ct->c); | ||
3484 | } | ||
3485 | |||
3486 | |||
3487 | /** | ||
3488 | * Iterate all channels of a tunnel. | ||
3489 | * | ||
3490 | * @param t Tunnel whose channels to iterate. | ||
3491 | * @param iter Iterator. | ||
3492 | * @param cls Closure for @c iter. | ||
3493 | */ | ||
3494 | void | ||
3495 | GCT_iterate_channels (struct CadetTunnel *t, GCT_chan_iter iter, void *cls) | ||
3496 | { | ||
3497 | struct CadetTChannel *cht; | ||
3498 | |||
3499 | for (cht = t->channel_head; NULL != cht; cht = cht->next) | ||
3500 | iter (cls, cht->ch); | ||
3501 | } | ||