libgnunetdhtlog.la
plugin_LTLIBRARIES = \
- libgnunet_plugin_dhtlog_dummy.la $(MYSQL_PLUGIN) \
+ $(MYSQL_PLUGIN) \
+ libgnunet_plugin_dhtlog_dummy.la \
libgnunet_plugin_dhtlog_mysql_dump.la
-if HAVE_MYSQL
+
libgnunet_plugin_dhtlog_mysql_la_SOURCES = \
plugin_dhtlog_mysql.c
libgnunet_plugin_dhtlog_mysql_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(XLIB)
+ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lz -lsqlite3
libgnunet_plugin_dhtlog_mysql_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient $(ZLIB_LNK)
-endif
+ $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient
+libgnunet_plugin_dhtlog_mysql_la_CPFLAGS = \
+ $(MYSQL_CPPFLAGS)
libgnunet_plugin_dhtlog_dummy_la_SOURCES = \
plugin_dhtlog_dummy.c
#define DHT_SEND_PRIORITY 4
+#define STAT_ROUTES "# DHT ROUTE Requests Seen"
+#define STAT_ROUTE_FORWARDS "# DHT ROUTE Requests Forwarded"
+#define STAT_RESULTS "# DHT ROUTE RESULT Requests Seen"
+#define STAT_RESULTS_TO_CLIENT "# DHT ROUTE RESULT Sent to Client"
+#define STAT_RESULT_FORWARDS "# DHT ROUTE RESULT Requests Forwarded"
+#define STAT_GETS "# DHT GET Requests Handled"
+#define STAT_PUTS "# DHT PUT Requests Handled"
+#define STAT_PUTS_INSERTED "# DHT PUT Data Inserts"
+#define STAT_FIND_PEER "# DHT FIND_PEER Requests Handled"
+#define STAT_FIND_PEER_START "# DHT FIND_PEER Requests Initiated"
+#define STAT_GET_START "# DHT GET Requests Initiated"
+#define STAT_PUT_START "# DHT PUT Requests Initiated"
+#define STAT_FIND_PEER_REPLY "# DHT FIND_PEER Responses Received"
+#define STAT_GET_REPLY "# DHT GET Responses Received"
+#define STAT_FIND_PEER_ANSWER "# DHT FIND_PEER Responses Initiated"
+#define STAT_GET_RESPONSE_START "# DHT GET Responses Initiated"
+
typedef void (*GNUNET_DHT_MessageReceivedHandler) (void *cls,
const struct GNUNET_MessageHeader
*msg);
pending->timeout = GNUNET_TIME_relative_get_forever();
pending->cont = cont;
pending->cont_cls = cont_cls;
+ pending->free_on_send = GNUNET_YES;
pending->unique_id = 0; /* When finished is called, free pending->msg */
if (route_handle->dht_handle->current == NULL)
int malicious_droppers,
char *message);
+ /*
+ * Inserts the specified stats into the dhttests.node_statistics table
+ *
+ * @param peer the peer inserting the statistic
+ * @param route_requests route requests seen
+ * @param route_forwards route requests forwarded
+ * @param result_requests route result requests seen
+ * @param client_requests client requests initiated
+ * @param result_forwards route results forwarded
+ * @param gets get requests handled
+ * @param puts put requests handle
+ * @param data_inserts data inserted at this node
+ * @param find_peer_requests find peer requests seen
+ * @param find_peers_started find peer requests initiated at this node
+ * @param gets_started get requests initiated at this node
+ * @param puts_started put requests initiated at this node
+ * @param find_peer_responses_received find peer responses received locally
+ * @param get_responses_received get responses received locally
+ * @param find_peer_responses_sent find peer responses sent from this node
+ * @param get_responses_sent get responses sent from this node
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+ int (*insert_stat)
+ (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
+ unsigned int route_forwards, unsigned int result_requests,
+ unsigned int client_requests, unsigned int result_forwards,
+ unsigned int gets, unsigned int puts,
+ unsigned int data_inserts, unsigned int find_peer_requests,
+ unsigned int find_peers_started, unsigned int gets_started,
+ unsigned int puts_started, unsigned int find_peer_responses_received,
+ unsigned int get_responses_received, unsigned int find_peer_responses_sent,
+ unsigned int get_responses_sent);
+
/*
* Update dhttests.trials table with current server time as end time
*
#include "gnunet_core_service.h"
#include "gnunet_dht_service.h"
#include "dhtlog.h"
+#include "dht.h"
/* DEFINES */
#define VERBOSE GNUNET_NO
char *startup_string;
};
+/**
+ * Linked list of information for populating statistics
+ * before ending trial.
+ */
+struct StatisticsIteratorContext
+{
+ const struct GNUNET_PeerIdentity *peer;
+ unsigned int stat_routes;
+ unsigned int stat_route_forwards;
+ unsigned int stat_results;
+ unsigned int stat_results_to_client;
+ unsigned int stat_result_forwards;
+ unsigned int stat_gets;
+ unsigned int stat_puts;
+ unsigned int stat_puts_inserted;
+ unsigned int stat_find_peer;
+ unsigned int stat_find_peer_start;
+ unsigned int stat_get_start;
+ unsigned int stat_put_start;
+ unsigned int stat_find_peer_reply;
+ unsigned int stat_get_reply;
+ unsigned int stat_find_peer_answer;
+ unsigned int stat_get_response_start;
+};
+
/**
* Context for getting a topology, logging it, and continuing
* on with some next operation.
struct TopologyIteratorContext
{
unsigned int total_connections;
+ struct GNUNET_PeerIdentity *peer;
GNUNET_SCHEDULER_Task cont;
void *cls;
struct GNUNET_TIME_Relative timeout;
static unsigned long long trialuid;
+/**
+ * Hash map of stats contexts.
+ */
+struct GNUNET_CONTAINER_MultiHashMap *stats_map;
+
/**
* List of GETS to perform
*/
GNUNET_TESTING_daemons_stop (pg, DEFAULT_TIMEOUT, &shutdown_callback, NULL);
- /* FIXME: optionally get stats for dropped messages, etc. */
if (dhtlog_handle != NULL)
{
fprintf(stderr, "Update trial endtime\n");
dhtlog_handle->update_trial (trialuid, 0, 0, 0);
+ GNUNET_DHTLOG_disconnect(dhtlog_handle);
+ dhtlog_handle = NULL;
}
if (hostkey_meter != NULL)
}
}
+/**
+ * Iterator over hash map entries.
+ *
+ * @param cls closure - always NULL
+ * @param key current key code
+ * @param value value in the hash map, a stats context
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+static int stats_iterate (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct StatisticsIteratorContext *stats_ctx;
+ if (value == NULL)
+ return GNUNET_NO;
+ stats_ctx = value;
+ dhtlog_handle->insert_stat(stats_ctx->peer, stats_ctx->stat_routes, stats_ctx->stat_route_forwards, stats_ctx->stat_results,
+ stats_ctx->stat_results_to_client, stats_ctx->stat_result_forwards, stats_ctx->stat_gets,
+ stats_ctx->stat_puts, stats_ctx->stat_puts_inserted, stats_ctx->stat_find_peer,
+ stats_ctx->stat_find_peer_start, stats_ctx->stat_get_start, stats_ctx->stat_put_start,
+ stats_ctx->stat_find_peer_reply, stats_ctx->stat_get_reply, stats_ctx->stat_find_peer_answer,
+ stats_ctx->stat_get_response_start);
+ GNUNET_free(stats_ctx);
+ return GNUNET_YES;
+}
+
+static void stats_finished (void *cls, int result)
+{
+ fprintf(stderr, "Finished getting all peers statistics, iterating!\n");
+ GNUNET_CONTAINER_multihashmap_iterate(stats_map, &stats_iterate, NULL);
+ GNUNET_CONTAINER_multihashmap_destroy(stats_map);
+ GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL);
+}
+
+/**
+ * Callback function to process statistic values.
+ *
+ * @param cls closure
+ * @param peer the peer the statistics belong to
+ * @param subsystem name of subsystem that created the statistic
+ * @param name the name of the datum
+ * @param value the current value
+ * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
+ * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
+ */
+static int stats_handle (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *subsystem,
+ const char *name,
+ uint64_t value,
+ int is_persistent)
+{
+ struct StatisticsIteratorContext *stats_ctx;
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s:%s:%s -- %llu\n", GNUNET_i2s(peer), subsystem, name, value);
+ if (GNUNET_CONTAINER_multihashmap_contains(stats_map, &peer->hashPubKey))
+ {
+ stats_ctx = GNUNET_CONTAINER_multihashmap_get(stats_map, &peer->hashPubKey);
+ }
+ else
+ {
+ stats_ctx = GNUNET_malloc(sizeof(struct StatisticsIteratorContext));
+ stats_ctx->peer = peer;
+ GNUNET_CONTAINER_multihashmap_put(stats_map, &peer->hashPubKey, stats_ctx, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ }
+
+ if (strcmp(name, STAT_ROUTES) == 0)
+ stats_ctx->stat_routes = value;
+ else if (strcmp(name, STAT_ROUTE_FORWARDS) == 0)
+ stats_ctx->stat_route_forwards = value;
+ else if (strcmp(name, STAT_RESULTS) == 0)
+ stats_ctx->stat_results = value;
+ else if (strcmp(name, STAT_RESULTS_TO_CLIENT) == 0)
+ stats_ctx->stat_results_to_client = value;
+ else if (strcmp(name, STAT_RESULT_FORWARDS) == 0)
+ stats_ctx->stat_result_forwards = value;
+ else if (strcmp(name, STAT_GETS) == 0)
+ stats_ctx->stat_gets = value;
+ else if (strcmp(name, STAT_PUTS) == 0)
+ stats_ctx->stat_puts = value;
+ else if (strcmp(name, STAT_PUTS_INSERTED) == 0)
+ stats_ctx->stat_puts_inserted = value;
+ else if (strcmp(name, STAT_FIND_PEER) == 0)
+ stats_ctx->stat_find_peer = value;
+ else if (strcmp(name, STAT_FIND_PEER_START) == 0)
+ stats_ctx->stat_find_peer_start = value;
+ else if (strcmp(name, STAT_GET_START) == 0)
+ stats_ctx->stat_get_start = value;
+ else if (strcmp(name, STAT_PUT_START) == 0)
+ stats_ctx->stat_put_start = value;
+ else if (strcmp(name, STAT_FIND_PEER_REPLY) == 0)
+ stats_ctx->stat_find_peer_reply = value;
+ else if (strcmp(name, STAT_GET_REPLY) == 0)
+ stats_ctx->stat_get_reply = value;
+ else if (strcmp(name, STAT_FIND_PEER_ANSWER) == 0)
+ stats_ctx->stat_find_peer_answer = value;
+ else if (strcmp(name, STAT_GET_RESPONSE_START) == 0)
+ stats_ctx->stat_get_response_start = value;
+
+ return GNUNET_OK;
+}
+
+/**
+ * Connect to statistics service for each peer and get the appropriate
+ * dht statistics for safe keeping.
+ */
+static void
+log_dht_statistics (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+ stats_map = GNUNET_CONTAINER_multihashmap_create(num_peers);
+ GNUNET_TESTING_get_statistics(pg, &stats_finished, &stats_handle, NULL);
+}
+
+
/**
* Connect to all peers in the peer group and iterate over their
* connections.
{
fprintf(stderr, "Update trial endtime\n");
dhtlog_handle->update_trial (trialuid, 0, 0, 0);
+ GNUNET_DHTLOG_disconnect(dhtlog_handle);
+ dhtlog_handle = NULL;
}
if (hostkey_meter != NULL)
if (dhtlog_handle != NULL)
{
topo_ctx = GNUNET_malloc(sizeof(struct TopologyIteratorContext));
- topo_ctx->cont = &finish_testing;
+ topo_ctx->cont = &log_dht_statistics;
GNUNET_SCHEDULER_add_now(sched, &capture_current_topology, topo_ctx);
}
else
continue_puts_and_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
{
int i;
+ int max;
struct TopologyIteratorContext *topo_ctx;
if (dhtlog_handle != NULL)
{
- for (i = 1; i < (settle_time / 60) - 2; i++)
+ if (settle_time >= 60 * 2)
+ max = (settle_time / 60) - 2;
+ else
+ max = 1;
+ for (i = 1; i < max; i++)
{
topo_ctx = GNUNET_malloc(sizeof(struct TopologyIteratorContext));
fprintf(stderr, "scheduled topology iteration in %d minutes\n", i);
#include "gnunet_transport_service.h"
#include "gnunet_hello_lib.h"
#include "gnunet_dht_service.h"
+#include "gnunet_statistics_service.h"
#include "dhtlog.h"
#include "dht.h"
#define DHT_DEFAULT_FIND_PEER_OPTIONS GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
-#define DHT_DEFAULT_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 1)
+#define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 1)
+#define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)
+
+/*
+ * Default frequency for sending malicious get messages
+ */
+#define DEFAULT_MALICIOUS_GET_FREQUENCY 1 /* Number of seconds */
+
+/*
+ * Default frequency for sending malicious put messages
+ */
+#define DEFAULT_MALICIOUS_PUT_FREQUENCY 1 /* Default is seconds */
#define DHT_DEFAULT_PING_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 1)
};
+
/**
* Per-peer information.
*/
*/
static struct GNUNET_DATACACHE_Handle *datacache;
+/**
+ * Handle for the statistics service.
+ */
+struct GNUNET_STATISTICS_Handle *stats;
+
/**
* The main scheduler to use for the DHT service
*/
*/
static unsigned int debug_routes_extended;
+/*
+ * GNUNET_YES or GNUNET_NO, whether or not to act as
+ * a malicious node which drops all messages
+ */
+static unsigned int malicious_dropper;
+
+/*
+ * GNUNET_YES or GNUNET_NO, whether or not to act as
+ * a malicious node which sends out lots of GETS
+ */
+static unsigned int malicious_getter;
+
+/*
+ * GNUNET_YES or GNUNET_NO, whether or not to act as
+ * a malicious node which sends out lots of PUTS
+ */
+static unsigned int malicious_putter;
+
+static unsigned long long malicious_get_frequency;
+
+static unsigned long long malicious_put_frequency;
+
/**
* Forward declaration.
*/
size_t core_transmit_notify (void *cls,
size_t size, void *buf);
+static void
+increment_stats(const char *value)
+{
+ if (stats != NULL)
+ {
+ GNUNET_STATISTICS_update (stats, value, 1, GNUNET_NO);
+ }
+}
+
/**
* Try to send another message from our core send list
*/
size_t msize;
size_t psize;
+ increment_stats(STAT_RESULT_FORWARDS);
msize = sizeof (struct GNUNET_DHT_P2PRouteResultMessage) + ntohs(msg->size);
GNUNET_assert(msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE);
psize = sizeof(struct P2PPendingMessage) + msize;
size_t msize;
size_t psize;
+ increment_stats(STAT_ROUTE_FORWARDS);
msize = sizeof (struct GNUNET_DHT_P2PRouteMessage) + ntohs(msg->size);
GNUNET_assert(msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE);
psize = sizeof(struct P2PPendingMessage) + msize;
{
int bucket;
+ if (GNUNET_CONTAINER_multihashmap_contains(all_known_peers, &peer->hashPubKey))
+ return GNUNET_NO; /* We already know this peer (are connected even!) */
bucket = find_current_bucket(&peer->hashPubKey);
if ((k_buckets[bucket].peers_size < bucket_size) || ((bucket == lowest_bucket) && (lowest_bucket > 0)))
return GNUNET_YES;
struct PeerInfo *peer_info;
const struct GNUNET_MessageHeader *hello_msg;
+ increment_stats(STAT_RESULTS);
/**
* If a find peer result message is received and contains a valid
* HELLO for another peer, offer it to the transport service.
}
else /* We have a valid hello, and peer id stored in new_peer */
{
+ increment_stats(STAT_FIND_PEER_REPLY);
if (GNUNET_YES == consider_peer(&new_peer))
{
GNUNET_TRANSPORT_offer_hello(transport_handle, hello_msg);
message_context->peer, NULL);
}
#endif
+ increment_stats(STAT_RESULTS_TO_CLIENT);
+ if (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT_GET_RESULT)
+ increment_stats(STAT_GET_REPLY);
+
send_reply_to_client(pos->client, msg, message_context->unique_id);
}
else /* Send to peer */
new_msg_ctx->peer = &my_identity;
new_msg_ctx->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
new_msg_ctx->hop_count = 0;
+ increment_stats(STAT_GET_RESPONSE_START);
route_result_message(cls, &get_result->header, new_msg_ctx);
GNUNET_free(new_msg_ctx);
//send_reply_to_client (datacache_get_ctx->client, &get_result->header,
get_type = ntohs (get_msg->type);
#if DEBUG_DHT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "`%s:%s': Received `%s' request from client, message type %u, key %s, uid %llu\n", my_short_id,
+ "`%s:%s': Received `%s' request, message type %u, key %s, uid %llu\n", my_short_id,
"DHT", "GET", get_type, GNUNET_h2s (message_context->key),
message_context->unique_id);
#endif
-
+ increment_stats(STAT_GETS);
results = 0;
if (datacache != NULL)
results =
new_msg_ctx->peer = &my_identity;
new_msg_ctx->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
new_msg_ctx->hop_count = 0;
+ increment_stats(STAT_FIND_PEER_ANSWER);
route_result_message(cls, find_peer_result, new_msg_ctx);
GNUNET_free(new_msg_ctx);
#if DEBUG_DHT_ROUTING
"`%s:%s': Received `%s' request (inserting data!), message type %d, key %s, uid %llu\n",
my_short_id, "DHT", "PUT", put_type, GNUNET_h2s (message_context->key), message_context->unique_id);
#endif
+ increment_stats(STAT_PUTS_INSERTED);
#if DEBUG_DHT_ROUTING
-
if ((debug_routes) && (dhtlog_handle != NULL))
{
dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_PUT,
int ret;
#endif
+ increment_stats(STAT_ROUTES);
message_context->closest = am_closest_peer(message_context->key);
forward_count = get_forward_count(message_context->hop_count, message_context->replication);
nearest = find_closest_peer(message_context->key);
forward_count = 0;
break;
case GNUNET_MESSAGE_TYPE_DHT_PUT: /* Check if closest, if so insert data. FIXME: thresholding to reduce complexity?*/
+ increment_stats(STAT_PUTS);
if (message_context->closest == GNUNET_YES)
{
#if DEBUG_DHT_ROUTING
#endif
break;
case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER: /* Check if closest and not started by us, check options, add to requests seen */
+ increment_stats(STAT_FIND_PEER);
if (((message_context->hop_count > 0) && (0 != memcmp(message_context->peer, &my_identity, sizeof(struct GNUNET_PeerIdentity)))) || (message_context->client != NULL))
{
cache_response (cls, message_context);
if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
return;
+ increment_stats(STAT_FIND_PEER_START);
+
find_peer_msg = GNUNET_malloc(sizeof(struct GNUNET_MessageHeader));
find_peer_msg->size = htons(sizeof(struct GNUNET_MessageHeader));
find_peer_msg->type = htons(GNUNET_MESSAGE_TYPE_DHT_FIND_PEER);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"`%s:%s': Sent `%s' request to %d peers\n", my_short_id, "DHT",
"FIND PEER", ret);
- next_send_time = DHT_DEFAULT_FIND_PEER_INTERVAL;
- next_send_time.value = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG, next_send_time.value * 3);
+ next_send_time.value = DHT_MINIMUM_FIND_PEER_INTERVAL.value +
+ GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG,
+ DHT_MAXIMUM_FIND_PEER_INTERVAL.value - DHT_MINIMUM_FIND_PEER_INTERVAL.value);
GNUNET_SCHEDULER_add_delayed (sched,
next_send_time,
&send_find_peer_message, NULL);
message_context.network_size = estimate_diameter();
message_context.peer = &my_identity;
+ if (ntohs(enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_GET)
+ increment_stats(STAT_GET_START);
+ else if (ntohs(enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT)
+ increment_stats(STAT_PUT_START);
+ else if (ntohs(enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_FIND_PEER)
+ increment_stats(STAT_FIND_PEER_START);
+
route_message(cls, enc_msg, &message_context);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
GNUNET_break_op(0);
return GNUNET_YES;
}
+
memset(&message_context, 0, sizeof(struct DHT_MessageContext));
message_context.bloom = GNUNET_CONTAINER_bloomfilter_init(incoming->bloomfilter, DHT_BLOOM_SIZE, DHT_BLOOM_K);
GNUNET_assert(message_context.bloom != NULL);
memcpy(my_hello, message, ntohs(message->size));
}
+
/**
* Task run during shutdown.
*
{
int bucket_count;
struct PeerInfo *pos;
-
if (transport_handle != NULL)
{
GNUNET_free_non_null(my_hello);
GNUNET_DATACACHE_destroy (datacache);
}
+ if (stats != NULL)
+ {
+ GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
+ }
+
if (dhtlog_handle != NULL)
GNUNET_DHTLOG_disconnect(dhtlog_handle);
"%s: Core connection initialized, I am peer: %s\n", "dht",
GNUNET_i2s (identity));
#endif
+
/* Copy our identity so we can use it */
memcpy (&my_identity, identity, sizeof (struct GNUNET_PeerIdentity));
+ if (my_short_id != NULL)
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s Receive CORE INIT message but have already been initialized! Did CORE fail?\n", "DHT SERVICE");
my_short_id = GNUNET_strdup(GNUNET_i2s(&my_identity));
/* Set the server to local variable */
coreAPI = server;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s:%s Receives core connect message for peer %s distance %d!\n", my_short_id, "dht", GNUNET_i2s(peer), distance);
#endif
+
+ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(all_known_peers, &peer->hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s:%s Received %s message for peer %s, but already have peer in RT!", my_short_id, "DHT", "CORE CONNECT", GNUNET_i2s(peer));
+ return;
+ }
+
if (datacache != NULL)
GNUNET_DATACACHE_put(datacache, &peer->hashPubKey, sizeof(struct GNUNET_PeerIdentity), (const char *)peer, 0, GNUNET_TIME_absolute_get_forever());
ret = try_add_peer(peer,
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s:%s: Received peer disconnect message for peer `%s' from %s\n", my_short_id, "DHT", GNUNET_i2s(peer), "CORE");
+ if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains(all_known_peers, &peer->hashPubKey))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s:%s: do not have peer `%s' in RT, can't disconnect!\n", my_short_id, "DHT", GNUNET_i2s(peer));
+ return;
+ }
GNUNET_assert(GNUNET_CONTAINER_multihashmap_contains(all_known_peers, &peer->hashPubKey));
to_remove = GNUNET_CONTAINER_multihashmap_get(all_known_peers, &peer->hashPubKey);
GNUNET_assert(0 == memcmp(peer, &to_remove->id, sizeof(struct GNUNET_PeerIdentity)));
NULL, /* Closure passed to DHT functionas around? */
&core_init, /* Call core_init once connected */
&handle_core_connect, /* Handle connects */
- &handle_core_disconnect, /* FIXME: remove peers on disconnects */
+ &handle_core_disconnect, /* remove peers on disconnects */
NULL, /* Do we care about "status" updates? */
NULL, /* Don't want notified about all incoming messages */
GNUNET_NO, /* For header only inbound notification */
stop_on_found = GNUNET_YES;
}
+ if (GNUNET_YES ==
+ GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht",
+ "malicious_getter"))
+ {
+ malicious_getter = GNUNET_YES;
+ if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT",
+ "MALICIOUS_GET_FREQUENCY",
+ &malicious_get_frequency))
+ malicious_get_frequency = DEFAULT_MALICIOUS_GET_FREQUENCY;
+ }
+
+ if (GNUNET_YES ==
+ GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht",
+ "malicious_putter"))
+ {
+ malicious_putter = GNUNET_YES;
+ if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT",
+ "MALICIOUS_PUT_FREQUENCY",
+ &malicious_put_frequency))
+ malicious_put_frequency = DEFAULT_MALICIOUS_PUT_FREQUENCY;
+ }
+
+ if (GNUNET_YES ==
+ GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht",
+ "malicious_dropper"))
+ {
+ malicious_dropper = GNUNET_YES;
+ }
+
if (GNUNET_YES ==
GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht_testing",
"mysql_logging_extended"))
}
}
+ stats = GNUNET_STATISTICS_create(sched, "dht", cfg);
+
+ if (stats != NULL)
+ {
+ GNUNET_STATISTICS_set(stats, STAT_ROUTES, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_ROUTE_FORWARDS, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_RESULTS, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_RESULTS_TO_CLIENT, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_RESULT_FORWARDS, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_GETS, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_PUTS, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_PUTS_INSERTED, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_FIND_PEER, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_FIND_PEER_START, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_GET_START, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_PUT_START, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_FIND_PEER_REPLY, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_FIND_PEER_ANSWER, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_GET_REPLY, 0, GNUNET_NO);
+ GNUNET_STATISTICS_set(stats, STAT_GET_RESPONSE_START, 0, GNUNET_NO);
+ }
#if DO_FIND_PEER
random_seconds = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 180);
GNUNET_SCHEDULER_add_delayed (sched,
- GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30),
+ GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, random_seconds),
&send_find_peer_message, NULL);
#endif
static struct StatementHandle *insert_trial;
+#define INSERT_STAT_STMT "INSERT INTO node_statistics"\
+ "(trialuid, nodeuid, route_requests,"\
+ "route_forwards, result_requests,"\
+ "client_results, result_forwards, gets,"\
+ "puts, data_inserts, find_peer_requests, "\
+ "find_peers_started, gets_started, puts_started, find_peer_responses_received,"\
+ "get_responses_received, find_peer_responses_sent, get_responses_sent) "\
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+
+static struct StatementHandle *insert_stat;
+
#define INSERT_DHTKEY_STMT "INSERT INTO dhtkeys (dhtkey, trialuid, keybits) "\
"VALUES (?, ?, ?)"
static struct StatementHandle *insert_dhtkey;
") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
return GNUNET_SYSERR;
+ if (MRUNS ("CREATE TABLE IF NOT EXISTS `node_statistics` ("
+ "`stat_uid` int(10) unsigned NOT NULL AUTO_INCREMENT,"
+ "`trialuid` int(10) unsigned NOT NULL,"
+ "`nodeuid` int(10) unsigned NOT NULL,"
+ "`route_requests` int(10) unsigned NOT NULL,"
+ "`route_forwards` int(10) unsigned NOT NULL,"
+ "`result_requests` int(10) unsigned NOT NULL,"
+ "`client_results` int(10) unsigned NOT NULL,"
+ "`result_forwards` int(10) unsigned NOT NULL,"
+ "`gets` int(10) unsigned NOT NULL,"
+ "`puts` int(10) unsigned NOT NULL,"
+ "`data_inserts` int(10) unsigned NOT NULL,"
+ "`find_peer_requests` int(10) unsigned NOT NULL,"
+ "`find_peers_started` int(10) unsigned NOT NULL,"
+ "`gets_started` int(10) unsigned NOT NULL,"
+ "`puts_started` int(10) unsigned NOT NULL,"
+ "`find_peer_responses_received` int(10) unsigned NOT NULL,"
+ "`get_responses_received` int(10) unsigned NOT NULL,"
+ "`find_peer_responses_sent` int(10) unsigned NOT NULL,"
+ "`get_responses_sent` int(10) unsigned NOT NULL,"
+ "PRIMARY KEY (`stat_uid`)"
+ ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"))
+ return GNUNET_SYSERR;
+
if (MRUNS ("SET AUTOCOMMIT = 1"))
return GNUNET_SYSERR;
prepared_statement_close (struct StatementHandle *s)
{
if (s == NULL)
- return;
+ {
+ return;
+ }
GNUNET_free_non_null(s->query);
+
if (s->valid == GNUNET_YES)
mysql_stmt_close(s->statement);
GNUNET_free(s);
if (PINIT (insert_query, INSERT_QUERIES_STMT) ||
PINIT (insert_route, INSERT_ROUTES_STMT) ||
PINIT (insert_trial, INSERT_TRIALS_STMT) ||
+ PINIT (insert_stat, INSERT_STAT_STMT) ||
PINIT (insert_node, INSERT_NODES_STMT) ||
PINIT (insert_dhtkey, INSERT_DHTKEY_STMT) ||
PINIT (update_trial, UPDATE_TRIALS_STMT) ||
}
get_current_trial (¤t_trial);
-#if DEBUG_DHTLOG
- fprintf (stderr, "Current trial is %llu\n", current_trial);
-#endif
+
+ mysql_stmt_close(stmt);
+ return GNUNET_OK;
+}
+
+
+/*
+ * Inserts the specified stats into the dhttests.node_statistics table
+ *
+ * @param peer the peer inserting the statistic
+ * @param route_requests route requests seen
+ * @param route_forwards route requests forwarded
+ * @param result_requests route result requests seen
+ * @param client_requests client requests initiated
+ * @param result_forwards route results forwarded
+ * @param gets get requests handled
+ * @param puts put requests handle
+ * @param data_inserts data inserted at this node
+ * @param find_peer_requests find peer requests seen
+ * @param find_peers_started find peer requests initiated at this node
+ * @param gets_started get requests initiated at this node
+ * @param puts_started put requests initiated at this node
+ * @param find_peer_responses_received find peer responses received locally
+ * @param get_responses_received get responses received locally
+ * @param find_peer_responses_sent find peer responses sent from this node
+ * @param get_responses_sent get responses sent from this node
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
+ unsigned int route_forwards, unsigned int result_requests,
+ unsigned int client_requests, unsigned int result_forwards,
+ unsigned int gets, unsigned int puts,
+ unsigned int data_inserts, unsigned int find_peer_requests,
+ unsigned int find_peers_started, unsigned int gets_started,
+ unsigned int puts_started, unsigned int find_peer_responses_received,
+ unsigned int get_responses_received, unsigned int find_peer_responses_sent,
+ unsigned int get_responses_sent)
+{
+ MYSQL_STMT *stmt;
+ int ret;
+ unsigned long long peer_uid;
+ unsigned long long return_uid;
+ if (peer == NULL)
+ return GNUNET_SYSERR;
+
+ if (GNUNET_OK != get_node_uid (&peer_uid, &peer->hashPubKey))
+ {
+ return GNUNET_SYSERR;
+ }
+
+ stmt = mysql_stmt_init(conn);
+ if (GNUNET_OK !=
+ (ret = prepared_statement_run (insert_stat,
+ &return_uid,
+ MYSQL_TYPE_LONGLONG, ¤t_trial, GNUNET_YES,
+ MYSQL_TYPE_LONGLONG, &peer_uid, GNUNET_YES,
+ MYSQL_TYPE_LONG, &route_requests, GNUNET_YES,
+ MYSQL_TYPE_LONG, &route_forwards, GNUNET_YES,
+ MYSQL_TYPE_LONG, &result_requests, GNUNET_YES,
+ MYSQL_TYPE_LONG, &client_requests, GNUNET_YES,
+ MYSQL_TYPE_LONG, &result_forwards, GNUNET_YES,
+ MYSQL_TYPE_LONG, &gets, GNUNET_YES,
+ MYSQL_TYPE_LONG, &puts, GNUNET_YES,
+ MYSQL_TYPE_LONG, &data_inserts, GNUNET_YES,
+ MYSQL_TYPE_LONG, &find_peer_requests, GNUNET_YES,
+ MYSQL_TYPE_LONG, &find_peers_started, GNUNET_YES,
+ MYSQL_TYPE_LONG, &gets_started, GNUNET_YES,
+ MYSQL_TYPE_LONG, &puts_started, GNUNET_YES,
+ MYSQL_TYPE_LONG, &find_peer_responses_received, GNUNET_YES,
+ MYSQL_TYPE_LONG, &get_responses_received, GNUNET_YES,
+ MYSQL_TYPE_LONG, &find_peer_responses_sent, GNUNET_YES,
+ MYSQL_TYPE_LONG, &get_responses_sent, GNUNET_YES,
+ -1)))
+ {
+ if (ret == GNUNET_SYSERR)
+ {
+ mysql_stmt_close(stmt);
+ return GNUNET_SYSERR;
+ }
+ }
+
mysql_stmt_close(stmt);
return GNUNET_OK;
}
unsigned long long unknownPeers)
{
int ret;
-#if DEBUG_DHTLOG
- if (trialuid != current_trial)
- {
- fprintf (stderr,
- _("Trialuid to update is not equal to current_trial\n"));
- }
-#endif
+
if (GNUNET_OK !=
(ret = prepared_statement_run (update_trial,
NULL,
add_connections (unsigned long long trialuid, unsigned int totalConnections)
{
int ret;
-#if DEBUG_DHTLOG
- if (trialuid != current_trial)
- {
- fprintf (stderr,
- _("Trialuid to update is not equal to current_trial(!)(?)\n"));
- }
-#endif
+
if (GNUNET_OK !=
(ret = prepared_statement_run (update_connection,
NULL,
GNUNET_assert(plugin->dhtlog_api == NULL);
plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
plugin->dhtlog_api->insert_trial = &add_trial;
+ plugin->dhtlog_api->insert_stat = &add_stat;
plugin->dhtlog_api->insert_query = &add_query;
plugin->dhtlog_api->update_trial = &update_trials;
plugin->dhtlog_api->insert_route = &add_route;
plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
get_current_trial (¤t_trial);
- return NULL;
+ return plugin;
}
/**
libgnunet_plugin_dhtlog_mysql_done (void * cls)
{
struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
-#if DEBUG_DHTLOG
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MySQL DHT Logger: database shutdown\n");
-#endif
GNUNET_assert(dhtlog_api != NULL);
prepared_statement_close(insert_query);
prepared_statement_close(insert_route);
"malicious_putters, malicious_droppers, message) "\
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'"
+#define INSERT_STAT_STMT "prepare insert_stat from 'INSERT INTO node_statistics"\
+ "(trialuid, nodeuid, route_requests,"\
+ "route_forwards, result_requests,"\
+ "client_results, result_forwards, gets,"\
+ "puts, data_inserts, find_peer_requests, "\
+ "find_peers_started, gets_started, puts_started, find_peer_responses_received,"\
+ "get_responses_received, find_peer_responses_sent, get_responses_sent) "\
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'"
+
#define INSERT_DHTKEY_STMT "prepare insert_dhtkey from 'INSERT ignore INTO dhtkeys (dhtkey, trialuid) "\
"VALUES (?, @temp_trial)'"
if (PINIT (INSERT_QUERIES_STMT) ||
PINIT (INSERT_ROUTES_STMT) ||
PINIT (INSERT_TRIALS_STMT) ||
+ PINIT (INSERT_STAT_STMT) ||
PINIT (INSERT_NODES_STMT) ||
PINIT (INSERT_DHTKEY_STMT) ||
PINIT (UPDATE_TRIALS_STMT) ||
return GNUNET_SYSERR;
}
+/*
+ * Inserts the specified stats into the dhttests.node_statistics table
+ *
+ * @param peer the peer inserting the statistic
+ * @param route_requests route requests seen
+ * @param route_forwards route requests forwarded
+ * @param result_requests route result requests seen
+ * @param client_requests client requests initiated
+ * @param result_forwards route results forwarded
+ * @param gets get requests handled
+ * @param puts put requests handle
+ * @param data_inserts data inserted at this node
+ * @param find_peer_requests find peer requests seen
+ * @param find_peers_started find peer requests initiated at this node
+ * @param gets_started get requests initiated at this node
+ * @param puts_started put requests initiated at this node
+ * @param find_peer_responses_received find peer responses received locally
+ * @param get_responses_received get responses received locally
+ * @param find_peer_responses_sent find peer responses sent from this node
+ * @param get_responses_sent get responses sent from this node
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
+ unsigned int route_forwards, unsigned int result_requests,
+ unsigned int client_requests, unsigned int result_forwards,
+ unsigned int gets, unsigned int puts,
+ unsigned int data_inserts, unsigned int find_peer_requests,
+ unsigned int find_peers_started, unsigned int gets_started,
+ unsigned int puts_started, unsigned int find_peer_responses_received,
+ unsigned int get_responses_received, unsigned int find_peer_responses_sent,
+ unsigned int get_responses_sent)
+{
+ int ret;
+ if (outfile == NULL)
+ return GNUNET_SYSERR;
+
+ if (peer != NULL)
+ ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_node;\n", GNUNET_h2s_full(&peer->hashPubKey));
+ else
+ ret = fprintf(outfile, "set @temp_node = 0;\n");
+
+ ret = fprintf(outfile, "set @r_r = %u, @r_f = %u, @res_r = %u, @c_r = %u, "
+ "@res_f = %u, @gets = %u, @puts = %u, @d_i = %u, "
+ "@f_p_r = %u, @f_p_s = %u, @g_s = %u, @p_s = %u, "
+ "@f_p_r_r = %u, @g_r_r = %u, @f_p_r_s = %u, @g_r_s = %u;\n",
+ route_requests, route_forwards, result_requests,
+ client_requests, result_forwards, gets, puts,
+ data_inserts, find_peer_requests, find_peers_started,
+ gets_started, puts_started, find_peer_responses_received,
+ get_responses_received, find_peer_responses_sent,
+ get_responses_sent);
+ if (ret < 0)
+ return GNUNET_SYSERR;
+
+ ret = fprintf(outfile, "execute insert_stat using "
+ "@temp_trial, @temp_node, @r_r, @r_f, @res_r, @c_r, "
+ "@res_f, @gets, @puts, @d_i, "
+ "@f_p_r, @f_p_s, @g_s, @p_s, "
+ "@f_p_r_r, @g_r_r, @f_p_r_s, @g_r_s;\n");
+
+ return GNUNET_OK;
+}
/*
* Inserts the specified dhtkey into the dhttests.dhtkeys table,
* stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
cfg = plugin->cfg;
max_varchar_len = 255;
-#if DEBUG_DHTLOG
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL (DUMP) DHT Logger: initializing\n");
-#endif
if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
"MYSQLDUMP", "PATH",
GNUNET_assert(plugin->dhtlog_api == NULL);
plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
plugin->dhtlog_api->insert_trial = &add_trial;
+ plugin->dhtlog_api->insert_stat = &add_stat;
plugin->dhtlog_api->insert_query = &add_query;
plugin->dhtlog_api->update_trial = &update_trials;
plugin->dhtlog_api->insert_route = &add_route;
plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
plugin->dhtlog_api->update_topology = &update_topology;
- return NULL;
+ return plugin;
}
/**
libgnunet_plugin_dhtlog_mysql_dump_done (void * cls)
{
struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
-#if DEBUG_DHTLOG
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MySQL DHT Logger: database shutdown\n");
-#endif
GNUNET_assert(dhtlog_api != NULL);
GNUNET_free(dhtlog_api);
5, 1, 12, 0, 0, 0,
"TEST INSERT TRIAL");
CHECK(ret);
-
ret = api->insert_topology(500);
-
CHECK(ret);
-
- fprintf (stderr, "Trial uid is %llu\n", trialuid);
-
ret = api->insert_node (&nodeuid, &p1);
ret = api->insert_node (&nodeuid, &p2);
ret = api->insert_node (&nodeuid, &p3);
ret = api->insert_node (&nodeuid, &p4);
-
CHECK(ret);
-
ret = api->insert_topology(0);
ret = api->insert_extended_topology(&p1, &p2);
ret = api->insert_extended_topology(&p3, &p4);
CHECK(ret);
ret = api->insert_dhtkey (&dhtkeyuid, &k1);
ret = api->insert_dhtkey (&dhtkeyuid, &k2);
-
CHECK(ret);
-
ret = api->insert_query (&sqlqueryuid, internaluid, 2, 4, 0, &p2, &k1);
-
- fprintf (stderr, "Sql uid for dht query is %llu\n", sqlqueryuid);
-
ret =
api->insert_route (&sqlrouteuid, sqlqueryuid, 1, 1, DHTLOG_GET, &p1, &k2,
&p4, &p3);
- fprintf (stderr, "Sql uid for dht route is %llu\n", sqlrouteuid);
ret =
api->insert_route (&sqlrouteuid, sqlqueryuid, 2, 0, DHTLOG_PUT, &p3, &k1,
&p4, &p2);
- fprintf (stderr, "Sql uid for dht route is %llu\n", sqlrouteuid);
ret =
api->insert_route (&sqlrouteuid, sqlqueryuid, 3, 1, DHTLOG_ROUTE, &p3, &k2,
&p2, NULL);
- fprintf (stderr, "Sql uid for dht route is %llu\n", sqlrouteuid);
ret =
api->insert_route (&sqlrouteuid, sqlqueryuid, 4, 7, DHTLOG_ROUTE, &p3, &k2,
NULL, NULL);
- fprintf (stderr, "Sql uid for dht route is %llu, ret %d\n", sqlrouteuid, ret);
sleep (1);
- fprintf (stderr, "Updating trial %llu with endtime of now\n", trialuid);
+ ret = api->insert_stat(&p1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+ ret = api->insert_stat(&p2, 12, 23, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27);
+ CHECK(ret);
ret = api->update_trial (trialuid, 0, 0, 0);
-
CHECK(ret);
-
return 0;
}
ok = test(api);
GNUNET_DHTLOG_disconnect(api);
- GNUNET_free(api);
}