- minor renamings
[oweals/gnunet.git] / src / hostlist / hostlist-client.c
index 422855f0eb3cae63832a9a0bb06b095d90e74565..8271ecc0cdc911d51fc437b53471d95255da58e8 100644 (file)
 #include "gnunet_transport_service.h"
 #include "gnunet-daemon-hostlist.h"
 #include <curl/curl.h>
-#include "gnunet_common.h"
-#include "gnunet_bio_lib.h"
-
-#define DEBUG_HOSTLIST_CLIENT GNUNET_NO
+#include "gnunet_util_lib.h"
 
 
 /**
@@ -208,6 +205,11 @@ static unsigned int linked_list_size;
  */
 static struct Hostlist *hostlist_to_test;
 
+/**
+ * Handle for our statistics GET operation.
+ */
+static struct GNUNET_STATISTICS_GetHandle *sget;
+
 /**
  * Set to GNUNET_YES if the current URL had some problems.
  */
@@ -295,7 +297,7 @@ callback_download (void *ptr, size_t size, size_t nmemb, void *ctx)
     left -= cpy;
     if (download_pos < sizeof (struct GNUNET_MessageHeader))
     {
-      GNUNET_assert (left == 0);
+      GNUNET_assert (0 == left);
       break;
     }
     msg = (const struct GNUNET_MessageHeader *) download_buffer;
@@ -320,11 +322,9 @@ callback_download (void *ptr, size_t size, size_t nmemb, void *ctx)
     }
     if (GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) msg) == msize)
     {
-#if DEBUG_HOSTLIST_CLIENT
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Received valid `%s' message from hostlist server.\n",
                   "HELLO");
-#endif
       GNUNET_STATISTICS_update (stats,
                                 gettext_noop
                                 ("# valid HELLOs downloaded from hostlist servers"),
@@ -366,13 +366,11 @@ get_bootstrap_server ()
   size_t pos;
 
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "HOSTLIST", "SERVERS", &servers))
+      GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "SERVERS",
+                                             &servers))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _
-                ("No `%s' specified in `%s' configuration, will not bootstrap.\n"),
-                "SERVERS", "HOSTLIST");
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                              "hostlist", "SERVERS");
     return NULL;
   }
 
@@ -390,10 +388,8 @@ get_bootstrap_server ()
   }
   if (urls == 0)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _
-                ("No `%s' specified in `%s' configuration, will not bootstrap.\n"),
-                "SERVERS", "HOSTLIST");
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                              "hostlist", "SERVERS");
     GNUNET_free (servers);
     return NULL;
   }
@@ -419,6 +415,7 @@ get_bootstrap_server ()
   return ret;
 }
 
+
 /**
  * Method deciding if a preconfigured or advertisied hostlist is used on a 50:50 ratio
  * @return uri to use, NULL if there is no URL available
@@ -443,7 +440,7 @@ download_get_url ()
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Testing new advertised hostlist if it is obtainable\n");
     current_hostlist = hostlist_to_test;
-    return strdup (hostlist_to_test->hostlist_uri);
+    return GNUNET_strdup (hostlist_to_test->hostlist_uri);
   }
 
   if ((GNUNET_YES == stat_use_bootstrap) || (linked_list_size == 0))
@@ -453,8 +450,8 @@ download_get_url ()
     current_hostlist = NULL;
     return get_bootstrap_server ();
   }
-  index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
-                                    linked_list_size);
+  index =
+      GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, linked_list_size);
   counter = 0;
   pos = linked_list_head;
   while (counter < index)
@@ -462,25 +459,27 @@ download_get_url ()
     pos = pos->next;
     counter++;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Using learned hostlist `%s'\n", pos->hostlist_uri);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using learned hostlist `%s'\n",
+              pos->hostlist_uri);
   current_hostlist = pos;
-  return strdup (pos->hostlist_uri);
+  return GNUNET_strdup (pos->hostlist_uri);
 }
 
 
-#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 (CURLE_OK != ret) 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 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);
+static void
+save_hostlist_file (int shutdown);
 
 
 /**
  * add val2 to val1 with overflow check
+ *
  * @param val1 value 1
  * @param val2 value 2
  * @return result
@@ -497,12 +496,13 @@ checked_add (uint64_t val1, uint64_t val2)
   temp = val1 + val2;
   if (temp < val1)
     return maxv;
-  else
-    return temp;
+  return temp;
 }
 
+
 /**
  * Subtract val2 from val1 with underflow check
+ *
  * @param val1 value 1
  * @param val2 value 2
  * @return result
@@ -512,14 +512,15 @@ checked_sub (uint64_t val1, uint64_t val2)
 {
   if (val1 <= val2)
     return 0;
-  else
-    return (val1 - val2);
+  return (val1 - val2);
 }
 
+
 /**
  * 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
+ * @return #GNUNET_YES if existing in linked list, #GNUNET_NO if not
  */
 static int
 linked_list_contains (const char *uri)
