X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fdht%2Ftest_dht_api.c;h=465a9246a248b0c575414fc23784cb67774c4109;hb=cf6c6eea38863e2abe0421762c5e9dd3becc0b24;hp=1e1a01e6e983a9cbd27d803a84c28d02c14e3b2a;hpb=76cd359a2bca34b49d829dd9dd3529386044b85a;p=oweals%2Fgnunet.git diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c index 1e1a01e6e..465a9246a 100644 --- a/src/dht/test_dht_api.c +++ b/src/dht/test_dht_api.c @@ -4,7 +4,7 @@ GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your + by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but @@ -32,20 +32,50 @@ #include "gnunet_program_lib.h" #include "gnunet_scheduler_lib.h" #include "gnunet_dht_service.h" +#include "gnunet_hello_lib.h" -#define VERBOSE GNUNET_NO +#define VERBOSE GNUNET_YES #define VERBOSE_ARM GNUNET_NO #define START_ARM GNUNET_YES /** - * How long until we give up on transmitting the message? + * How long until we really give up on a particular testcase portion? + */ +#define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 360) + +/** + * How long until we give up on any particular operation (and retry)? */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 50) +#define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) #define MTYPE 12345 +struct RetryContext +{ + /** + * When to really abort the operation. + */ + struct GNUNET_TIME_Absolute real_timeout; + + /** + * What timeout to set for the current attempt (increases) + */ + struct GNUNET_TIME_Relative next_timeout; + + /** + * The context of the peer we are dealing with. + */ + struct PeerContext *peer_ctx; + + /** + * The task identifier of the retry task, so it can be cancelled. + */ + GNUNET_SCHEDULER_TaskIdentifier retry_task; + +}; + struct PeerContext { struct GNUNET_CONFIGURATION_Handle *cfg; @@ -61,6 +91,8 @@ struct PeerContext static struct PeerContext p1; +struct RetryContext retry_context; + static struct GNUNET_SCHEDULER_Handle *sched; static int ok; @@ -77,25 +109,12 @@ GNUNET_SCHEDULER_TaskIdentifier die_task; static void end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - /* do work here */ GNUNET_SCHEDULER_cancel (sched, die_task); - - GNUNET_DHT_disconnect (p1.dht_handle); - die_task = GNUNET_SCHEDULER_NO_TASK; - - if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "DHT disconnected, returning FAIL!\n"); - ok = 365; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "DHT disconnected, returning success!\n"); - ok = 0; - } + GNUNET_DHT_disconnect (p1.dht_handle); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "DHT disconnected, returning success!\n"); + ok = 0; } static void @@ -118,12 +137,25 @@ end_badly () fprintf (stderr, "Ending on an unhappy note.\n"); #endif + if ( (retry_context.peer_ctx != NULL) && + (retry_context.peer_ctx->find_peer_handle != NULL) ) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Stopping find peer request!\n"); + GNUNET_DHT_find_peer_stop(retry_context.peer_ctx->find_peer_handle); + } + if ( (retry_context.peer_ctx != NULL) && + (retry_context.peer_ctx->get_handle != NULL) ) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Stopping get request!\n"); + GNUNET_DHT_get_stop (retry_context.peer_ctx->get_handle); + } + if (retry_context.retry_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel(sched, retry_context.retry_task); GNUNET_DHT_disconnect (p1.dht_handle); - ok = 1; - return; } + /** * Signature of the main function of a task. * @@ -137,14 +169,25 @@ test_find_peer_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer_stop!\n"); if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) - GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL); + { + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (sched, die_task); + GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL); + return; + } GNUNET_assert (peer->dht_handle != NULL); - GNUNET_DHT_find_peer_stop (peer->find_peer_handle, &end, &p1); - - //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &end, &p1); + GNUNET_DHT_find_peer_stop (peer->find_peer_handle); +#if HAVE_MALICIOUS + GNUNET_DHT_set_malicious_getter (peer->dht_handle, GNUNET_TIME_UNIT_SECONDS); + GNUNET_DHT_set_malicious_putter (peer->dht_handle, GNUNET_TIME_UNIT_SECONDS); + GNUNET_DHT_set_malicious_dropper (peer->dht_handle); +#endif + GNUNET_SCHEDULER_add_delayed(sched, + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), + &end, &p1); } @@ -157,20 +200,107 @@ test_find_peer_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param reply response */ void test_find_peer_processor (void *cls, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *reply) + const struct GNUNET_HELLO_Message *hello) { + struct RetryContext *retry_ctx = cls; + struct GNUNET_PeerIdentity peer; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test_find_peer_processor called (peer `%s'), stopping find peer request!\n", GNUNET_i2s(peer)); + if (GNUNET_OK == GNUNET_HELLO_get_id(hello, &peer)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "test_find_peer_processor called (peer `%s'), stopping find peer request!\n", GNUNET_i2s(&peer)); + + if (retry_ctx->retry_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(sched, retry_ctx->retry_task); + retry_ctx->retry_task = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_SCHEDULER_add_continuation (sched, &test_find_peer_stop, &p1, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "received find peer request, but hello_get_id failed!\n"); + } - GNUNET_SCHEDULER_add_continuation (sched, &test_find_peer_stop, &p1, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); } +/** + * Retry the find_peer task on timeout. (Forward declaration) + * + * @param cls closure + * @param tc context information (why was this task triggered now?) + */ +void +retry_find_peer_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** - * Signature of the main function of a task. + * Retry the find_peer task on timeout. + * + * @param cls closure + * @param tc context information (why was this task triggered now) + */ +void +retry_find_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct RetryContext *retry_ctx = cls; + GNUNET_HashCode hash; + memset (&hash, 42, sizeof (GNUNET_HashCode)); + + if (GNUNET_TIME_absolute_get_remaining(retry_ctx->real_timeout).value > 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "test_find_peer timed out, retrying!\n"); + retry_ctx->next_timeout = GNUNET_TIME_relative_multiply(retry_ctx->next_timeout, 2); + retry_ctx->peer_ctx->find_peer_handle + = GNUNET_DHT_find_peer_start (retry_ctx->peer_ctx->dht_handle, + retry_ctx->next_timeout, &hash, + GNUNET_DHT_RO_NONE, + &test_find_peer_processor, retry_ctx); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "test_find_peer timed out for good, failing!\n"); + + retry_ctx->peer_ctx->find_peer_handle = NULL; + } + + if (retry_ctx->peer_ctx->find_peer_handle == NULL) + { + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (sched, die_task); + GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1); + return; + } + retry_ctx->retry_task = GNUNET_SCHEDULER_add_delayed(sched, retry_ctx->next_timeout, &retry_find_peer_stop, retry_ctx); +} + +/** + * Retry the find_peer task on timeout. + * + * @param cls closure + * @param tc context information (why was this task triggered now?) + */ +void +retry_find_peer_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct RetryContext *retry_ctx = cls; + GNUNET_HashCode hash; + memset (&hash, 42, sizeof (GNUNET_HashCode)); + + if (retry_ctx->peer_ctx->find_peer_handle != NULL) + { + GNUNET_DHT_find_peer_stop(retry_ctx->peer_ctx->find_peer_handle); + retry_ctx->peer_ctx->find_peer_handle = NULL; + } + GNUNET_SCHEDULER_add_now (sched, &retry_find_peer, retry_ctx); +} + +/** + * Entry point for test of find_peer functionality. * * @param cls closure * @param tc context information (why was this task triggered now) @@ -185,12 +315,24 @@ test_find_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer!\n"); GNUNET_assert (peer->dht_handle != NULL); - peer->find_peer_handle = - GNUNET_DHT_find_peer_start (peer->dht_handle, TIMEOUT, 0, NULL, &hash, - &test_find_peer_processor, NULL, NULL, NULL); + retry_context.real_timeout = GNUNET_TIME_relative_to_absolute(TOTAL_TIMEOUT); + retry_context.next_timeout = BASE_TIMEOUT; + retry_context.peer_ctx = peer; + + peer->find_peer_handle + = GNUNET_DHT_find_peer_start (peer->dht_handle, retry_context.next_timeout, + &hash, + GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, + &test_find_peer_processor, &retry_context); if (peer->find_peer_handle == NULL) - GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1); + { + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (sched, die_task); + GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1); + return; + } + retry_context.retry_task = GNUNET_SCHEDULER_add_delayed(sched, retry_context.next_timeout, &retry_find_peer_stop, &retry_context); } /** @@ -206,21 +348,27 @@ test_get_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n"); if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) - GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL); - + { + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (sched, die_task); + GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL); + return; + } GNUNET_assert (peer->dht_handle != NULL); - - GNUNET_DHT_get_stop (peer->get_handle, &test_find_peer, &p1); - - //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1); - + GNUNET_DHT_get_stop (peer->get_handle); + GNUNET_SCHEDULER_add_now(sched, + &test_find_peer, + &p1); } void test_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, const GNUNET_HashCode * key, - uint32_t type, uint32_t size, const void *data) + const struct GNUNET_PeerIdentity * const *get_path, + const struct GNUNET_PeerIdentity * const *put_path, + enum GNUNET_BLOCK_Type type, + size_t size, const void *data) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_get_iterator called (we got a result), stopping get request!\n"); @@ -245,13 +393,28 @@ test_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get!\n"); GNUNET_assert (peer->dht_handle != NULL); + retry_context.real_timeout = GNUNET_TIME_relative_to_absolute(TOTAL_TIMEOUT); + retry_context.next_timeout = BASE_TIMEOUT; peer->get_handle = - GNUNET_DHT_get_start (peer->dht_handle, TIMEOUT, 42, &hash, - &test_get_iterator, NULL, NULL, NULL); + GNUNET_DHT_get_start (peer->dht_handle, + TOTAL_TIMEOUT, + GNUNET_BLOCK_TYPE_TEST, + &hash, + GNUNET_DHT_RO_NONE, + NULL, 0, + NULL, 0, + &test_get_iterator, NULL); if (peer->get_handle == NULL) - GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1); + { + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (sched, die_task); + GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1); + return; + } + + retry_context.peer_ctx = peer; } /** @@ -275,10 +438,14 @@ test_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (peer->dht_handle != NULL); - GNUNET_DHT_put (peer->dht_handle, &hash, 42, data_size, data, - GNUNET_TIME_relative_to_absolute (TIMEOUT), TIMEOUT, + GNUNET_DHT_put (peer->dht_handle, &hash, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_TEST, + data_size, data, + GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT), + TOTAL_TIMEOUT, &test_get, &p1); - + GNUNET_free(data); } static void @@ -316,7 +483,7 @@ run (void *cls, GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 3), &test_put, + (GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1); }