#include "gnunet_peerinfo_service.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
+#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
#include "core.h"
#define DEBUG_HANDSHAKE GNUNET_NO
-#define DEBUG_CORE_QUOTA GNUNET_YES
+#define DEBUG_CORE_QUOTA GNUNET_NO
/**
* Receive and send buffer windows grow over time. For
*/
#define PAST_EXPIRATION_DISCARD_TIME GNUNET_TIME_UNIT_SECONDS
+/**
+ * How long do we delay messages to get larger packet sizes (CORKing)?
+ */
+#define MAX_CORK_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
+
/**
* What is the maximum delay for a SET_KEY message?
*/
*/
#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 PONG_PRIORITY 0xFFFFFF
/**
- * How many messages do we queue per peer at most?
+ * How many messages do we queue per peer at most? Must be at
+ * least two.
*/
#define MAX_PEER_QUEUE_SIZE 16
*/
struct GNUNET_TIME_Absolute deadline;
+ /**
+ * By when are we supposed to transmit this message (after
+ * giving slack)?
+ */
+ struct GNUNET_TIME_Absolute slack_deadline;
+
/**
* How important is this message to us?
*/
*/
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.
*/
*/
static struct Neighbour *neighbours;
+/**
+ * For creating statistics.
+ */
+static struct GNUNET_STATISTICS_Handle *stats;
+
/**
* Sum of all preferences among all neighbours.
*/
preference_sum += n->current_preference;
n = n->next;
}
+ GNUNET_STATISTICS_set (stats, gettext_noop ("# total peer preference"), preference_sum, GNUNET_NO);
}
while (c != NULL)
{
if (0 != (c->options & options))
- send_to_client (c, msg, can_drop);
+ {
+#if DEBUG_CORE_CLIENT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending message of type %u to client.\n",
+ ntohs (msg->type));
+#endif
+ send_to_client (c, msg, can_drop);
+ }
c = c->next;
}
}
"Sending `%s' message to client.\n", "INIT_REPLY");
#endif
send_to_client (c, &irm.header, GNUNET_NO);
- /* notify new client about existing neighbours */
- cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
- cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- n = neighbours;
- while (n != NULL)
+ if (0 != (c->options & GNUNET_CORE_OPTION_SEND_CONNECT))
{
- if (n->status == PEER_STATE_KEY_CONFIRMED)
+ /* notify new client about existing neighbours */
+ cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
+ cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
+ n = neighbours;
+ while (n != NULL)
{
+ if (n->status == PEER_STATE_KEY_CONFIRMED)
+ {
#if DEBUG_CORE_CLIENT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
#endif
- cnm.distance = htonl (n->last_distance);
- cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
- cnm.peer = n->peer;
- send_to_client (c, &cnm.header, GNUNET_NO);
+ cnm.distance = htonl (n->last_distance);
+ cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
+ cnm.peer = n->peer;
+ send_to_client (c, &cnm.header, GNUNET_NO);
+ }
+ n = n->next;
}
- n = n->next;
}
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
if (n != NULL)
{
want_reserv = ntohl (rcm->reserve_inbound);
- n->bw_out_internal_limit = rcm->limit_outbound;
- n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
- n->bw_out_external_limit);
- GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
- n->bw_out);
+ if (n->bw_out_internal_limit.value__ != rcm->limit_outbound.value__)
+ {
+ n->bw_out_internal_limit = rcm->limit_outbound;
+ n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
+ n->bw_out_external_limit);
+ GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
+ n->bw_out);
+ GNUNET_TRANSPORT_set_quota (transport,
+ &n->peer,
+ n->bw_in,
+ n->bw_out,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL, NULL);
+ }
if (want_reserv < 0)
{
got_reserv = want_reserv;
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);
+ if (n->status == PEER_STATE_KEY_CONFIRMED)
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# peers connected"), -1, GNUNET_NO);
GNUNET_free_non_null (n->public_key);
GNUNET_free_non_null (n->pending_ping);
GNUNET_free_non_null (n->pending_pong);
}
+/**
+ * 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));
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes encrypted"), size, GNUNET_NO);
+#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.
consider_free_neighbour (struct Neighbour *n);
+/**
+ * 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);
+ GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head,
+ n->encrypted_tail,
+ 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,
+ retry,
+ &send_keep_alive,
+ n);
+
+}
+
+
/**
* Task triggered when a neighbour entry might have gotten stale.
*
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct Neighbour *n = cls;
+
n->dead_clean_task = GNUNET_SCHEDULER_NO_TASK;
consider_free_neighbour (n);
}
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)
prev->next = n->next;
GNUNET_assert (neighbour_count > 0);
neighbour_count--;
+ GNUNET_STATISTICS_set (stats, gettext_noop ("# active neighbours"), neighbour_count, GNUNET_NO);
free_neighbour (n);
}
-/**
- * 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
GNUNET_break (0);
return GNUNET_SYSERR;
}
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes decrypted"), size, GNUNET_NO);
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Decrypted %u bytes from `%4s' using key %u\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;
-}
-
-
/**
* Select messages for transmission. This heuristic uses a combination
* of earliest deadline first (EDF) scheduling (with bounded horizon)
uint64_t avail;
struct GNUNET_TIME_Relative slack; /* how long could we wait before missing deadlines? */
size_t off;
- int discard_low_prio;
+ uint64_t tsize;
unsigned int queue_size;
+ int discard_low_prio;
GNUNET_assert (NULL != n->messages);
now = GNUNET_TIME_absolute_get ();
priority from consideration for scheduling at the
end of the loop? */
queue_size = 0;
+ tsize = 0;
pos = n->messages;
while (pos != NULL)
{
queue_size++;
+ tsize += pos->size;
pos = pos->next;
}
discard_low_prio = GNUNET_YES;
off = 0;
/* maximum time we can wait before transmitting anything
and still make all of our deadlines */
- slack = GNUNET_TIME_UNIT_FOREVER_REL;
+ slack = MAX_CORK_DELAY;
pos = n->messages;
/* note that we use "*2" here because we want to look
a bit further into the future; much more makes no
slack = GNUNET_TIME_relative_min (slack,
GNUNET_BANDWIDTH_value_get_delay_for (n->bw_out,
avail));
- if ( (pos->deadline.value < now.value) ||
- (GNUNET_YES == pos->got_slack) )
+ if (pos->deadline.value <= now.value)
{
+ /* now or never */
slack = GNUNET_TIME_UNIT_ZERO;
}
+ else if (GNUNET_YES == pos->got_slack)
+ {
+ /* should be soon now! */
+ slack = GNUNET_TIME_relative_min (slack,
+ GNUNET_TIME_absolute_get_remaining (pos->slack_deadline));
+ }
else
{
slack =
GNUNET_TIME_relative_min (slack,
GNUNET_TIME_absolute_get_difference (now, pos->deadline));
pos->got_slack = GNUNET_YES;
+ pos->slack_deadline = GNUNET_TIME_absolute_min (pos->deadline,
+ GNUNET_TIME_relative_to_absolute (MAX_CORK_DELAY));
}
}
}
}
/* guard against sending "tiny" messages with large headers without
urgent deadlines */
- if ( (slack.value > 1000) &&
+ if ( (slack.value > 0) &&
(size > 4 * off) &&
- (queue_size < MAX_PEER_QUEUE_SIZE / 2) )
+ (queue_size <= MAX_PEER_QUEUE_SIZE - 2) )
{
/* less than 25% of message would be filled with deadlines still
being met if we delay by one second or more; so just wait for
more data; but do not wait longer than 1s (since we don't want
to delay messages for a really long time either). */
- retry_time->value = 1000;
+ *retry_time = MAX_CORK_DELAY;
/* reset do_transmit values for next time */
while (pos != last)
{
}
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Deferring transmission for 1s due to underfull message buffer size (%u/%u)\n",
+ "Deferring transmission for %llums due to underfull message buffer size (%u/%u)\n",
+ (unsigned long long) slack.value,
(unsigned int) off,
(unsigned int) size);
#endif
}
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Selected %u bytes of plaintext messages for transmission to `%4s'.\n",
- off, GNUNET_i2s (&n->peer));
+ "Selected %u/%u bytes of %u/%u plaintext messages for transmission to `%4s'.\n",
+ off, tsize,
+ queue_size, MAX_PEER_QUEUE_SIZE,
+ GNUNET_i2s (&n->peer));
#endif
return off;
}
*retry_time = GNUNET_TIME_UNIT_FOREVER_REL;
if (0 == select_messages (n, size, retry_time))
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"No messages selected, will try again in %llu ms\n",
retry_time->value);
+#endif
return 0;
}
ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND);
*priority += pos->priority;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding plaintext message with deadline %llu ms to batch\n",
+ "Adding plaintext message of size %u with deadline %llu ms to batch\n",
+ pos->size,
GNUNET_TIME_absolute_get_remaining (pos->deadline).value);
#endif
deadline->value = GNUNET_MIN (deadline->value, pos->deadline.value);
{
struct Neighbour *n = cls;
+#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Retrying key transmission to `%4s'\n",
GNUNET_i2s (&n->peer));
+#endif
n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
n->set_key_retry_frequency =
GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
n->next = neighbours;
neighbours = n;
neighbour_count++;
+ GNUNET_STATISTICS_set (stats, gettext_noop ("# active neighbours"), neighbour_count, GNUNET_NO);
n->peer = *pid;
GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
now = GNUNET_TIME_absolute_get ();
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding transmission request for `%4s' to queue\n",
- GNUNET_i2s (&sm->peer));
+ "Adding transmission request for `%4s' of size %u to queue\n",
+ GNUNET_i2s (&sm->peer),
+ msize);
#endif
e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
if ( (n->is_connected) ||
(n->th != NULL) )
return; /* already connected, or at least trying */
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# connection requests received"), 1, GNUNET_NO);
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Core received `%s' request for `%4s', will try to establish connection\n",
n->pitr = NULL;
if (n->public_key != NULL)
{
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# SETKEY messages deferred (need public key)"),
+ -1,
+ GNUNET_NO);
send_key (n);
}
else
{
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# Delayed connecting due to lack of public key"),
+ 1,
+ GNUNET_NO);
if (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task)
n->retry_set_key_task
= GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
{
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# Error extracting public key from HELLO"),
+ 1,
+ GNUNET_NO);
GNUNET_free (n->public_key);
n->public_key = NULL;
#if DEBUG_CORE
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;
+ GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head,
+ n->encrypted_tail,
+ 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);
"Target of `%s' request is `%4s'.\n",
"PING", GNUNET_i2s (&t.target));
#endif
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# ping messages decrypted"), 1, GNUNET_NO);
if (0 != memcmp (&t.target,
&my_identity, sizeof (struct GNUNET_PeerIdentity)))
{
return;
case PEER_STATE_KEY_RECEIVED:
n->status = PEER_STATE_KEY_CONFIRMED;
- n->bw_out_external_limit = t.inbound_bw_limit;
- n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
- n->bw_out_internal_limit);
- GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
- n->bw_out);
+ if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__)
+ {
+ n->bw_out_external_limit = t.inbound_bw_limit;
+ n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
+ n->bw_out_internal_limit);
+ GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
+ n->bw_out);
+ GNUNET_TRANSPORT_set_quota (transport,
+ &n->peer,
+ n->bw_in,
+ n->bw_out,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL, NULL);
+ }
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Confirmed key via `%s' message for peer `%4s'\n",
"PONG", GNUNET_i2s (&n->peer));
-#endif
+#endif
if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
{
GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
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);
0,
GNUNET_TIME_UNIT_MINUTES,
&process_hello_retry_handle_set_key, n);
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# SETKEY messages deferred (need public key)"), 1, GNUNET_NO);
return;
}
if (0 != memcmp (&m->target,
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) !=
return;
}
#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Decrypting key material.\n");
#endif
if ((GNUNET_CRYPTO_rsa_decrypt (my_private_key,
&m->encrypted_key,
}
/* process decrypted message(s) */
-#if DEBUG_CORE_QUOTA
if (n->bw_out_external_limit.value__ != pt->inbound_bw_limit.value__)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received %u b/s as new inbound limit for peer `%4s'\n",
- (unsigned int) ntohl (pt->inbound_bw_limit.value__),
- GNUNET_i2s (&n->peer));
-#endif
- n->bw_out_external_limit = pt->inbound_bw_limit;
- n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
- n->bw_out_internal_limit);
- GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
- n->bw_out);
+ {
+#if DEBUG_CORE_SET_QUOTA
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received %u b/s as new inbound limit for peer `%4s'\n",
+ (unsigned int) ntohl (pt->inbound_bw_limit.value__),
+ GNUNET_i2s (&n->peer));
+#endif
+ n->bw_out_external_limit = pt->inbound_bw_limit;
+ n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
+ n->bw_out_internal_limit);
+ GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
+ n->bw_out);
+ GNUNET_TRANSPORT_set_quota (transport,
+ &n->peer,
+ n->bw_in,
+ n->bw_out,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ 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);
}
GNUNET_break_op (0);
return;
}
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# session keys received"), 1, GNUNET_NO);
handle_set_key (n, (const struct SetKeyMessage *) message);
break;
case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
(n->status != PEER_STATE_KEY_CONFIRMED))
{
GNUNET_break_op (0);
+ /* blacklist briefly (?); might help recover (?) */
+ GNUNET_TRANSPORT_blacklist (sched, cfg,
+ &n->peer,
+ GNUNET_TIME_UNIT_SECONDS,
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
+ 5),
+ NULL, NULL);
return;
}
handle_encrypted_message (n, (const struct EncryptedMessage *) message);
GNUNET_break_op (0);
return;
}
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# ping messages received"), 1, GNUNET_NO);
if ((n->status != PEER_STATE_KEY_RECEIVED) &&
(n->status != PEER_STATE_KEY_CONFIRMED))
{
GNUNET_break_op (0);
return;
}
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# pong messages received"), 1, GNUNET_NO);
if ( (n->status != PEER_STATE_KEY_RECEIVED) &&
(n->status != PEER_STATE_KEY_CONFIRMED) )
{
now = GNUNET_TIME_absolute_get ();
n->last_activity = now;
if (!up)
- n->time_established = now;
+ {
+ GNUNET_STATISTICS_update (stats, gettext_noop ("# peers connected"), 1, GNUNET_NO);
+ 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);
}
}
unsigned int distance)
{
struct Neighbour *n;
- struct GNUNET_TIME_Absolute now;
struct ConnectNotifyMessage cnm;
n = find_neighbour (peer);
{
n = create_neighbour (peer);
}
- now = GNUNET_TIME_absolute_get ();
n->is_connected = GNUNET_YES;
n->last_latency = latency;
n->last_distance = distance;
cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
cnm.peer = *peer;
send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_PRE_CONNECT);
- send_key (n);
+ GNUNET_TRANSPORT_set_quota (transport,
+ &n->peer,
+ n->bw_in,
+ n->bw_out,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL, NULL);
+ send_key (n);
}
neighbour_count--;
free_neighbour (n);
}
+ GNUNET_STATISTICS_set (stats, gettext_noop ("# active neighbours"), neighbour_count, GNUNET_NO);
GNUNET_SERVER_notification_context_destroy (notifier);
notifier = NULL;
while (NULL != (c = clients))
handle_client_disconnect (NULL, c->client_handle);
if (my_private_key != NULL)
GNUNET_CRYPTO_rsa_key_free (my_private_key);
+ if (stats != NULL)
+ GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
}
&handle_transport_notify_connect,
&handle_transport_notify_disconnect);
GNUNET_assert (NULL != transport);
+ stats = GNUNET_STATISTICS_create (sched, "core", cfg);
GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_TIME_UNIT_FOREVER_REL,
&cleaning_task, NULL);