@@ -585,11 +586,10 @@ insert_hostlist ()
     linked_list_size--;
     GNUNET_free (lowest_quality);
   }
-  GNUNET_CONTAINER_DLL_insert (linked_list_head,
-                               linked_list_tail, hostlist_to_test);
+  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"),
+  GNUNET_STATISTICS_set (stats, gettext_noop ("# advertised hostlist URIs"),
                          linked_list_size, GNUNET_NO);
   stat_testing_hostlist = GNUNET_NO;
 }
@@ -646,6 +646,7 @@ update_hostlist ()
     stat_use_bootstrap = GNUNET_YES;
 }
 
+
 /**
  * Clean up the state from the task that downloaded the
  * hostlist and schedule the next task.
@@ -679,15 +680,13 @@ clean_up ()
     mret = curl_multi_remove_handle (multi, curl);
     if (mret != CURLM_OK)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("%s failed at %s:%d: `%s'\n"),
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                   "curl_multi_remove_handle", __FILE__, __LINE__,
                   curl_multi_strerror (mret));
     }
     mret = curl_multi_cleanup (multi);
     if (mret != CURLM_OK)
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("%s failed at %s:%d: `%s'\n"),
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                   "curl_multi_cleanup", __FILE__, __LINE__,
                   curl_multi_strerror (mret));
     multi = NULL;
@@ -739,8 +738,7 @@ download_prepare ()
   mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
   if (mret != CURLM_OK)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("%s failed at %s:%d: `%s'\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                 "curl_multi_fdset", __FILE__, __LINE__,
                 curl_multi_strerror (mret));
     clean_up ();
@@ -749,8 +747,7 @@ download_prepare ()
   mret = curl_multi_timeout (multi, &timeout);
   if (mret != CURLM_OK)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("%s failed at %s:%d: `%s'\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                 "curl_multi_timeout", __FILE__, __LINE__,
                 curl_multi_strerror (mret));
     clean_up ();
@@ -764,14 +761,12 @@ download_prepare ()
   gws = GNUNET_NETWORK_fdset_create ();
   GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
   GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
-#if DEBUG_HOSTLIST_CLIENT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Scheduling task for hostlist download using cURL\n");
-#endif
-  ti_download
-      = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
-                                     GNUNET_SCHEDULER_NO_TASK,
-                                     rtime, grs, gws, &task_download, multi);
+  ti_download =
+      GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                   rtime, grs, gws,
+                                   &task_download, multi);
   GNUNET_NETWORK_fdset_destroy (gws);
   GNUNET_NETWORK_fdset_destroy (grs);
 }
@@ -779,7 +774,7 @@ download_prepare ()
 
 /**
  * Task that is run when we are ready to receive more data from the hostlist
- * server. 
+ * server.
  *
  * @param cls closure, unused
  * @param tc task context, unused
@@ -794,16 +789,14 @@ task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   ti_download = GNUNET_SCHEDULER_NO_TASK;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
   {
-#if DEBUG_HOSTLIST_CLIENT
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Shutdown requested while trying to download hostlist from `%s'\n",
                 current_url);
-#endif
     update_hostlist ();
     clean_up ();
     return;
   }
-  if (GNUNET_TIME_absolute_get_remaining (end_time).rel_value == 0)
+  if (0 == GNUNET_TIME_absolute_get_remaining (end_time).rel_value_us)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 _("Timeout trying to download hostlist from `%s'\n"),
@@ -812,11 +805,8 @@ task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     clean_up ();
     return;
   }
-#if DEBUG_HOSTLIST_CLIENT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Ready for processing hostlist client request\n");
-#endif
-
   do
   {
     running = 0;
@@ -842,12 +832,10 @@ task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
         case CURLMSG_DONE:
           if ((msg->data.result != CURLE_OK) &&
               (msg->data.result != CURLE_GOT_NOTHING))
-            GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                        _("%s failed for `%s' at %s:%d: `%s'\n"),
-                        "curl_multi_perform",
+            GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                        _("Download of hostlist from `%s' failed: `%s'\n"),
                         current_url,
-                        __FILE__,
-                        __LINE__, curl_easy_strerror (msg->data.result));
+                        curl_easy_strerror (msg->data.result));
           else
           {
             GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -880,8 +868,7 @@ task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
   if (mret != CURLM_OK)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("%s failed at %s:%d: `%s'\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("%s failed at %s:%d: `%s'\n"),
                 "curl_multi_perform", __FILE__, __LINE__,
                 curl_multi_strerror (mret));
     clean_up ();
@@ -921,8 +908,8 @@ download_hostlist ()
   stat_bytes_downloaded = 0;
 
   GNUNET_STATISTICS_update (stats,
-                            gettext_noop ("# hostlist downloads initiated"),
-                            1, GNUNET_NO);
+                            gettext_noop ("# hostlist downloads initiated"), 1,
+                            GNUNET_NO);
   if (proxy != NULL)
     CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
   download_pos = 0;
@@ -940,6 +927,8 @@ download_hostlist ()
     return;
   }
   CURL_EASY_SETOPT (curl, CURLOPT_FOLLOWLOCATION, 1);
+  CURL_EASY_SETOPT (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+  CURL_EASY_SETOPT (curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
   CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 4);
   /* no need to abort if the above failed */
   CURL_EASY_SETOPT (curl, CURLOPT_URL, current_url);
