#endif /* ENABLE_MALICIOUS */
+/**
+ * @brief This number determines the number of slots for files that represent
+ * histograms
+ */
+#define HISTOGRAM_FILE_SLOTS 32
+
+/**
+ * @brief The size (in bytes) a file needs to store the histogram
+ *
+ * Per slot: 1 newline, up to 4 chars,
+ * Additionally: 1 null termination
+ */
+#define SIZE_DUMP_FILE (HISTOGRAM_FILE_SLOTS * 5) + 1
+
/**
* @brief One Sub.
*
unsigned int sampler_size_est_need;
/**
- * Time inverval the do_round task runs in.
+ * Time interval the do_round task runs in.
*/
struct GNUNET_TIME_Relative round_interval;
*/
struct RPS_Sampler *sampler;
+#ifdef TO_FILE_FULL
/**
* Name to log view to
*/
char *file_name_view_log;
+#endif /* TO_FILE_FULL */
#ifdef TO_FILE
+#ifdef TO_FILE_FULL
/**
* Name to log number of observed peers to
*/
char *file_name_observed_log;
+#endif /* TO_FILE_FULL */
/**
* @brief Count the observed peers
*/
uint32_t num_observed_peers;
- /**
- * @brief File name to log number of pushes per round to
- */
- char *file_name_push_recv;
-
- /**
- * @brief File name to log number of pushes per round to
- */
- char *file_name_pull_delays;
-
/**
* @brief Multipeermap (ab-) used to count unique peer_ids
*/
*
* Number at index i represents the number of rounds with i observed pushes.
*/
- uint32_t push_recv[256];
+ uint32_t push_recv[HISTOGRAM_FILE_SLOTS];
+
+ /**
+ * @brief Histogram of deltas between the expected and actual number of
+ * received pushes.
+ *
+ * As half of the entries are expected to be negative, this is shifted by
+ * #HISTOGRAM_FILE_SLOTS/2.
+ */
+ uint32_t push_delta[HISTOGRAM_FILE_SLOTS];
/**
* @brief Number of pull replies with this delay measured in rounds.
* Number at index i represents the number of pull replies with a delay of i
* rounds.
*/
- uint32_t pull_delays[256];
+ uint32_t pull_delays[HISTOGRAM_FILE_SLOTS];
};
if ( (NULL != peer_ctx->recv_channel_ctx) ||
(NULL != peer_ctx->pending_messages_head) ||
- (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) )
+ (GNUNET_YES == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) )
{
return GNUNET_NO;
}
for ( i = 0 ; i < *list_size ; i++ )
{
- if (0 == GNUNET_CRYPTO_cmp_peer_identity (&tmp[i], peer))
+ if (0 == GNUNET_memcmp (&tmp[i], peer))
{
if (i < *list_size -1)
{ /* Not at the last entry -- shift peers left */
for (i = 0; i < num_peers; i++)
{
int inserted;
+ if (GNUNET_YES != check_peer_known (sub->peer_map, &ids[i]))
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Peer in history update not known!\n");
+ continue;
+ }
inserted = insert_in_view (sub, &ids[i]);
if (GNUNET_OK == inserted)
{
clients_notify_stream_peer (sub, 1, &ids[i]);
}
+#ifdef TO_FILE_FULL
to_file (sub->file_name_view_log,
"+%s\t(hist)",
GNUNET_i2s_full (ids));
+#endif /* TO_FILE_FULL */
}
clients_notify_view_update (sub);
}
* messages to it */
//indicate_sending_intention (peer);
}
+ if (sub == msub)
+ {
+ GNUNET_STATISTICS_update (stats,
+ "# observed peers in gossip",
+ 1,
+ GNUNET_NO);
+ }
#ifdef TO_FILE
sub->num_observed_peers++;
GNUNET_CONTAINER_multipeermap_put
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
uint32_t num_observed_unique_peers =
GNUNET_CONTAINER_multipeermap_size (sub->observed_unique_peers);
+ GNUNET_STATISTICS_set (stats,
+ "# unique peers in gossip",
+ num_observed_unique_peers,
+ GNUNET_NO);
+#ifdef TO_FILE_FULL
to_file (sub->file_name_observed_log,
"%" PRIu32 " %" PRIu32 " %f\n",
sub->num_observed_peers,
num_observed_unique_peers,
1.0*num_observed_unique_peers/sub->num_observed_peers)
+#endif /* TO_FILE_FULL */
#endif /* TO_FILE */
}
if (GNUNET_YES == check_peer_known (sub->peer_map,
peer))
{
- destroy_peer (get_peer_ctx (sub->peer_map,
- peer));
+ destroy_peer (get_peer_ctx (sub->peer_map,
+ peer));
}
}
"Going to remove send channel to peer %s\n",
GNUNET_i2s (peer));
#if ENABLE_MALICIOUS
- if (0 != GNUNET_CRYPTO_cmp_peer_identity (&attacked_peer,
+ if (0 != GNUNET_memcmp (&attacked_peer,
peer))
(void) destroy_sending_channel (get_peer_ctx (sub->peer_map,
peer));
(GNUNET_NO == View_contains_peer (sub->view, peer)) &&
(GNUNET_NO == CustomPeerMap_contains_peer (sub->push_map, peer)) &&
(GNUNET_NO == CustomPeerMap_contains_peer (sub->push_map, peer)) &&
- (0 == RPS_sampler_count_id (sub->sampler, peer)) &&
- (GNUNET_NO != check_removable (get_peer_ctx (sub->peer_map, peer))) )
+ (0 == RPS_sampler_count_id (sub->sampler, peer)) &&
+ (GNUNET_YES == check_removable (get_peer_ctx (sub->peer_map, peer))) )
{ /* We can safely remove this peer */
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Going to remove peer %s\n",
round_interval);
/* Logging of internals */
+#ifdef TO_FILE_FULL
sub->file_name_view_log = store_prefix_file_name (&own_identity, "view");
+#endif /* TO_FILE_FULL */
#ifdef TO_FILE
+#ifdef TO_FILE_FULL
sub->file_name_observed_log = store_prefix_file_name (&own_identity,
"observed");
- sub->file_name_push_recv = store_prefix_file_name (&own_identity,
- "push_recv");
- sub->file_name_pull_delays = store_prefix_file_name (&own_identity,
- "pull_delays");
+#endif /* TO_FILE_FULL */
sub->num_observed_peers = 0;
sub->observed_unique_peers = GNUNET_CONTAINER_multipeermap_create (1,
GNUNET_NO);
}
+#ifdef TO_FILE
+/**
+ * @brief Write all numbers in the given array into the given file
+ *
+ * Single numbers devided by a newline
+ *
+ * @param hist_array[] the array to dump
+ * @param file_name file to dump into
+ */
+static void
+write_histogram_to_file (const uint32_t hist_array[],
+ const char *file_name)
+{
+ char collect_str[SIZE_DUMP_FILE + 1] = "";
+ char *recv_str_iter;
+ char *file_name_full;
+
+ recv_str_iter = collect_str;
+ file_name_full = store_prefix_file_name (&own_identity,
+ file_name);
+ for (uint32_t i = 0; i < HISTOGRAM_FILE_SLOTS; i++)
+ {
+ char collect_str_tmp[8];
+
+ GNUNET_snprintf (collect_str_tmp,
+ sizeof (collect_str_tmp),
+ "%" PRIu32 "\n",
+ hist_array[i]);
+ recv_str_iter = stpncpy (recv_str_iter,
+ collect_str_tmp,
+ 6);
+ }
+ (void) stpcpy (recv_str_iter,
+ "\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Writing push stats to disk\n");
+ to_file_w_len (file_name_full,
+ SIZE_DUMP_FILE,
+ collect_str);
+ GNUNET_free (file_name_full);
+}
+#endif /* TO_FILE */
+
+
/**
* @brief Destroy Sub.
*
static void
destroy_sub (struct Sub *sub)
{
-#ifdef TO_FILE
- char push_recv_str[1536] = ""; /* 256 * 6 (1 whitespace, 1 comma, up to 4 chars) */
- char pull_delays_str[1536] = ""; /* 256 * 6 (1 whitespace, 1 comma, up to 4 chars) */
-#endif /* TO_FILE */
GNUNET_assert (NULL != sub);
GNUNET_assert (NULL != sub->do_round_task);
GNUNET_SCHEDULER_cancel (sub->do_round_task);
/* Disconnect from cadet */
GNUNET_CADET_close_port (sub->cadet_port);
+ sub->cadet_port= NULL;
/* Clean up data structures for peers */
RPS_sampler_destroy (sub->sampler);
peers_terminate (sub);
/* Free leftover data structures */
+#ifdef TO_FILE_FULL
GNUNET_free (sub->file_name_view_log);
sub->file_name_view_log = NULL;
+#endif /* TO_FILE_FULL */
#ifdef TO_FILE
+#ifdef TO_FILE_FULL
GNUNET_free (sub->file_name_observed_log);
sub->file_name_observed_log = NULL;
+#endif /* TO_FILE_FULL */
/* Write push frequencies to disk */
- for (uint32_t i = 0; i < 256; i++)
- {
- char push_recv_str_tmp[8];
-
- GNUNET_snprintf (push_recv_str_tmp,
- sizeof (push_recv_str_tmp),
- "%" PRIu32 "\n",
- sub->push_recv[i]);
- // FIXME: better use stpcpy!
- (void) strncat (push_recv_str,
- push_recv_str_tmp,
- 1535 - strnlen (push_recv_str, 1536));
- }
- (void) strncat (push_recv_str,
- "\n",
- 1535 - strnlen (push_recv_str, 1536));
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Writing push stats to disk\n");
- to_file_w_len (sub->file_name_push_recv, 1535, push_recv_str);
- GNUNET_free (sub->file_name_push_recv);
- sub->file_name_push_recv = NULL;
+ write_histogram_to_file (sub->push_recv,
+ "push_recv");
- /* Write pull delays to disk */
- for (uint32_t i = 0; i < 256; i++)
- {
- char pull_delays_str_tmp[8];
+ /* Write push deltas to disk */
+ write_histogram_to_file (sub->push_delta,
+ "push_delta");
- GNUNET_snprintf (pull_delays_str_tmp,
- sizeof (pull_delays_str_tmp),
- "%" PRIu32 "\n",
- sub->pull_delays[i]);
- // FIXME: better use stpcpy!
- (void) strncat (pull_delays_str,
- pull_delays_str_tmp,
- 1535 - strnlen (pull_delays_str, 1536));
- }
- (void) strncat (pull_delays_str,
- "\n",
- 1535 - strnlen (pull_delays_str, 1536));
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing pull delays to disk\n");
- to_file_w_len (sub->file_name_pull_delays, 1535, pull_delays_str);
- GNUNET_free (sub->file_name_pull_delays);
- sub->file_name_pull_delays = NULL;
+ /* Write pull delays to disk */
+ write_histogram_to_file (sub->pull_delays,
+ "pull_delays");
GNUNET_CONTAINER_multipeermap_destroy (sub->observed_unique_peers);
sub->observed_unique_peers = NULL;
if (channel_ctx->peer_ctx->sub == msub)
{
GNUNET_STATISTICS_update(stats, "# push message received", 1, GNUNET_NO);
+ if (NULL != map_single_hop &&
+ GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (map_single_hop,
+ peer))
+ {
+ GNUNET_STATISTICS_update (stats,
+ "# push message received (multi-hop peer)",
+ 1,
+ GNUNET_NO);
+ }
}
#if ENABLE_MALICIOUS
else if (2 == mal_type)
{ /* Try to partition network */
- if (0 == GNUNET_CRYPTO_cmp_peer_identity (&attacked_peer, peer))
+ if (0 == GNUNET_memcmp (&attacked_peer, peer))
{
send_pull_reply (peer_ctx, mal_peers, num_mal_peers);
}
1,
GNUNET_NO);
}
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
}
return GNUNET_OK;
}
GNUNET_assert (GNUNET_NO == check_peer_flag (peer_ctx->sub->peer_map,
&peer_ctx->peer_id,
Peers_PULL_REPLY_PENDING));
- SET_PEER_FLAG (peer_ctx, Peers_PULL_REPLY_PENDING);
+ SET_PEER_FLAG (peer_ctx,
+ Peers_PULL_REPLY_PENDING);
peer_ctx->round_pull_req = peer_ctx->sub->num_rounds;
LOG (GNUNET_ERROR_TYPE_DEBUG,
GNUNET_i2s (&peer_ctx->peer_id));
ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST);
- send_message (peer_ctx, ev, "PULL REQUEST");
+ send_message (peer_ctx,
+ ev,
+ "PULL REQUEST");
if (peer_ctx->sub)
{
GNUNET_STATISTICS_update (stats,
"# push send issued",
1,
GNUNET_NO);
+ if (NULL != map_single_hop &&
+ GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (map_single_hop,
+ &peer_ctx->peer_id))
+ {
+ GNUNET_STATISTICS_update (stats,
+ "# push send issued (multi-hop peer)",
+ 1,
+ GNUNET_NO);
+ }
}
}
GNUNET_STATISTICS_update (stats, "# rounds", 1, GNUNET_NO);
}
sub->do_round_task = NULL;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Printing view:\n");
+#ifdef TO_FILE_FULL
to_file (sub->file_name_view_log,
"___ new round ___");
+#endif /* TO_FILE_FULL */
view_array = View_get_as_array (sub->view);
for (i = 0; i < View_size (sub->view); i++)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"\t%s\n", GNUNET_i2s (&view_array[i]));
+#ifdef TO_FILE_FULL
to_file (sub->file_name_view_log,
"=%s\t(do round)",
GNUNET_i2s_full (&view_array[i]));
+#endif /* TO_FILE_FULL */
}
/* Seems like recreating is the easiest way of emptying the peermap */
View_clear (sub->view);
+#ifdef TO_FILE_FULL
to_file (sub->file_name_view_log,
"--- emptied ---");
+#endif /* TO_FILE_FULL */
first_border = GNUNET_MIN (ceil (alpha * sub->view_size_est_need),
CustomPeerMap_size (sub->push_map));
1,
CustomPeerMap_get_peer_by_index (sub->push_map, permut[i]));
}
+#ifdef TO_FILE_FULL
to_file (sub->file_name_view_log,
"+%s\t(push list)",
GNUNET_i2s_full (&view_array[i]));
+#endif /* TO_FILE_FULL */
// TODO change the peer_flags accordingly
}
GNUNET_free (permut);
CustomPeerMap_get_peer_by_index (sub->pull_map,
permut[i - first_border]));
}
+#ifdef TO_FILE_FULL
to_file (sub->file_name_view_log,
"+%s\t(pull list)",
GNUNET_i2s_full (&view_array[i]));
+#endif /* TO_FILE_FULL */
// TODO change the peer_flags accordingly
}
GNUNET_free (permut);
/* Clean peers that were removed from the view */
for (i = 0; i < peers_to_clean_size; i++)
{
+#ifdef TO_FILE_FULL
to_file (sub->file_name_view_log,
"-%s",
GNUNET_i2s_full (&peers_to_clean[i]));
+#endif /* TO_FILE_FULL */
clean_peer (sub, &peers_to_clean[i]);
}
if (sub == msub)
{
GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO);
- if (CustomPeerMap_size (sub->push_map) > alpha * View_size (sub->view) &&
+ if (CustomPeerMap_size (sub->push_map) > alpha * sub->view_size_est_need &&
!(0 >= CustomPeerMap_size (sub->pull_map)))
GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes", 1, GNUNET_NO);
- if (CustomPeerMap_size (sub->push_map) > alpha * View_size (sub->view) &&
+ if (CustomPeerMap_size (sub->push_map) > alpha * sub->view_size_est_need &&
(0 >= CustomPeerMap_size (sub->pull_map)))
GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes, no pull replies", 1, GNUNET_NO);
if (0 >= CustomPeerMap_size (sub->push_map) &&
(0 >= CustomPeerMap_size (sub->pull_map)))
GNUNET_STATISTICS_update(stats, "# rounds blocked - no pushes, no pull replies", 1, GNUNET_NO);
if (0 >= CustomPeerMap_size (sub->pull_map) &&
- CustomPeerMap_size (sub->push_map) > alpha * View_size (sub->view) &&
+ CustomPeerMap_size (sub->push_map) > alpha * sub->view_size_est_need &&
0 >= CustomPeerMap_size (sub->push_map))
GNUNET_STATISTICS_update(stats, "# rounds blocked - no pull replies", 1, GNUNET_NO);
}
}
// TODO independent of that also get some peers from CADET_get_peers()?
- sub->push_recv[CustomPeerMap_size (sub->push_map)]++;
+ if (CustomPeerMap_size (sub->push_map) < HISTOGRAM_FILE_SLOTS)
+ {
+ sub->push_recv[CustomPeerMap_size (sub->push_map)]++;
+ }
+ else
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Push map size too big for histogram (%u, %u)\n",
+ CustomPeerMap_size (sub->push_map),
+ HISTOGRAM_FILE_SLOTS);
+ }
+ // FIXME check bounds of histogram
+ sub->push_delta[(int32_t) (CustomPeerMap_size (sub->push_map) -
+ (alpha * sub->view_size_est_need)) +
+ (HISTOGRAM_FILE_SLOTS/2)]++;
if (sub == msub)
{
GNUNET_STATISTICS_set (stats,
"# peers in view at end of round",
View_size (sub->view),
GNUNET_NO);
+ GNUNET_STATISTICS_set (stats,
+ "# expected pushes",
+ alpha * sub->view_size_est_need,
+ GNUNET_NO);
+ GNUNET_STATISTICS_set (stats,
+ "delta expected - received pushes",
+ CustomPeerMap_size (sub->push_map) - (alpha * sub->view_size_est_need),
+ GNUNET_NO);
}
LOG (GNUNET_ERROR_TYPE_DEBUG,