diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet_tunnel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnel.c | 2887 |
1 files changed, 2887 insertions, 0 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c new file mode 100644 index 000000000..f2be27bf5 --- /dev/null +++ b/src/cadet/gnunet-service-cadet_tunnel.c | |||
@@ -0,0 +1,2887 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2013 Christian Grothoff (and other contributing authors) | ||
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., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include "platform.h" | ||
22 | #include "gnunet_util_lib.h" | ||
23 | |||
24 | #include "gnunet_signatures.h" | ||
25 | #include "gnunet_statistics_service.h" | ||
26 | |||
27 | #include "cadet_protocol.h" | ||
28 | #include "cadet_path.h" | ||
29 | |||
30 | #include "gnunet-service-cadet_tunnel.h" | ||
31 | #include "gnunet-service-cadet_connection.h" | ||
32 | #include "gnunet-service-cadet_channel.h" | ||
33 | #include "gnunet-service-cadet_peer.h" | ||
34 | |||
35 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-tun",__VA_ARGS__) | ||
36 | |||
37 | #define REKEY_WAIT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5) | ||
38 | |||
39 | #define CONNECTIONS_PER_TUNNEL 3 | ||
40 | |||
41 | /******************************************************************************/ | ||
42 | /******************************** STRUCTS **********************************/ | ||
43 | /******************************************************************************/ | ||
44 | |||
45 | struct CadetTChannel | ||
46 | { | ||
47 | struct CadetTChannel *next; | ||
48 | struct CadetTChannel *prev; | ||
49 | struct CadetChannel *ch; | ||
50 | }; | ||
51 | |||
52 | |||
53 | /** | ||
54 | * Connection list and metadata. | ||
55 | */ | ||
56 | struct CadetTConnection | ||
57 | { | ||
58 | /** | ||
59 | * Next in DLL. | ||
60 | */ | ||
61 | struct CadetTConnection *next; | ||
62 | |||
63 | /** | ||
64 | * Prev in DLL. | ||
65 | */ | ||
66 | struct CadetTConnection *prev; | ||
67 | |||
68 | /** | ||
69 | * Connection handle. | ||
70 | */ | ||
71 | struct CadetConnection *c; | ||
72 | |||
73 | /** | ||
74 | * Creation time, to keep oldest connection alive. | ||
75 | */ | ||
76 | struct GNUNET_TIME_Absolute created; | ||
77 | |||
78 | /** | ||
79 | * Connection throughput, to keep fastest connection alive. | ||
80 | */ | ||
81 | uint32_t throughput; | ||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * Structure used during a Key eXchange. | ||
86 | */ | ||
87 | struct CadetTunnelKXCtx | ||
88 | { | ||
89 | /** | ||
90 | * Decryption ("their") old key, for decrypting traffic sent by the | ||
91 | * other end before the key exchange started. | ||
92 | */ | ||
93 | struct GNUNET_CRYPTO_SymmetricSessionKey d_key_old; | ||
94 | |||
95 | /** | ||
96 | * Challenge to send in a ping and expect in the pong. | ||
97 | */ | ||
98 | uint32_t challenge; | ||
99 | }; | ||
100 | |||
101 | /** | ||
102 | * Struct containing all information regarding a tunnel to a peer. | ||
103 | */ | ||
104 | struct CadetTunnel3 | ||
105 | { | ||
106 | /** | ||
107 | * Endpoint of the tunnel. | ||
108 | */ | ||
109 | struct CadetPeer *peer; | ||
110 | |||
111 | /** | ||
112 | * State of the tunnel connectivity. | ||
113 | */ | ||
114 | enum CadetTunnel3CState cstate; | ||
115 | |||
116 | /** | ||
117 | * State of the tunnel encryption. | ||
118 | */ | ||
119 | enum CadetTunnel3EState estate; | ||
120 | |||
121 | /** | ||
122 | * Key eXchange context. | ||
123 | */ | ||
124 | struct CadetTunnelKXCtx *kx_ctx; | ||
125 | |||
126 | /** | ||
127 | * Encryption ("our") key. | ||
128 | */ | ||
129 | struct GNUNET_CRYPTO_SymmetricSessionKey e_key; | ||
130 | |||
131 | /** | ||
132 | * Decryption ("their") key. | ||
133 | */ | ||
134 | struct GNUNET_CRYPTO_SymmetricSessionKey d_key; | ||
135 | |||
136 | /** | ||
137 | * Task to start the rekey process. | ||
138 | */ | ||
139 | GNUNET_SCHEDULER_TaskIdentifier rekey_task; | ||
140 | |||
141 | /** | ||
142 | * Paths that are actively used to reach the destination peer. | ||
143 | */ | ||
144 | struct CadetTConnection *connection_head; | ||
145 | struct CadetTConnection *connection_tail; | ||
146 | |||
147 | /** | ||
148 | * Next connection number. | ||
149 | */ | ||
150 | uint32_t next_cid; | ||
151 | |||
152 | /** | ||
153 | * Channels inside this tunnel. | ||
154 | */ | ||
155 | struct CadetTChannel *channel_head; | ||
156 | struct CadetTChannel *channel_tail; | ||
157 | |||
158 | /** | ||
159 | * Channel ID for the next created channel. | ||
160 | */ | ||
161 | CADET_ChannelNumber next_chid; | ||
162 | |||
163 | /** | ||
164 | * Destroy flag: if true, destroy on last message. | ||
165 | */ | ||
166 | GNUNET_SCHEDULER_TaskIdentifier destroy_task; | ||
167 | |||
168 | /** | ||
169 | * Queued messages, to transmit once tunnel gets connected. | ||
170 | */ | ||
171 | struct CadetTunnelDelayed *tq_head; | ||
172 | struct CadetTunnelDelayed *tq_tail; | ||
173 | }; | ||
174 | |||
175 | |||
176 | /** | ||
177 | * Struct used to save messages in a non-ready tunnel to send once connected. | ||
178 | */ | ||
179 | struct CadetTunnelDelayed | ||
180 | { | ||
181 | /** | ||
182 | * DLL | ||
183 | */ | ||
184 | struct CadetTunnelDelayed *next; | ||
185 | struct CadetTunnelDelayed *prev; | ||
186 | |||
187 | /** | ||
188 | * Tunnel. | ||
189 | */ | ||
190 | struct CadetTunnel3 *t; | ||
191 | |||
192 | /** | ||
193 | * Tunnel queue given to the channel to cancel request. Update on send_queued. | ||
194 | */ | ||
195 | struct CadetTunnel3Queue *tq; | ||
196 | |||
197 | /** | ||
198 | * Message to send. | ||
199 | */ | ||
200 | /* struct GNUNET_MessageHeader *msg; */ | ||
201 | }; | ||
202 | |||
203 | |||
204 | /** | ||
205 | * Handle for messages queued but not yet sent. | ||
206 | */ | ||
207 | struct CadetTunnel3Queue | ||
208 | { | ||
209 | /** | ||
210 | * Connection queue handle, to cancel if necessary. | ||
211 | */ | ||
212 | struct CadetConnectionQueue *cq; | ||
213 | |||
214 | /** | ||
215 | * Handle in case message hasn't been given to a connection yet. | ||
216 | */ | ||
217 | struct CadetTunnelDelayed *tqd; | ||
218 | |||
219 | /** | ||
220 | * Continuation to call once sent. | ||
221 | */ | ||
222 | GMT_sent cont; | ||
223 | |||
224 | /** | ||
225 | * Closure for @c cont. | ||
226 | */ | ||
227 | void *cont_cls; | ||
228 | }; | ||
229 | |||
230 | |||
231 | /******************************************************************************/ | ||
232 | /******************************* GLOBALS ***********************************/ | ||
233 | /******************************************************************************/ | ||
234 | |||
235 | /** | ||
236 | * Global handle to the statistics service. | ||
237 | */ | ||
238 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
239 | |||
240 | /** | ||
241 | * Local peer own ID (memory efficient handle). | ||
242 | */ | ||
243 | extern GNUNET_PEER_Id myid; | ||
244 | |||
245 | /** | ||
246 | * Local peer own ID (full value). | ||
247 | */ | ||
248 | extern struct GNUNET_PeerIdentity my_full_id; | ||
249 | |||
250 | |||
251 | /** | ||
252 | * Don't try to recover tunnels if shutting down. | ||
253 | */ | ||
254 | extern int shutting_down; | ||
255 | |||
256 | |||
257 | /** | ||
258 | * Set of all tunnels, in order to trigger a new exchange on rekey. | ||
259 | * Indexed by peer's ID. | ||
260 | */ | ||
261 | static struct GNUNET_CONTAINER_MultiPeerMap *tunnels; | ||
262 | |||
263 | /** | ||
264 | * Default TTL for payload packets. | ||
265 | */ | ||
266 | static unsigned long long default_ttl; | ||
267 | |||
268 | /** | ||
269 | * Own private key. | ||
270 | */ | ||
271 | const static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; | ||
272 | |||
273 | /** | ||
274 | * Own ephemeral private key. | ||
275 | */ | ||
276 | static struct GNUNET_CRYPTO_EcdhePrivateKey *my_ephemeral_key; | ||
277 | |||
278 | /** | ||
279 | * Cached message used to perform a key exchange. | ||
280 | */ | ||
281 | static struct GNUNET_CADET_KX_Ephemeral kx_msg; | ||
282 | |||
283 | /** | ||
284 | * Task to generate a new ephemeral key. | ||
285 | */ | ||
286 | static GNUNET_SCHEDULER_TaskIdentifier rekey_task; | ||
287 | |||
288 | /** | ||
289 | * Rekey period. | ||
290 | */ | ||
291 | static struct GNUNET_TIME_Relative rekey_period; | ||
292 | |||
293 | /******************************************************************************/ | ||
294 | /******************************** STATIC ***********************************/ | ||
295 | /******************************************************************************/ | ||
296 | |||
297 | /** | ||
298 | * Get string description for tunnel connectivity state. | ||
299 | * | ||
300 | * @param cs Tunnel state. | ||
301 | * | ||
302 | * @return String representation. | ||
303 | */ | ||
304 | static const char * | ||
305 | cstate2s (enum CadetTunnel3CState cs) | ||
306 | { | ||
307 | static char buf[128]; | ||
308 | |||
309 | switch (cs) | ||
310 | { | ||
311 | case CADET_TUNNEL3_NEW: | ||
312 | return "CADET_TUNNEL3_NEW"; | ||
313 | case CADET_TUNNEL3_SEARCHING: | ||
314 | return "CADET_TUNNEL3_SEARCHING"; | ||
315 | case CADET_TUNNEL3_WAITING: | ||
316 | return "CADET_TUNNEL3_WAITING"; | ||
317 | case CADET_TUNNEL3_READY: | ||
318 | return "CADET_TUNNEL3_READY"; | ||
319 | |||
320 | default: | ||
321 | sprintf (buf, "%u (UNKNOWN STATE)", cs); | ||
322 | return buf; | ||
323 | } | ||
324 | return ""; | ||
325 | } | ||
326 | |||
327 | |||
328 | /** | ||
329 | * Get string description for tunnel encryption state. | ||
330 | * | ||
331 | * @param es Tunnel state. | ||
332 | * | ||
333 | * @return String representation. | ||
334 | */ | ||
335 | static const char * | ||
336 | estate2s (enum CadetTunnel3EState es) | ||
337 | { | ||
338 | static char buf[128]; | ||
339 | |||
340 | switch (es) | ||
341 | { | ||
342 | case CADET_TUNNEL3_KEY_UNINITIALIZED: | ||
343 | return "CADET_TUNNEL3_KEY_UNINITIALIZED"; | ||
344 | case CADET_TUNNEL3_KEY_SENT: | ||
345 | return "CADET_TUNNEL3_KEY_SENT"; | ||
346 | case CADET_TUNNEL3_KEY_PING: | ||
347 | return "CADET_TUNNEL3_KEY_PING"; | ||
348 | case CADET_TUNNEL3_KEY_OK: | ||
349 | return "CADET_TUNNEL3_KEY_OK"; | ||
350 | |||
351 | default: | ||
352 | sprintf (buf, "%u (UNKNOWN STATE)", es); | ||
353 | return buf; | ||
354 | } | ||
355 | return ""; | ||
356 | } | ||
357 | |||
358 | |||
359 | /** | ||
360 | * @brief Check if tunnel is ready to send traffic. | ||
361 | * | ||
362 | * Tunnel must be connected and with encryption correctly set up. | ||
363 | * | ||
364 | * @param t Tunnel to check. | ||
365 | * | ||
366 | * @return #GNUNET_YES if ready, #GNUNET_NO otherwise | ||
367 | */ | ||
368 | static int | ||
369 | is_ready (struct CadetTunnel3 *t) | ||
370 | { | ||
371 | int ready; | ||
372 | |||
373 | GMT_debug (t); | ||
374 | ready = (CADET_TUNNEL3_READY == t->cstate && CADET_TUNNEL3_KEY_OK == t->estate); | ||
375 | ready = ready || GMT_is_loopback (t); | ||
376 | return ready; | ||
377 | } | ||
378 | |||
379 | |||
380 | /** | ||
381 | * Ephemeral key message purpose size. | ||
382 | * | ||
383 | * @return Size of the part of the ephemeral key message that must be signed. | ||
384 | */ | ||
385 | size_t | ||
386 | ephemeral_purpose_size (void) | ||
387 | { | ||
388 | return sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
389 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | ||
390 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | ||
391 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + | ||
392 | sizeof (struct GNUNET_PeerIdentity); | ||
393 | } | ||
394 | |||
395 | |||
396 | /** | ||
397 | * Size of the encrypted part of a ping message. | ||
398 | * | ||
399 | * @return Size of the encrypted part of a ping message. | ||
400 | */ | ||
401 | size_t | ||
402 | ping_encryption_size (void) | ||
403 | { | ||
404 | return sizeof (struct GNUNET_PeerIdentity) + sizeof (uint32_t); | ||
405 | } | ||
406 | |||
407 | |||
408 | /** | ||
409 | * Get the channel's buffer. ONLY FOR NON-LOOPBACK CHANNELS!! | ||
410 | * | ||
411 | * @param tch Tunnel's channel handle. | ||
412 | * | ||
413 | * @return Amount of messages the channel can still buffer towards the client. | ||
414 | */ | ||
415 | static unsigned int | ||
416 | get_channel_buffer (const struct CadetTChannel *tch) | ||
417 | { | ||
418 | int fwd; | ||
419 | |||
420 | /* If channel is outgoing, is origin in the FWD direction and fwd is YES */ | ||
421 | fwd = GMCH_is_origin (tch->ch, GNUNET_YES); | ||
422 | |||
423 | return GMCH_get_buffer (tch->ch, fwd); | ||
424 | } | ||
425 | |||
426 | |||
427 | /** | ||
428 | * Get the channel's allowance status. | ||
429 | * | ||
430 | * @param tch Tunnel's channel handle. | ||
431 | * | ||
432 | * @return #GNUNET_YES if we allowed the client to send data to us. | ||
433 | */ | ||
434 | static int | ||
435 | get_channel_allowed (const struct CadetTChannel *tch) | ||
436 | { | ||
437 | int fwd; | ||
438 | |||
439 | /* If channel is outgoing, is origin in the FWD direction and fwd is YES */ | ||
440 | fwd = GMCH_is_origin (tch->ch, GNUNET_YES); | ||
441 | |||
442 | return GMCH_get_allowed (tch->ch, fwd); | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * Get the connection's buffer. | ||
448 | * | ||
449 | * @param tc Tunnel's connection handle. | ||
450 | * | ||
451 | * @return Amount of messages the connection can still buffer. | ||
452 | */ | ||
453 | static unsigned int | ||
454 | get_connection_buffer (const struct CadetTConnection *tc) | ||
455 | { | ||
456 | int fwd; | ||
457 | |||
458 | /* If connection is outgoing, is origin in the FWD direction and fwd is YES */ | ||
459 | fwd = GMC_is_origin (tc->c, GNUNET_YES); | ||
460 | |||
461 | return GMC_get_buffer (tc->c, fwd); | ||
462 | } | ||
463 | |||
464 | |||
465 | /** | ||
466 | * Get the connection's allowance. | ||
467 | * | ||
468 | * @param tc Tunnel's connection handle. | ||
469 | * | ||
470 | * @return Amount of messages we have allowed the next peer to send us. | ||
471 | */ | ||
472 | static unsigned int | ||
473 | get_connection_allowed (const struct CadetTConnection *tc) | ||
474 | { | ||
475 | int fwd; | ||
476 | |||
477 | /* If connection is outgoing, is origin in the FWD direction and fwd is YES */ | ||
478 | fwd = GMC_is_origin (tc->c, GNUNET_YES); | ||
479 | |||
480 | return GMC_get_allowed (tc->c, fwd); | ||
481 | } | ||
482 | |||
483 | |||
484 | /** | ||
485 | * Check that a ephemeral key message s well formed and correctly signed. | ||
486 | * | ||
487 | * @param t Tunnel on which the message came. | ||
488 | * @param msg The ephemeral key message. | ||
489 | * | ||
490 | * @return GNUNET_OK if message is fine, GNUNET_SYSERR otherwise. | ||
491 | */ | ||
492 | int | ||
493 | check_ephemeral (struct CadetTunnel3 *t, | ||
494 | const struct GNUNET_CADET_KX_Ephemeral *msg) | ||
495 | { | ||
496 | /* Check message size */ | ||
497 | if (ntohs (msg->header.size) != sizeof (struct GNUNET_CADET_KX_Ephemeral)) | ||
498 | return GNUNET_SYSERR; | ||
499 | |||
500 | /* Check signature size */ | ||
501 | if (ntohl (msg->purpose.size) != ephemeral_purpose_size ()) | ||
502 | return GNUNET_SYSERR; | ||
503 | |||
504 | /* Check origin */ | ||
505 | if (0 != memcmp (&msg->origin_identity, | ||
506 | GMP_get_id (t->peer), | ||
507 | sizeof (struct GNUNET_PeerIdentity))) | ||
508 | return GNUNET_SYSERR; | ||
509 | |||
510 | /* Check signature */ | ||
511 | if (GNUNET_OK != | ||
512 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_CADET_KX, | ||
513 | &msg->purpose, | ||
514 | &msg->signature, | ||
515 | &msg->origin_identity.public_key)) | ||
516 | return GNUNET_SYSERR; | ||
517 | |||
518 | return GNUNET_OK; | ||
519 | } | ||
520 | |||
521 | |||
522 | /** | ||
523 | * Encrypt data with the tunnel key. | ||
524 | * | ||
525 | * @param t Tunnel whose key to use. | ||
526 | * @param dst Destination for the encrypted data. | ||
527 | * @param src Source of the plaintext. Can overlap with @c dst. | ||
528 | * @param size Size of the plaintext. | ||
529 | * @param iv Initialization Vector to use. | ||
530 | */ | ||
531 | static int | ||
532 | t_encrypt (struct CadetTunnel3 *t, | ||
533 | void *dst, const void *src, | ||
534 | size_t size, uint32_t iv) | ||
535 | { | ||
536 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; | ||
537 | size_t out_size; | ||
538 | |||
539 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt start\n"); | ||
540 | GNUNET_CRYPTO_symmetric_derive_iv (&siv, &t->e_key, &iv, sizeof (iv), NULL); | ||
541 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt IV derived\n"); | ||
542 | out_size = GNUNET_CRYPTO_symmetric_encrypt (src, size, &t->e_key, &siv, dst); | ||
543 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt end\n"); | ||
544 | |||
545 | return out_size; | ||
546 | } | ||
547 | |||
548 | |||
549 | /** | ||
550 | * Decrypt data with the tunnel key. | ||
551 | * | ||
552 | * @param t Tunnel whose key to use. | ||
553 | * @param dst Destination for the plaintext. | ||
554 | * @param src Source of the encrypted data. Can overlap with @c dst. | ||
555 | * @param size Size of the encrypted data. | ||
556 | * @param iv Initialization Vector to use. | ||
557 | */ | ||
558 | static int | ||
559 | t_decrypt (struct CadetTunnel3 *t, | ||
560 | void *dst, const void *src, | ||
561 | size_t size, uint32_t iv) | ||
562 | { | ||
563 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; | ||
564 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; | ||
565 | size_t out_size; | ||
566 | |||
567 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt start\n"); | ||
568 | if (t->estate == CADET_TUNNEL3_KEY_OK || t->estate == CADET_TUNNEL3_KEY_PING) | ||
569 | { | ||
570 | key = &t->d_key; | ||
571 | } | ||
572 | else if (NULL != t->kx_ctx) | ||
573 | { | ||
574 | key = &t->kx_ctx->d_key_old; | ||
575 | } | ||
576 | else | ||
577 | { | ||
578 | GNUNET_STATISTICS_update (stats, "# non decryptable data", 1, GNUNET_NO); | ||
579 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
580 | "WARNING got data on %s without a valid key\n", | ||
581 | GMT_2s (t)); | ||
582 | GMT_debug (t); | ||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt iv\n"); | ||
587 | GNUNET_CRYPTO_symmetric_derive_iv (&siv, key, &iv, sizeof (iv), NULL); | ||
588 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt iv done\n"); | ||
589 | out_size = GNUNET_CRYPTO_symmetric_decrypt (src, size, key, &siv, dst); | ||
590 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt end\n"); | ||
591 | |||
592 | return out_size; | ||
593 | } | ||
594 | |||
595 | |||
596 | /** | ||
597 | * Create key material by doing ECDH on the local and remote ephemeral keys. | ||
598 | * | ||
599 | * @param key_material Where to store the key material. | ||
600 | * @param ephemeral_key Peer's public ephemeral key. | ||
601 | */ | ||
602 | void | ||
603 | derive_key_material (struct GNUNET_HashCode *key_material, | ||
604 | const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key) | ||
605 | { | ||
606 | if (GNUNET_OK != | ||
607 | GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key, | ||
608 | ephemeral_key, | ||
609 | key_material)) | ||
610 | { | ||
611 | GNUNET_break (0); | ||
612 | } | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * Create a symmetic key from the identities of both ends and the key material | ||
617 | * from ECDH. | ||
618 | * | ||
619 | * @param key Destination for the generated key. | ||
620 | * @param sender ID of the peer that will encrypt with @c key. | ||
621 | * @param receiver ID of the peer that will decrypt with @c key. | ||
622 | * @param key_material Hash created with ECDH with the ephemeral keys. | ||
623 | */ | ||
624 | void | ||
625 | derive_symmertic (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
626 | const struct GNUNET_PeerIdentity *sender, | ||
627 | const struct GNUNET_PeerIdentity *receiver, | ||
628 | const struct GNUNET_HashCode *key_material) | ||
629 | { | ||
630 | const char salt[] = "CADET kx salt"; | ||
631 | |||
632 | GNUNET_CRYPTO_kdf (key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
633 | salt, sizeof (salt), | ||
634 | key_material, sizeof (struct GNUNET_HashCode), | ||
635 | sender, sizeof (struct GNUNET_PeerIdentity), | ||
636 | receiver, sizeof (struct GNUNET_PeerIdentity), | ||
637 | NULL); | ||
638 | } | ||
639 | |||
640 | /** | ||
641 | * Pick a connection on which send the next data message. | ||
642 | * | ||
643 | * @param t Tunnel on which to send the message. | ||
644 | * | ||
645 | * @return The connection on which to send the next message. | ||
646 | */ | ||
647 | static struct CadetConnection * | ||
648 | tunnel_get_connection (struct CadetTunnel3 *t) | ||
649 | { | ||
650 | struct CadetTConnection *iter; | ||
651 | struct CadetConnection *best; | ||
652 | unsigned int qn; | ||
653 | unsigned int lowest_q; | ||
654 | |||
655 | LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GMT_2s (t)); | ||
656 | best = NULL; | ||
657 | lowest_q = UINT_MAX; | ||
658 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
659 | { | ||
660 | LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n", | ||
661 | GMC_2s (iter->c), GMC_get_state (iter->c)); | ||
662 | if (CADET_CONNECTION_READY == GMC_get_state (iter->c)) | ||
663 | { | ||
664 | qn = GMC_get_qn (iter->c, GMC_is_origin (iter->c, GNUNET_YES)); | ||
665 | LOG (GNUNET_ERROR_TYPE_DEBUG, " q_n %u, \n", qn); | ||
666 | if (qn < lowest_q) | ||
667 | { | ||
668 | best = iter->c; | ||
669 | lowest_q = qn; | ||
670 | } | ||
671 | } | ||
672 | } | ||
673 | LOG (GNUNET_ERROR_TYPE_DEBUG, " selected: connection %s\n", GMC_2s (best)); | ||
674 | return best; | ||
675 | } | ||
676 | |||
677 | |||
678 | /** | ||
679 | * Callback called when a queued message is sent. | ||
680 | * | ||
681 | * Calculates the average time and connection packet tracking. | ||
682 | * | ||
683 | * @param cls Closure (TunnelQueue handle). | ||
684 | * @param c Connection this message was on. | ||
685 | * @param q Connection queue handle (unused). | ||
686 | * @param type Type of message sent. | ||
687 | * @param fwd Was this a FWD going message? | ||
688 | * @param size Size of the message. | ||
689 | */ | ||
690 | static void | ||
691 | tun_message_sent (void *cls, | ||
692 | struct CadetConnection *c, | ||
693 | struct CadetConnectionQueue *q, | ||
694 | uint16_t type, int fwd, size_t size) | ||
695 | { | ||
696 | struct CadetTunnel3Queue *qt = cls; | ||
697 | struct CadetTunnel3 *t; | ||
698 | |||
699 | LOG (GNUNET_ERROR_TYPE_DEBUG, "tun_message_sent\n"); | ||
700 | |||
701 | GNUNET_assert (NULL != qt->cont); | ||
702 | t = NULL == c ? NULL : GMC_get_tunnel (c); | ||
703 | qt->cont (qt->cont_cls, t, qt, type, size); | ||
704 | GNUNET_free (qt); | ||
705 | } | ||
706 | |||
707 | |||
708 | /** | ||
709 | * Delete a queued message: either was sent or the channel was destroyed | ||
710 | * before the tunnel's key exchange had a chance to finish. | ||
711 | * | ||
712 | * @param tqd Delayed queue handle. | ||
713 | */ | ||
714 | static void | ||
715 | unqueue_data (struct CadetTunnelDelayed *tqd) | ||
716 | { | ||
717 | GNUNET_CONTAINER_DLL_remove (tqd->t->tq_head, tqd->t->tq_tail, tqd); | ||
718 | GNUNET_free (tqd); | ||
719 | } | ||
720 | |||
721 | |||
722 | /** | ||
723 | * Cache a message to be sent once tunnel is online. | ||
724 | * | ||
725 | * @param t Tunnel to hold the message. | ||
726 | * @param msg Message itself (copy will be made). | ||
727 | */ | ||
728 | static struct CadetTunnelDelayed * | ||
729 | queue_data (struct CadetTunnel3 *t, const struct GNUNET_MessageHeader *msg) | ||
730 | { | ||
731 | struct CadetTunnelDelayed *tqd; | ||
732 | uint16_t size = ntohs (msg->size); | ||
733 | |||
734 | LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GMT_2s (t)); | ||
735 | |||
736 | if (GNUNET_YES == is_ready (t)) | ||
737 | { | ||
738 | GNUNET_break (0); | ||
739 | return NULL; | ||
740 | } | ||
741 | |||
742 | tqd = GNUNET_malloc (sizeof (struct CadetTunnelDelayed) + size); | ||
743 | |||
744 | tqd->t = t; | ||
745 | memcpy (&tqd[1], msg, size); | ||
746 | GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tqd); | ||
747 | return tqd; | ||
748 | } | ||
749 | |||
750 | |||
751 | /** | ||
752 | * Calculate HMAC. | ||
753 | * | ||
754 | * @param t Tunnel to get keys from. | ||
755 | * @param plaintext Content to HMAC. | ||
756 | * @param size Size of @c plaintext. | ||
757 | * @param iv Initialization vector for the message. | ||
758 | * @param outgoing Is this an outgoing message that we encrypted? | ||
759 | * @param hmac Destination to store the HMAC. | ||
760 | */ | ||
761 | static void | ||
762 | t_hmac (struct CadetTunnel3 *t, const void *plaintext, size_t size, uint32_t iv, | ||
763 | int outgoing, struct GNUNET_CADET_Hash *hmac) | ||
764 | { | ||
765 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
766 | static const char ctx[] = "cadet authentication key"; | ||
767 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; | ||
768 | struct GNUNET_HashCode hash; | ||
769 | |||
770 | key = outgoing ? &t->e_key : &t->d_key; | ||
771 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, key, | ||
772 | &iv, sizeof (iv), | ||
773 | key, sizeof (*key), | ||
774 | ctx, sizeof (ctx), | ||
775 | NULL); | ||
776 | GNUNET_CRYPTO_hmac (&auth_key, plaintext, size, &hash); | ||
777 | memcpy (hmac, &hash, sizeof (*hmac)); | ||
778 | } | ||
779 | |||
780 | |||
781 | /** | ||
782 | * Sends an already built message on a tunnel, encrypting it and | ||
783 | * choosing the best connection. | ||
784 | * | ||
785 | * @param message Message to send. Function modifies it. | ||
786 | * @param t Tunnel on which this message is transmitted. | ||
787 | * @param c Connection to use (autoselect if NULL). | ||
788 | * @param force Force the tunnel to take the message (buffer overfill). | ||
789 | * @param cont Continuation to call once message is really sent. | ||
790 | * @param cont_cls Closure for @c cont. | ||
791 | * @param existing_q In case this a transmission of previously queued data, | ||
792 | * this should be TunnelQueue given to the client. | ||
793 | * Otherwise, NULL. | ||
794 | * | ||
795 | * @return Handle to cancel message. NULL if @c cont is NULL. | ||
796 | */ | ||
797 | static struct CadetTunnel3Queue * | ||
798 | send_prebuilt_message (const struct GNUNET_MessageHeader *message, | ||
799 | struct CadetTunnel3 *t, struct CadetConnection *c, | ||
800 | int force, GMT_sent cont, void *cont_cls, | ||
801 | struct CadetTunnel3Queue *existing_q) | ||
802 | { | ||
803 | struct CadetTunnel3Queue *tq; | ||
804 | struct GNUNET_CADET_Encrypted *msg; | ||
805 | size_t size = ntohs (message->size); | ||
806 | char cbuf[sizeof (struct GNUNET_CADET_Encrypted) + size]; | ||
807 | uint32_t mid; | ||
808 | uint32_t iv; | ||
809 | uint16_t type; | ||
810 | int fwd; | ||
811 | |||
812 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t)); | ||
813 | |||
814 | if (GNUNET_NO == is_ready (t)) | ||
815 | { | ||
816 | struct CadetTunnelDelayed *tqd; | ||
817 | /* A non null existing_q indicates sending of queued data. | ||
818 | * Should only happen after tunnel becomes ready. | ||
819 | */ | ||
820 | GNUNET_assert (NULL == existing_q); | ||
821 | tqd = queue_data (t, message); | ||
822 | if (NULL == cont) | ||
823 | return NULL; | ||
824 | tq = GNUNET_new (struct CadetTunnel3Queue); | ||
825 | tq->tqd = tqd; | ||
826 | tqd->tq = tq; | ||
827 | tq->cont = cont; | ||
828 | tq->cont_cls = cont_cls; | ||
829 | return tq; | ||
830 | } | ||
831 | |||
832 | GNUNET_assert (GNUNET_NO == GMT_is_loopback (t)); | ||
833 | |||
834 | iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
835 | msg = (struct GNUNET_CADET_Encrypted *) cbuf; | ||
836 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED); | ||
837 | msg->iv = iv; | ||
838 | GNUNET_assert (t_encrypt (t, &msg[1], message, size, iv) == size); | ||
839 | t_hmac (t, &msg[1], size, iv, GNUNET_YES, &msg->hmac); | ||
840 | msg->header.size = htons (sizeof (struct GNUNET_CADET_Encrypted) + size); | ||
841 | |||
842 | if (NULL == c) | ||
843 | c = tunnel_get_connection (t); | ||
844 | if (NULL == c) | ||
845 | { | ||
846 | if (GNUNET_SCHEDULER_NO_TASK != t->destroy_task | ||
847 | || CADET_TUNNEL3_SEARCHING != t->cstate) | ||
848 | { | ||
849 | GNUNET_break (0); | ||
850 | GMT_debug (t); | ||
851 | } | ||
852 | return NULL; | ||
853 | } | ||
854 | |||
855 | mid = 0; | ||
856 | type = ntohs (message->type); | ||
857 | switch (type) | ||
858 | { | ||
859 | case GNUNET_MESSAGE_TYPE_CADET_DATA: | ||
860 | case GNUNET_MESSAGE_TYPE_CADET_DATA_ACK: | ||
861 | if (GNUNET_MESSAGE_TYPE_CADET_DATA == type) | ||
862 | mid = ntohl (((struct GNUNET_CADET_Data *) message)->mid); | ||
863 | else | ||
864 | mid = ntohl (((struct GNUNET_CADET_DataACK *) message)->mid); | ||
865 | /* Fall thru */ | ||
866 | case GNUNET_MESSAGE_TYPE_CADET_KEEPALIVE: | ||
867 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE: | ||
868 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: | ||
869 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_ACK: | ||
870 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_NACK: | ||
871 | msg->cid = *GMC_get_id (c); | ||
872 | msg->ttl = htonl (default_ttl); | ||
873 | break; | ||
874 | default: | ||
875 | GNUNET_break (0); | ||
876 | } | ||
877 | LOG (GNUNET_ERROR_TYPE_DEBUG, "type %s\n", GM_m2s (type)); | ||
878 | |||
879 | fwd = GMC_is_origin (c, GNUNET_YES); | ||
880 | |||
881 | if (NULL == cont) | ||
882 | { | ||
883 | GNUNET_break (NULL == | ||
884 | GMC_send_prebuilt_message (&msg->header, type, mid, | ||
885 | c, fwd, force, NULL, NULL)); | ||
886 | return NULL; | ||
887 | } | ||
888 | if (NULL == existing_q) | ||
889 | { | ||
890 | tq = GNUNET_new (struct CadetTunnel3Queue); /* FIXME valgrind: leak*/ | ||
891 | } | ||
892 | else | ||
893 | { | ||
894 | tq = existing_q; | ||
895 | tq->tqd = NULL; | ||
896 | } | ||
897 | tq->cq = GMC_send_prebuilt_message (&msg->header, type, mid, c, fwd, force, | ||
898 | &tun_message_sent, tq); | ||
899 | tq->cont = cont; | ||
900 | tq->cont_cls = cont_cls; | ||
901 | |||
902 | return tq; | ||
903 | } | ||
904 | |||
905 | |||
906 | /** | ||
907 | * Send all cached messages that we can, tunnel is online. | ||
908 | * | ||
909 | * @param t Tunnel that holds the messages. Cannot be loopback. | ||
910 | */ | ||
911 | static void | ||
912 | send_queued_data (struct CadetTunnel3 *t) | ||
913 | { | ||
914 | struct CadetTunnelDelayed *tqd; | ||
915 | struct CadetTunnelDelayed *next; | ||
916 | unsigned int room; | ||
917 | |||
918 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
919 | "GMT_send_queued_data on tunnel %s\n", | ||
920 | GMT_2s (t)); | ||
921 | |||
922 | if (GMT_is_loopback (t)) | ||
923 | { | ||
924 | GNUNET_break (0); | ||
925 | return; | ||
926 | } | ||
927 | |||
928 | if (GNUNET_NO == is_ready (t)) | ||
929 | { | ||
930 | LOG (GNUNET_ERROR_TYPE_DEBUG, " not ready yet: %s/%s\n", | ||
931 | estate2s (t->estate), cstate2s (t->cstate)); | ||
932 | return; | ||
933 | } | ||
934 | |||
935 | room = GMT_get_connections_buffer (t); | ||
936 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room); | ||
937 | LOG (GNUNET_ERROR_TYPE_DEBUG, " tq head: %p\n", t->tq_head); | ||
938 | for (tqd = t->tq_head; NULL != tqd && room > 0; tqd = next) | ||
939 | { | ||
940 | LOG (GNUNET_ERROR_TYPE_DEBUG, " sending queued data\n"); | ||
941 | next = tqd->next; | ||
942 | room--; | ||
943 | send_prebuilt_message ((struct GNUNET_MessageHeader *) &tqd[1], | ||
944 | tqd->t, NULL, GNUNET_YES, | ||
945 | NULL != tqd->tq ? tqd->tq->cont : NULL, | ||
946 | NULL != tqd->tq ? tqd->tq->cont_cls : NULL, | ||
947 | tqd->tq); | ||
948 | unqueue_data (tqd); | ||
949 | } | ||
950 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT_send_queued_data end\n", GMP_2s (t->peer)); | ||
951 | } | ||
952 | |||
953 | |||
954 | /** | ||
955 | * Sends key exchange message on a tunnel, choosing the best connection. | ||
956 | * Should not be called on loopback tunnels. | ||
957 | * | ||
958 | * @param t Tunnel on which this message is transmitted. | ||
959 | * @param message Message to send. Function modifies it. | ||
960 | */ | ||
961 | static void | ||
962 | send_kx (struct CadetTunnel3 *t, | ||
963 | const struct GNUNET_MessageHeader *message) | ||
964 | { | ||
965 | struct CadetConnection *c; | ||
966 | struct GNUNET_CADET_KX *msg; | ||
967 | size_t size = ntohs (message->size); | ||
968 | char cbuf[sizeof (struct GNUNET_CADET_KX) + size]; | ||
969 | uint16_t type; | ||
970 | int fwd; | ||
971 | |||
972 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT KX on Tunnel %s\n", GMT_2s (t)); | ||
973 | |||
974 | /* Avoid loopback. */ | ||
975 | if (GMT_is_loopback (t)) | ||
976 | { | ||
977 | LOG (GNUNET_ERROR_TYPE_DEBUG, " loopback!\n"); | ||
978 | GNUNET_break (0); | ||
979 | return; | ||
980 | } | ||
981 | |||
982 | if (GNUNET_SCHEDULER_NO_TASK != t->destroy_task) | ||
983 | { | ||
984 | LOG (GNUNET_ERROR_TYPE_DEBUG, " being destroyed, why bother\n"); | ||
985 | return; | ||
986 | } | ||
987 | |||
988 | /* Must have a connection. */ | ||
989 | if (NULL == t->connection_head) | ||
990 | { | ||
991 | GNUNET_break (CADET_TUNNEL3_SEARCHING == t->cstate); | ||
992 | GMT_debug (t); | ||
993 | return; | ||
994 | } | ||
995 | |||
996 | msg = (struct GNUNET_CADET_KX *) cbuf; | ||
997 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_KX); | ||
998 | msg->header.size = htons (sizeof (struct GNUNET_CADET_KX) + size); | ||
999 | c = tunnel_get_connection (t); | ||
1000 | if (NULL == c) | ||
1001 | { | ||
1002 | GNUNET_break (GNUNET_SCHEDULER_NO_TASK != t->destroy_task | ||
1003 | || CADET_TUNNEL3_READY != t->cstate); | ||
1004 | GMT_debug (t); | ||
1005 | return; | ||
1006 | } | ||
1007 | type = ntohs (message->type); | ||
1008 | switch (type) | ||
1009 | { | ||
1010 | case GNUNET_MESSAGE_TYPE_CADET_KX_EPHEMERAL: | ||
1011 | case GNUNET_MESSAGE_TYPE_CADET_KX_PING: | ||
1012 | case GNUNET_MESSAGE_TYPE_CADET_KX_PONG: | ||
1013 | memcpy (&msg[1], message, size); | ||
1014 | break; | ||
1015 | default: | ||
1016 | LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n", | ||
1017 | GM_m2s (type)); | ||
1018 | GNUNET_break (0); | ||
1019 | } | ||
1020 | |||
1021 | fwd = GMC_is_origin (t->connection_head->c, GNUNET_YES); | ||
1022 | /* TODO save handle and cancel in case of a unneeded retransmission */ | ||
1023 | GMC_send_prebuilt_message (&msg->header, GNUNET_MESSAGE_TYPE_CADET_KX, | ||
1024 | message->type, c, fwd, GNUNET_YES, NULL, NULL); | ||
1025 | } | ||
1026 | |||
1027 | |||
1028 | /** | ||
1029 | * Send the ephemeral key on a tunnel. | ||
1030 | * | ||
1031 | * @param t Tunnel on which to send the key. | ||
1032 | */ | ||
1033 | static void | ||
1034 | send_ephemeral (struct CadetTunnel3 *t) | ||
1035 | { | ||
1036 | LOG (GNUNET_ERROR_TYPE_INFO, "=> EPHM for %s\n", GMT_2s (t)); | ||
1037 | |||
1038 | kx_msg.sender_status = htonl (t->estate); | ||
1039 | send_kx (t, &kx_msg.header); | ||
1040 | } | ||
1041 | |||
1042 | /** | ||
1043 | * Send a ping message on a tunnel. | ||
1044 | * | ||
1045 | * @param t Tunnel on which to send the ping. | ||
1046 | */ | ||
1047 | static void | ||
1048 | send_ping (struct CadetTunnel3 *t) | ||
1049 | { | ||
1050 | struct GNUNET_CADET_KX_Ping msg; | ||
1051 | |||
1052 | LOG (GNUNET_ERROR_TYPE_INFO, "=> PING for %s\n", GMT_2s (t)); | ||
1053 | msg.header.size = htons (sizeof (msg)); | ||
1054 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_KX_PING); | ||
1055 | msg.iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
1056 | msg.target = *GMP_get_id (t->peer); | ||
1057 | msg.nonce = t->kx_ctx->challenge; | ||
1058 | |||
1059 | LOG (GNUNET_ERROR_TYPE_DEBUG, " sending %u\n", msg.nonce); | ||
1060 | LOG (GNUNET_ERROR_TYPE_DEBUG, " towards %s\n", GNUNET_i2s (&msg.target)); | ||
1061 | t_encrypt (t, &msg.target, &msg.target, ping_encryption_size(), msg.iv); | ||
1062 | LOG (GNUNET_ERROR_TYPE_DEBUG, " e sending %u\n", msg.nonce); | ||
1063 | LOG (GNUNET_ERROR_TYPE_DEBUG, " e towards %s\n", GNUNET_i2s (&msg.target)); | ||
1064 | |||
1065 | send_kx (t, &msg.header); | ||
1066 | } | ||
1067 | |||
1068 | |||
1069 | /** | ||
1070 | * Send a pong message on a tunnel. | ||
1071 | * | ||
1072 | * @param t Tunnel on which to send the pong. | ||
1073 | * @param challenge Value sent in the ping that we have to send back. | ||
1074 | */ | ||
1075 | static void | ||
1076 | send_pong (struct CadetTunnel3 *t, uint32_t challenge) | ||
1077 | { | ||
1078 | struct GNUNET_CADET_KX_Pong msg; | ||
1079 | |||
1080 | LOG (GNUNET_ERROR_TYPE_INFO, "=> PONG for %s\n", GMT_2s (t)); | ||
1081 | msg.header.size = htons (sizeof (msg)); | ||
1082 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_KX_PONG); | ||
1083 | msg.iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
1084 | msg.nonce = challenge; | ||
1085 | LOG (GNUNET_ERROR_TYPE_DEBUG, " sending %u\n", msg.nonce); | ||
1086 | t_encrypt (t, &msg.nonce, &msg.nonce, sizeof (msg.nonce), msg.iv); | ||
1087 | LOG (GNUNET_ERROR_TYPE_DEBUG, " e sending %u\n", msg.nonce); | ||
1088 | |||
1089 | send_kx (t, &msg.header); | ||
1090 | } | ||
1091 | |||
1092 | |||
1093 | /** | ||
1094 | * Initiate a rekey with the remote peer. | ||
1095 | * | ||
1096 | * @param cls Closure (tunnel). | ||
1097 | * @param tc TaskContext. | ||
1098 | */ | ||
1099 | static void | ||
1100 | rekey_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1101 | { | ||
1102 | struct CadetTunnel3 *t = cls; | ||
1103 | |||
1104 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; | ||
1105 | |||
1106 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Re-key Tunnel %s\n", GMT_2s (t)); | ||
1107 | if (NULL != tc && 0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | ||
1108 | return; | ||
1109 | |||
1110 | if (NULL == t->kx_ctx) | ||
1111 | { | ||
1112 | LOG (GNUNET_ERROR_TYPE_DEBUG, " new kx ctx\n"); | ||
1113 | t->kx_ctx = GNUNET_new (struct CadetTunnelKXCtx); | ||
1114 | t->kx_ctx->challenge = | ||
1115 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
1116 | t->kx_ctx->d_key_old = t->d_key; | ||
1117 | LOG (GNUNET_ERROR_TYPE_DEBUG, " new challenge for %s: %u\n", | ||
1118 | GMT_2s (t), t->kx_ctx->challenge); | ||
1119 | } | ||
1120 | send_ephemeral (t); | ||
1121 | switch (t->estate) | ||
1122 | { | ||
1123 | case CADET_TUNNEL3_KEY_UNINITIALIZED: | ||
1124 | t->estate = CADET_TUNNEL3_KEY_SENT; | ||
1125 | break; | ||
1126 | case CADET_TUNNEL3_KEY_SENT: | ||
1127 | break; | ||
1128 | case CADET_TUNNEL3_KEY_PING: | ||
1129 | case CADET_TUNNEL3_KEY_OK: | ||
1130 | send_ping (t); | ||
1131 | t->estate = CADET_TUNNEL3_KEY_PING; | ||
1132 | break; | ||
1133 | default: | ||
1134 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Unexpected state %u\n", t->estate); | ||
1135 | } | ||
1136 | |||
1137 | LOG (GNUNET_ERROR_TYPE_DEBUG, " next call in %s\n", | ||
1138 | GNUNET_STRINGS_relative_time_to_string (REKEY_WAIT, GNUNET_YES)); | ||
1139 | t->rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_WAIT, &rekey_tunnel, t); | ||
1140 | } | ||
1141 | |||
1142 | |||
1143 | /** | ||
1144 | * Out ephemeral key has changed, create new session key on all tunnels. | ||
1145 | * | ||
1146 | * @param cls Closure (size of the hashmap). | ||
1147 | * @param key Current public key. | ||
1148 | * @param value Value in the hash map (tunnel). | ||
1149 | * | ||
1150 | * @return #GNUNET_YES, so we should continue to iterate, | ||
1151 | */ | ||
1152 | static int | ||
1153 | rekey_iterator (void *cls, | ||
1154 | const struct GNUNET_PeerIdentity *key, | ||
1155 | void *value) | ||
1156 | { | ||
1157 | struct CadetTunnel3 *t = value; | ||
1158 | struct GNUNET_TIME_Relative delay; | ||
1159 | long n = (long) cls; | ||
1160 | uint32_t r; | ||
1161 | |||
1162 | if (GNUNET_SCHEDULER_NO_TASK != t->rekey_task) | ||
1163 | return GNUNET_YES; | ||
1164 | |||
1165 | if (GNUNET_YES == GMT_is_loopback (t)) | ||
1166 | return GNUNET_YES; | ||
1167 | |||
1168 | r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, (uint32_t) n * 100); | ||
1169 | delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, r); | ||
1170 | t->rekey_task = GNUNET_SCHEDULER_add_delayed (delay, &rekey_tunnel, t); | ||
1171 | |||
1172 | return GNUNET_YES; | ||
1173 | } | ||
1174 | |||
1175 | |||
1176 | /** | ||
1177 | * Create a new ephemeral key and key message, schedule next rekeying. | ||
1178 | * | ||
1179 | * @param cls Closure (unused). | ||
1180 | * @param tc TaskContext. | ||
1181 | */ | ||
1182 | static void | ||
1183 | rekey (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1184 | { | ||
1185 | struct GNUNET_TIME_Absolute time; | ||
1186 | long n; | ||
1187 | |||
1188 | rekey_task = GNUNET_SCHEDULER_NO_TASK; | ||
1189 | |||
1190 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | ||
1191 | return; | ||
1192 | |||
1193 | GNUNET_free_non_null (my_ephemeral_key); | ||
1194 | my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create (); | ||
1195 | |||
1196 | time = GNUNET_TIME_absolute_get (); | ||
1197 | kx_msg.creation_time = GNUNET_TIME_absolute_hton (time); | ||
1198 | time = GNUNET_TIME_absolute_add (time, rekey_period); | ||
1199 | time = GNUNET_TIME_absolute_add (time, GNUNET_TIME_UNIT_MINUTES); | ||
1200 | kx_msg.expiration_time = GNUNET_TIME_absolute_hton (time); | ||
1201 | GNUNET_CRYPTO_ecdhe_key_get_public (my_ephemeral_key, &kx_msg.ephemeral_key); | ||
1202 | |||
1203 | GNUNET_assert (GNUNET_OK == | ||
1204 | GNUNET_CRYPTO_eddsa_sign (my_private_key, | ||
1205 | &kx_msg.purpose, | ||
1206 | &kx_msg.signature)); | ||
1207 | |||
1208 | n = (long) GNUNET_CONTAINER_multipeermap_size (tunnels); | ||
1209 | GNUNET_CONTAINER_multipeermap_iterate (tunnels, &rekey_iterator, (void *) n); | ||
1210 | |||
1211 | rekey_task = GNUNET_SCHEDULER_add_delayed (rekey_period, &rekey, NULL); | ||
1212 | } | ||
1213 | |||
1214 | |||
1215 | /** | ||
1216 | * Called only on shutdown, destroy every tunnel. | ||
1217 | * | ||
1218 | * @param cls Closure (unused). | ||
1219 | * @param key Current public key. | ||
1220 | * @param value Value in the hash map (tunnel). | ||
1221 | * | ||
1222 | * @return #GNUNET_YES, so we should continue to iterate, | ||
1223 | */ | ||
1224 | static int | ||
1225 | destroy_iterator (void *cls, | ||
1226 | const struct GNUNET_PeerIdentity *key, | ||
1227 | void *value) | ||
1228 | { | ||
1229 | struct CadetTunnel3 *t = value; | ||
1230 | |||
1231 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT_shutdown destroying tunnel at %p\n", t); | ||
1232 | GMT_destroy (t); | ||
1233 | return GNUNET_YES; | ||
1234 | } | ||
1235 | |||
1236 | |||
1237 | /** | ||
1238 | * Notify remote peer that we don't know a channel he is talking about, | ||
1239 | * probably CHANNEL_DESTROY was missed. | ||
1240 | * | ||
1241 | * @param t Tunnel on which to notify. | ||
1242 | * @param gid ID of the channel. | ||
1243 | */ | ||
1244 | static void | ||
1245 | send_channel_destroy (struct CadetTunnel3 *t, unsigned int gid) | ||
1246 | { | ||
1247 | struct GNUNET_CADET_ChannelManage msg; | ||
1248 | |||
1249 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | ||
1250 | msg.header.size = htons (sizeof (msg)); | ||
1251 | msg.chid = htonl (gid); | ||
1252 | |||
1253 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1254 | "WARNING destroying unknown channel %u on tunnel %s\n", | ||
1255 | gid, GMT_2s (t)); | ||
1256 | send_prebuilt_message (&msg.header, t, NULL, GNUNET_YES, NULL, NULL, NULL); | ||
1257 | } | ||
1258 | |||
1259 | |||
1260 | /** | ||
1261 | * Demultiplex data per channel and call appropriate channel handler. | ||
1262 | * | ||
1263 | * @param t Tunnel on which the data came. | ||
1264 | * @param msg Data message. | ||
1265 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1266 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1267 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1268 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1269 | */ | ||
1270 | static void | ||
1271 | handle_data (struct CadetTunnel3 *t, | ||
1272 | const struct GNUNET_CADET_Data *msg, | ||
1273 | int fwd) | ||
1274 | { | ||
1275 | struct CadetChannel *ch; | ||
1276 | size_t size; | ||
1277 | |||
1278 | /* Check size */ | ||
1279 | size = ntohs (msg->header.size); | ||
1280 | if (size < | ||
1281 | sizeof (struct GNUNET_CADET_Data) + | ||
1282 | sizeof (struct GNUNET_MessageHeader)) | ||
1283 | { | ||
1284 | GNUNET_break (0); | ||
1285 | return; | ||
1286 | } | ||
1287 | LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n", | ||
1288 | GM_m2s (ntohs (msg[1].header.type))); | ||
1289 | |||
1290 | /* Check channel */ | ||
1291 | ch = GMT_get_channel (t, ntohl (msg->chid)); | ||
1292 | if (NULL == ch) | ||
1293 | { | ||
1294 | GNUNET_STATISTICS_update (stats, "# data on unknown channel", | ||
1295 | 1, GNUNET_NO); | ||
1296 | LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel 0x%X unknown\n", | ||
1297 | ntohl (msg->chid)); | ||
1298 | send_channel_destroy (t, ntohl (msg->chid)); | ||
1299 | return; | ||
1300 | } | ||
1301 | |||
1302 | GMCH_handle_data (ch, msg, fwd); | ||
1303 | } | ||
1304 | |||
1305 | |||
1306 | /** | ||
1307 | * Demultiplex data ACKs per channel and update appropriate channel buffer info. | ||
1308 | * | ||
1309 | * @param t Tunnel on which the DATA ACK came. | ||
1310 | * @param msg DATA ACK message. | ||
1311 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1312 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1313 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1314 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1315 | */ | ||
1316 | static void | ||
1317 | handle_data_ack (struct CadetTunnel3 *t, | ||
1318 | const struct GNUNET_CADET_DataACK *msg, | ||
1319 | int fwd) | ||
1320 | { | ||
1321 | struct CadetChannel *ch; | ||
1322 | size_t size; | ||
1323 | |||
1324 | /* Check size */ | ||
1325 | size = ntohs (msg->header.size); | ||
1326 | if (size != sizeof (struct GNUNET_CADET_DataACK)) | ||
1327 | { | ||
1328 | GNUNET_break (0); | ||
1329 | return; | ||
1330 | } | ||
1331 | |||
1332 | /* Check channel */ | ||
1333 | ch = GMT_get_channel (t, ntohl (msg->chid)); | ||
1334 | if (NULL == ch) | ||
1335 | { | ||
1336 | GNUNET_STATISTICS_update (stats, "# data ack on unknown channel", | ||
1337 | 1, GNUNET_NO); | ||
1338 | LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", | ||
1339 | ntohl (msg->chid)); | ||
1340 | return; | ||
1341 | } | ||
1342 | |||
1343 | GMCH_handle_data_ack (ch, msg, fwd); | ||
1344 | } | ||
1345 | |||
1346 | |||
1347 | /** | ||
1348 | * Handle channel create. | ||
1349 | * | ||
1350 | * @param t Tunnel on which the data came. | ||
1351 | * @param msg Data message. | ||
1352 | */ | ||
1353 | static void | ||
1354 | handle_ch_create (struct CadetTunnel3 *t, | ||
1355 | const struct GNUNET_CADET_ChannelCreate *msg) | ||
1356 | { | ||
1357 | struct CadetChannel *ch; | ||
1358 | size_t size; | ||
1359 | |||
1360 | /* Check size */ | ||
1361 | size = ntohs (msg->header.size); | ||
1362 | if (size != sizeof (struct GNUNET_CADET_ChannelCreate)) | ||
1363 | { | ||
1364 | GNUNET_break (0); | ||
1365 | return; | ||
1366 | } | ||
1367 | |||
1368 | /* Check channel */ | ||
1369 | ch = GMT_get_channel (t, ntohl (msg->chid)); | ||
1370 | if (NULL != ch && ! GMT_is_loopback (t)) | ||
1371 | { | ||
1372 | /* Probably a retransmission, safe to ignore */ | ||
1373 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n"); | ||
1374 | } | ||
1375 | ch = GMCH_handle_create (t, msg); | ||
1376 | if (NULL != ch) | ||
1377 | GMT_add_channel (t, ch); | ||
1378 | } | ||
1379 | |||
1380 | |||
1381 | |||
1382 | /** | ||
1383 | * Handle channel NACK: check correctness and call channel handler for NACKs. | ||
1384 | * | ||
1385 | * @param t Tunnel on which the NACK came. | ||
1386 | * @param msg NACK message. | ||
1387 | */ | ||
1388 | static void | ||
1389 | handle_ch_nack (struct CadetTunnel3 *t, | ||
1390 | const struct GNUNET_CADET_ChannelManage *msg) | ||
1391 | { | ||
1392 | struct CadetChannel *ch; | ||
1393 | size_t size; | ||
1394 | |||
1395 | /* Check size */ | ||
1396 | size = ntohs (msg->header.size); | ||
1397 | if (size != sizeof (struct GNUNET_CADET_ChannelManage)) | ||
1398 | { | ||
1399 | GNUNET_break (0); | ||
1400 | return; | ||
1401 | } | ||
1402 | |||
1403 | /* Check channel */ | ||
1404 | ch = GMT_get_channel (t, ntohl (msg->chid)); | ||
1405 | if (NULL == ch) | ||
1406 | { | ||
1407 | GNUNET_STATISTICS_update (stats, "# channel NACK on unknown channel", | ||
1408 | 1, GNUNET_NO); | ||
1409 | LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", | ||
1410 | ntohl (msg->chid)); | ||
1411 | return; | ||
1412 | } | ||
1413 | |||
1414 | GMCH_handle_nack (ch); | ||
1415 | } | ||
1416 | |||
1417 | |||
1418 | /** | ||
1419 | * Handle a CHANNEL ACK (SYNACK/ACK). | ||
1420 | * | ||
1421 | * @param t Tunnel on which the CHANNEL ACK came. | ||
1422 | * @param msg CHANNEL ACK message. | ||
1423 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1424 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1425 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1426 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1427 | */ | ||
1428 | static void | ||
1429 | handle_ch_ack (struct CadetTunnel3 *t, | ||
1430 | const struct GNUNET_CADET_ChannelManage *msg, | ||
1431 | int fwd) | ||
1432 | { | ||
1433 | struct CadetChannel *ch; | ||
1434 | size_t size; | ||
1435 | |||
1436 | /* Check size */ | ||
1437 | size = ntohs (msg->header.size); | ||
1438 | if (size != sizeof (struct GNUNET_CADET_ChannelManage)) | ||
1439 | { | ||
1440 | GNUNET_break (0); | ||
1441 | return; | ||
1442 | } | ||
1443 | |||
1444 | /* Check channel */ | ||
1445 | ch = GMT_get_channel (t, ntohl (msg->chid)); | ||
1446 | if (NULL == ch) | ||
1447 | { | ||
1448 | GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel", | ||
1449 | 1, GNUNET_NO); | ||
1450 | LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", | ||
1451 | ntohl (msg->chid)); | ||
1452 | return; | ||
1453 | } | ||
1454 | |||
1455 | GMCH_handle_ack (ch, msg, fwd); | ||
1456 | } | ||
1457 | |||
1458 | |||
1459 | |||
1460 | /** | ||
1461 | * Handle a channel destruction message. | ||
1462 | * | ||
1463 | * @param t Tunnel on which the message came. | ||
1464 | * @param msg Channel destroy message. | ||
1465 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1466 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1467 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1468 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1469 | */ | ||
1470 | static void | ||
1471 | handle_ch_destroy (struct CadetTunnel3 *t, | ||
1472 | const struct GNUNET_CADET_ChannelManage *msg, | ||
1473 | int fwd) | ||
1474 | { | ||
1475 | struct CadetChannel *ch; | ||
1476 | size_t size; | ||
1477 | |||
1478 | /* Check size */ | ||
1479 | size = ntohs (msg->header.size); | ||
1480 | if (size != sizeof (struct GNUNET_CADET_ChannelManage)) | ||
1481 | { | ||
1482 | GNUNET_break (0); | ||
1483 | return; | ||
1484 | } | ||
1485 | |||
1486 | /* Check channel */ | ||
1487 | ch = GMT_get_channel (t, ntohl (msg->chid)); | ||
1488 | if (NULL == ch) | ||
1489 | { | ||
1490 | /* Probably a retransmission, safe to ignore */ | ||
1491 | return; | ||
1492 | } | ||
1493 | |||
1494 | GMCH_handle_destroy (ch, msg, fwd); | ||
1495 | } | ||
1496 | |||
1497 | |||
1498 | /** | ||
1499 | * The peer's ephemeral key has changed: update the symmetrical keys. | ||
1500 | * | ||
1501 | * @param t Tunnel this message came on. | ||
1502 | * @param msg Key eXchange message. | ||
1503 | */ | ||
1504 | static void | ||
1505 | handle_ephemeral (struct CadetTunnel3 *t, | ||
1506 | const struct GNUNET_CADET_KX_Ephemeral *msg) | ||
1507 | { | ||
1508 | struct GNUNET_HashCode km; | ||
1509 | LOG (GNUNET_ERROR_TYPE_INFO, "<=== EPHM for %s\n", GMT_2s (t)); | ||
1510 | |||
1511 | if (GNUNET_OK != check_ephemeral (t, msg)) | ||
1512 | { | ||
1513 | GNUNET_break_op (0); | ||
1514 | return; | ||
1515 | } | ||
1516 | derive_key_material (&km, &msg->ephemeral_key); | ||
1517 | LOG (GNUNET_ERROR_TYPE_DEBUG, " km is %s\n", GNUNET_h2s (&km)); | ||
1518 | derive_symmertic (&t->e_key, &my_full_id, GMP_get_id (t->peer), &km); | ||
1519 | derive_symmertic (&t->d_key, GMP_get_id (t->peer), &my_full_id, &km); | ||
1520 | if (CADET_TUNNEL3_KEY_SENT == t->estate) | ||
1521 | { | ||
1522 | LOG (GNUNET_ERROR_TYPE_DEBUG, " our key was sent, send ping\n"); | ||
1523 | send_ping (t); | ||
1524 | t->estate = CADET_TUNNEL3_KEY_PING; | ||
1525 | } | ||
1526 | } | ||
1527 | |||
1528 | |||
1529 | /** | ||
1530 | * Peer wants to check our symmetrical keys by sending an encrypted challenge. | ||
1531 | * Answer with by retransmitting the challenge with the "opposite" key. | ||
1532 | * | ||
1533 | * @param t Tunnel this message came on. | ||
1534 | * @param msg Key eXchange Ping message. | ||
1535 | */ | ||
1536 | static void | ||
1537 | handle_ping (struct CadetTunnel3 *t, | ||
1538 | const struct GNUNET_CADET_KX_Ping *msg) | ||
1539 | { | ||
1540 | struct GNUNET_CADET_KX_Ping res; | ||
1541 | |||
1542 | if (ntohs (msg->header.size) != sizeof (res)) | ||
1543 | { | ||
1544 | GNUNET_break_op (0); | ||
1545 | return; | ||
1546 | } | ||
1547 | |||
1548 | LOG (GNUNET_ERROR_TYPE_INFO, "<=== PING for %s\n", GMT_2s (t)); | ||
1549 | t_decrypt (t, &res.target, &msg->target, ping_encryption_size (), msg->iv); | ||
1550 | if (0 != memcmp (&my_full_id, &res.target, sizeof (my_full_id))) | ||
1551 | { | ||
1552 | // FIXME: move to debug | ||
1553 | GNUNET_STATISTICS_update (stats, "# malformed PINGs", 1, GNUNET_NO); | ||
1554 | LOG (GNUNET_ERROR_TYPE_WARNING, " malformed PING on %s\n", GMT_2s (t)); | ||
1555 | LOG (GNUNET_ERROR_TYPE_WARNING, " e got %u\n", msg->nonce); | ||
1556 | LOG (GNUNET_ERROR_TYPE_WARNING, " e towards %s\n", GNUNET_i2s (&msg->target)); | ||
1557 | LOG (GNUNET_ERROR_TYPE_WARNING, " got %u\n", res.nonce); | ||
1558 | LOG (GNUNET_ERROR_TYPE_WARNING, " towards %s\n", GNUNET_i2s (&res.target)); | ||
1559 | return; | ||
1560 | } | ||
1561 | |||
1562 | send_pong (t, res.nonce); | ||
1563 | } | ||
1564 | |||
1565 | |||
1566 | /** | ||
1567 | * Peer has answer to our challenge. | ||
1568 | * If answer is successful, consider the key exchange finished and clean | ||
1569 | * up all related state. | ||
1570 | * | ||
1571 | * @param t Tunnel this message came on. | ||
1572 | * @param msg Key eXchange Pong message. | ||
1573 | */ | ||
1574 | static void | ||
1575 | handle_pong (struct CadetTunnel3 *t, | ||
1576 | const struct GNUNET_CADET_KX_Pong *msg) | ||
1577 | { | ||
1578 | uint32_t challenge; | ||
1579 | |||
1580 | LOG (GNUNET_ERROR_TYPE_INFO, "<=== PONG for %s\n", GMT_2s (t)); | ||
1581 | if (GNUNET_SCHEDULER_NO_TASK == t->rekey_task) | ||
1582 | { | ||
1583 | GNUNET_STATISTICS_update (stats, "# duplicate PONG messages", 1, GNUNET_NO); | ||
1584 | return; | ||
1585 | } | ||
1586 | t_decrypt (t, &challenge, &msg->nonce, sizeof (uint32_t), msg->iv); | ||
1587 | |||
1588 | if (challenge != t->kx_ctx->challenge) | ||
1589 | { | ||
1590 | LOG (GNUNET_ERROR_TYPE_WARNING, "Wrong PONG challenge\n"); | ||
1591 | LOG (GNUNET_ERROR_TYPE_DEBUG, "PONG: %u (e: %u). Expected: %u.\n", | ||
1592 | challenge, msg->nonce, t->kx_ctx->challenge); | ||
1593 | GNUNET_break_op (0); | ||
1594 | return; | ||
1595 | } | ||
1596 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
1597 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; | ||
1598 | GNUNET_free (t->kx_ctx); | ||
1599 | t->kx_ctx = NULL; | ||
1600 | GMT_change_estate (t, CADET_TUNNEL3_KEY_OK); | ||
1601 | } | ||
1602 | |||
1603 | |||
1604 | /** | ||
1605 | * Demultiplex by message type and call appropriate handler for a message | ||
1606 | * towards a channel of a local tunnel. | ||
1607 | * | ||
1608 | * @param t Tunnel this message came on. | ||
1609 | * @param msgh Message header. | ||
1610 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1611 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1612 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1613 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1614 | */ | ||
1615 | static void | ||
1616 | handle_decrypted (struct CadetTunnel3 *t, | ||
1617 | const struct GNUNET_MessageHeader *msgh, | ||
1618 | int fwd) | ||
1619 | { | ||
1620 | uint16_t type; | ||
1621 | |||
1622 | type = ntohs (msgh->type); | ||
1623 | LOG (GNUNET_ERROR_TYPE_INFO, "<=== %s on %s\n", GM_m2s (type), GMT_2s (t)); | ||
1624 | |||
1625 | switch (type) | ||
1626 | { | ||
1627 | case GNUNET_MESSAGE_TYPE_CADET_KEEPALIVE: | ||
1628 | /* Do nothing, connection aleady got updated. */ | ||
1629 | GNUNET_STATISTICS_update (stats, "# keepalives received", 1, GNUNET_NO); | ||
1630 | break; | ||
1631 | |||
1632 | case GNUNET_MESSAGE_TYPE_CADET_DATA: | ||
1633 | /* Don't send hop ACK, wait for client to ACK */ | ||
1634 | handle_data (t, (struct GNUNET_CADET_Data *) msgh, fwd); | ||
1635 | break; | ||
1636 | |||
1637 | case GNUNET_MESSAGE_TYPE_CADET_DATA_ACK: | ||
1638 | handle_data_ack (t, (struct GNUNET_CADET_DataACK *) msgh, fwd); | ||
1639 | break; | ||
1640 | |||
1641 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE: | ||
1642 | handle_ch_create (t, | ||
1643 | (struct GNUNET_CADET_ChannelCreate *) msgh); | ||
1644 | break; | ||
1645 | |||
1646 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_NACK: | ||
1647 | handle_ch_nack (t, | ||
1648 | (struct GNUNET_CADET_ChannelManage *) msgh); | ||
1649 | break; | ||
1650 | |||
1651 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_ACK: | ||
1652 | handle_ch_ack (t, | ||
1653 | (struct GNUNET_CADET_ChannelManage *) msgh, | ||
1654 | fwd); | ||
1655 | break; | ||
1656 | |||
1657 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: | ||
1658 | handle_ch_destroy (t, | ||
1659 | (struct GNUNET_CADET_ChannelManage *) msgh, | ||
1660 | fwd); | ||
1661 | break; | ||
1662 | |||
1663 | default: | ||
1664 | GNUNET_break_op (0); | ||
1665 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1666 | "end-to-end message not known (%u)\n", | ||
1667 | ntohs (msgh->type)); | ||
1668 | GMT_debug (t); | ||
1669 | } | ||
1670 | } | ||
1671 | |||
1672 | /******************************************************************************/ | ||
1673 | /******************************** API ***********************************/ | ||
1674 | /******************************************************************************/ | ||
1675 | |||
1676 | /** | ||
1677 | * Decrypt and demultiplex by message type. Call appropriate handler | ||
1678 | * for every message. | ||
1679 | * | ||
1680 | * @param t Tunnel this message came on. | ||
1681 | * @param msg Encrypted message. | ||
1682 | */ | ||
1683 | void | ||
1684 | GMT_handle_encrypted (struct CadetTunnel3 *t, | ||
1685 | const struct GNUNET_CADET_Encrypted *msg) | ||
1686 | { | ||
1687 | size_t size = ntohs (msg->header.size); | ||
1688 | size_t payload_size = size - sizeof (struct GNUNET_CADET_Encrypted); | ||
1689 | size_t decrypted_size; | ||
1690 | char cbuf [payload_size]; | ||
1691 | struct GNUNET_MessageHeader *msgh; | ||
1692 | unsigned int off; | ||
1693 | struct GNUNET_CADET_Hash hmac; | ||
1694 | |||
1695 | decrypted_size = t_decrypt (t, cbuf, &msg[1], payload_size, msg->iv); | ||
1696 | t_hmac (t, &msg[1], payload_size, msg->iv, GNUNET_NO, &hmac); | ||
1697 | if (0 != memcmp (&hmac, &msg->hmac, sizeof (hmac))) | ||
1698 | { | ||
1699 | /* checksum failed */ | ||
1700 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1701 | "Failed checksum validation for a message on tunnel `%s'\n", | ||
1702 | GMT_2s (t)); | ||
1703 | GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); | ||
1704 | return; | ||
1705 | } | ||
1706 | off = 0; | ||
1707 | while (off < decrypted_size) | ||
1708 | { | ||
1709 | msgh = (struct GNUNET_MessageHeader *) &cbuf[off]; | ||
1710 | handle_decrypted (t, msgh, GNUNET_SYSERR); | ||
1711 | off += ntohs (msgh->size); | ||
1712 | } | ||
1713 | } | ||
1714 | |||
1715 | |||
1716 | /** | ||
1717 | * Demultiplex an encapsulated KX message by message type. | ||
1718 | * | ||
1719 | * @param t Tunnel on which the message came. | ||
1720 | * @param message Payload of KX message. | ||
1721 | */ | ||
1722 | void | ||
1723 | GMT_handle_kx (struct CadetTunnel3 *t, | ||
1724 | const struct GNUNET_MessageHeader *message) | ||
1725 | { | ||
1726 | uint16_t type; | ||
1727 | |||
1728 | type = ntohs (message->type); | ||
1729 | LOG (GNUNET_ERROR_TYPE_DEBUG, "kx message received\n", type); | ||
1730 | switch (type) | ||
1731 | { | ||
1732 | case GNUNET_MESSAGE_TYPE_CADET_KX_EPHEMERAL: | ||
1733 | handle_ephemeral (t, (struct GNUNET_CADET_KX_Ephemeral *) message); | ||
1734 | break; | ||
1735 | |||
1736 | case GNUNET_MESSAGE_TYPE_CADET_KX_PING: | ||
1737 | handle_ping (t, (struct GNUNET_CADET_KX_Ping *) message); | ||
1738 | break; | ||
1739 | |||
1740 | case GNUNET_MESSAGE_TYPE_CADET_KX_PONG: | ||
1741 | handle_pong (t, (struct GNUNET_CADET_KX_Pong *) message); | ||
1742 | break; | ||
1743 | |||
1744 | default: | ||
1745 | GNUNET_break_op (0); | ||
1746 | LOG (GNUNET_ERROR_TYPE_DEBUG, "kx message not known (%u)\n", type); | ||
1747 | } | ||
1748 | } | ||
1749 | |||
1750 | |||
1751 | /** | ||
1752 | * Initialize the tunnel subsystem. | ||
1753 | * | ||
1754 | * @param c Configuration handle. | ||
1755 | * @param key ECC private key, to derive all other keys and do crypto. | ||
1756 | */ | ||
1757 | void | ||
1758 | GMT_init (const struct GNUNET_CONFIGURATION_Handle *c, | ||
1759 | const struct GNUNET_CRYPTO_EddsaPrivateKey *key) | ||
1760 | { | ||
1761 | LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); | ||
1762 | if (GNUNET_OK != | ||
1763 | GNUNET_CONFIGURATION_get_value_number (c, "CADET", "DEFAULT_TTL", | ||
1764 | &default_ttl)) | ||
1765 | { | ||
1766 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, | ||
1767 | "CADET", "DEFAULT_TTL", "USING DEFAULT"); | ||
1768 | default_ttl = 64; | ||
1769 | } | ||
1770 | if (GNUNET_OK != | ||
1771 | GNUNET_CONFIGURATION_get_value_time (c, "CADET", "REKEY_PERIOD", | ||
1772 | &rekey_period)) | ||
1773 | { | ||
1774 | rekey_period = GNUNET_TIME_UNIT_DAYS; | ||
1775 | } | ||
1776 | |||
1777 | my_private_key = key; | ||
1778 | kx_msg.header.size = htons (sizeof (kx_msg)); | ||
1779 | kx_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_KX_EPHEMERAL); | ||
1780 | kx_msg.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CADET_KX); | ||
1781 | kx_msg.purpose.size = htonl (ephemeral_purpose_size ()); | ||
1782 | kx_msg.origin_identity = my_full_id; | ||
1783 | rekey_task = GNUNET_SCHEDULER_add_now (&rekey, NULL); | ||
1784 | |||
1785 | tunnels = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES); | ||
1786 | } | ||
1787 | |||
1788 | |||
1789 | /** | ||
1790 | * Shut down the tunnel subsystem. | ||
1791 | */ | ||
1792 | void | ||
1793 | GMT_shutdown (void) | ||
1794 | { | ||
1795 | if (GNUNET_SCHEDULER_NO_TASK != rekey_task) | ||
1796 | { | ||
1797 | GNUNET_SCHEDULER_cancel (rekey_task); | ||
1798 | rekey_task = GNUNET_SCHEDULER_NO_TASK; | ||
1799 | } | ||
1800 | GNUNET_CONTAINER_multipeermap_iterate (tunnels, &destroy_iterator, NULL); | ||
1801 | GNUNET_CONTAINER_multipeermap_destroy (tunnels); | ||
1802 | } | ||
1803 | |||
1804 | |||
1805 | /** | ||
1806 | * Create a tunnel. | ||
1807 | * | ||
1808 | * @param destination Peer this tunnel is towards. | ||
1809 | */ | ||
1810 | struct CadetTunnel3 * | ||
1811 | GMT_new (struct CadetPeer *destination) | ||
1812 | { | ||
1813 | struct CadetTunnel3 *t; | ||
1814 | |||
1815 | t = GNUNET_new (struct CadetTunnel3); | ||
1816 | t->next_chid = 0; | ||
1817 | t->peer = destination; | ||
1818 | |||
1819 | if (GNUNET_OK != | ||
1820 | GNUNET_CONTAINER_multipeermap_put (tunnels, GMP_get_id (destination), t, | ||
1821 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
1822 | { | ||
1823 | GNUNET_break (0); | ||
1824 | GNUNET_free (t); | ||
1825 | return NULL; | ||
1826 | } | ||
1827 | return t; | ||
1828 | } | ||
1829 | |||
1830 | |||
1831 | /** | ||
1832 | * Change the tunnel's connection state. | ||
1833 | * | ||
1834 | * @param t Tunnel whose connection state to change. | ||
1835 | * @param cstate New connection state. | ||
1836 | */ | ||
1837 | void | ||
1838 | GMT_change_cstate (struct CadetTunnel3* t, enum CadetTunnel3CState cstate) | ||
1839 | { | ||
1840 | if (NULL == t) | ||
1841 | return; | ||
1842 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s cstate %s => %s\n", | ||
1843 | GMP_2s (t->peer), cstate2s (t->cstate), cstate2s (cstate)); | ||
1844 | if (myid != GMP_get_short_id (t->peer) && | ||
1845 | CADET_TUNNEL3_READY != t->cstate && | ||
1846 | CADET_TUNNEL3_READY == cstate) | ||
1847 | { | ||
1848 | t->cstate = cstate; | ||
1849 | if (CADET_TUNNEL3_KEY_OK == t->estate) | ||
1850 | { | ||
1851 | LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered send queued data\n"); | ||
1852 | send_queued_data (t); | ||
1853 | } | ||
1854 | else if (CADET_TUNNEL3_KEY_UNINITIALIZED == t->estate) | ||
1855 | { | ||
1856 | LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered rekey\n"); | ||
1857 | rekey_tunnel (t, NULL); | ||
1858 | } | ||
1859 | } | ||
1860 | t->cstate = cstate; | ||
1861 | |||
1862 | if (CADET_TUNNEL3_READY == cstate | ||
1863 | && CONNECTIONS_PER_TUNNEL <= GMT_count_connections (t)) | ||
1864 | { | ||
1865 | LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered stop dht\n"); | ||
1866 | GMP_stop_search (t->peer); | ||
1867 | } | ||
1868 | } | ||
1869 | |||
1870 | /** | ||
1871 | * Change the tunnel encryption state. | ||
1872 | * | ||
1873 | * @param t Tunnel whose encryption state to change. | ||
1874 | * @param state New encryption state. | ||
1875 | */ | ||
1876 | void | ||
1877 | GMT_change_estate (struct CadetTunnel3* t, enum CadetTunnel3EState state) | ||
1878 | { | ||
1879 | if (NULL == t) | ||
1880 | return; | ||
1881 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1882 | "Tunnel %s estate was %s\n", | ||
1883 | GMP_2s (t->peer), estate2s (t->estate)); | ||
1884 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1885 | "Tunnel %s estate is now %s\n", | ||
1886 | GMP_2s (t->peer), estate2s (state)); | ||
1887 | if (myid != GMP_get_short_id (t->peer) && | ||
1888 | CADET_TUNNEL3_KEY_OK != t->estate && CADET_TUNNEL3_KEY_OK == state) | ||
1889 | { | ||
1890 | t->estate = state; | ||
1891 | send_queued_data (t); | ||
1892 | return; | ||
1893 | } | ||
1894 | t->estate = state; | ||
1895 | } | ||
1896 | |||
1897 | |||
1898 | /** | ||
1899 | * @brief Check if tunnel has too many connections, and remove one if necessary. | ||
1900 | * | ||
1901 | * Currently this means the newest connection, unless it is a direct one. | ||
1902 | * Implemented as a task to avoid freeing a connection that is in the middle | ||
1903 | * of being created/processed. | ||
1904 | * | ||
1905 | * @param cls Closure (Tunnel to check). | ||
1906 | * @param tc Task context. | ||
1907 | */ | ||
1908 | static void | ||
1909 | trim_connections (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1910 | { | ||
1911 | struct CadetTunnel3 *t = cls; | ||
1912 | |||
1913 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
1914 | return; | ||
1915 | |||
1916 | if (GMT_count_connections (t) > 2 * CONNECTIONS_PER_TUNNEL) | ||
1917 | { | ||
1918 | struct CadetTConnection *iter; | ||
1919 | struct CadetTConnection *c; | ||
1920 | |||
1921 | for (c = iter = t->connection_head; NULL != iter; iter = iter->next) | ||
1922 | { | ||
1923 | if ((NULL == c || iter->created.abs_value_us > c->created.abs_value_us) | ||
1924 | && GNUNET_NO == GMC_is_direct (iter->c)) | ||
1925 | { | ||
1926 | c = iter; | ||
1927 | } | ||
1928 | } | ||
1929 | if (NULL != c) | ||
1930 | { | ||
1931 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Too many connections on tunnel %s\n", | ||
1932 | GMT_2s (t)); | ||
1933 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying connection %s\n", | ||
1934 | GMC_2s (c->c)); | ||
1935 | GMC_destroy (c->c); | ||
1936 | } | ||
1937 | else | ||
1938 | { | ||
1939 | GNUNET_break (0); | ||
1940 | } | ||
1941 | } | ||
1942 | } | ||
1943 | |||
1944 | |||
1945 | /** | ||
1946 | * Add a connection to a tunnel. | ||
1947 | * | ||
1948 | * @param t Tunnel. | ||
1949 | * @param c Connection. | ||
1950 | */ | ||
1951 | void | ||
1952 | GMT_add_connection (struct CadetTunnel3 *t, struct CadetConnection *c) | ||
1953 | { | ||
1954 | struct CadetTConnection *aux; | ||
1955 | |||
1956 | GNUNET_assert (NULL != c); | ||
1957 | |||
1958 | LOG (GNUNET_ERROR_TYPE_DEBUG, "add connection %s\n", GMC_2s (c)); | ||
1959 | LOG (GNUNET_ERROR_TYPE_DEBUG, " to tunnel %s\n", GMT_2s (t)); | ||
1960 | for (aux = t->connection_head; aux != NULL; aux = aux->next) | ||
1961 | if (aux->c == c) | ||
1962 | return; | ||
1963 | |||
1964 | aux = GNUNET_new (struct CadetTConnection); | ||
1965 | aux->c = c; | ||
1966 | aux->created = GNUNET_TIME_absolute_get (); | ||
1967 | |||
1968 | GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, aux); | ||
1969 | |||
1970 | GNUNET_SCHEDULER_add_now (&trim_connections, t); | ||
1971 | } | ||
1972 | |||
1973 | |||
1974 | /** | ||
1975 | * Mark a path as no longer valid for this tunnel: has been tried and failed. | ||
1976 | * | ||
1977 | * @param t Tunnel to update. | ||
1978 | * @param path Invalid path to remove. Is destroyed after removal. | ||
1979 | */ | ||
1980 | void | ||
1981 | GMT_remove_path (struct CadetTunnel3 *t, struct CadetPeerPath *path) | ||
1982 | { | ||
1983 | GMP_remove_path (t->peer, path); | ||
1984 | } | ||
1985 | |||
1986 | |||
1987 | /** | ||
1988 | * Remove a connection from a tunnel. | ||
1989 | * | ||
1990 | * @param t Tunnel. | ||
1991 | * @param c Connection. | ||
1992 | */ | ||
1993 | void | ||
1994 | GMT_remove_connection (struct CadetTunnel3 *t, | ||
1995 | struct CadetConnection *c) | ||
1996 | { | ||
1997 | struct CadetTConnection *aux; | ||
1998 | struct CadetTConnection *next; | ||
1999 | |||
2000 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing connection %s from tunnel %s\n", | ||
2001 | GMC_2s (c), GMT_2s (t)); | ||
2002 | for (aux = t->connection_head; aux != NULL; aux = next) | ||
2003 | { | ||
2004 | next = aux->next; | ||
2005 | if (aux->c == c) | ||
2006 | { | ||
2007 | GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux); | ||
2008 | GNUNET_free (aux); | ||
2009 | } | ||
2010 | } | ||
2011 | |||
2012 | /* Start new connections if needed */ | ||
2013 | if (CONNECTIONS_PER_TUNNEL < GMT_count_connections (t) | ||
2014 | && GNUNET_SCHEDULER_NO_TASK == t->destroy_task | ||
2015 | && CADET_TUNNEL3_SHUTDOWN != t->cstate | ||
2016 | && GNUNET_NO == shutting_down) | ||
2017 | { | ||
2018 | LOG (GNUNET_ERROR_TYPE_DEBUG, " no more connections, getting new ones\n"); | ||
2019 | t->cstate = CADET_TUNNEL3_SEARCHING; | ||
2020 | GMP_connect (t->peer); | ||
2021 | return; | ||
2022 | } | ||
2023 | |||
2024 | /* If not marked as ready, no change is needed */ | ||
2025 | if (CADET_TUNNEL3_READY != t->cstate) | ||
2026 | return; | ||
2027 | |||
2028 | /* Check if any connection is ready to maintaing cstate */ | ||
2029 | for (aux = t->connection_head; aux != NULL; aux = aux->next) | ||
2030 | if (CADET_CONNECTION_READY == GMC_get_state (aux->c)) | ||
2031 | return; | ||
2032 | |||
2033 | t->cstate = CADET_TUNNEL3_WAITING; | ||
2034 | } | ||
2035 | |||
2036 | |||
2037 | /** | ||
2038 | * Add a channel to a tunnel. | ||
2039 | * | ||
2040 | * @param t Tunnel. | ||
2041 | * @param ch Channel. | ||
2042 | */ | ||
2043 | void | ||
2044 | GMT_add_channel (struct CadetTunnel3 *t, struct CadetChannel *ch) | ||
2045 | { | ||
2046 | struct CadetTChannel *aux; | ||
2047 | |||
2048 | GNUNET_assert (NULL != ch); | ||
2049 | |||
2050 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding channel %p to tunnel %p\n", ch, t); | ||
2051 | |||
2052 | for (aux = t->channel_head; aux != NULL; aux = aux->next) | ||
2053 | { | ||
2054 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already there %p\n", aux->ch); | ||
2055 | if (aux->ch == ch) | ||
2056 | return; | ||
2057 | } | ||
2058 | |||
2059 | aux = GNUNET_new (struct CadetTChannel); | ||
2060 | aux->ch = ch; | ||
2061 | LOG (GNUNET_ERROR_TYPE_DEBUG, " adding %p to %p\n", aux, t->channel_head); | ||
2062 | GNUNET_CONTAINER_DLL_insert_tail (t->channel_head, t->channel_tail, aux); | ||
2063 | |||
2064 | if (GNUNET_SCHEDULER_NO_TASK != t->destroy_task) | ||
2065 | { | ||
2066 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
2067 | t->destroy_task = GNUNET_SCHEDULER_NO_TASK; | ||
2068 | LOG (GNUNET_ERROR_TYPE_DEBUG, " undo destroy!\n"); | ||
2069 | } | ||
2070 | } | ||
2071 | |||
2072 | |||
2073 | /** | ||
2074 | * Remove a channel from a tunnel. | ||
2075 | * | ||
2076 | * @param t Tunnel. | ||
2077 | * @param ch Channel. | ||
2078 | */ | ||
2079 | void | ||
2080 | GMT_remove_channel (struct CadetTunnel3 *t, struct CadetChannel *ch) | ||
2081 | { | ||
2082 | struct CadetTChannel *aux; | ||
2083 | |||
2084 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing channel %p from tunnel %p\n", ch, t); | ||
2085 | for (aux = t->channel_head; aux != NULL; aux = aux->next) | ||
2086 | { | ||
2087 | if (aux->ch == ch) | ||
2088 | { | ||
2089 | LOG (GNUNET_ERROR_TYPE_DEBUG, " found! %s\n", GMCH_2s (ch)); | ||
2090 | GNUNET_CONTAINER_DLL_remove (t->channel_head, t->channel_tail, aux); | ||
2091 | GNUNET_free (aux); | ||
2092 | return; | ||
2093 | } | ||
2094 | } | ||
2095 | } | ||
2096 | |||
2097 | |||
2098 | /** | ||
2099 | * Search for a channel by global ID. | ||
2100 | * | ||
2101 | * @param t Tunnel containing the channel. | ||
2102 | * @param chid Public channel number. | ||
2103 | * | ||
2104 | * @return channel handler, NULL if doesn't exist | ||
2105 | */ | ||
2106 | struct CadetChannel * | ||
2107 | GMT_get_channel (struct CadetTunnel3 *t, CADET_ChannelNumber chid) | ||
2108 | { | ||
2109 | struct CadetTChannel *iter; | ||
2110 | |||
2111 | if (NULL == t) | ||
2112 | return NULL; | ||
2113 | |||
2114 | for (iter = t->channel_head; NULL != iter; iter = iter->next) | ||
2115 | { | ||
2116 | if (GMCH_get_id (iter->ch) == chid) | ||
2117 | break; | ||
2118 | } | ||
2119 | |||
2120 | return NULL == iter ? NULL : iter->ch; | ||
2121 | } | ||
2122 | |||
2123 | |||
2124 | /** | ||
2125 | * @brief Destroy a tunnel and free all resources. | ||
2126 | * | ||
2127 | * Should only be called a while after the tunnel has been marked as destroyed, | ||
2128 | * in case there is a new channel added to the same peer shortly after marking | ||
2129 | * the tunnel. This way we avoid a new public key handshake. | ||
2130 | * | ||
2131 | * @param cls Closure (tunnel to destroy). | ||
2132 | * @param tc Task context. | ||
2133 | */ | ||
2134 | static void | ||
2135 | delayed_destroy (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2136 | { | ||
2137 | struct CadetTunnel3 *t = cls; | ||
2138 | struct CadetTConnection *iter; | ||
2139 | |||
2140 | LOG (GNUNET_ERROR_TYPE_DEBUG, "delayed destroying tunnel %p\n", t); | ||
2141 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | ||
2142 | { | ||
2143 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2144 | "Not destroying tunnel, due to shutdown. " | ||
2145 | "Tunnel at %p should have been freed by GMT_shutdown\n", t); | ||
2146 | return; | ||
2147 | } | ||
2148 | t->destroy_task = GNUNET_SCHEDULER_NO_TASK; | ||
2149 | t->cstate = CADET_TUNNEL3_SHUTDOWN; | ||
2150 | |||
2151 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2152 | { | ||
2153 | GMC_send_destroy (iter->c); | ||
2154 | } | ||
2155 | GMT_destroy (t); | ||
2156 | } | ||
2157 | |||
2158 | |||
2159 | /** | ||
2160 | * Tunnel is empty: destroy it. | ||
2161 | * | ||
2162 | * Notifies all connections about the destruction. | ||
2163 | * | ||
2164 | * @param t Tunnel to destroy. | ||
2165 | */ | ||
2166 | void | ||
2167 | GMT_destroy_empty (struct CadetTunnel3 *t) | ||
2168 | { | ||
2169 | if (GNUNET_YES == shutting_down) | ||
2170 | return; /* Will be destroyed immediately anyway */ | ||
2171 | |||
2172 | if (GNUNET_SCHEDULER_NO_TASK != t->destroy_task) | ||
2173 | { | ||
2174 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2175 | "Tunnel %s is already scheduled for destruction\n", | ||
2176 | GMT_2s (t)); | ||
2177 | GNUNET_break (0); | ||
2178 | /* should never happen, tunnel can only become empty once, and the | ||
2179 | * task identifier should be NO_TASK (cleaned when the tunnel was created | ||
2180 | * or became un-empty) | ||
2181 | */ | ||
2182 | return; | ||
2183 | } | ||
2184 | |||
2185 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s empty: destroying scheduled\n", | ||
2186 | GMT_2s (t)); | ||
2187 | |||
2188 | t->destroy_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, | ||
2189 | &delayed_destroy, t); | ||
2190 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled destroy of %p as %llX\n", | ||
2191 | t, t->destroy_task); | ||
2192 | } | ||
2193 | |||
2194 | |||
2195 | /** | ||
2196 | * Destroy tunnel if empty (no more channels). | ||
2197 | * | ||
2198 | * @param t Tunnel to destroy if empty. | ||
2199 | */ | ||
2200 | void | ||
2201 | GMT_destroy_if_empty (struct CadetTunnel3 *t) | ||
2202 | { | ||
2203 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s destroy if empty\n", GMT_2s (t)); | ||
2204 | if (1 < GMT_count_channels (t)) | ||
2205 | return; | ||
2206 | |||
2207 | GMT_destroy_empty (t); | ||
2208 | } | ||
2209 | |||
2210 | |||
2211 | /** | ||
2212 | * Destroy the tunnel. | ||
2213 | * | ||
2214 | * This function does not generate any warning traffic to clients or peers. | ||
2215 | * | ||
2216 | * Tasks: | ||
2217 | * Cancel messages belonging to this tunnel queued to neighbors. | ||
2218 | * Free any allocated resources linked to the tunnel. | ||
2219 | * | ||
2220 | * @param t The tunnel to destroy. | ||
2221 | */ | ||
2222 | void | ||
2223 | GMT_destroy (struct CadetTunnel3 *t) | ||
2224 | { | ||
2225 | struct CadetTConnection *iter_c; | ||
2226 | struct CadetTConnection *next_c; | ||
2227 | struct CadetTChannel *iter_ch; | ||
2228 | struct CadetTChannel *next_ch; | ||
2229 | |||
2230 | if (NULL == t) | ||
2231 | return; | ||
2232 | |||
2233 | LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer)); | ||
2234 | |||
2235 | GNUNET_break (GNUNET_YES == | ||
2236 | GNUNET_CONTAINER_multipeermap_remove (tunnels, | ||
2237 | GMP_get_id (t->peer), t)); | ||
2238 | |||
2239 | for (iter_c = t->connection_head; NULL != iter_c; iter_c = next_c) | ||
2240 | { | ||
2241 | next_c = iter_c->next; | ||
2242 | GMC_destroy (iter_c->c); | ||
2243 | } | ||
2244 | for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = next_ch) | ||
2245 | { | ||
2246 | next_ch = iter_ch->next; | ||
2247 | GMCH_destroy (iter_ch->ch); | ||
2248 | /* Should only happen on shutdown, but it's ok. */ | ||
2249 | } | ||
2250 | |||
2251 | if (GNUNET_SCHEDULER_NO_TASK != t->destroy_task) | ||
2252 | { | ||
2253 | LOG (GNUNET_ERROR_TYPE_DEBUG, "cancelling %llX\n", t->destroy_task); | ||
2254 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
2255 | t->destroy_task = GNUNET_SCHEDULER_NO_TASK; | ||
2256 | } | ||
2257 | |||
2258 | GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO); | ||
2259 | GMP_set_tunnel (t->peer, NULL); | ||
2260 | |||
2261 | if (GNUNET_SCHEDULER_NO_TASK != t->rekey_task) | ||
2262 | { | ||
2263 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
2264 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; | ||
2265 | if (NULL != t->kx_ctx) | ||
2266 | GNUNET_free (t->kx_ctx); | ||
2267 | else | ||
2268 | GNUNET_break (0); | ||
2269 | } | ||
2270 | |||
2271 | GNUNET_free (t); | ||
2272 | } | ||
2273 | |||
2274 | |||
2275 | /** | ||
2276 | * @brief Use the given path for the tunnel. | ||
2277 | * Update the next and prev hops (and RCs). | ||
2278 | * (Re)start the path refresh in case the tunnel is locally owned. | ||
2279 | * | ||
2280 | * @param t Tunnel to update. | ||
2281 | * @param p Path to use. | ||
2282 | * | ||
2283 | * @return Connection created. | ||
2284 | */ | ||
2285 | struct CadetConnection * | ||
2286 | GMT_use_path (struct CadetTunnel3 *t, struct CadetPeerPath *p) | ||
2287 | { | ||
2288 | struct CadetConnection *c; | ||
2289 | struct GNUNET_CADET_Hash cid; | ||
2290 | unsigned int own_pos; | ||
2291 | |||
2292 | if (NULL == t || NULL == p) | ||
2293 | { | ||
2294 | GNUNET_break (0); | ||
2295 | return NULL; | ||
2296 | } | ||
2297 | |||
2298 | if (CADET_TUNNEL3_SHUTDOWN == t->cstate) | ||
2299 | { | ||
2300 | GNUNET_break (0); | ||
2301 | return NULL; | ||
2302 | } | ||
2303 | |||
2304 | for (own_pos = 0; own_pos < p->length; own_pos++) | ||
2305 | { | ||
2306 | if (p->peers[own_pos] == myid) | ||
2307 | break; | ||
2308 | } | ||
2309 | if (own_pos >= p->length) | ||
2310 | { | ||
2311 | GNUNET_break_op (0); | ||
2312 | return NULL; | ||
2313 | } | ||
2314 | |||
2315 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &cid, sizeof (cid)); | ||
2316 | c = GMC_new (&cid, t, p, own_pos); | ||
2317 | if (NULL == c) | ||
2318 | { | ||
2319 | /* Path was flawed */ | ||
2320 | return NULL; | ||
2321 | } | ||
2322 | GMT_add_connection (t, c); | ||
2323 | return c; | ||
2324 | } | ||
2325 | |||
2326 | |||
2327 | /** | ||
2328 | * Count established (ready) connections of a tunnel. | ||
2329 | * | ||
2330 | * @param t Tunnel on which to count. | ||
2331 | * | ||
2332 | * @return Number of connections. | ||
2333 | */ | ||
2334 | unsigned int | ||
2335 | GMT_count_connections (struct CadetTunnel3 *t) | ||
2336 | { | ||
2337 | struct CadetTConnection *iter; | ||
2338 | unsigned int count; | ||
2339 | |||
2340 | if (NULL == t) | ||
2341 | return 0; | ||
2342 | |||
2343 | for (count = 0, iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2344 | if (CADET_CONNECTION_DESTROYED != GMC_get_state (iter->c)) | ||
2345 | count++; | ||
2346 | |||
2347 | return count; | ||
2348 | } | ||
2349 | |||
2350 | /** | ||
2351 | * Count channels of a tunnel. | ||
2352 | * | ||
2353 | * @param t Tunnel on which to count. | ||
2354 | * | ||
2355 | * @return Number of channels. | ||
2356 | */ | ||
2357 | unsigned int | ||
2358 | GMT_count_channels (struct CadetTunnel3 *t) | ||
2359 | { | ||
2360 | struct CadetTChannel *iter; | ||
2361 | unsigned int count; | ||
2362 | |||
2363 | for (count = 0, iter = t->channel_head; | ||
2364 | NULL != iter; | ||
2365 | iter = iter->next, count++) /* skip */; | ||
2366 | |||
2367 | return count; | ||
2368 | } | ||
2369 | |||
2370 | |||
2371 | /** | ||
2372 | * Get the connectivity state of a tunnel. | ||
2373 | * | ||
2374 | * @param t Tunnel. | ||
2375 | * | ||
2376 | * @return Tunnel's connectivity state. | ||
2377 | */ | ||
2378 | enum CadetTunnel3CState | ||
2379 | GMT_get_cstate (struct CadetTunnel3 *t) | ||
2380 | { | ||
2381 | if (NULL == t) | ||
2382 | { | ||
2383 | GNUNET_assert (0); | ||
2384 | return (enum CadetTunnel3CState) -1; | ||
2385 | } | ||
2386 | return t->cstate; | ||
2387 | } | ||
2388 | |||
2389 | |||
2390 | /** | ||
2391 | * Get the encryption state of a tunnel. | ||
2392 | * | ||
2393 | * @param t Tunnel. | ||
2394 | * | ||
2395 | * @return Tunnel's encryption state. | ||
2396 | */ | ||
2397 | enum CadetTunnel3EState | ||
2398 | GMT_get_estate (struct CadetTunnel3 *t) | ||
2399 | { | ||
2400 | if (NULL == t) | ||
2401 | { | ||
2402 | GNUNET_assert (0); | ||
2403 | return (enum CadetTunnel3EState) -1; | ||
2404 | } | ||
2405 | return t->estate; | ||
2406 | } | ||
2407 | |||
2408 | /** | ||
2409 | * Get the maximum buffer space for a tunnel towards a local client. | ||
2410 | * | ||
2411 | * @param t Tunnel. | ||
2412 | * | ||
2413 | * @return Biggest buffer space offered by any channel in the tunnel. | ||
2414 | */ | ||
2415 | unsigned int | ||
2416 | GMT_get_channels_buffer (struct CadetTunnel3 *t) | ||
2417 | { | ||
2418 | struct CadetTChannel *iter; | ||
2419 | unsigned int buffer; | ||
2420 | unsigned int ch_buf; | ||
2421 | |||
2422 | if (NULL == t->channel_head) | ||
2423 | { | ||
2424 | /* Probably getting buffer for a channel create/handshake. */ | ||
2425 | return 64; | ||
2426 | } | ||
2427 | |||
2428 | buffer = 0; | ||
2429 | for (iter = t->channel_head; NULL != iter; iter = iter->next) | ||
2430 | { | ||
2431 | ch_buf = get_channel_buffer (iter); | ||
2432 | if (ch_buf > buffer) | ||
2433 | buffer = ch_buf; | ||
2434 | } | ||
2435 | return buffer; | ||
2436 | } | ||
2437 | |||
2438 | |||
2439 | /** | ||
2440 | * Get the total buffer space for a tunnel for P2P traffic. | ||
2441 | * | ||
2442 | * @param t Tunnel. | ||
2443 | * | ||
2444 | * @return Buffer space offered by all connections in the tunnel. | ||
2445 | */ | ||
2446 | unsigned int | ||
2447 | GMT_get_connections_buffer (struct CadetTunnel3 *t) | ||
2448 | { | ||
2449 | struct CadetTConnection *iter; | ||
2450 | unsigned int buffer; | ||
2451 | |||
2452 | buffer = 0; | ||
2453 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2454 | { | ||
2455 | if (GMC_get_state (iter->c) != CADET_CONNECTION_READY) | ||
2456 | { | ||
2457 | continue; | ||
2458 | } | ||
2459 | buffer += get_connection_buffer (iter); | ||
2460 | } | ||
2461 | |||
2462 | return buffer; | ||
2463 | } | ||
2464 | |||
2465 | |||
2466 | /** | ||
2467 | * Get the tunnel's destination. | ||
2468 | * | ||
2469 | * @param t Tunnel. | ||
2470 | * | ||
2471 | * @return ID of the destination peer. | ||
2472 | */ | ||
2473 | const struct GNUNET_PeerIdentity * | ||
2474 | GMT_get_destination (struct CadetTunnel3 *t) | ||
2475 | { | ||
2476 | return GMP_get_id (t->peer); | ||
2477 | } | ||
2478 | |||
2479 | |||
2480 | /** | ||
2481 | * Get the tunnel's next free global channel ID. | ||
2482 | * | ||
2483 | * @param t Tunnel. | ||
2484 | * | ||
2485 | * @return GID of a channel free to use. | ||
2486 | */ | ||
2487 | CADET_ChannelNumber | ||
2488 | GMT_get_next_chid (struct CadetTunnel3 *t) | ||
2489 | { | ||
2490 | CADET_ChannelNumber chid; | ||
2491 | CADET_ChannelNumber mask; | ||
2492 | int result; | ||
2493 | |||
2494 | /* Set bit 30 depending on the ID relationship. Bit 31 is always 0 for GID. | ||
2495 | * If our ID is bigger or loopback tunnel, start at 0, bit 30 = 0 | ||
2496 | * If peer's ID is bigger, start at 0x4... bit 30 = 1 | ||
2497 | */ | ||
2498 | result = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, GMP_get_id (t->peer)); | ||
2499 | if (0 > result) | ||
2500 | mask = 0x40000000; | ||
2501 | else | ||
2502 | mask = 0x0; | ||
2503 | t->next_chid |= mask; | ||
2504 | |||
2505 | while (NULL != GMT_get_channel (t, t->next_chid)) | ||
2506 | { | ||
2507 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", t->next_chid); | ||
2508 | t->next_chid = (t->next_chid + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; | ||
2509 | t->next_chid |= mask; | ||
2510 | } | ||
2511 | chid = t->next_chid; | ||
2512 | t->next_chid = (t->next_chid + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; | ||
2513 | t->next_chid |= mask; | ||
2514 | |||
2515 | return chid; | ||
2516 | } | ||
2517 | |||
2518 | |||
2519 | /** | ||
2520 | * Send ACK on one or more channels due to buffer in connections. | ||
2521 | * | ||
2522 | * @param t Channel which has some free buffer space. | ||
2523 | */ | ||
2524 | void | ||
2525 | GMT_unchoke_channels (struct CadetTunnel3 *t) | ||
2526 | { | ||
2527 | struct CadetTChannel *iter; | ||
2528 | unsigned int buffer; | ||
2529 | unsigned int channels = GMT_count_channels (t); | ||
2530 | unsigned int choked_n; | ||
2531 | struct CadetChannel *choked[channels]; | ||
2532 | |||
2533 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT_unchoke_channels on %s\n", GMT_2s (t)); | ||
2534 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head: %p\n", t->channel_head); | ||
2535 | if (NULL != t->channel_head) | ||
2536 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head ch: %p\n", t->channel_head->ch); | ||
2537 | |||
2538 | /* Get buffer space */ | ||
2539 | buffer = GMT_get_connections_buffer (t); | ||
2540 | if (0 == buffer) | ||
2541 | { | ||
2542 | return; | ||
2543 | } | ||
2544 | |||
2545 | /* Count and remember choked channels */ | ||
2546 | choked_n = 0; | ||
2547 | for (iter = t->channel_head; NULL != iter; iter = iter->next) | ||
2548 | { | ||
2549 | if (GNUNET_NO == get_channel_allowed (iter)) | ||
2550 | { | ||
2551 | choked[choked_n++] = iter->ch; | ||
2552 | } | ||
2553 | } | ||
2554 | |||
2555 | /* Unchoke random channels */ | ||
2556 | while (0 < buffer && 0 < choked_n) | ||
2557 | { | ||
2558 | unsigned int r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
2559 | choked_n); | ||
2560 | GMCH_allow_client (choked[r], GMCH_is_origin (choked[r], GNUNET_YES)); | ||
2561 | choked_n--; | ||
2562 | buffer--; | ||
2563 | choked[r] = choked[choked_n]; | ||
2564 | } | ||
2565 | } | ||
2566 | |||
2567 | |||
2568 | /** | ||
2569 | * Send ACK on one or more connections due to buffer space to the client. | ||
2570 | * | ||
2571 | * Iterates all connections of the tunnel and sends ACKs appropriately. | ||
2572 | * | ||
2573 | * @param t Tunnel. | ||
2574 | */ | ||
2575 | void | ||
2576 | GMT_send_connection_acks (struct CadetTunnel3 *t) | ||
2577 | { | ||
2578 | struct CadetTConnection *iter; | ||
2579 | uint32_t allowed; | ||
2580 | uint32_t to_allow; | ||
2581 | uint32_t allow_per_connection; | ||
2582 | unsigned int cs; | ||
2583 | unsigned int buffer; | ||
2584 | |||
2585 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel send connection ACKs on %s\n", | ||
2586 | GMT_2s (t)); | ||
2587 | |||
2588 | if (NULL == t) | ||
2589 | { | ||
2590 | GNUNET_break (0); | ||
2591 | return; | ||
2592 | } | ||
2593 | |||
2594 | buffer = GMT_get_channels_buffer (t); | ||
2595 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer %u\n", buffer); | ||
2596 | |||
2597 | /* Count connections, how many messages are already allowed */ | ||
2598 | cs = GMT_count_connections (t); | ||
2599 | for (allowed = 0, iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2600 | { | ||
2601 | allowed += get_connection_allowed (iter); | ||
2602 | } | ||
2603 | LOG (GNUNET_ERROR_TYPE_DEBUG, " allowed %u\n", allowed); | ||
2604 | |||
2605 | /* Make sure there is no overflow */ | ||
2606 | if (allowed > buffer) | ||
2607 | { | ||
2608 | return; | ||
2609 | } | ||
2610 | |||
2611 | /* Authorize connections to send more data */ | ||
2612 | to_allow = buffer; /* - allowed; */ | ||
2613 | |||
2614 | for (iter = t->connection_head; | ||
2615 | NULL != iter && to_allow > 0; | ||
2616 | iter = iter->next) | ||
2617 | { | ||
2618 | allow_per_connection = to_allow/cs; | ||
2619 | to_allow -= allow_per_connection; | ||
2620 | cs--; | ||
2621 | if (get_connection_allowed (iter) > 64 / 3) | ||
2622 | { | ||
2623 | continue; | ||
2624 | } | ||
2625 | GMC_allow (iter->c, allow_per_connection, | ||
2626 | GMC_is_origin (iter->c, GNUNET_NO)); | ||
2627 | } | ||
2628 | |||
2629 | GNUNET_break (to_allow == 0); | ||
2630 | } | ||
2631 | |||
2632 | |||
2633 | /** | ||
2634 | * Cancel a previously sent message while it's in the queue. | ||
2635 | * | ||
2636 | * ONLY can be called before the continuation given to the send function | ||
2637 | * is called. Once the continuation is called, the message is no longer in the | ||
2638 | * queue. | ||
2639 | * | ||
2640 | * @param q Handle to the queue. | ||
2641 | */ | ||
2642 | void | ||
2643 | GMT_cancel (struct CadetTunnel3Queue *q) | ||
2644 | { | ||
2645 | if (NULL != q->cq) | ||
2646 | { | ||
2647 | GMC_cancel (q->cq); | ||
2648 | /* tun_message_sent() will be called and free q */ | ||
2649 | } | ||
2650 | else if (NULL != q->tqd) | ||
2651 | { | ||
2652 | unqueue_data (q->tqd); | ||
2653 | q->tqd = NULL; | ||
2654 | if (NULL != q->cont) | ||
2655 | q->cont (q->cont_cls, NULL, q, 0, 0); | ||
2656 | GNUNET_free (q); | ||
2657 | } | ||
2658 | else | ||
2659 | { | ||
2660 | GNUNET_break (0); | ||
2661 | } | ||
2662 | } | ||
2663 | |||
2664 | |||
2665 | /** | ||
2666 | * Sends an already built message on a tunnel, encrypting it and | ||
2667 | * choosing the best connection if not provided. | ||
2668 | * | ||
2669 | * @param message Message to send. Function modifies it. | ||
2670 | * @param t Tunnel on which this message is transmitted. | ||
2671 | * @param c Connection to use (autoselect if NULL). | ||
2672 | * @param force Force the tunnel to take the message (buffer overfill). | ||
2673 | * @param cont Continuation to call once message is really sent. | ||
2674 | * @param cont_cls Closure for @c cont. | ||
2675 | * | ||
2676 | * @return Handle to cancel message. NULL if @c cont is NULL. | ||
2677 | */ | ||
2678 | struct CadetTunnel3Queue * | ||
2679 | GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message, | ||
2680 | struct CadetTunnel3 *t, struct CadetConnection *c, | ||
2681 | int force, GMT_sent cont, void *cont_cls) | ||
2682 | { | ||
2683 | return send_prebuilt_message (message, t, c, force, cont, cont_cls, NULL); | ||
2684 | } | ||
2685 | |||
2686 | |||
2687 | /** | ||
2688 | * Is the tunnel directed towards the local peer? | ||
2689 | * | ||
2690 | * @param t Tunnel. | ||
2691 | * | ||
2692 | * @return #GNUNET_YES if it is loopback. | ||
2693 | */ | ||
2694 | int | ||
2695 | GMT_is_loopback (const struct CadetTunnel3 *t) | ||
2696 | { | ||
2697 | return (myid == GMP_get_short_id (t->peer)); | ||
2698 | } | ||
2699 | |||
2700 | |||
2701 | /** | ||
2702 | * Is the tunnel this path already? | ||
2703 | * | ||
2704 | * @param t Tunnel. | ||
2705 | * @param p Path. | ||
2706 | * | ||
2707 | * @return #GNUNET_YES a connection uses this path. | ||
2708 | */ | ||
2709 | int | ||
2710 | GMT_is_path_used (const struct CadetTunnel3 *t, const struct CadetPeerPath *p) | ||
2711 | { | ||
2712 | struct CadetTConnection *iter; | ||
2713 | |||
2714 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2715 | if (GMC_get_path (iter->c) == p) | ||
2716 | return GNUNET_YES; | ||
2717 | |||
2718 | return GNUNET_NO; | ||
2719 | } | ||
2720 | |||
2721 | |||
2722 | /** | ||
2723 | * Get a cost of a path for a tunnel considering existing connections. | ||
2724 | * | ||
2725 | * @param t Tunnel. | ||
2726 | * @param path Candidate path. | ||
2727 | * | ||
2728 | * @return Cost of the path (path length + number of overlapping nodes) | ||
2729 | */ | ||
2730 | unsigned int | ||
2731 | GMT_get_path_cost (const struct CadetTunnel3 *t, | ||
2732 | const struct CadetPeerPath *path) | ||
2733 | { | ||
2734 | struct CadetTConnection *iter; | ||
2735 | const struct CadetPeerPath *aux; | ||
2736 | unsigned int overlap; | ||
2737 | unsigned int i; | ||
2738 | unsigned int j; | ||
2739 | |||
2740 | if (NULL == path) | ||
2741 | return 0; | ||
2742 | |||
2743 | overlap = 0; | ||
2744 | GNUNET_assert (NULL != t); | ||
2745 | |||
2746 | for (i = 0; i < path->length; i++) | ||
2747 | { | ||
2748 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | ||
2749 | { | ||
2750 | aux = GMC_get_path (iter->c); | ||
2751 | if (NULL == aux) | ||
2752 | continue; | ||
2753 | |||
2754 | for (j = 0; j < aux->length; j++) | ||
2755 | { | ||
2756 | if (path->peers[i] == aux->peers[j]) | ||
2757 | { | ||
2758 | overlap++; | ||
2759 | break; | ||
2760 | } | ||
2761 | } | ||
2762 | } | ||
2763 | } | ||
2764 | return path->length + overlap; | ||
2765 | } | ||
2766 | |||
2767 | |||
2768 | /** | ||
2769 | * Get the static string for the peer this tunnel is directed. | ||
2770 | * | ||
2771 | * @param t Tunnel. | ||
2772 | * | ||
2773 | * @return Static string the destination peer's ID. | ||
2774 | */ | ||
2775 | const char * | ||
2776 | GMT_2s (const struct CadetTunnel3 *t) | ||
2777 | { | ||
2778 | if (NULL == t) | ||
2779 | return "(NULL)"; | ||
2780 | |||
2781 | return GMP_2s (t->peer); | ||
2782 | } | ||
2783 | |||
2784 | |||
2785 | /******************************************************************************/ | ||
2786 | /***************************** INFO/DEBUG *******************************/ | ||
2787 | /******************************************************************************/ | ||
2788 | |||
2789 | |||
2790 | /** | ||
2791 | * Log all possible info about the tunnel state to stderr. | ||
2792 | * | ||
2793 | * @param t Tunnel to debug. | ||
2794 | */ | ||
2795 | void | ||
2796 | GMT_debug (const struct CadetTunnel3 *t) | ||
2797 | { | ||
2798 | struct CadetTChannel *iterch; | ||
2799 | struct CadetTConnection *iterc; | ||
2800 | |||
2801 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT DEBUG TUNNEL TOWARDS %s\n", GMT_2s (t)); | ||
2802 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT cstate %s, estate %s\n", | ||
2803 | cstate2s (t->cstate), estate2s (t->estate)); | ||
2804 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT kx_ctx %p, rekey_task %u\n", | ||
2805 | t->kx_ctx, t->rekey_task); | ||
2806 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT tq_head %p, tq_tail %p\n", | ||
2807 | t->tq_head, t->tq_tail); | ||
2808 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT destroy %u\n", t->destroy_task); | ||
2809 | |||
2810 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT channels:\n"); | ||
2811 | for (iterch = t->channel_head; NULL != iterch; iterch = iterch->next) | ||
2812 | { | ||
2813 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT - %s\n", GMCH_2s (iterch->ch)); | ||
2814 | } | ||
2815 | |||
2816 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT connections:\n"); | ||
2817 | for (iterc = t->connection_head; NULL != iterc; iterc = iterc->next) | ||
2818 | { | ||
2819 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT - %s [%u] buf: %u/%u (qn %u/%u)\n", | ||
2820 | GMC_2s (iterc->c), GMC_get_state (iterc->c), | ||
2821 | GMC_get_buffer (iterc->c, GNUNET_YES), | ||
2822 | GMC_get_buffer (iterc->c, GNUNET_NO), | ||
2823 | GMC_get_qn (iterc->c, GNUNET_YES), | ||
2824 | GMC_get_qn (iterc->c, GNUNET_NO)); | ||
2825 | } | ||
2826 | |||
2827 | LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT DEBUG TUNNEL END\n"); | ||
2828 | } | ||
2829 | |||
2830 | |||
2831 | /** | ||
2832 | * Iterate all tunnels. | ||
2833 | * | ||
2834 | * @param iter Iterator. | ||
2835 | * @param cls Closure for @c iter. | ||
2836 | */ | ||
2837 | void | ||
2838 | GMT_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls) | ||
2839 | { | ||
2840 | GNUNET_CONTAINER_multipeermap_iterate (tunnels, iter, cls); | ||
2841 | } | ||
2842 | |||
2843 | |||
2844 | /** | ||
2845 | * Count all tunnels. | ||
2846 | * | ||
2847 | * @return Number of tunnels to remote peers kept by this peer. | ||
2848 | */ | ||
2849 | unsigned int | ||
2850 | GMT_count_all (void) | ||
2851 | { | ||
2852 | return GNUNET_CONTAINER_multipeermap_size (tunnels); | ||
2853 | } | ||
2854 | |||
2855 | |||
2856 | /** | ||
2857 | * Iterate all connections of a tunnel. | ||
2858 | * | ||
2859 | * @param t Tunnel whose connections to iterate. | ||
2860 | * @param iter Iterator. | ||
2861 | * @param cls Closure for @c iter. | ||
2862 | */ | ||
2863 | void | ||
2864 | GMT_iterate_connections (struct CadetTunnel3 *t, GMT_conn_iter iter, void *cls) | ||
2865 | { | ||
2866 | struct CadetTConnection *ct; | ||
2867 | |||
2868 | for (ct = t->connection_head; NULL != ct; ct = ct->next) | ||
2869 | iter (cls, ct->c); | ||
2870 | } | ||
2871 | |||
2872 | |||
2873 | /** | ||
2874 | * Iterate all channels of a tunnel. | ||
2875 | * | ||
2876 | * @param t Tunnel whose channels to iterate. | ||
2877 | * @param iter Iterator. | ||
2878 | * @param cls Closure for @c iter. | ||
2879 | */ | ||
2880 | void | ||
2881 | GMT_iterate_channels (struct CadetTunnel3 *t, GMT_chan_iter iter, void *cls) | ||
2882 | { | ||
2883 | struct CadetTChannel *cht; | ||
2884 | |||
2885 | for (cht = t->channel_head; NULL != cht; cht = cht->next) | ||
2886 | iter (cls, cht->ch); | ||
2887 | } | ||