@@ -971,14 +960,12 @@ download_hostlist ()
   mret = curl_multi_add_handle (multi, curl);
   if (mret != CURLM_OK)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("%s failed at %s:%d: `%s'\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                 "curl_multi_add_handle", __FILE__, __LINE__,
                 curl_multi_strerror (mret));
     mret = curl_multi_cleanup (multi);
     if (mret != CURLM_OK)
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("%s failed at %s:%d: `%s'\n"),
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                   "curl_multi_cleanup", __FILE__, __LINE__,
                   curl_multi_strerror (mret));
     multi = NULL;
@@ -1013,6 +1000,7 @@ task_download_dispatcher (void *cls,
   }
 }
 
+
 /**
  * Task that checks if we should try to download a hostlist.
  * If so, we initiate the download, otherwise we schedule
@@ -1027,42 +1015,40 @@ task_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   ti_check_download = GNUNET_SCHEDULER_NO_TASK;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
-
-  if (stat_connection_count < MIN_CONNECTIONS)
-  {
-    ti_download_dispatcher_task =
-        GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL);
-  }
-
   if (stats == NULL)
   {
     curl_global_cleanup ();
     return;                     /* in shutdown */
   }
+  if ( (stat_connection_count < MIN_CONNECTIONS) &&
+       (GNUNET_SCHEDULER_NO_TASK == ti_download_dispatcher_task) )
+    ti_download_dispatcher_task =
+        GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL);
+
   delay = hostlist_delay;
