[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r10529 - in gnunet: . src/core src/include src/util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r10529 - in gnunet: . src/core src/include src/util |
Date: |
Wed, 10 Mar 2010 11:55:01 +0100 |
Author: grothoff
Date: 2010-03-10 11:55:01 +0100 (Wed, 10 Mar 2010)
New Revision: 10529
Modified:
gnunet/TODO
gnunet/src/core/gnunet-service-core.c
gnunet/src/include/gnunet_time_lib.h
gnunet/src/util/time.c
Log:
keepalive PINGs
Modified: gnunet/TODO
===================================================================
--- gnunet/TODO 2010-03-10 10:27:23 UTC (rev 10528)
+++ gnunet/TODO 2010-03-10 10:55:01 UTC (rev 10529)
@@ -13,7 +13,6 @@
* ARM [Safey]
Urgent items (before announcing ng.gnunet.org):
-* core fails to do keepalive on idle connections => disconnect!
* new webpage
- run peer => have a 0.9.x hostlist
=> Deploy(able) development network
Modified: gnunet/src/core/gnunet-service-core.c
===================================================================
--- gnunet/src/core/gnunet-service-core.c 2010-03-10 10:27:23 UTC (rev
10528)
+++ gnunet/src/core/gnunet-service-core.c 2010-03-10 10:55:01 UTC (rev
10529)
@@ -101,6 +101,11 @@
#define MAX_PONG_DELAY GNUNET_TIME_relative_multiply (MAX_PING_DELAY, 2)
/**
+ * What is the minimum frequency for a PING message?
+ */
+#define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 5)
+
+/**
* How often do we recalculate bandwidth quotas?
*/
#define QUOTA_UPDATE_FREQUENCY GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 5)
@@ -477,6 +482,11 @@
GNUNET_SCHEDULER_TaskIdentifier quota_update_task;
/**
+ * ID of task used for sending keep-alive pings.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier keep_alive_task;
+
+ /**
* ID of task used for cleaning up dead neighbour entries.
*/
GNUNET_SCHEDULER_TaskIdentifier dead_clean_task;
@@ -1074,6 +1084,8 @@
GNUNET_SCHEDULER_cancel (sched, n->quota_update_task);
if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
GNUNET_SCHEDULER_cancel (sched, n->dead_clean_task);
+ if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (sched, n->keep_alive_task);
GNUNET_free_non_null (n->public_key);
GNUNET_free_non_null (n->pending_ping);
GNUNET_free_non_null (n->pending_pong);
@@ -1082,6 +1094,53 @@
/**
+ * Check if we have encrypted messages for the specified neighbour
+ * pending, and if so, check with the transport about sending them
+ * out.
+ *
+ * @param n neighbour to check.
+ */
+static void process_encrypted_neighbour_queue (struct Neighbour *n);
+
+
+/**
+ * Encrypt size bytes from in and write the result to out. Use the
+ * key for outbound traffic of the given neighbour.
+ *
+ * @param n neighbour we are sending to
+ * @param iv initialization vector to use
+ * @param in ciphertext
+ * @param out plaintext
+ * @param size size of in/out
+ * @return GNUNET_OK on success
+ */
+static int
+do_encrypt (struct Neighbour *n,
+ const GNUNET_HashCode * iv,
+ const void *in, void *out, size_t size)
+{
+ if (size != (uint16_t) size)
+ {
+ GNUNET_break (0);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (size ==
+ GNUNET_CRYPTO_aes_encrypt (in,
+ (uint16_t) size,
+ &n->encrypt_key,
+ (const struct
+
GNUNET_CRYPTO_AesInitializationVector
+ *) iv, out));
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Encrypted %u bytes for `%4s' using key %u\n", size,
+ GNUNET_i2s (&n->peer), n->encrypt_key.crc32);
+#endif
+ return GNUNET_OK;
+}
+
+
+/**
* Consider freeing the given neighbour since we may not need
* to keep it around anymore.
*
@@ -1092,6 +1151,68 @@
/**
+ * Task triggered when a neighbour entry is about to time out
+ * (and we should prevent this by sending a PING).
+ *
+ * @param cls the 'struct Neighbour'
+ * @param tc scheduler context (not used)
+ */
+static void
+send_keep_alive (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct Neighbour *n = cls;
+ struct GNUNET_TIME_Relative retry;
+ struct GNUNET_TIME_Relative left;
+ struct MessageEntry *me;
+ struct PingMessage pp;
+ struct PingMessage *pm;
+
+ n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
+ /* send PING */
+ me = GNUNET_malloc (sizeof (struct MessageEntry) +
+ sizeof (struct PingMessage));
+ me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
+ me->priority = PING_PRIORITY;
+ me->size = sizeof (struct PingMessage);
+ n->encrypted_tail->next = me;
+ n->encrypted_tail = me;
+ pm = (struct PingMessage *) &me[1];
+ pm->header.size = htons (sizeof (struct PingMessage));
+ pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
+ pp.challenge = htonl (n->ping_challenge);
+ pp.target = n->peer;
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Encrypting `%s' and `%s' messages for `%4s'.\n",
+ "SET_KEY", "PING", GNUNET_i2s (&n->peer));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending `%s' to `%4s' with challenge %u encrypted using key
%u\n",
+ "PING",
+ GNUNET_i2s (&n->peer), n->ping_challenge, n->encrypt_key.crc32);
+#endif
+ do_encrypt (n,
+ &n->peer.hashPubKey,
+ &pp.challenge,
+ &pm->challenge,
+ sizeof (struct PingMessage) -
+ sizeof (struct GNUNET_MessageHeader));
+ process_encrypted_neighbour_queue (n);
+ /* reschedule PING job */
+ left = GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_add
(n->last_activity,
+
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
+ retry = GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2),
+ MIN_PING_FREQUENCY);
+ n->keep_alive_task
+ = GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_relative_divide (left, 2),
+ &send_keep_alive,
+ n);
+
+}
+
+
+/**
* Task triggered when a neighbour entry might have gotten stale.
*
* @param cls the 'struct Neighbour'
@@ -1102,6 +1223,7 @@
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct Neighbour *n = cls;
+
n->dead_clean_task = GNUNET_SCHEDULER_NO_TASK;
consider_free_neighbour (n);
}
@@ -1127,7 +1249,7 @@
return; /* no chance */
left = GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_add
(n->last_activity,
-
MAX_PONG_DELAY));
+
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
if (left.value > 0)
{
if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
@@ -1157,16 +1279,6 @@
/**
- * Check if we have encrypted messages for the specified neighbour
- * pending, and if so, check with the transport about sending them
- * out.
- *
- * @param n neighbour to check.
- */
-static void process_encrypted_neighbour_queue (struct Neighbour *n);
-
-
-/**
* Function called when the transport service is ready to
* receive an encrypted message for the respective peer
*
@@ -1330,43 +1442,6 @@
/**
- * Encrypt size bytes from in and write the result to out. Use the
- * key for outbound traffic of the given neighbour.
- *
- * @param n neighbour we are sending to
- * @param iv initialization vector to use
- * @param in ciphertext
- * @param out plaintext
- * @param size size of in/out
- * @return GNUNET_OK on success
- */
-static int
-do_encrypt (struct Neighbour *n,
- const GNUNET_HashCode * iv,
- const void *in, void *out, size_t size)
-{
- if (size != (uint16_t) size)
- {
- GNUNET_break (0);
- return GNUNET_NO;
- }
- GNUNET_assert (size ==
- GNUNET_CRYPTO_aes_encrypt (in,
- (uint16_t) size,
- &n->encrypt_key,
- (const struct
-
GNUNET_CRYPTO_AesInitializationVector
- *) iv, out));
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Encrypted %u bytes for `%4s' using key %u\n", size,
- GNUNET_i2s (&n->peer), n->encrypt_key.crc32);
-#endif
- return GNUNET_OK;
-}
-
-
-/**
* Select messages for transmission. This heuristic uses a combination
* of earliest deadline first (EDF) scheduling (with bounded horizon)
* and priority-based discard (in case no feasible schedule exist) and
@@ -2645,9 +2720,16 @@
cnm.peer = n->peer;
send_to_all_clients (&cnm.header, GNUNET_YES,
GNUNET_CORE_OPTION_SEND_CONNECT);
process_encrypted_neighbour_queue (n);
- break;
+ /* fall-through! */
case PEER_STATE_KEY_CONFIRMED:
- /* duplicate PONG? */
+ n->last_activity = GNUNET_TIME_absolute_get ();
+ if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (sched, n->keep_alive_task);
+ n->keep_alive_task
+ = GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_relative_divide
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2),
+ &send_keep_alive,
+ n);
break;
default:
GNUNET_break (0);
@@ -2711,8 +2793,9 @@
sizeof (struct GNUNET_PeerIdentity)))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Received `%s' message that was not for me. Ignoring.\n"),
- "SET_KEY");
+ _("Received `%s' message that was for `%s', not for me.
Ignoring.\n"),
+ "SET_KEY",
+ GNUNET_i2s (&m->target));
return;
}
if ((ntohl (m->purpose.size) !=
@@ -3106,6 +3189,13 @@
NULL, NULL);
}
n->last_activity = GNUNET_TIME_absolute_get ();
+ if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (sched, n->keep_alive_task);
+ n->keep_alive_task
+ = GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_relative_divide
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2),
+ &send_keep_alive,
+ n);
off = sizeof (struct EncryptedMessage);
deliver_messages (n, buf, size, off);
}
@@ -3233,6 +3323,13 @@
n->last_activity = now;
if (!up)
n->time_established = now;
+ if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (sched, n->keep_alive_task);
+ n->keep_alive_task
+ = GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_relative_divide
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2),
+ &send_keep_alive,
+ n);
}
}
Modified: gnunet/src/include/gnunet_time_lib.h
===================================================================
--- gnunet/src/include/gnunet_time_lib.h 2010-03-10 10:27:23 UTC (rev
10528)
+++ gnunet/src/include/gnunet_time_lib.h 2010-03-10 10:55:01 UTC (rev
10529)
@@ -204,7 +204,21 @@
struct
GNUNET_TIME_Relative t2);
+
/**
+ * Return the maximum of two relative time values.
+ *
+ * @param t1 first timestamp
+ * @param t2 other timestamp
+ * @return timestamp that is larger
+ */
+struct GNUNET_TIME_Relative GNUNET_TIME_relative_max (struct
+ GNUNET_TIME_Relative
+ t1,
+ struct
+ GNUNET_TIME_Relative t2);
+
+/**
* Return the minimum of two absolute time values.
*
* @param t1 first timestamp
@@ -314,6 +328,19 @@
factor);
/**
+ * Divide relative time by a given factor.
+ *
+ * @param rel some duration
+ * @param factor integer to divide by
+ * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
+ */
+struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide (struct
+ GNUNET_TIME_Relative
+ rel,
+ unsigned int
+ factor);
+
+/**
* Add relative times together.
*
* @param a1 some relative time
Modified: gnunet/src/util/time.c
===================================================================
--- gnunet/src/util/time.c 2010-03-10 10:27:23 UTC (rev 10528)
+++ gnunet/src/util/time.c 2010-03-10 10:55:01 UTC (rev 10529)
@@ -137,7 +137,23 @@
}
+/**
+ * Return the maximum of two relative time values.
+ *
+ * @param t1 first timestamp
+ * @param t2 other timestamp
+ * @return timestamp that is larger
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_max (struct
+ GNUNET_TIME_Relative
+ t1, struct GNUNET_TIME_Relative t2)
+{
+ return (t1.value > t2.value) ? t1 : t2;
+}
+
+
/**
* Return the minimum of two relative time values.
*
@@ -277,6 +293,26 @@
/**
+ * Divide relative time by a given factor.
+ *
+ * @param rel some duration
+ * @param factor integer to divide by
+ * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
+ unsigned int factor)
+{
+ struct GNUNET_TIME_Relative ret;
+ if ( (factor == 0) ||
+ (rel.value == GNUNET_TIME_UNIT_FOREVER_REL.value) )
+ return GNUNET_TIME_UNIT_FOREVER_REL;
+ ret.value = rel.value / (unsigned long long) factor;
+ return ret;
+}
+
+
+/**
* Calculate the estimate time of arrival/completion
* for an operation.
*
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r10529 - in gnunet: . src/core src/include src/util,
gnunet <=