X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fhostlist%2Fhostlist-client.c;h=049e78c52f10131fc068d549bbb690550812478f;hb=3c82a48a3a22b65b5f0db85528c1979ac0c878ed;hp=084277af4b9b592f4c51c615722285f9add9c085;hpb=4de943d80f5ad59ac39e22381106a72c5f7d1cc0;p=oweals%2Fgnunet.git diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c index 084277af4..049e78c52 100644 --- a/src/hostlist/hostlist-client.c +++ b/src/hostlist/hostlist-client.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 @@ -36,7 +36,7 @@ #include "gnunet_common.h" #include "gnunet_bio_lib.h" -#define DEBUG_HOSTLIST_CLIENT GNUNET_YES +#define DEBUG_HOSTLIST_CLIENT GNUNET_NO /** @@ -45,6 +45,11 @@ */ #define MIN_CONNECTIONS 4 +/** + * Interval between two advertised hostlist tests + */ +#define TESTING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) + /** * A single hostlist obtained by hostlist advertisements */ @@ -103,31 +108,21 @@ struct Hostlist */ static const struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Our scheduler. - */ -static struct GNUNET_SCHEDULER_Handle *sched; - /** * Statistics handle. */ -struct GNUNET_STATISTICS_Handle *stats; +static struct GNUNET_STATISTICS_Handle *stats; /** * Transport handle. */ -struct GNUNET_TRANSPORT_Handle *transport; +static struct GNUNET_TRANSPORT_Handle *transport; /** * Proxy that we are using (can be NULL). */ static char *proxy; -/** - * Buffer for data downloaded via HTTP. - */ -static char download_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE]; - /** * Number of bytes valid in 'download_buffer'. */ @@ -149,45 +144,38 @@ static CURL *curl; static CURLM *multi; /** - * ID of the current task scheduled. + * How many bytes did we download from the current hostlist URL? */ -static GNUNET_SCHEDULER_TaskIdentifier ti_check_download; - +static uint32_t stat_bytes_downloaded; /** - * ID of the current task scheduled. + * Amount of time we wait between hostlist downloads. */ -static GNUNET_SCHEDULER_TaskIdentifier ti_download; +static struct GNUNET_TIME_Relative hostlist_delay; /** - * ID of the current hostlist saving task scheduled. + * ID of the task, checking if hostlist download should take plate */ -static GNUNET_SCHEDULER_TaskIdentifier ti_saving_task; +static GNUNET_SCHEDULER_TaskIdentifier ti_check_download; /** - * ID of the current hostlist saving task scheduled. + * ID of the task downloading the hostlist */ -static GNUNET_SCHEDULER_TaskIdentifier ti_download_dispatcher_task; - +static GNUNET_SCHEDULER_TaskIdentifier ti_download; /** - * ID of the task checking the intervall between to hostlist tests + * ID of the task saving the hostlsit in a regular intervall */ -static GNUNET_SCHEDULER_TaskIdentifier ti_testing_intervall_task; +static GNUNET_SCHEDULER_TaskIdentifier ti_saving_task; /** - * Amount of time we wait between hostlist downloads. + * ID of the task called to initiate a download */ -static struct GNUNET_TIME_Relative hostlist_delay; - -/** - * Set to GNUNET_YES if the current URL had some problems. - */ -static int bogus_url; +static GNUNET_SCHEDULER_TaskIdentifier ti_download_dispatcher_task; /** - * Number of active connections (according to core service). + * ID of the task controlling the locking between two hostlist tests */ -static unsigned int connection_count; +static GNUNET_SCHEDULER_TaskIdentifier ti_testing_intervall_task; /** * At what time MUST the current hostlist request be done? @@ -219,31 +207,50 @@ static unsigned int linked_list_size; */ static struct Hostlist * hostlist_to_test; -static int testing_hostlist; +/** + * Set to GNUNET_YES if the current URL had some problems. + */ +static int stat_bogus_url; -static int testing_allowed; +/** + * Value controlling if a hostlist is tested at the moment + */ +static int stat_testing_hostlist; -static int download_in_progress; +/** + * Value controlling if a hostlist testing is allowed at the moment + */ +static int stat_testing_allowed; /** - * Value saying if preconfigured is used + * Value controlling if a hostlist download is running at the moment */ -static unsigned int use_preconfigured_list; +static int stat_download_in_progress; +/** + * Value saying if a preconfigured bootstrap server is used + */ +static unsigned int stat_use_bootstrap; /** * Set if we are allowed to learn new hostlists and use them */ -static int learning; +static int stat_learning; + +/** + * Value saying if hostlist download was successful + */ +static unsigned int stat_download_successful; /** * Value saying how many valid HELLO messages were obtained during download */ -static unsigned int hellos_obtained; +static unsigned int stat_hellos_obtained; /** - * Value saying if hostlist download was successful + * Number of active connections (according to core service). */ -static unsigned int download_successful; +static unsigned int stat_connection_count; + /** * Process downloaded bits by calling callback on each HELLO. @@ -255,11 +262,12 @@ static unsigned int download_successful; * @return number of bytes that were processed (always size*nmemb) */ static size_t -download_hostlist_processor (void *ptr, +callback_download (void *ptr, size_t size, size_t nmemb, void *ctx) { + static char download_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; const char * cbuf = ptr; const struct GNUNET_MessageHeader *msg; size_t total; @@ -268,10 +276,12 @@ download_hostlist_processor (void *ptr, uint16_t msize; total = size * nmemb; - if ( (total == 0) || (bogus_url) ) + stat_bytes_downloaded += total; + if ( (total == 0) || (stat_bogus_url) ) { return total; /* ok, no data or bogus data */ } + GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes downloaded from hostlist servers"), (int64_t) total, @@ -280,7 +290,7 @@ download_hostlist_processor (void *ptr, while ( (left > 0) || (download_pos > 0) ) { - cpy = GNUNET_MIN (left, GNUNET_SERVER_MAX_MESSAGE_SIZE - download_pos); + cpy = GNUNET_MIN (left, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - download_pos); memcpy (&download_buffer[download_pos], cbuf, cpy); @@ -303,8 +313,9 @@ download_hostlist_processor (void *ptr, GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Invalid `%s' message received from hostlist at `%s'\n"), "HELLO", - current_url); - bogus_url = 1; + current_url); + stat_hellos_obtained++; + stat_bogus_url = 1; return total; } if (download_pos < msize) @@ -323,8 +334,8 @@ download_hostlist_processor (void *ptr, gettext_noop ("# valid HELLOs downloaded from hostlist servers"), 1, GNUNET_NO); - hellos_obtained++; - GNUNET_TRANSPORT_offer_hello (transport, msg); + stat_hellos_obtained++; + GNUNET_TRANSPORT_offer_hello (transport, msg, NULL, NULL); } else { @@ -336,7 +347,8 @@ download_hostlist_processor (void *ptr, _("Invalid `%s' message received from hostlist at `%s'\n"), "HELLO", current_url); - bogus_url = GNUNET_YES; + stat_bogus_url = GNUNET_YES; + stat_hellos_obtained++; return total; } memmove (download_buffer, @@ -354,7 +366,7 @@ download_hostlist_processor (void *ptr, * @return NULL if there is no URL available */ static char * -get_bootstrap_url () +get_bootstrap_server () { char *servers; char *ret; @@ -420,21 +432,21 @@ get_bootstrap_url () * @return uri to use, NULL if there is no URL available */ static char * -get_list_url () +download_get_url () { uint32_t index; unsigned int counter; struct Hostlist * pos; - if ( GNUNET_NO == learning) + if ( GNUNET_NO == stat_learning) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using preconfigured bootstrap server\n"); current_hostlist = NULL; - return get_bootstrap_url(); + return get_bootstrap_server(); } - if ( ( GNUNET_YES == testing_hostlist) && (NULL != hostlist_to_test) ) + if ( ( GNUNET_YES == stat_testing_hostlist) && (NULL != hostlist_to_test) ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing new advertised hostlist if it is obtainable\n"); @@ -442,13 +454,13 @@ get_list_url () return strdup(hostlist_to_test->hostlist_uri); } - if ( (GNUNET_YES == use_preconfigured_list) || + if ( (GNUNET_YES == stat_use_bootstrap) || (linked_list_size == 0) ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using preconfigured bootstrap server\n"); current_hostlist = NULL; - return get_bootstrap_url(); + return get_bootstrap_server(); } index = GNUNET_CRYPTO_random_u32 ( GNUNET_CRYPTO_QUALITY_WEAK, linked_list_size); counter = 0; @@ -465,10 +477,10 @@ get_list_url () } -#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0); +#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0) /** - * Method to load persistent hostlist file during hostlist client shutdown + * Method to save hostlist to a file during hostlist client shutdown * @param shutdown set if called because of shutdown, entries in linked list will be destroyed */ static void save_hostlist_file ( int shutdown ); @@ -509,7 +521,7 @@ static uint64_t checked_sub (uint64_t val1, uint64_t val2) } /** - * Method to check if URI is in hostlist linked list + * Method to check if a URI is in hostlist linked list * @param uri uri to check * @return GNUNET_YES if existing in linked list, GNUNET_NO if not */ @@ -530,7 +542,7 @@ linked_list_contains (const char * uri) /** - * Method returning the uri with the lowest quality in the datastore + * Method returning the hostlist element with the lowest quality in the datastore * @return hostlist with lowest quality */ static struct Hostlist * @@ -557,39 +569,32 @@ linked_list_get_lowest_quality ( ) * Method to insert a hostlist into the datastore. If datastore contains maximum number of elements, the elements with lowest quality is dismissed */ static void -insert_hostlist ( void ) +insert_hostlist ( ) { - GNUNET_CONTAINER_DLL_insert(linked_list_head, linked_list_tail, hostlist_to_test); - linked_list_size++; - - GNUNET_STATISTICS_set (stats, - gettext_noop("# advertised hostlist URIs"), - linked_list_size, - GNUNET_NO); - - if (MAX_NUMBER_HOSTLISTS >= linked_list_size) - return; - - /* No free entries available, replace existing entry */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Removing lowest quality entry\n" ); - struct Hostlist * lowest_quality = linked_list_get_lowest_quality(); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Hostlist with URI `%s' has the worst quality of all with value %llu\n", - lowest_quality->hostlist_uri, - (unsigned long long) lowest_quality->quality); - GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail, lowest_quality); - linked_list_size--; + struct Hostlist * lowest_quality; + if (MAX_NUMBER_HOSTLISTS <= linked_list_size) + { + /* No free entries available, replace existing entry */ + lowest_quality = linked_list_get_lowest_quality(); + GNUNET_assert (lowest_quality != NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Removing hostlist with URI `%s' which has the worst quality of all (%llu)\n", + lowest_quality->hostlist_uri, + (unsigned long long) lowest_quality->quality); + GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail, lowest_quality); + linked_list_size--; + GNUNET_free (lowest_quality); + } + GNUNET_CONTAINER_DLL_insert(linked_list_head, + linked_list_tail, + hostlist_to_test); + linked_list_size++; GNUNET_STATISTICS_set (stats, gettext_noop("# advertised hostlist URIs"), linked_list_size, GNUNET_NO); - - GNUNET_free (lowest_quality); - - testing_hostlist = GNUNET_NO; - return; + stat_testing_hostlist = GNUNET_NO; } @@ -599,15 +604,15 @@ insert_hostlist ( void ) static void update_hostlist ( ) { char *stat; - if ( ((use_preconfigured_list == GNUNET_NO) && ( NULL != current_hostlist )) || - ((testing_hostlist == GNUNET_YES) && ( NULL != current_hostlist )) ) + if ( ((stat_use_bootstrap == GNUNET_NO) && ( NULL != current_hostlist )) || + ((stat_testing_hostlist == GNUNET_YES) && ( NULL != current_hostlist )) ) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updating hostlist statics for URI `%s'\n",current_hostlist->hostlist_uri ); - current_hostlist->hello_count = hellos_obtained; + current_hostlist->hello_count = stat_hellos_obtained; current_hostlist->time_last_usage = GNUNET_TIME_absolute_get(); - current_hostlist->quality = checked_add ( current_hostlist->quality, (hellos_obtained * HOSTLIST_SUCCESSFUL_HELLO)); - if ( GNUNET_YES == download_successful ) + current_hostlist->quality = checked_add ( current_hostlist->quality, (stat_hellos_obtained * HOSTLIST_SUCCESSFUL_HELLO)); + if ( GNUNET_YES == stat_download_successful ) { current_hostlist->times_used++; current_hostlist->quality = checked_add ( current_hostlist->quality, HOSTLIST_SUCCESSFUL_DOWNLOAD); @@ -627,18 +632,18 @@ static void update_hostlist ( ) current_hostlist = NULL; /* Alternating the usage of preconfigured and learned hostlists */ - if (testing_hostlist == GNUNET_YES) + if (stat_testing_hostlist == GNUNET_YES) return; - if ( GNUNET_YES == learning) + if ( GNUNET_YES == stat_learning) { - if (use_preconfigured_list == GNUNET_YES) - use_preconfigured_list = GNUNET_NO; + if (stat_use_bootstrap == GNUNET_YES) + stat_use_bootstrap = GNUNET_NO; else - use_preconfigured_list = GNUNET_YES; + stat_use_bootstrap = GNUNET_YES; } else - use_preconfigured_list = GNUNET_YES; + stat_use_bootstrap = GNUNET_YES; } /** @@ -650,15 +655,15 @@ clean_up () { CURLMcode mret; - if ( ( testing_hostlist == GNUNET_YES ) && ( GNUNET_NO == download_successful) && (NULL != hostlist_to_test)) + if ( ( stat_testing_hostlist == GNUNET_YES ) && ( GNUNET_NO == stat_download_successful) && (NULL != hostlist_to_test)) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Advertised hostlist with URI `%s' could not be downloaded. Advertised URI gets dismissed.\n"),hostlist_to_test->hostlist_uri); } - if ( testing_hostlist == GNUNET_YES ) + if ( stat_testing_hostlist == GNUNET_YES ) { - testing_hostlist = GNUNET_NO; + stat_testing_hostlist = GNUNET_NO; } if ( NULL != hostlist_to_test) { @@ -666,7 +671,6 @@ clean_up () hostlist_to_test = NULL; } - if (multi != NULL) { mret = curl_multi_remove_handle (multi, curl); @@ -692,8 +696,8 @@ clean_up () } GNUNET_free_non_null (current_url); current_url = NULL; - - download_in_progress = GNUNET_NO; + stat_bytes_downloaded = 0; + stat_download_in_progress = GNUNET_NO; } /** @@ -704,7 +708,7 @@ clean_up () * @param tc task context, unused */ static void -multi_ready (void *cls, +task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** @@ -712,7 +716,7 @@ multi_ready (void *cls, * receiving task with the scheduler. */ static void -run_multi () +download_prepare () { CURLMcode mret; fd_set rs; @@ -760,13 +764,12 @@ run_multi () "Scheduling task for hostlist download using cURL\n"); #endif ti_download - = GNUNET_SCHEDULER_add_select (sched, - GNUNET_SCHEDULER_PRIORITY_DEFAULT, + = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, GNUNET_SCHEDULER_NO_TASK, rtime, grs, gws, - &multi_ready, + &task_download, multi); GNUNET_NETWORK_fdset_destroy (gws); GNUNET_NETWORK_fdset_destroy (grs); @@ -781,15 +784,14 @@ run_multi () * @param tc task context, unused */ static void -multi_ready (void *cls, +task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - unsigned int counter; + int running; struct CURLMsg *msg; CURLMcode mret; - ti_download = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { @@ -802,7 +804,7 @@ multi_ready (void *cls, clean_up (); return; } - if (GNUNET_TIME_absolute_get_remaining (end_time).value == 0) + if (GNUNET_TIME_absolute_get_remaining (end_time).rel_value == 0) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Timeout trying to download hostlist from `%s'\n"), @@ -815,18 +817,25 @@ multi_ready (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ready for processing hostlist client request\n"); #endif - counter = 0; + do { running = 0; + if (stat_bytes_downloaded > MAX_BYTES_PER_HOSTLISTS) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Download limit of %u bytes exceeded, stopping download\n"),MAX_BYTES_PER_HOSTLISTS); + clean_up(); + return; + } mret = curl_multi_perform (multi, &running); if (running == 0) { do { + msg = curl_multi_info_read (multi, &running); - counter ++; GNUNET_break (msg != NULL); if (msg == NULL) break; @@ -847,15 +856,15 @@ multi_ready (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Download of hostlist `%s' completed.\n"), current_url); - download_successful = GNUNET_YES; + stat_download_successful = GNUNET_YES; update_hostlist(); - if (GNUNET_YES == testing_hostlist) + if (GNUNET_YES == stat_testing_hostlist) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Adding successfully tested hostlist `%s' datastore.\n"),current_url); insert_hostlist(); hostlist_to_test = NULL; - testing_hostlist = GNUNET_NO; + stat_testing_hostlist = GNUNET_NO; } } clean_up (); @@ -865,10 +874,11 @@ multi_ready (void *cls, } } - while (running > 0); + while ( (running > 0) ); } } while (mret == CURLM_CALL_MULTI_PERFORM); + if (mret != CURLM_OK) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -877,7 +887,7 @@ multi_ready (void *cls, curl_multi_strerror (mret)); clean_up (); } - run_multi (); + download_prepare (); } @@ -892,7 +902,7 @@ download_hostlist () CURLMcode mret; - current_url = get_list_url (); + current_url = download_get_url (); if (current_url == NULL) return; curl = curl_easy_init (); @@ -907,9 +917,10 @@ download_hostlist () _("Bootstrapping using hostlist at `%s'.\n"), current_url); - download_in_progress = GNUNET_YES; - download_successful = GNUNET_NO; - hellos_obtained = 0; + stat_download_in_progress = GNUNET_YES; + stat_download_successful = GNUNET_NO; + stat_hellos_obtained = 0; + stat_bytes_downloaded = 0; GNUNET_STATISTICS_update (stats, gettext_noop ("# hostlist downloads initiated"), @@ -918,10 +929,10 @@ download_hostlist () if (proxy != NULL) CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy); download_pos = 0; - bogus_url = 0; + stat_bogus_url = 0; CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, - &download_hostlist_processor); + &callback_download); if (ret != CURLE_OK) { clean_up (); @@ -975,7 +986,7 @@ download_hostlist () if (multi == NULL) { GNUNET_break (0); - clean_up (); + /* clean_up (); */ return; } mret = curl_multi_add_handle (multi, curl); @@ -996,12 +1007,12 @@ download_hostlist () return; } end_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); - run_multi (); + download_prepare (); } static void -download_dispatcher (void *cls, +task_download_dispatcher (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK; @@ -1009,7 +1020,7 @@ download_dispatcher (void *cls, return; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download is initiated...\n"); - if ( GNUNET_NO == download_in_progress ) + if ( GNUNET_NO == stat_download_in_progress ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download can start immediately...\n"); @@ -1019,9 +1030,8 @@ download_dispatcher (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download in progess, have to wait...\n"); - ti_download_dispatcher_task = GNUNET_SCHEDULER_add_delayed (sched, - WAITING_INTERVALL, - &download_dispatcher, + ti_download_dispatcher_task = GNUNET_SCHEDULER_add_delayed (WAITING_INTERVALL, + &task_download_dispatcher, NULL); } } @@ -1032,39 +1042,38 @@ download_dispatcher (void *cls, * this task again for a later time. */ static void -check_task (void *cls, +task_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + static int once; + struct GNUNET_TIME_Relative delay; + ti_check_download = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - if (connection_count < MIN_CONNECTIONS) + if (stat_connection_count < MIN_CONNECTIONS) { - ti_download_dispatcher_task = GNUNET_SCHEDULER_add_now ( sched, - &download_dispatcher, + ti_download_dispatcher_task = GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL); } - static int once; - struct GNUNET_TIME_Relative delay; - if (stats == NULL) - { - curl_global_cleanup (); - return; /* in shutdown */ - } + { + curl_global_cleanup (); + return; /* in shutdown */ + } delay = hostlist_delay; - if (hostlist_delay.value == 0) + if (hostlist_delay.rel_value == 0) hostlist_delay = GNUNET_TIME_UNIT_SECONDS; else hostlist_delay = GNUNET_TIME_relative_multiply (hostlist_delay, 2); - if (hostlist_delay.value > GNUNET_TIME_UNIT_HOURS.value * (1 + connection_count)) + if (hostlist_delay.rel_value > GNUNET_TIME_UNIT_HOURS.rel_value * (1 + stat_connection_count)) hostlist_delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, - (1 + connection_count)); + (1 + stat_connection_count)); GNUNET_STATISTICS_set (stats, - gettext_noop("# seconds between hostlist downloads"), - hostlist_delay.value, + gettext_noop("# milliseconds between hostlist downloads"), + hostlist_delay.rel_value, GNUNET_YES); if (0 == once) { @@ -1073,12 +1082,11 @@ check_task (void *cls, } GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Have %u/%u connections. Will consider downloading hostlist in %llums\n"), - connection_count, + stat_connection_count, MIN_CONNECTIONS, - (unsigned long long) delay.value); - ti_check_download = GNUNET_SCHEDULER_add_delayed (sched, - delay, - &check_task, + (unsigned long long) delay.rel_value); + ti_check_download = GNUNET_SCHEDULER_add_delayed (delay, + &task_check, NULL); } @@ -1094,7 +1102,7 @@ task_testing_intervall_reset (void *cls, ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - testing_allowed = GNUNET_OK; + stat_testing_allowed = GNUNET_OK; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing new hostlist advertisements is allowed again\n"); } @@ -1118,9 +1126,8 @@ task_hostlist_saving (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Hostlists will be saved to file again in %llums\n"), - (unsigned long long) SAVING_INTERVALL.value); - ti_saving_task = GNUNET_SCHEDULER_add_delayed (sched, - SAVING_INTERVALL, + (unsigned long long) SAVING_INTERVALL.rel_value); + ti_saving_task = GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL, &task_hostlist_saving, NULL); } @@ -1130,21 +1137,20 @@ task_hostlist_saving (void *cls, * * @param cls closure * @param peer peer identity this notification is about - * @param latency reported latency of the connection with 'other' - * @param distance reported distance (DV) to 'other' + * @param atsi performance data */ static void handler_connect (void *cls, const struct GNUNET_PeerIdentity * peer, - struct GNUNET_TIME_Relative latency, - uint32_t distance) + const struct GNUNET_TRANSPORT_ATS_Information *atsi) { - connection_count++; + GNUNET_assert (stat_connection_count < UINT_MAX); + stat_connection_count++; GNUNET_STATISTICS_update (stats, gettext_noop ("# active connections"), 1, - GNUNET_NO); + GNUNET_NO); } @@ -1159,11 +1165,12 @@ handler_disconnect (void *cls, const struct GNUNET_PeerIdentity * peer) { - connection_count--; - GNUNET_STATISTICS_update (stats, - gettext_noop ("# active connections"), - -1, - GNUNET_NO); + GNUNET_assert (stat_connection_count > 0); + stat_connection_count--; + GNUNET_STATISTICS_update (stats, + gettext_noop ("# active connections"), + -1, + GNUNET_NO); } /** @@ -1172,17 +1179,15 @@ handler_disconnect (void *cls, * @param cls closure (always NULL) * @param peer the peer sending the message * @param message the actual message - * @param latency latency - * @param distance distance + * @param atsi performance data * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ static int handler_advertisement (void *cls, - const struct GNUNET_PeerIdentity * peer, - const struct GNUNET_MessageHeader * message, - struct GNUNET_TIME_Relative latency, - uint32_t distance) + const struct GNUNET_PeerIdentity * peer, + const struct GNUNET_MessageHeader * message, + const struct GNUNET_TRANSPORT_ATS_Information *atsi) { size_t size; size_t uri_size; @@ -1217,13 +1222,13 @@ handler_advertisement (void *cls, return GNUNET_OK; } - if ( GNUNET_NO == testing_allowed ) + if ( GNUNET_NO == stat_testing_allowed ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Currently not accepting new advertisements: interval between to advertisements is not reached\n"); return GNUNET_SYSERR; } - if ( GNUNET_YES == testing_hostlist ) + if ( GNUNET_YES == stat_testing_hostlist ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Currently not accepting new advertisements: we are already testing a hostlist\n"); @@ -1238,19 +1243,17 @@ handler_advertisement (void *cls, hostlist->quality = HOSTLIST_INITIAL; hostlist_to_test = hostlist; - testing_hostlist = GNUNET_YES; - testing_allowed = GNUNET_NO; - ti_testing_intervall_task = GNUNET_SCHEDULER_add_delayed (sched, - TESTING_INTERVALL, + stat_testing_hostlist = GNUNET_YES; + stat_testing_allowed = GNUNET_NO; + ti_testing_intervall_task = GNUNET_SCHEDULER_add_delayed (TESTING_INTERVAL, &task_testing_intervall_reset, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing new hostlist advertisements is locked for the next %u ms\n", - TESTING_INTERVALL); + TESTING_INTERVAL.rel_value); - ti_download_dispatcher_task = GNUNET_SCHEDULER_add_now (sched, - &download_dispatcher, + ti_download_dispatcher_task = GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL); return GNUNET_OK; @@ -1275,8 +1278,7 @@ primary_task (void *cls, int success) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Statistics request done, scheduling hostlist download\n"); #endif - ti_check_download = GNUNET_SCHEDULER_add_now (sched, - &check_task, + ti_check_download = GNUNET_SCHEDULER_add_now (&task_check, NULL); } @@ -1291,7 +1293,7 @@ process_stat (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Initial time between hostlist downloads is %llums\n"), (unsigned long long) value); - hostlist_delay.value = value; + hostlist_delay.rel_value = value; return GNUNET_OK; } @@ -1314,10 +1316,10 @@ load_hostlist_file () uint32_t counter; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "HOSTLIST", - "HOSTLISTFILE", - &filename)) + GNUNET_CONFIGURATION_get_value_filename (cfg, + "HOSTLIST", + "HOSTLISTFILE", + &filename)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No `%s' specified in `%s' configuration, cannot load hostlists from file.\n"), @@ -1348,6 +1350,7 @@ load_hostlist_file () counter = 0; while ( (GNUNET_OK == GNUNET_BIO_read_string (rh, "url" , &uri, MAX_URL_LEN)) && + (NULL != uri) && (GNUNET_OK == GNUNET_BIO_read_int32 (rh, ×_used)) && (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) && (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used)) && @@ -1359,8 +1362,8 @@ load_hostlist_file () hostlist->hostlist_uri = (const char *) &hostlist[1]; memcpy (&hostlist[1], uri, strlen(uri)+1); hostlist->quality = quality; - hostlist->time_creation.value = created; - hostlist->time_last_usage.value = last_used; + hostlist->time_creation.abs_value = created; + hostlist->time_last_usage.abs_value = last_used; GNUNET_CONTAINER_DLL_insert(linked_list_head, linked_list_tail, hostlist); linked_list_size++; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1404,7 +1407,7 @@ static void save_hostlist_file ( int shutdown ) uint32_t counter; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, + GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE", &filename)) @@ -1414,6 +1417,11 @@ static void save_hostlist_file ( int shutdown ) "HOSTLISTFILE", "HOSTLIST"); return; } + if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) + { + GNUNET_free (filename); + return; + } wh = GNUNET_BIO_write_open (filename); if ( NULL == wh) { @@ -1427,7 +1435,6 @@ static void save_hostlist_file ( int shutdown ) GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Writing %u hostlist URIs to `%s'\n" ), linked_list_size, filename); - /* add code to write hostlists to file using bio */ ok = GNUNET_YES; counter = 0; @@ -1447,9 +1454,9 @@ static void save_hostlist_file ( int shutdown ) (GNUNET_OK != GNUNET_BIO_write_int64 (wh, pos->quality)) || (GNUNET_OK != - GNUNET_BIO_write_int64 (wh, pos->time_last_usage.value)) || + GNUNET_BIO_write_int64 (wh, pos->time_last_usage.abs_value)) || (GNUNET_OK != - GNUNET_BIO_write_int64 (wh, pos->time_creation.value)) || + GNUNET_BIO_write_int64 (wh, pos->time_creation.abs_value)) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->hello_count))) { @@ -1482,7 +1489,6 @@ static void save_hostlist_file ( int shutdown ) */ int GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, - struct GNUNET_SCHEDULER_Handle *s, struct GNUNET_STATISTICS_Handle *st, GNUNET_CORE_ConnectEventHandler *ch, GNUNET_CORE_DisconnectEventHandler *dh, @@ -1497,14 +1503,13 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, GNUNET_break (0); return GNUNET_SYSERR; } - transport = GNUNET_TRANSPORT_connect (s, c, NULL, NULL, NULL, NULL); + transport = GNUNET_TRANSPORT_connect (c, NULL, NULL, NULL, NULL, NULL); if (NULL == transport) { curl_global_cleanup (); return GNUNET_SYSERR; } cfg = c; - sched = s; stats = st; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, @@ -1512,16 +1517,16 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, "HTTP-PROXY", &proxy)) proxy = NULL; - learning = learn; + stat_learning = learn; *ch = &handler_connect; *dh = &handler_disconnect; linked_list_head = NULL; linked_list_tail = NULL; - use_preconfigured_list = GNUNET_YES; - testing_hostlist = GNUNET_NO; - testing_allowed = GNUNET_YES; + stat_use_bootstrap = GNUNET_YES; + stat_testing_hostlist = GNUNET_NO; + stat_testing_allowed = GNUNET_YES; - if ( GNUNET_YES == learning ) + if ( GNUNET_YES == stat_learning ) { *msgh = &handler_advertisement; GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -1529,9 +1534,8 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, load_hostlist_file (); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Hostlists will be saved to file again in %llums\n"), - (unsigned long long) SAVING_INTERVALL.value); - ti_saving_task = GNUNET_SCHEDULER_add_delayed (sched, - SAVING_INTERVALL, + (unsigned long long) SAVING_INTERVALL.rel_value); + ti_saving_task = GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL, &task_hostlist_saving, NULL); } @@ -1540,7 +1544,7 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Learning is not enabled on this peer\n")); *msgh = NULL; - if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE", &filename)) @@ -1560,7 +1564,7 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, } GNUNET_STATISTICS_get (stats, "hostlist", - gettext_noop("# seconds between hostlist downloads"), + gettext_noop("# milliseconds between hostlist downloads"), GNUNET_TIME_UNIT_MINUTES, &primary_task, &process_stat, @@ -1575,38 +1579,35 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, void GNUNET_HOSTLIST_client_stop () { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Hostlist client shutdown\n"); #if DEBUG_HOSTLIST_CLIENT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n"); #endif - if ( GNUNET_YES == learning ) + if ( GNUNET_YES == stat_learning ) save_hostlist_file ( GNUNET_YES ); if (ti_saving_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel (sched, - ti_saving_task); + GNUNET_SCHEDULER_cancel (ti_saving_task); } if (ti_download_dispatcher_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel (sched, - ti_download_dispatcher_task); + GNUNET_SCHEDULER_cancel (ti_download_dispatcher_task); } if (ti_testing_intervall_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel (sched, - ti_testing_intervall_task); + GNUNET_SCHEDULER_cancel (ti_testing_intervall_task); } if (ti_download != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel (sched, - ti_download); + GNUNET_SCHEDULER_cancel (ti_download); } if (ti_check_download != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel (sched, - ti_check_download); + GNUNET_SCHEDULER_cancel (ti_check_download); curl_global_cleanup (); } if (transport != NULL) @@ -1618,7 +1619,6 @@ GNUNET_HOSTLIST_client_stop () GNUNET_free_non_null (proxy); proxy = NULL; cfg = NULL; - sched = NULL; } /* end of hostlist-client.c */