-  if (hostlist_delay.rel_value == 0)
+  if (0 == hostlist_delay.rel_value_us)
     hostlist_delay = GNUNET_TIME_UNIT_SECONDS;
   else
     hostlist_delay = GNUNET_TIME_relative_multiply (hostlist_delay, 2);
-  if (hostlist_delay.rel_value >
-      GNUNET_TIME_UNIT_HOURS.rel_value * (1 + stat_connection_count))
+  if (hostlist_delay.rel_value_us >
+      GNUNET_TIME_UNIT_HOURS.rel_value_us * (1 + stat_connection_count))
     hostlist_delay =
         GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS,
                                        (1 + stat_connection_count));
   GNUNET_STATISTICS_set (stats,
                          gettext_noop
                          ("# milliseconds between hostlist downloads"),
-                         hostlist_delay.rel_value, GNUNET_YES);
+                         hostlist_delay.rel_value_us / 1000LL,
+                        GNUNET_YES);
   if (0 == once)
   {
     delay = GNUNET_TIME_UNIT_ZERO;
     once = 1;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _
-              ("Have %u/%u connections.  Will consider downloading hostlist in %llums\n"),
+              _("Have %u/%u connections.  Will consider downloading hostlist in %s\n"),
               stat_connection_count, MIN_CONNECTIONS,
-              (unsigned long long) delay.rel_value);
+              GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
   ti_check_download = GNUNET_SCHEDULER_add_delayed (delay, &task_check, NULL);
 }
 
@@ -1098,14 +1084,14 @@ task_hostlist_saving (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   ti_saving_task = GNUNET_SCHEDULER_NO_TASK;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Scheduled saving of hostlists\n"));
   save_hostlist_file (GNUNET_NO);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Hostlists will be saved to file again in %llums\n"),
-              (unsigned long long) SAVING_INTERVALL.rel_value);
-  ti_saving_task = GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL,
-                                                 &task_hostlist_saving, NULL);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Hostlists will be saved to file again in %s\n",
+             GNUNET_STRINGS_relative_time_to_string(SAVING_INTERVALL, GNUNET_YES));
+  ti_saving_task =
+      GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL, &task_hostlist_saving,
+                                    NULL);
 }
 
 
@@ -1114,19 +1100,14 @@ task_hostlist_saving (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  *
  * @param cls closure
  * @param peer peer identity this notification is about
- * @param atsi performance data
  */
 static void
-handler_connect (void *cls,
-                 const struct
-                 GNUNET_PeerIdentity *peer,
-                 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+handler_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
 {
   GNUNET_assert (stat_connection_count < UINT_MAX);
   stat_connection_count++;
-  GNUNET_STATISTICS_update (stats,
-                            gettext_noop ("# active connections"),
-                            1, GNUNET_NO);
+  GNUNET_STATISTICS_update (stats, gettext_noop ("# active connections"), 1,
+                            GNUNET_NO);
 }
 
 
@@ -1141,9 +1122,8 @@ handler_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
 {
   GNUNET_assert (stat_connection_count > 0);
   stat_connection_count--;
-  GNUNET_STATISTICS_update (stats,
-                            gettext_noop ("# active connections"),
-                            -1, GNUNET_NO);
+  GNUNET_STATISTICS_update (stats, gettext_noop ("# active connections"), -1,
+                            GNUNET_NO);
 }
 
 
@@ -1153,15 +1133,12 @@ handler_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
  * @param cls closure (always NULL)
  * @param peer the peer sending the message
  * @param message the actual message
- * @param atsi performance data
- * @return GNUNET_OK to keep the connection open,
- *         GNUNET_SYSERR to close it (signal serious error)
+ * @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,
-                       const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer,
+                       const struct GNUNET_MessageHeader *message)
 {
   size_t size;
   size_t uri_size;
@@ -1211,19 +1188,19 @@ handler_advertisement (void *cls,
   hostlist->hostlist_uri = (const char *) &hostlist[1];
   memcpy (&hostlist[1], uri, uri_size);
   hostlist->time_creation = GNUNET_TIME_absolute_get ();
-  hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero ();
   hostlist->quality = HOSTLIST_INITIAL;
   hostlist_to_test = hostlist;
 
   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);
+  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_INTERVAL.rel_value);
+              "Testing new hostlist advertisements is locked for the next %s\n",
+              GNUNET_STRINGS_relative_time_to_string (TESTING_INTERVAL,
+                                                     GNUNET_YES));
 
   ti_download_dispatcher_task =
       GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL);
