diff options
-rw-r--r-- | src/core/gnunet-service-core_kx.c | 63 | ||||
-rw-r--r-- | src/core/gnunet-service-core_kx.h | 5 | ||||
-rw-r--r-- | src/core/gnunet-service-core_neighbours.c | 2 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.c | 94 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.h | 69 |
5 files changed, 167 insertions, 66 deletions
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index b10e0bc58..1ab31cb2b 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c | |||
@@ -371,6 +371,9 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx) | |||
371 | GNUNET_PEERINFO_iterate_cancel (kx->pitr); | 371 | GNUNET_PEERINFO_iterate_cancel (kx->pitr); |
372 | kx->pitr = NULL; | 372 | kx->pitr = NULL; |
373 | } | 373 | } |
374 | |||
375 | GNUNET_SCHEDULER_cancel (n->dead_clean_task); | ||
376 | if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
374 | if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) | 377 | if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) |
375 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); | 378 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); |
376 | GNUNET_free_non_null (kx->public_key); | 379 | GNUNET_free_non_null (kx->public_key); |
@@ -1513,6 +1516,66 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *n, | |||
1513 | } | 1516 | } |
1514 | 1517 | ||
1515 | 1518 | ||
1519 | /** | ||
1520 | * Task triggered when a neighbour entry is about to time out | ||
1521 | * (and we should prevent this by sending a PING). | ||
1522 | * | ||
1523 | * @param cls the 'struct Neighbour' | ||
1524 | * @param tc scheduler context (not used) | ||
1525 | */ | ||
1526 | static void | ||
1527 | send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1528 | { | ||
1529 | struct Neighbour *n = cls; | ||
1530 | struct GNUNET_TIME_Relative retry; | ||
1531 | struct GNUNET_TIME_Relative left; | ||
1532 | struct MessageEntry *me; | ||
1533 | struct PingMessage pp; | ||
1534 | struct PingMessage *pm; | ||
1535 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
1536 | |||
1537 | n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; | ||
1538 | /* send PING */ | ||
1539 | me = GNUNET_malloc (sizeof (struct MessageEntry) + | ||
1540 | sizeof (struct PingMessage)); | ||
1541 | me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY); | ||
1542 | me->priority = PING_PRIORITY; | ||
1543 | me->size = sizeof (struct PingMessage); | ||
1544 | GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail, | ||
1545 | n->encrypted_tail, me); | ||
1546 | pm = (struct PingMessage *) &me[1]; | ||
1547 | pm->header.size = htons (sizeof (struct PingMessage)); | ||
1548 | pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); | ||
1549 | pm->iv_seed = | ||
1550 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
1551 | derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer); | ||
1552 | pp.challenge = n->ping_challenge; | ||
1553 | pp.target = n->peer; | ||
1554 | #if DEBUG_HANDSHAKE | ||
1555 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1556 | "Encrypting `%s' message with challenge %u for `%4s' using key %u, IV %u (salt %u).\n", | ||
1557 | "PING", (unsigned int) n->ping_challenge, GNUNET_i2s (&n->peer), | ||
1558 | (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv, | ||
1559 | sizeof | ||
1560 | (iv)), | ||
1561 | pm->iv_seed); | ||
1562 | #endif | ||
1563 | do_encrypt (n, &iv, &pp.target, &pm->target, | ||
1564 | sizeof (struct PingMessage) - ((void *) &pm->target - | ||
1565 | (void *) pm)); | ||
1566 | process_encrypted_neighbour_queue (n); | ||
1567 | /* reschedule PING job */ | ||
1568 | left = GNUNET_TIME_absolute_get_remaining (get_neighbour_timeout (n)); | ||
1569 | retry = | ||
1570 | GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2), | ||
1571 | MIN_PING_FREQUENCY); | ||
1572 | n->keep_alive_task = | ||
1573 | GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, n); | ||
1574 | |||
1575 | } | ||
1576 | |||
1577 | |||
1578 | |||
1516 | 1579 | ||
1517 | 1580 | ||
1518 | /** | 1581 | /** |
diff --git a/src/core/gnunet-service-core_kx.h b/src/core/gnunet-service-core_kx.h index b5b9b712e..104aed5e4 100644 --- a/src/core/gnunet-service-core_kx.h +++ b/src/core/gnunet-service-core_kx.h | |||
@@ -99,6 +99,11 @@ struct GSC_KeyExchangeInfo | |||
99 | GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task; | 99 | GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task; |
100 | 100 | ||
101 | /** | 101 | /** |
102 | * ID of task used for sending keep-alive pings. | ||
103 | */ | ||
104 | GNUNET_SCHEDULER_TaskIdentifier keep_alive_task; | ||
105 | |||
106 | /** | ||
102 | * What was our PING challenge number (for this peer)? | 107 | * What was our PING challenge number (for this peer)? |
103 | */ | 108 | */ |
104 | uint32_t ping_challenge; | 109 | uint32_t ping_challenge; |
diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c index 0e50454d1..8a0677c88 100644 --- a/src/core/gnunet-service-core_neighbours.c +++ b/src/core/gnunet-service-core_neighbours.c | |||
@@ -166,7 +166,7 @@ free_neighbour (struct Neighbour *n) | |||
166 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th); | 166 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th); |
167 | n->th = NULL; | 167 | n->th = NULL; |
168 | } | 168 | } |
169 | GSC_SESSION_end (&n->peer); | 169 | GSC_SESSIONS_end (&n->peer); |
170 | if (NULL != n->kx) | 170 | if (NULL != n->kx) |
171 | { | 171 | { |
172 | GSC_KX_stop (n->kx); | 172 | GSC_KX_stop (n->kx); |
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 1c1332bd4..23d53022e 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -1,5 +1,33 @@ | |||
1 | /* code for managing of 'encrypted' sessions (key exchange done) */ | 1 | /* |
2 | This file is part of GNUnet. | ||
3 | (C) 2009, 2010, 2011 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 | */ | ||
2 | 20 | ||
21 | /** | ||
22 | * @file core/gnunet-service-core_neighbours.c | ||
23 | * @brief code for managing of 'encrypted' sessions (key exchange done) | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_service_core.h" | ||
28 | #include "gnunet_service_core_neighbours.h" | ||
29 | #include "gnunet_service_core_kx.h" | ||
30 | #include "gnunet_service_core_sessions.h" | ||
3 | 31 | ||
4 | /** | 32 | /** |
5 | * Record kept for each request for transmission issued by a | 33 | * Record kept for each request for transmission issued by a |
@@ -39,10 +67,6 @@ struct Session | |||
39 | */ | 67 | */ |
40 | struct GSC_KeyExchangeInfo *kxinfo; | 68 | struct GSC_KeyExchangeInfo *kxinfo; |
41 | 69 | ||
42 | /** | ||
43 | * ID of task used for sending keep-alive pings. | ||
44 | */ | ||
45 | GNUNET_SCHEDULER_TaskIdentifier keep_alive_task; | ||
46 | 70 | ||
47 | /** | 71 | /** |
48 | * ID of task used for cleaning up dead neighbour entries. | 72 | * ID of task used for cleaning up dead neighbour entries. |
@@ -386,8 +410,6 @@ free_neighbour (struct Neighbour *n) | |||
386 | if (n->quota_update_task != GNUNET_SCHEDULER_NO_TASK) | 410 | if (n->quota_update_task != GNUNET_SCHEDULER_NO_TASK) |
387 | GNUNET_SCHEDULER_cancel (n->quota_update_task); | 411 | GNUNET_SCHEDULER_cancel (n->quota_update_task); |
388 | if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK) | 412 | if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK) |
389 | GNUNET_SCHEDULER_cancel (n->dead_clean_task); | ||
390 | if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
391 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); | 413 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); |
392 | if (n->status == PEER_STATE_KEY_CONFIRMED) | 414 | if (n->status == PEER_STATE_KEY_CONFIRMED) |
393 | GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), | 415 | GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), |
@@ -401,64 +423,6 @@ free_neighbour (struct Neighbour *n) | |||
401 | 423 | ||
402 | 424 | ||
403 | /** | 425 | /** |
404 | * Task triggered when a neighbour entry is about to time out | ||
405 | * (and we should prevent this by sending a PING). | ||
406 | * | ||
407 | * @param cls the 'struct Neighbour' | ||
408 | * @param tc scheduler context (not used) | ||
409 | */ | ||
410 | static void | ||
411 | send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
412 | { | ||
413 | struct Neighbour *n = cls; | ||
414 | struct GNUNET_TIME_Relative retry; | ||
415 | struct GNUNET_TIME_Relative left; | ||
416 | struct MessageEntry *me; | ||
417 | struct PingMessage pp; | ||
418 | struct PingMessage *pm; | ||
419 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
420 | |||
421 | n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; | ||
422 | /* send PING */ | ||
423 | me = GNUNET_malloc (sizeof (struct MessageEntry) + | ||
424 | sizeof (struct PingMessage)); | ||
425 | me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY); | ||
426 | me->priority = PING_PRIORITY; | ||
427 | me->size = sizeof (struct PingMessage); | ||
428 | GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail, | ||
429 | n->encrypted_tail, me); | ||
430 | pm = (struct PingMessage *) &me[1]; | ||
431 | pm->header.size = htons (sizeof (struct PingMessage)); | ||
432 | pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); | ||
433 | pm->iv_seed = | ||
434 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
435 | derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer); | ||
436 | pp.challenge = n->ping_challenge; | ||
437 | pp.target = n->peer; | ||
438 | #if DEBUG_HANDSHAKE | ||
439 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
440 | "Encrypting `%s' message with challenge %u for `%4s' using key %u, IV %u (salt %u).\n", | ||
441 | "PING", (unsigned int) n->ping_challenge, GNUNET_i2s (&n->peer), | ||
442 | (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv, | ||
443 | sizeof | ||
444 | (iv)), | ||
445 | pm->iv_seed); | ||
446 | #endif | ||
447 | do_encrypt (n, &iv, &pp.target, &pm->target, | ||
448 | sizeof (struct PingMessage) - ((void *) &pm->target - | ||
449 | (void *) pm)); | ||
450 | process_encrypted_neighbour_queue (n); | ||
451 | /* reschedule PING job */ | ||
452 | left = GNUNET_TIME_absolute_get_remaining (get_neighbour_timeout (n)); | ||
453 | retry = | ||
454 | GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2), | ||
455 | MIN_PING_FREQUENCY); | ||
456 | n->keep_alive_task = | ||
457 | GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, n); | ||
458 | |||
459 | } | ||
460 | |||
461 | /** | ||
462 | * Consider freeing the given neighbour since we may not need | 426 | * Consider freeing the given neighbour since we may not need |
463 | * to keep it around anymore. | 427 | * to keep it around anymore. |
464 | * | 428 | * |
diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h new file mode 100644 index 000000000..2f8c01840 --- /dev/null +++ b/src/core/gnunet-service-core_sessions.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009, 2010, 2011 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 | /** | ||
22 | * @file core/gnunet-service-core_neighbours.h | ||
23 | * @brief code for managing of 'encrypted' sessions (key exchange done) | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_CORE_SESSIONS_H | ||
27 | #define GNUNET_SERVICE_CORE_SESSIONS_H | ||
28 | |||
29 | #include "gnunet_service_core_kx.h" | ||
30 | #include "gnunet_service_core_sessions.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * End the session with the given peer (we are no longer | ||
35 | * connected). | ||
36 | * | ||
37 | * @param pid identity of peer to kill session with | ||
38 | */ | ||
39 | void | ||
40 | GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid); | ||
41 | |||
42 | |||
43 | /** | ||
44 | * Traffic is being solicited for the given peer. This means that | ||
45 | * the message queue on the transport-level is now empty and it | ||
46 | * is now OK to transmit another (non-control) message. | ||
47 | * | ||
48 | * @param pid identity of peer ready to receive data | ||
49 | */ | ||
50 | void | ||
51 | GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid); | ||
52 | |||
53 | |||
54 | /** | ||
55 | * Initialize sessions subsystem. | ||
56 | */ | ||
57 | void | ||
58 | GSC_SESSIONS_init (void); | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Shutdown sessions subsystem. | ||
63 | */ | ||
64 | void | ||
65 | GSC_SESSIONS_done (void); | ||
66 | |||
67 | |||
68 | |||
69 | #endif | ||