aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/gnunet-service-core_kx.c63
-rw-r--r--src/core/gnunet-service-core_kx.h5
-rw-r--r--src/core/gnunet-service-core_neighbours.c2
-rw-r--r--src/core/gnunet-service-core_sessions.c94
-rw-r--r--src/core/gnunet-service-core_sessions.h69
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 */
1526static void
1527send_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 */
410static void
411send_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 */
39void
40GSC_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 */
50void
51GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid);
52
53
54/**
55 * Initialize sessions subsystem.
56 */
57void
58GSC_SESSIONS_init (void);
59
60
61/**
62 * Shutdown sessions subsystem.
63 */
64void
65GSC_SESSIONS_done (void);
66
67
68
69#endif