@@ -1232,40 +1209,46 @@ handler_advertisement (void *cls,
 }
 
 
-
 /**
- * Continuation called by the statistics code once 
+ * Continuation called by the statistics code once
  * we go the stat.  Initiates hostlist download scheduling.
  *
  * @param cls closure
- * @param success GNUNET_OK if statistics were
- *        successfully obtained, GNUNET_SYSERR if not.
+ * @param success #GNUNET_OK if statistics were
+ *        successfully obtained, #GNUNET_SYSERR if not.
  */
 static void
 primary_task (void *cls, int success)
 {
-  if (stats == NULL)
-    return;                     /* in shutdown */
-#if DEBUG_HOSTLIST_CLIENT
+  sget = NULL;
+  GNUNET_assert (stats != NULL);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Statistics request done, scheduling hostlist download\n");
-#endif
   ti_check_download = GNUNET_SCHEDULER_add_now (&task_check, NULL);
 }
 
 
+/**
+ * We've received the previous delay value from statistics.  Remember it.
+ *
+ * @param cls NULL, unused
+ * @param subsystem should be "hostlist", unused
+ * @param name will be "milliseconds between hostlist downloads", unused
+ * @param value previous delay value, in milliseconds (!)
+ * @param is_persistent unused, will be GNUNET_YES
+ */
 static int
-process_stat (void *cls,
-              const char *subsystem,
-              const char *name, uint64_t value, int is_persistent)
+process_stat (void *cls, const char *subsystem, const char *name,
+              uint64_t value, int is_persistent)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Initial time between hostlist downloads is %llums\n"),
-              (unsigned long long) value);
-  hostlist_delay.rel_value = value;
+  hostlist_delay.rel_value_us = value * 1000LL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Initial time between hostlist downloads is %s\n",
+              GNUNET_STRINGS_relative_time_to_string (hostlist_delay, GNUNET_YES));
   return GNUNET_OK;
 }
 
+
 /**
  * Method to load persistent hostlist file during hostlist client startup
  */
@@ -1276,8 +1259,6 @@ load_hostlist_file ()
   char *uri;
   char *emsg;
   struct Hostlist *hostlist;
-
-  uri = NULL;
   uint32_t times_used;
   uint32_t hellos_returned;
   uint64_t quality;
@@ -1285,24 +1266,23 @@ load_hostlist_file ()
   uint64_t created;
   uint32_t counter;
 
+  uri = NULL;
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (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"),
-                "HOSTLISTFILE", "HOSTLIST");
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                              "hostlist", "HOSTLISTFILE");
     return;
   }
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Loading saved hostlist entries from file `%s' \n"), filename);
+              _("Loading saved hostlist entries from file `%s' \n"),
+             filename);
   if (GNUNET_NO == GNUNET_DISK_file_test (filename))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Hostlist file `%s' is not existing\n"), filename);
+                _("Hostlist file `%s' does not exist\n"), filename);
     GNUNET_free (filename);
     return;
   }
