plugin datastore mysql
[oweals/gnunet.git] / src / hostlist / gnunet-daemon-hostlist_client.c
index b92f195f889bad0b49284f80258c173330c0629b..df0cabe1d348294a2f0eb800d14955e956e3b446 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001-2010, 2014 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2001-2010, 2014 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 /**
  * @file hostlist/gnunet-daemon-hostlist_client.c
 #include "gnunet_statistics_service.h"
 #include "gnunet_transport_service.h"
 #include "gnunet-daemon-hostlist.h"
+#if HAVE_CURL_CURL_H
 #include <curl/curl.h>
+#elif HAVE_GNURL_CURL_H
+#include <gnurl/curl.h>
+#endif
+
 
 
 /**
@@ -205,27 +210,27 @@ static struct GNUNET_TIME_Relative hostlist_delay;
 /**
  * ID of the task, checking if hostlist download should take plate
  */
-static GNUNET_SCHEDULER_TaskIdentifier ti_check_download;
+static struct GNUNET_SCHEDULER_Task *ti_check_download;
 
 /**
  * ID of the task downloading the hostlist
  */
-static GNUNET_SCHEDULER_TaskIdentifier ti_download;
+static struct GNUNET_SCHEDULER_Task *ti_download;
 
 /**
  * ID of the task saving the hostlsit in a regular intervall
  */
-static GNUNET_SCHEDULER_TaskIdentifier ti_saving_task;
+static struct GNUNET_SCHEDULER_Task *ti_saving_task;
 
 /**
  * ID of the task called to initiate a download
  */
-static GNUNET_SCHEDULER_TaskIdentifier ti_download_dispatcher_task;
+static struct GNUNET_SCHEDULER_Task *ti_download_dispatcher_task;
 
 /**
  * ID of the task controlling the locking between two hostlist tests
  */
-static GNUNET_SCHEDULER_TaskIdentifier ti_testing_intervall_task;
+static struct GNUNET_SCHEDULER_Task *ti_testing_intervall_task;
 
 /**
  * At what time MUST the current hostlist request be done?
@@ -714,8 +719,9 @@ clean_up ()
 {
   CURLMcode mret;
 
-  if ((stat_testing_hostlist == GNUNET_YES) &&
-      (GNUNET_NO == stat_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,
                 _
@@ -733,7 +739,7 @@ clean_up ()
     hostlist_to_test = NULL;
   }
 
-  if (multi != NULL)
+  if (NULL != multi)
   {
     mret = curl_multi_remove_handle (multi, curl);
     if (mret != CURLM_OK)
@@ -749,7 +755,7 @@ clean_up ()
                   curl_multi_strerror (mret));
     multi = NULL;
   }
-  if (curl != NULL)
+  if (NULL != curl)
   {
     curl_easy_cleanup (curl);
     curl = NULL;
@@ -769,8 +775,7 @@ clean_up ()
  * @param tc task context, unused
  */
 static void
-task_download (void *cls,
-               const struct GNUNET_SCHEDULER_TaskContext *tc);
+task_download (void *cls);
 
 
 /**
@@ -836,26 +841,15 @@ download_prepare ()
  * server.
  *
  * @param cls closure, unused
- * @param tc task context, unused
  */
 static void