@@ -1321,9 +1301,8 @@ 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, &times_used)) &&
-         (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) &&
+         (NULL != uri) && (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &times_used))
+         && (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) &&
          (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used)) &&
          (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &created)) &&
          (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &hellos_returned)))
@@ -1333,8 +1312,8 @@ load_hostlist_file ()
     hostlist->hostlist_uri = (const char *) &hostlist[1];
     memcpy (&hostlist[1], uri, strlen (uri) + 1);
     hostlist->quality = quality;
-    hostlist->time_creation.abs_value = created;
-    hostlist->time_last_usage.abs_value = last_used;
+    hostlist->time_creation.abs_value_us = created;
+    hostlist->time_last_usage.abs_value_us = last_used;
     GNUNET_CONTAINER_DLL_insert (linked_list_head, linked_list_tail, hostlist);
     linked_list_size++;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1347,18 +1326,16 @@ load_hostlist_file ()
       break;
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("%u hostlist URIs loaded from file\n"), counter);
-  GNUNET_STATISTICS_set (stats,
-                         gettext_noop ("# hostlist URIs read from file"),
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("%u hostlist URIs loaded from file\n"),
+              counter);
+  GNUNET_STATISTICS_set (stats, gettext_noop ("# hostlist URIs read from file"),
                          counter, GNUNET_YES);
-  GNUNET_STATISTICS_set (stats,
-                         gettext_noop ("# advertised hostlist URIs"),
+  GNUNET_STATISTICS_set (stats, gettext_noop ("# advertised hostlist URIs"),
                          linked_list_size, GNUNET_NO);
 
   GNUNET_free_non_null (uri);
   emsg = NULL;
-  GNUNET_BIO_read_close (rh, &emsg);
+  (void) GNUNET_BIO_read_close (rh, &emsg);
   if (emsg != NULL)
     GNUNET_free (emsg);
   GNUNET_free (filename);
@@ -1379,14 +1356,11 @@ save_hostlist_file (int shutdown)
   uint32_t counter;
 
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (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 save hostlists to file.\n"),
-                "HOSTLISTFILE", "HOSTLIST");
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                              "hostlist", "HOSTLISTFILE");
     return;
   }
   if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
@@ -1404,8 +1378,7 @@ save_hostlist_file (int shutdown)
     GNUNET_free (filename);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Writing %u hostlist URIs to `%s'\n"),
+  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;
@@ -1419,16 +1392,13 @@ save_hostlist_file (int shutdown)
     }
     if (GNUNET_YES == ok)
     {
-      if ((GNUNET_OK !=
-           GNUNET_BIO_write_string (wh, pos->hostlist_uri)) ||
+      if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pos->hostlist_uri)) ||
+          (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->times_used)) ||
+          (GNUNET_OK != GNUNET_BIO_write_int64 (wh, pos->quality)) ||
           (GNUNET_OK !=
-           GNUNET_BIO_write_int32 (wh, pos->times_used)) ||
+           GNUNET_BIO_write_int64 (wh, pos->time_last_usage.abs_value_us)) ||
           (GNUNET_OK !=
-           GNUNET_BIO_write_int64 (wh, pos->quality)) ||
-          (GNUNET_OK !=
-           GNUNET_BIO_write_int64 (wh, pos->time_last_usage.abs_value)) ||
-          (GNUNET_OK !=
-           GNUNET_BIO_write_int64 (wh, pos->time_creation.abs_value)) ||
+           GNUNET_BIO_write_int64 (wh, pos->time_creation.abs_value_us)) ||
           (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->hello_count)))
       {
         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1453,6 +1423,7 @@ save_hostlist_file (int shutdown)
   GNUNET_free (filename);
 }
 
+
 /**
  * Start downloading hostlists from hostlist servers as necessary.
  */
@@ -1466,6 +1437,7 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
   char *filename;
   int result;
 
+  GNUNET_assert (NULL != st);
   if (0 != curl_global_init (CURL_GLOBAL_WIN32))
   {
     GNUNET_break (0);
@@ -1480,8 +1452,8 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
   cfg = c;
   stats = st;
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "HOSTLIST", "HTTP-PROXY", &proxy))
+      GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "HTTP-PROXY",
+                                             &proxy))
     proxy = NULL;
   stat_learning = learn;
   *ch = &handler_connect;
@@ -1498,21 +1470,21 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 _("Learning is enabled on this peer\n"));
     load_hostlist_file ();
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Hostlists will be saved to file again in  %llums\n"),
-                (unsigned long long) SAVING_INTERVALL.rel_value);
-    ti_saving_task = GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL,
-                                                   &task_hostlist_saving, NULL);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Hostlists will be saved to file again in %s\n",
+               GNUNET_STRINGS_relative_time_to_string (SAVING_INTERVALL, GNUNET_YES));
+    ti_saving_task =
+        GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL, &task_hostlist_saving,
+                                      NULL);
   }
   else
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 _("Learning is not enabled on this peer\n"));
     *msgh = NULL;
-    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg,
-                                                              "HOSTLIST",
-                                                              "HOSTLISTFILE",
-                                                              &filename))
+    if (GNUNET_OK ==
+        GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST",
+                                                 "HOSTLISTFILE", &filename))
     {
       if (GNUNET_YES == GNUNET_DISK_file_test (filename))
       {
@@ -1529,12 +1501,11 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
     }
     GNUNET_free (filename);
   }
-  GNUNET_STATISTICS_get (stats,
-                         "hostlist",
-                         gettext_noop
-                         ("# milliseconds between hostlist downloads"),
-                         GNUNET_TIME_UNIT_MINUTES, &primary_task, &process_stat,
-                         NULL);
+  sget = GNUNET_STATISTICS_get (stats, "hostlist",
+                               gettext_noop
+                               ("# milliseconds between hostlist downloads"),
+                               GNUNET_TIME_UNIT_MINUTES, &primary_task, &process_stat,
+                               NULL);
   return GNUNET_OK;
 }
 
@@ -1546,32 +1517,39 @@ 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 (NULL != sget)
+  {
+    GNUNET_STATISTICS_get_cancel (sget);
+    sget = NULL;
+  }
+  stats = NULL;
   if (GNUNET_YES == stat_learning)
     save_hostlist_file (GNUNET_YES);
-
   if (ti_saving_task != GNUNET_SCHEDULER_NO_TASK)
   {
     GNUNET_SCHEDULER_cancel (ti_saving_task);
+    ti_saving_task = GNUNET_SCHEDULER_NO_TASK;
   }
 
   if (ti_download_dispatcher_task != GNUNET_SCHEDULER_NO_TASK)
-  {
+    {
     GNUNET_SCHEDULER_cancel (ti_download_dispatcher_task);
+    ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK;
   }
   if (ti_testing_intervall_task != GNUNET_SCHEDULER_NO_TASK)
   {
     GNUNET_SCHEDULER_cancel (ti_testing_intervall_task);
+    ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK;
   }
   if (ti_download != GNUNET_SCHEDULER_NO_TASK)
   {
     GNUNET_SCHEDULER_cancel (ti_download);
+    ti_download = GNUNET_SCHEDULER_NO_TASK;
   }
   if (ti_check_download != GNUNET_SCHEDULER_NO_TASK)
   {
     GNUNET_SCHEDULER_cancel (ti_check_download);
+    ti_check_download = GNUNET_SCHEDULER_NO_TASK;
     curl_global_cleanup ();
   }
   if (transport != NULL)
@@ -1579,7 +1557,6 @@ GNUNET_HOSTLIST_client_stop ()
     GNUNET_TRANSPORT_disconnect (transport);
     transport = NULL;
   }
-  GNUNET_assert (NULL == transport);
   GNUNET_free_non_null (proxy);
   proxy = NULL;
   cfg = NULL;