-task_download (void *cls,
-               const struct GNUNET_SCHEDULER_TaskContext *tc)
+task_download (void *cls)
 {
   int running;
   struct CURLMsg *msg;
   CURLMcode mret;
 
-  ti_download = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Shutdown requested while trying to download hostlist from `%s'\n",
-                current_url);
-    update_hostlist ();
-    clean_up ();
-    return;
-  }
+  ti_download = NULL;
   if (0 == GNUNET_TIME_absolute_get_remaining (end_time).rel_value_us)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1041,12 +1035,9 @@ download_hostlist ()
 
 
 static void
-task_download_dispatcher (void *cls,
-                          const struct GNUNET_SCHEDULER_TaskContext *tc)
+task_download_dispatcher (void *cls)
 {
-  ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
+  ti_download_dispatcher_task = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download is initiated...\n");
   if (GNUNET_NO == stat_download_in_progress)
   {
@@ -1070,21 +1061,19 @@ task_download_dispatcher (void *cls,
  * this task again for a later time.
  */
 static void
-task_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+task_check (void *cls)
 {
   static int once;
   struct GNUNET_TIME_Relative delay;
 
-  ti_check_download = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
+  ti_check_download = NULL;
   if (stats == NULL)
   {
     curl_global_cleanup ();
     return;                     /* in shutdown */
   }
   if ( (stat_connection_count < MIN_CONNECTIONS) &&
-       (GNUNET_SCHEDULER_NO_TASK == ti_download_dispatcher_task) )
+       (NULL == ti_download_dispatcher_task) )
     ti_download_dispatcher_task =
         GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL);
 
@@ -1112,7 +1101,8 @@ task_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
               _("Have %u/%u connections.  Will consider downloading hostlist in %s\n"),
               stat_connection_count, MIN_CONNECTIONS,
               GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
-  ti_check_download = GNUNET_SCHEDULER_add_delayed (delay, &task_check, NULL);
+  ti_check_download = GNUNET_SCHEDULER_add_delayed (delay,
+                                                   &task_check, NULL);
 }
 
 
@@ -1120,15 +1110,11 @@ task_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * This tasks sets hostlist testing to allowed after intervall between to testings is reached
  *
  * @param cls closure
- * @param tc TaskContext
  */
 static void
-task_testing_intervall_reset (void *cls,
-                              const struct GNUNET_SCHEDULER_TaskContext *tc)
+task_testing_intervall_reset (void *cls)
 {
-  ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
+  ti_testing_intervall_task = NULL;
   stat_testing_allowed = GNUNET_OK;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Testing new hostlist advertisements is allowed again\n");
@@ -1139,21 +1125,19 @@ task_testing_intervall_reset (void *cls,
  * Task that writes hostlist entries to a file on a regular base
  *
  * @param cls closure
- * @param tc TaskContext
  */
 static void
-task_hostlist_saving (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+task_hostlist_saving (void *cls)
 {
-  ti_saving_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
+  ti_saving_task = NULL;
   save_hostlist_file (GNUNET_NO);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Hostlists will be saved to file again in %s\n",
              GNUNET_STRINGS_relative_time_to_string(SAVING_INTERVAL, GNUNET_YES));
   ti_saving_task =
-      GNUNET_SCHEDULER_add_delayed (SAVING_INTERVAL, &task_hostlist_saving,
+      GNUNET_SCHEDULER_add_delayed (SAVING_INTERVAL,
+                                   &task_hostlist_saving,
                                     NULL);
 }
 
@@ -1281,16 +1265,40 @@ handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer,
  *        successfully obtained, #GNUNET_SYSERR if not.
  */
 static void
-primary_task (void *cls, int success)
+primary_task (void *cls,
+              int success)
 {
+  if (NULL != ti_check_download)
+  {
+    GNUNET_SCHEDULER_cancel (ti_check_download);
+    ti_check_download = NULL;
+  }
   sget = NULL;
-  GNUNET_assert (stats != NULL);
+  GNUNET_assert (NULL != stats);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Statistics request done, scheduling hostlist download\n");
   ti_check_download = GNUNET_SCHEDULER_add_now (&task_check, NULL);
 }
 
 
+/**
+ * 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.
+ */
+static void
+stat_timeout_task (void *cls)
+{
+  GNUNET_STATISTICS_get_cancel (sget);
+  sget = NULL;
+  ti_check_download = GNUNET_SCHEDULER_add_now (&task_check,
+                                                NULL);
+}
+
+
 /**
  * We've received the previous delay value from statistics.  Remember it.
  *
@@ -1310,7 +1318,8 @@ process_stat (void *cls,
   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));
+              GNUNET_STRINGS_relative_time_to_string (hostlist_delay,
+                                                      GNUNET_YES));
   return GNUNET_OK;
 }
 
@@ -1441,13 +1450,14 @@ save_hostlist_file (int shutdown)
   if (NULL == wh)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _
-                ("Could not open file `%s' for writing to save hostlists: %s\n"),
-                filename, STRERROR (errno));
+                _("Could not open file `%s' for writing to save hostlists: %s\n"),
+                filename,
+                STRERROR (errno));
     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;
@@ -1525,6 +1535,7 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
   transport = GNUNET_TRANSPORT_connect (c, NULL, NULL, NULL, NULL, NULL);
   if (NULL == transport)
   {
+    GNUNET_break (0);
     curl_global_cleanup ();
     return GNUNET_SYSERR;
   }
@@ -1532,8 +1543,9 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
   stats = st;
 
   /* Read proxy configuration */
-  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
-      "HOSTLIST", "PROXY", &proxy))
+  if (GNUNET_OK ==
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "HOSTLIST", "PROXY", &proxy))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                      "Found proxy host: `%s'\n",
@@ -1557,23 +1569,26 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
     }
 
     /* proxy type */
-    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
-        "HOSTLIST", "PROXY_TYPE", &proxytype_str))
+    if (GNUNET_OK ==
+        GNUNET_CONFIGURATION_get_value_string (cfg,
+                                               "HOSTLIST",
+                                               "PROXY_TYPE",
+                                               &proxytype_str))
     {
-      GNUNET_STRINGS_utf8_toupper (proxytype_str, proxytype_str);
-
+      GNUNET_STRINGS_utf8_toupper (proxytype_str,
+                                   proxytype_str);
       proxy_type = CURLPROXY_HTTP;
-      if (0 == strcmp(proxytype_str, "HTTP"))
+      if (0 == strcmp (proxytype_str, "HTTP"))
         proxy_type = CURLPROXY_HTTP;
-      else if (0 == strcmp(proxytype_str, "HTTP_1_0"))
+      else if (0 == strcmp (proxytype_str, "HTTP_1_0"))
         proxy_type = CURLPROXY_HTTP_1_0;
-      else if (0 == strcmp(proxytype_str, "SOCKS4"))
+      else if (0 == strcmp (proxytype_str, "SOCKS4"))
         proxy_type = CURLPROXY_SOCKS4;
-      else if (0 == strcmp(proxytype_str, "SOCKS5"))
+      else if (0 == strcmp (proxytype_str, "SOCKS5"))
         proxy_type = CURLPROXY_SOCKS5;
-      else if (0 == strcmp(proxytype_str, "SOCKS4A"))
+      else if (0 == strcmp (proxytype_str, "SOCKS4A"))
         proxy_type = CURLPROXY_SOCKS4A;
-      else if (0 == strcmp(proxytype_str, "SOCKS5_HOSTNAME"))
+      else if (0 == strcmp (proxytype_str, "SOCKS5_HOSTNAME"))
         proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
       else
       {
@@ -1613,7 +1628,8 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
                 "Hostlists will be saved to file again in %s\n",
                GNUNET_STRINGS_relative_time_to_string (SAVING_INTERVAL, GNUNET_YES));
     ti_saving_task =
-        GNUNET_SCHEDULER_add_delayed (SAVING_INTERVAL, &task_hostlist_saving,
+        GNUNET_SCHEDULER_add_delayed (SAVING_INTERVAL,
+                                      &task_hostlist_saving,
                                       NULL);
   }
   else
@@ -1628,23 +1644,39 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
       if (GNUNET_YES == GNUNET_DISK_file_test (filename))
       {
         result = remove (filename);
-        if (result == 0)
+        if (0 == result)
           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                      _
-                      ("Since learning is not enabled on this peer, hostlist file `%s' was removed\n"),
+                      _("Since learning is not enabled on this peer, hostlist file `%s' was removed\n"),
                       filename);
         else
-          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                      _("Hostlist file `%s' could not be removed\n"), filename);
+          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+                                    "remove",
+                                    filename);
       }
     }
     GNUNET_free (filename);
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Loading stats value on hostlist download frequency\n");
   sget = GNUNET_STATISTICS_get (stats, "hostlist",
                                gettext_noop
                                ("# milliseconds between hostlist downloads"),
-                               GNUNET_TIME_UNIT_MINUTES, &primary_task, &process_stat,
+                                &primary_task,
+                                &process_stat,
                                NULL);
+  if (NULL == sget)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Statistics request failed, scheduling hostlist download\n");
+    ti_check_download = GNUNET_SCHEDULER_add_now (&task_check,
+                                                  NULL);
+  }
+  else
+  {
+    ti_check_download = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
+                                                      &stat_timeout_task,
+                                                      NULL);
+  }
   return GNUNET_OK;
 }
 
@@ -1655,7 +1687,8 @@ 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");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Hostlist client shutdown\n");
   if (NULL != sget)
   {
     GNUNET_STATISTICS_get_cancel (sget);
@@ -1664,31 +1697,32 @@ GNUNET_HOSTLIST_client_stop ()
   stats = NULL;
   if (GNUNET_YES == stat_learning)
     save_hostlist_file (GNUNET_YES);
-  if (ti_saving_task != GNUNET_SCHEDULER_NO_TASK)
+  if (NULL != ti_saving_task)
   {
     GNUNET_SCHEDULER_cancel (ti_saving_task);
-    ti_saving_task = GNUNET_SCHEDULER_NO_TASK;
+    ti_saving_task = NULL;
   }
-
-  if (ti_download_dispatcher_task != GNUNET_SCHEDULER_NO_TASK)
+  if (NULL != ti_download_dispatcher_task)
     {
     GNUNET_SCHEDULER_cancel (ti_download_dispatcher_task);
-    ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK;
+    ti_download_dispatcher_task = NULL;
   }
-  if (ti_testing_intervall_task != GNUNET_SCHEDULER_NO_TASK)
+  if (NULL != ti_testing_intervall_task)
   {
     GNUNET_SCHEDULER_cancel (ti_testing_intervall_task);
-    ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK;
+    ti_testing_intervall_task = NULL;
   }
-  if (ti_download != GNUNET_SCHEDULER_NO_TASK)
+  if (NULL != ti_download)
   {
     GNUNET_SCHEDULER_cancel (ti_download);
-    ti_download = GNUNET_SCHEDULER_NO_TASK;
+    ti_download = NULL;
+    update_hostlist ();
+    clean_up ();
   }
-  if (ti_check_download != GNUNET_SCHEDULER_NO_TASK)
+  if (NULL != ti_check_download)
   {
     GNUNET_SCHEDULER_cancel (ti_check_download);
-    ti_check_download = GNUNET_SCHEDULER_NO_TASK;
+    ti_check_download = NULL;
     curl_global_cleanup ();
   }
   if (NULL != transport)