gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r33489 - gnunet/src/hostlist


From: gnunet
Subject: [GNUnet-SVN] r33489 - gnunet/src/hostlist
Date: Tue, 3 Jun 2014 10:41:00 +0200

Author: grothoff
Date: 2014-06-03 10:41:00 +0200 (Tue, 03 Jun 2014)
New Revision: 33489

Added:
   gnunet/src/hostlist/gnunet-daemon-hostlist_client.c
   gnunet/src/hostlist/gnunet-daemon-hostlist_client.h
   gnunet/src/hostlist/gnunet-daemon-hostlist_server.c
   gnunet/src/hostlist/gnunet-daemon-hostlist_server.h
Removed:
   gnunet/src/hostlist/hostlist-client.c
   gnunet/src/hostlist/hostlist-client.h
   gnunet/src/hostlist/hostlist-server.c
   gnunet/src/hostlist/hostlist-server.h
Modified:
   gnunet/src/hostlist/Makefile.am
   gnunet/src/hostlist/gnunet-daemon-hostlist.c
   gnunet/src/hostlist/gnunet-daemon-hostlist.h
   gnunet/src/hostlist/test_gnunet_daemon_hostlist_learning.c
Log:
-doxygen, code cleanup

Modified: gnunet/src/hostlist/Makefile.am
===================================================================
--- gnunet/src/hostlist/Makefile.am     2014-06-03 08:19:03 UTC (rev 33488)
+++ gnunet/src/hostlist/Makefile.am     2014-06-03 08:41:00 UTC (rev 33489)
@@ -12,7 +12,8 @@
 endif
 
 if HAVE_MHD
- HOSTLIST_SERVER_SOURCES =  hostlist-server.c hostlist-server.h
+ HOSTLIST_SERVER_SOURCES = \
+   gnunet-daemon-hostlist_server.c gnunet-daemon-hostlist_server.h
  GN_LIBMHD = -lmicrohttpd
 endif
 
@@ -23,7 +24,7 @@
 
 gnunet_daemon_hostlist_SOURCES = \
  gnunet-daemon-hostlist.c gnunet-daemon-hostlist.h \
- hostlist-client.c hostlist-client.h \
+ gnunet-daemon-hostlist_client.c gnunet-daemon-hostlist_client.h \
  $(HOSTLIST_SERVER_SOURCES)
 
 gnunet_daemon_hostlist_LDADD = \

Modified: gnunet/src/hostlist/gnunet-daemon-hostlist.c
===================================================================
--- gnunet/src/hostlist/gnunet-daemon-hostlist.c        2014-06-03 08:19:03 UTC 
(rev 33488)
+++ gnunet/src/hostlist/gnunet-daemon-hostlist.c        2014-06-03 08:41:00 UTC 
(rev 33489)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
+     (C) 2007, 2008, 2009, 2014 Christian Grothoff (and other contributing 
authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -23,10 +23,8 @@
  * @brief code for bootstrapping via hostlist servers
  * @author Christian Grothoff
  */
-
-#include <stdlib.h>
 #include "platform.h"
-#include "hostlist-client.h"
+#include "gnunet-daemon-hostlist_client.h"
 #include "gnunet_core_service.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_protocols.h"
@@ -34,7 +32,7 @@
 
 #if HAVE_MHD
 
-#include "hostlist-server.h"
+#include "gnunet-daemon-hostlist_server.h"
 
 /**
  * Set if we are allowed to advertise our hostlist to others.
@@ -123,9 +121,19 @@
 };
 GNUNET_NETWORK_STRUCT_END
 
+
+/**
+ * Our own peer identity.
+ */
 static struct GNUNET_PeerIdentity me;
 
 
+/**
+ * Callback invoked once our connection to CORE service is up.
+ *
+ * @param cls NULL
+ * @param my_identity our peer's identity
+ */
 static void
 core_init (void *cls,
            const struct GNUNET_PeerIdentity *my_identity)
@@ -143,7 +151,8 @@
  * @return #GNUNET_OK on success
  */
 static int
-advertisement_handler (void *cls, const struct GNUNET_PeerIdentity *peer,
+advertisement_handler (void *cls,
+                       const struct GNUNET_PeerIdentity *peer,
                        const struct GNUNET_MessageHeader *message)
 {
   GNUNET_assert (NULL != client_adv_handler);
@@ -182,7 +191,8 @@
  * @param peer peer identity this notification is about
  */
 static void
-disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer)
+disconnect_handler (void *cls,
+                    const struct GNUNET_PeerIdentity *peer)
 {
   if (0 == memcmp (&me, peer, sizeof (struct GNUNET_PeerIdentity)))
     return;
@@ -200,13 +210,17 @@
 /**
  * Last task run during shutdown.  Disconnects us from
  * the other services.
+ *
+ * @param cls NULL
+ * @param tc scheduler context
  */
 static void
-cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+cleaning_task (void *cls,
+               const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Hostlist daemon is shutting down\n");
-  if (core != NULL)
+  if (NULL != core)
   {
     GNUNET_CORE_disconnect (core);
     core = NULL;
@@ -221,7 +235,7 @@
     GNUNET_HOSTLIST_server_stop ();
   }
 #endif
-  if (stats != NULL)
+  if (NULL != stats)
   {
     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
     stats = NULL;
@@ -238,7 +252,9 @@
  * @param cfg configuration
  */
 static void
-run (void *cls, char *const *args, const char *cfgfile,
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   static const struct GNUNET_CORE_MessageHandler learn_handlers[] = {
@@ -248,15 +264,14 @@
   static const struct GNUNET_CORE_MessageHandler no_learn_handlers[] = {
     {NULL, 0, 0}
   };
-  if ((!bootstrapping) && (!learning)
+  if ((! bootstrapping) && (! learning)
 #if HAVE_MHD
-      && (!provide_hostlist)
+      && (! provide_hostlist)
 #endif
       )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _
-                ("None of the functions for the hostlist daemon were enabled.  
I have no reason to run!\n"));
+                _("None of the functions for the hostlist daemon were enabled. 
 I have no reason to run!\n"));
     return;
   }
   stats = GNUNET_STATISTICS_create ("hostlist", cfg);
@@ -332,7 +347,8 @@
   ret =
       (GNUNET_OK ==
        GNUNET_PROGRAM_run (argc, argv, "hostlist",
-                           _("GNUnet hostlist server and client"), options,
+                           _("GNUnet hostlist server and client"),
+                           options,
                            &run, NULL)) ? 0 : 1;
   GNUNET_free ((void*) argv);
   return ret;

Modified: gnunet/src/hostlist/gnunet-daemon-hostlist.h
===================================================================
--- gnunet/src/hostlist/gnunet-daemon-hostlist.h        2014-06-03 08:19:03 UTC 
(rev 33488)
+++ gnunet/src/hostlist/gnunet-daemon-hostlist.h        2014-06-03 08:41:00 UTC 
(rev 33489)
@@ -25,23 +25,19 @@
  */
 #include <stdlib.h>
 #include "platform.h"
-#include "hostlist-client.h"
-#include "hostlist-server.h"
 #include "gnunet_core_service.h"
-#include "gnunet_getopt_lib.h"
 #include "gnunet_protocols.h"
-#include "gnunet_program_lib.h"
 #include "gnunet_statistics_service.h"
-#include "gnunet_strings_lib.h"
-#include "gnunet_time_lib.h"
 #include "gnunet_util_lib.h"
 
 /**
- * General hostlist daemon debugging.
+ * How long can hostlist URLs be?
  */
-#define DEBUG_HOSTLIST GNUNET_EXTRA_LOGGING
+#define MAX_URL_LEN 1000
 
-#define MAX_URL_LEN 1000
+/**
+ * How many bytes do we download at most from a hostlist server?
+ */
 #define MAX_BYTES_PER_HOSTLISTS 500000
 
 /* end of gnunet-daemon-hostlist.h */

Copied: gnunet/src/hostlist/gnunet-daemon-hostlist_client.c (from rev 33486, 
gnunet/src/hostlist/hostlist-client.c)
===================================================================
--- gnunet/src/hostlist/gnunet-daemon-hostlist_client.c                         
(rev 0)
+++ gnunet/src/hostlist/gnunet-daemon-hostlist_client.c 2014-06-03 08:41:00 UTC 
(rev 33489)
@@ -0,0 +1,1710 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001-2010, 2014 Christian Grothoff (and other contributing authors)
+
+     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 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+/**
+ * @file hostlist/gnunet-daemon-hostlist_client.c
+ * @brief hostlist support.  Downloads HELLOs via HTTP.
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet-daemon-hostlist_client.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_transport_service.h"
+#include "gnunet-daemon-hostlist.h"
+#include <curl/curl.h>
+
+
+/**
+ * Number of connections that we must have to NOT download
+ * hostlists anymore.
+ */
+#define MIN_CONNECTIONS 4
+
+/**
+ * Maximum number of hostlist that are saved
+ */
+#define MAX_NUMBER_HOSTLISTS 30
+
+/**
+ * Time interval hostlists are saved to disk
+ */
+#define SAVING_INTERVAL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MINUTES, 30)
+
+/**
+ * Time interval between two hostlist tests
+ */
+#define TESTING_INTERVAL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 3)
+
+/**
+ * Time interval for download dispatcher before a download is re-scheduled
+ */
+#define WAITING_INTERVAL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 1)
+
+/**
+ * Defines concerning the hostlist quality metric
+ */
+
+/**
+ * Initial quality of a new created hostlist
+ */
+#define HOSTLIST_INITIAL 10000
+
+/**
+ * Value subtracted each time a hostlist download fails
+ */
+#define HOSTLIST_FAILED_DOWNLOAD 100
+
+/**
+ * Value added each time a hostlist download is successful
+ */
+#define HOSTLIST_SUCCESSFUL_DOWNLOAD 100
+
+/**
+ * Value added for each valid HELLO recived during a hostlist download
+ */
+#define HOSTLIST_SUCCESSFUL_HELLO 1
+
+
+
+/**
+ * A single hostlist obtained by hostlist advertisements
+ */
+struct Hostlist
+{
+  /**
+   * previous entry, used to manage entries in a double linked list
+   */
+  struct Hostlist *prev;
+
+  /**
+   * next entry, used to manage entries in a double linked list
+   */
+  struct Hostlist *next;
+
+  /**
+   * URI where hostlist can be obtained
+   */
+  const char *hostlist_uri;
+
+  /**
+   * Value describing the quality of the hostlist, the bigger the better but 
(should) never < 0
+   * used for deciding which hostlist is replaced if MAX_NUMBER_HOSTLISTS in 
data structure is reached
+   * intial value = HOSTLIST_INITIAL
+   * increased every successful download by HOSTLIST_SUCCESSFULL_DOWNLOAD
+   * increased every successful download by number of obtained HELLO messages
+   * decreased every failed download by HOSTLIST_SUCCESSFULL_DOWNLOAD
+   */
+  uint64_t quality;
+
+  /**
+   * Time the hostlist advertisement was recieved and the entry was created
+   */
+  struct GNUNET_TIME_Absolute time_creation;
+
+  /**
+   * Last time the hostlist was obtained
+   */
+  struct GNUNET_TIME_Absolute time_last_usage;
+
+  /**
+   * Number of HELLO messages obtained during last download
+   */
+  uint32_t hello_count;
+
+  /**
+   * Number of times the hostlist was successfully obtained
+   */
+  uint32_t times_used;
+
+};
+
+
+/**
+ * Our configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Statistics handle.
+ */
+static struct GNUNET_STATISTICS_Handle *stats;
+
+/**
+ * Transport handle.
+ */
+static struct GNUNET_TRANSPORT_Handle *transport;
+
+/**
+ * Proxy hostname or ip we are using (can be NULL).
+ */
+static char *proxy;
+
+/**
+ * Proxy username we are using (can be NULL).
+ */
+static char *proxy_username;
+
+/**
+ * Proxy password we are using (can be NULL).
+ */
+static char *proxy_password;
+
+/**
+ * Proxy type we are using (can be NULL).
+ */
+static curl_proxytype proxy_type;
+
+/**
+ * Number of bytes valid in 'download_buffer'.
+ */
+static size_t download_pos;
+
+/**
+ * Current URL that we are using.
+ */
+static char *current_url;
+
+/**
+ * Current CURL handle.
+ */
+static CURL *curl;
+
+/**
+ * Current multi-CURL handle.
+ */
+static CURLM *multi;
+
+/**
+ * How many bytes did we download from the current hostlist URL?
+ */
+static uint32_t stat_bytes_downloaded;
+
+/**
+ * Amount of time we wait between hostlist downloads.
+ */
+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;
+
+/**
+ * ID of the task downloading the hostlist
+ */
+static GNUNET_SCHEDULER_TaskIdentifier ti_download;
+
+/**
+ * ID of the task saving the hostlsit in a regular intervall
+ */
+static GNUNET_SCHEDULER_TaskIdentifier ti_saving_task;
+
+/**
+ * ID of the task called to initiate a download
+ */
+static GNUNET_SCHEDULER_TaskIdentifier ti_download_dispatcher_task;
+
+/**
+ * ID of the task controlling the locking between two hostlist tests
+ */
+static GNUNET_SCHEDULER_TaskIdentifier ti_testing_intervall_task;
+
+/**
+ * At what time MUST the current hostlist request be done?
+ */
+static struct GNUNET_TIME_Absolute end_time;
+
+/**
+ * Head of the linked list used to store hostlists
+ */
+static struct Hostlist *linked_list_head;
+
+/**
+ *  Tail of the linked list used to store hostlists
+ */
+static struct Hostlist *linked_list_tail;
+
+/**
+ *  Current hostlist used for downloading
+ */
+static struct Hostlist *current_hostlist;
+
+/**
+ *  Size of the linke list  used to store hostlists
+ */
+static unsigned int linked_list_size;
+
+/**
+ * Head of the linked list used to store hostlists
+ */
+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.
+ */
+static int stat_bogus_url;
+
+/**
+ * Value controlling if a hostlist is tested at the moment
+ */
+static int stat_testing_hostlist;
+
+/**
+ * Value controlling if a hostlist testing is allowed at the moment
+ */
+static int stat_testing_allowed;
+
+/**
+ * Value controlling if a hostlist download is running at the moment
+ */
+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 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 stat_hellos_obtained;
+
+/**
+ * Number of active connections (according to core service).
+ */
+static unsigned int stat_connection_count;
+
+
+/**
+ * Process downloaded bits by calling callback on each HELLO.
+ *
+ * @param ptr buffer with downloaded data
+ * @param size size of a record
+ * @param nmemb number of records downloaded
+ * @param ctx unused
+ * @return number of bytes that were processed (always size*nmemb)
+ */
+static size_t
+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;
+  size_t cpy;
+  size_t left;
+  uint16_t msize;
+
+  total = size * nmemb;
+  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, GNUNET_NO);
+  left = total;
+  while ((left > 0) || (download_pos > 0))
+  {
+    cpy = GNUNET_MIN (left, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - download_pos);
+    memcpy (&download_buffer[download_pos], cbuf, cpy);
+    cbuf += cpy;
+    download_pos += cpy;
+    left -= cpy;
+    if (download_pos < sizeof (struct GNUNET_MessageHeader))
+    {
+      GNUNET_assert (0 == left);
+      break;
+    }
+    msg = (const struct GNUNET_MessageHeader *) download_buffer;
+    msize = ntohs (msg->size);
+    if (msize < sizeof (struct GNUNET_MessageHeader))
+    {
+      GNUNET_STATISTICS_update (stats,
+                                gettext_noop
+                                ("# invalid HELLOs downloaded from hostlist 
servers"),
+                                1, GNUNET_NO);
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  _("Invalid `%s' message received from hostlist at `%s'\n"),
+                  "HELLO", current_url);
+      stat_hellos_obtained++;
+      stat_bogus_url = 1;
+      return total;
+    }
+    if (download_pos < msize)
+    {
+      GNUNET_assert (left == 0);
+      break;
+    }
+    if (GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) msg) == msize)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Received valid `%s' message from hostlist server.\n",
+                  "HELLO");
+      GNUNET_STATISTICS_update (stats,
+                                gettext_noop
+                                ("# valid HELLOs downloaded from hostlist 
servers"),
+                                1, GNUNET_NO);
+      stat_hellos_obtained++;
+      GNUNET_TRANSPORT_offer_hello (transport, msg, NULL, NULL);
+    }
+    else
+    {
+      GNUNET_STATISTICS_update (stats,
+                                gettext_noop
+                                ("# invalid HELLOs downloaded from hostlist 
servers"),
+                                1, GNUNET_NO);
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  _("Invalid `%s' message received from hostlist at `%s'\n"),
+                  "HELLO", current_url);
+      stat_bogus_url = GNUNET_YES;
+      stat_hellos_obtained++;
+      return total;
+    }
+    memmove (download_buffer, &download_buffer[msize], download_pos - msize);
+    download_pos -= msize;
+  }
+  return total;
+}
+
+
+/**
+ * Obtain a hostlist URL that we should use.
+ *
+ * @return NULL if there is no URL available
+ */
+static char *
+get_bootstrap_server ()
+{
+  char *servers;
+  char *ret;
+  size_t urls;
+  size_t pos;
+
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "SERVERS",
+                                             &servers))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                              "hostlist", "SERVERS");
+    return NULL;
+  }
+
+  urls = 0;
+  if (strlen (servers) > 0)
+  {
+    urls++;
+    pos = strlen (servers) - 1;
+    while (pos > 0)
+    {
+      if (servers[pos] == ' ')
+        urls++;
+      pos--;
+    }
+  }
+  if (urls == 0)
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                              "hostlist", "SERVERS");
+    GNUNET_free (servers);
+    return NULL;
+  }
+
+  urls = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, urls) + 1;
+  pos = strlen (servers) - 1;
+  while (pos > 0)
+  {
+    if (servers[pos] == ' ')
+    {
+      urls--;
+      servers[pos] = '\0';
+    }
+    if (urls == 0)
+    {
+      pos++;
+      break;
+    }
+    pos--;
+  }
+  ret = GNUNET_strdup (&servers[pos]);
+  GNUNET_free (servers);
+  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
+ */
+static char *
+download_get_url ()
+{
+  uint32_t index;
+  unsigned int counter;
+  struct Hostlist *pos;
+
+  if (GNUNET_NO == stat_learning)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Using preconfigured bootstrap server\n");
+    current_hostlist = NULL;
+    return get_bootstrap_server ();
+  }
+
+  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");
+    current_hostlist = hostlist_to_test;
+    return GNUNET_strdup (hostlist_to_test->hostlist_uri);
+  }
+
+  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_server ();
+  }
+  index =
+      GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, linked_list_size);
+  counter = 0;
+  pos = linked_list_head;
+  while (counter < index)
+  {
+    pos = pos->next;
+    counter++;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using learned hostlist `%s'\n",
+              pos->hostlist_uri);
+  current_hostlist = pos;
+  return GNUNET_strdup (pos->hostlist_uri);
+}
+
+
+#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);
+
+
+/**
+ * Add val2 to val1 with overflow check
+ *
+ * @param val1 value 1
+ * @param val2 value 2
+ * @return result
+ */
+static uint64_t
+checked_add (uint64_t val1,
+             uint64_t val2)
+{
+  static uint64_t temp;
+  static uint64_t maxv;
+
+  maxv = 0;
+  maxv--;
+
+  temp = val1 + val2;
+  if (temp < val1)
+    return maxv;
+  return temp;
+}
+
+
+/**
+ * Subtract val2 from val1 with underflow check
+ *
+ * @param val1 value 1
+ * @param val2 value 2
+ * @return result
+ */
+static uint64_t
+checked_sub (uint64_t val1,
+             uint64_t val2)
+{
+  if (val1 <= val2)
+    return 0;
+  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
+ */
+static int
+linked_list_contains (const char *uri)
+{
+  struct Hostlist *pos;
+
+  pos = linked_list_head;
+  while (pos != NULL)
+  {
+    if (0 == strcmp (pos->hostlist_uri, uri))
+      return GNUNET_YES;
+    pos = pos->next;
+  }
+  return GNUNET_NO;
+}
+
+
+/**
+ * Method returning the hostlist element with the lowest quality in the 
datastore
+ * @return hostlist with lowest quality
+ */
+static struct Hostlist *
+linked_list_get_lowest_quality ()
+{
+  struct Hostlist *pos;
+  struct Hostlist *lowest;
+
+  if (linked_list_size == 0)
+    return NULL;
+  lowest = linked_list_head;
+  pos = linked_list_head->next;
+  while (pos != NULL)
+  {
+    if (pos->quality < lowest->quality)
+      lowest = pos;
+    pos = pos->next;
+  }
+  return lowest;
+}
+
+
+/**
+ * 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 ()
+{
+  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);
+  stat_testing_hostlist = GNUNET_NO;
+}
+
+
+/**
+ * Method updating hostlist statistics
+ */
+static void
+update_hostlist ()
+{
+  char *stat;
+
+  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 = stat_hellos_obtained;
+    current_hostlist->time_last_usage = GNUNET_TIME_absolute_get ();
+    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);
+      GNUNET_asprintf (&stat, gettext_noop ("# advertised URI `%s' 
downloaded"),
+                       current_hostlist->hostlist_uri);
+
+      GNUNET_STATISTICS_update (stats, stat, 1, GNUNET_YES);
+      GNUNET_free (stat);
+    }
+    else
+      current_hostlist->quality =
+          checked_sub (current_hostlist->quality, HOSTLIST_FAILED_DOWNLOAD);
+  }
+  current_hostlist = NULL;
+  /* Alternating the usage of preconfigured and learned hostlists */
+
+  if (stat_testing_hostlist == GNUNET_YES)
+    return;
+
+  if (GNUNET_YES == stat_learning)
+  {
+    if (stat_use_bootstrap == GNUNET_YES)
+      stat_use_bootstrap = GNUNET_NO;
+    else
+      stat_use_bootstrap = GNUNET_YES;
+  }
+  else
+    stat_use_bootstrap = GNUNET_YES;
+}
+
+
+/**
+ * Clean up the state from the task that downloaded the
+ * hostlist and schedule the next task.
+ */
+static void
+clean_up ()
+{
+  CURLMcode mret;
+
+  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 (stat_testing_hostlist == GNUNET_YES)
+  {
+    stat_testing_hostlist = GNUNET_NO;
+  }
+  if (NULL != hostlist_to_test)
+  {
+    GNUNET_free (hostlist_to_test);
+    hostlist_to_test = NULL;
+  }
+
+  if (multi != NULL)
+  {
+    mret = curl_multi_remove_handle (multi, curl);
+    if (mret != CURLM_OK)
+    {
+      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"),
+                  "curl_multi_cleanup", __FILE__, __LINE__,
+                  curl_multi_strerror (mret));
+    multi = NULL;
+  }
+  if (curl != NULL)
+  {
+    curl_easy_cleanup (curl);
+    curl = NULL;
+  }
+  GNUNET_free_non_null (current_url);
+  current_url = NULL;
+  stat_bytes_downloaded = 0;
+  stat_download_in_progress = GNUNET_NO;
+}
+
+
+/**
+ * Task that is run when we are ready to receive more data from the hostlist
+ * server.
+ *
+ * @param cls closure, unused
+ * @param tc task context, unused
+ */
+static void
+task_download (void *cls,
+               const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+/**
+ * Ask CURL for the select set and then schedule the
+ * receiving task with the scheduler.
+ */
+static void
+download_prepare ()
+{
+  CURLMcode mret;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  int max;
+  struct GNUNET_NETWORK_FDSet *grs;
+  struct GNUNET_NETWORK_FDSet *gws;
+  long timeout;
+  struct GNUNET_TIME_Relative rtime;
+
+  max = -1;
+  FD_ZERO (&rs);
+  FD_ZERO (&ws);
+  FD_ZERO (&es);
+  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"),
+                "curl_multi_fdset", __FILE__, __LINE__,
+                curl_multi_strerror (mret));
+    clean_up ();
+    return;
+  }
+  mret = curl_multi_timeout (multi, &timeout);
+  if (mret != CURLM_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
+                "curl_multi_timeout", __FILE__, __LINE__,
+                curl_multi_strerror (mret));
+    clean_up ();
+    return;
+  }
+  rtime =
+      GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining (end_time),
+                                GNUNET_TIME_relative_multiply
+                                (GNUNET_TIME_UNIT_MILLISECONDS, timeout));
+  grs = GNUNET_NETWORK_fdset_create ();
+  gws = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
+  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Scheduling task for hostlist download using cURL\n");
+  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);
+}
+
+
+/**
+ * Task that is run when we are ready to receive more data from the hostlist
+ * server.
+ *
+ * @param cls closure, unused
+ * @param tc task context, unused
+ */
+static void
+task_download (void *cls,
+               const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  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;
+  }
+  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"),
+                current_url);
+    update_hostlist ();
+    clean_up ();
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Ready for processing hostlist client request\n");
+  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);
+        GNUNET_break (msg != NULL);
+        if (msg == NULL)
+          break;
+        switch (msg->msg)
+        {
+        case CURLMSG_DONE:
+          if ((msg->data.result != CURLE_OK) &&
+              (msg->data.result != CURLE_GOT_NOTHING))
+            GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                        _("Download of hostlist from `%s' failed: `%s'\n"),
+                        current_url,
+                        curl_easy_strerror (msg->data.result));
+          else
+          {
+            GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                        _("Download of hostlist `%s' completed.\n"),
+                        current_url);
+            stat_download_successful = GNUNET_YES;
+            update_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;
+              stat_testing_hostlist = GNUNET_NO;
+            }
+          }
+          clean_up ();
+          return;
+        default:
+          break;
+        }
+
+      }
+      while ((running > 0));
+    }
+  }
+  while (mret == CURLM_CALL_MULTI_PERFORM);
+
+  if (mret != CURLM_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("%s failed at %s:%d: `%s'\n"),
+                "curl_multi_perform", __FILE__, __LINE__,
+                curl_multi_strerror (mret));
+    clean_up ();
+  }
+  download_prepare ();
+}
+
+
+/**
+ * Main function that will download a hostlist and process its
+ * data.
+ */
+static void
+download_hostlist ()
+{
+  CURLcode ret;
+  CURLMcode mret;
+
+
+  current_url = download_get_url ();
+  if (current_url == NULL)
+    return;
+  curl = curl_easy_init ();
+  multi = NULL;
+  if (curl == NULL)
+  {
+    GNUNET_break (0);
+    clean_up ();
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
+              _("Bootstrapping using hostlist at `%s'.\n"), current_url);
+
+  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"), 1,
+                            GNUNET_NO);
+  if (proxy != NULL)
+  {
+    CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
+    CURL_EASY_SETOPT (curl, CURLOPT_PROXYTYPE, proxy_type);
+    if (NULL != proxy_username)
+      CURL_EASY_SETOPT (curl, CURLOPT_PROXYUSERNAME, proxy_username);
+    if (NULL != proxy_password)
+      CURL_EASY_SETOPT (curl, CURLOPT_PROXYPASSWORD, proxy_password);
+  }
+  download_pos = 0;
+  stat_bogus_url = 0;
+  CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, &callback_download);
+  if (ret != CURLE_OK)
+  {
+    clean_up ();
+    return;
+  }
+  CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, NULL);
+  if (ret != CURLE_OK)
+  {
+    clean_up ();
+    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);
+  if (ret != CURLE_OK)
+  {
+    clean_up ();
+    return;
+  }
+  CURL_EASY_SETOPT (curl, CURLOPT_FAILONERROR, 1);
+#if 0
+  CURL_EASY_SETOPT (curl, CURLOPT_VERBOSE, 1);
+#endif
+  CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE);
+  if (0 == strncmp (current_url, "http", 4))
+    CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet");
+  CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 60L);
+  CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 60L);
+  multi = curl_multi_init ();
+  if (multi == NULL)
+  {
+    GNUNET_break (0);
+    /* clean_up (); */
+    return;
+  }
+  mret = curl_multi_add_handle (multi, curl);
+  if (mret != CURLM_OK)
+  {
+    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"),
+                  "curl_multi_cleanup", __FILE__, __LINE__,
+                  curl_multi_strerror (mret));
+    multi = NULL;
+    clean_up ();
+    return;
+  }
+  end_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
+  download_prepare ();
+}
+
+
+static void
+task_download_dispatcher (void *cls,
+                          const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download is initiated...\n");
+  if (GNUNET_NO == stat_download_in_progress)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download can start 
immediately...\n");
+    download_hostlist ();
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Download in progess, have to wait...\n");
+    ti_download_dispatcher_task =
+        GNUNET_SCHEDULER_add_delayed (WAITING_INTERVAL,
+                                      &task_download_dispatcher, NULL);
+  }
+}
+
+
+/**
+ * Task that checks if we should try to download a hostlist.
+ * If so, we initiate the download, otherwise we schedule
+ * this task again for a later time.
+ */
+static void
+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 (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 (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_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_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 %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);
+}
+
+
+/**
+ * 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)
+{
+  ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+  stat_testing_allowed = GNUNET_OK;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Testing new hostlist advertisements is allowed again\n");
+}
+
+
+/**
+ * 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)
+{
+  ti_saving_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+  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,
+                                    NULL);
+}
+
+
+/**
+ * Method called whenever a given peer connects.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ */
+static void
+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);
+}
+
+
+/**
+ * Method called whenever a given peer disconnects.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ */
+static void
+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);
+}
+
+
+/**
+ * Method called whenever an advertisement message arrives.
+ *
+ * @param cls closure (always NULL)
+ * @param peer the peer sending the message
+ * @param message the actual message
+ * @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)
+{
+  size_t size;
+  size_t uri_size;
+  const struct GNUNET_MessageHeader *incoming;
+  const char *uri;
+  struct Hostlist *hostlist;
+
+  GNUNET_assert (ntohs (message->type) ==
+                 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT);
+  size = ntohs (message->size);
+  if (size <= sizeof (struct GNUNET_MessageHeader))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  incoming = (const struct GNUNET_MessageHeader *) message;
+  uri = (const char *) &incoming[1];
+  uri_size = size - sizeof (struct GNUNET_MessageHeader);
+  if (uri[uri_size - 1] != '\0')
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Hostlist client recieved advertisement from `%s' containing URI 
`%s'\n",
+              GNUNET_i2s (peer), uri);
+  if (GNUNET_NO != linked_list_contains (uri))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URI `%s' is already known\n", uri);
+    return GNUNET_OK;
+  }
+
+  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 == stat_testing_hostlist)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Currently not accepting new advertisements: we are already 
testing a hostlist\n");
+    return GNUNET_SYSERR;
+  }
+
+  hostlist = GNUNET_malloc (sizeof (struct Hostlist) + uri_size);
+  hostlist->hostlist_uri = (const char *) &hostlist[1];
+  memcpy (&hostlist[1], uri, uri_size);
+  hostlist->time_creation = GNUNET_TIME_absolute_get ();
+  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);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "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);
+
+  return GNUNET_OK;
+}
+
+
+/**
+ * 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
+primary_task (void *cls, int success)
+{
+  sget = NULL;
+  GNUNET_assert (stats != NULL);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Statistics request done, scheduling hostlist download\n");
+  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)
+{
+  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
+ */
+static void
+load_hostlist_file ()
+{
+  char *filename;
+  char *uri;
+  char *emsg;
+  struct Hostlist *hostlist;
+  uint32_t times_used;
+  uint32_t hellos_returned;
+  uint64_t quality;
+  uint64_t last_used;
+  uint64_t created;
+  uint32_t counter;
+  struct GNUNET_BIO_ReadHandle *rh;
+
+  uri = NULL;
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE",
+                                               &filename))
+  {
+    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);
+  if (GNUNET_NO == GNUNET_DISK_file_test (filename))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Hostlist file `%s' does not exist\n"), filename);
+    GNUNET_free (filename);
+    return;
+  }
+
+  rh = GNUNET_BIO_read_open (filename);
+  if (NULL == rh)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Could not open file `%s' for reading to load hostlists: 
%s\n"),
+                filename, STRERROR (errno));
+    GNUNET_free (filename);
+    return;
+  }
+
+  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)) &&
+         (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)))
+  {
+    hostlist = GNUNET_malloc (sizeof (struct Hostlist) + strlen (uri) + 1);
+    hostlist->hello_count = hellos_returned;
+    hostlist->hostlist_uri = (const char *) &hostlist[1];
+    memcpy (&hostlist[1], uri, strlen (uri) + 1);
+    hostlist->quality = quality;
+    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,
+                "Added hostlist entry eith URI `%s' \n",
+                hostlist->hostlist_uri);
+    GNUNET_free (uri);
+    uri = NULL;
+    counter++;
+    if (counter >= MAX_NUMBER_HOSTLISTS)
+      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"),
+                         counter, GNUNET_YES);
+  GNUNET_STATISTICS_set (stats,
+                         gettext_noop ("# advertised hostlist URIs"),
+                         linked_list_size, GNUNET_NO);
+
+  GNUNET_free_non_null (uri);
+  emsg = NULL;
+  (void) GNUNET_BIO_read_close (rh, &emsg);
+  if (emsg != NULL)
+    GNUNET_free (emsg);
+  GNUNET_free (filename);
+}
+
+
+/**
+ * Method to save persistent hostlist 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)
+{
+  char *filename;
+  struct Hostlist *pos;
+  struct GNUNET_BIO_WriteHandle *wh;
+  int ok;
+  uint32_t counter;
+
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE",
+                                               &filename))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                              "hostlist", "HOSTLISTFILE");
+    return;
+  }
+  if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
+  {
+    GNUNET_free (filename);
+    return;
+  }
+  wh = GNUNET_BIO_write_open (filename);
+  if (NULL == wh)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _
+                ("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"),
+              linked_list_size, filename);
+  /* add code to write hostlists to file using bio */
+  ok = GNUNET_YES;
+  counter = 0;
+  while (NULL != (pos = linked_list_head))
+  {
+    if (GNUNET_YES == shutdown)
+    {
+      GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail, pos);
+      linked_list_size--;
+    }
+    if (GNUNET_YES == ok)
+    {
+      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_int64 (wh, pos->time_last_usage.abs_value_us)) ||
+          (GNUNET_OK !=
+           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,
+                    _("Error writing hostlist URIs to file `%s'\n"), filename);
+        ok = GNUNET_NO;
+      }
+    }
+
+    if (GNUNET_YES == shutdown)
+      GNUNET_free (pos);
+    counter++;
+    if (counter >= MAX_NUMBER_HOSTLISTS)
+      break;
+  }
+  GNUNET_STATISTICS_set (stats,
+                         gettext_noop ("# hostlist URIs written to file"),
+                         counter, GNUNET_YES);
+
+  if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Error writing hostlist URIs to file `%s'\n"), filename);
+  GNUNET_free (filename);
+}
+
+
+/**
+ * Start downloading hostlists from hostlist servers as necessary.
+ *
+ * @param c configuration to use
+ * @param st statistics handle to use
+ * @param ch[OUT] set to handler for CORE connect events
+ * @param dh[OUT] set to handler for CORE disconnect events
+ * @param msgh[OUT] set to handler for CORE advertisement messages
+ * @param learn should we learn hostlist URLs from CORE
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
+                              struct GNUNET_STATISTICS_Handle *st,
+                              GNUNET_CORE_ConnectEventHandler *ch,
+                              GNUNET_CORE_DisconnectEventHandler *dh,
+                              GNUNET_CORE_MessageCallback *msgh,
+                              int learn)
+{
+  char *filename;
+  char *proxytype_str;
+  int result;
+
+  GNUNET_assert (NULL != st);
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  transport = GNUNET_TRANSPORT_connect (c, NULL, NULL, NULL, NULL, NULL);
+  if (NULL == transport)
+  {
+    curl_global_cleanup ();
+    return GNUNET_SYSERR;
+  }
+  cfg = c;
+  stats = st;
+
+  /* Read proxy configuration */
+  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
+      "HOSTLIST", "PROXY", &proxy))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Found proxy host: `%s'\n",
+                     proxy);
+    /* proxy username */
+    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
+        "HOSTLIST", "PROXY_USERNAME", &proxy_username))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                       "Found proxy username name: `%s'\n",
+                       proxy_username);
+    }
+
+    /* proxy password */
+    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
+        "HOSTLIST", "PROXY_PASSWORD", &proxy_password))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                       "Found proxy password name: `%s'\n",
+                       proxy_password);
+    }
+
+    /* proxy type */
+    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
+        "HOSTLIST", "PROXY_TYPE", &proxytype_str))
+    {
+      GNUNET_STRINGS_utf8_toupper (proxytype_str, proxytype_str);
+
+      proxy_type = CURLPROXY_HTTP;
+      if (0 == strcmp(proxytype_str, "HTTP"))
+        proxy_type = CURLPROXY_HTTP;
+      else if (0 == strcmp(proxytype_str, "HTTP_1_0"))
+        proxy_type = CURLPROXY_HTTP_1_0;
+      else if (0 == strcmp(proxytype_str, "SOCKS4"))
+        proxy_type = CURLPROXY_SOCKS4;
+      else if (0 == strcmp(proxytype_str, "SOCKS5"))
+        proxy_type = CURLPROXY_SOCKS5;
+      else if (0 == strcmp(proxytype_str, "SOCKS4A"))
+        proxy_type = CURLPROXY_SOCKS4A;
+      else if (0 == strcmp(proxytype_str, "SOCKS5_HOSTNAME"))
+        proxy_type = CURLPROXY_SOCKS5_HOSTNAME ;
+      else
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+             _("Invalid proxy type: `%s', disabling proxy! Check 
configuration!\n"),
+             proxytype_str);
+        GNUNET_free (proxytype_str);
+
+        GNUNET_free (proxy);
+        proxy = NULL;
+        GNUNET_free_non_null (proxy_username);
+        proxy_username = NULL;
+        GNUNET_free_non_null (proxy_password);
+        proxy_password = NULL;
+
+        return GNUNET_SYSERR;
+      }
+    }
+    GNUNET_free_non_null (proxytype_str);
+  }
+
+  stat_learning = learn;
+  *ch = &handler_connect;
+  *dh = &handler_disconnect;
+  linked_list_head = NULL;
+  linked_list_tail = NULL;
+  stat_use_bootstrap = GNUNET_YES;
+  stat_testing_hostlist = GNUNET_NO;
+  stat_testing_allowed = GNUNET_YES;
+
+  if (GNUNET_YES == stat_learning)
+  {
+    *msgh = &handler_advertisement;
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Learning is enabled on this peer\n"));
+    load_hostlist_file ();
+    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,
+                                      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_YES == GNUNET_DISK_file_test (filename))
+      {
+        result = remove (filename);
+        if (result == 0)
+          GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                      _
+                      ("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_free (filename);
+  }
+  sget = GNUNET_STATISTICS_get (stats, "hostlist",
+                               gettext_noop
+                               ("# milliseconds between hostlist downloads"),
+                               GNUNET_TIME_UNIT_MINUTES, &primary_task, 
&process_stat,
+                               NULL);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Stop downloading hostlists from hostlist servers as necessary.
+ */
+void
+GNUNET_HOSTLIST_client_stop ()
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n");
+  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 (NULL != transport)
+  {
+    GNUNET_TRANSPORT_disconnect (transport);
+    transport = NULL;
+  }
+  GNUNET_free_non_null (proxy);
+  proxy = NULL;
+  GNUNET_free_non_null (proxy_username);
+  proxy_username = NULL;
+  GNUNET_free_non_null (proxy_password);
+  proxy_password = NULL;
+
+  cfg = NULL;
+}
+
+/* end of gnunet-daemon-hostlist_client.c */

Copied: gnunet/src/hostlist/gnunet-daemon-hostlist_client.h (from rev 33486, 
gnunet/src/hostlist/hostlist-client.h)
===================================================================
--- gnunet/src/hostlist/gnunet-daemon-hostlist_client.h                         
(rev 0)
+++ gnunet/src/hostlist/gnunet-daemon-hostlist_client.h 2014-06-03 08:41:00 UTC 
(rev 33489)
@@ -0,0 +1,61 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009 Christian Grothoff (and other contributing authors)
+
+     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 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+/**
+ * @file hostlist/gnunet-daemon-hostlist_client.h
+ * @brief hostlist support.  Downloads HELLOs via HTTP.
+ * @author Christian Grothoff
+ */
+#ifndef GNUNET_DAEMON_HOSTLIST_CLIENT_H
+#define GNUNET_DAEMON_HOSTLIST_CLIENT_H
+
+#include "gnunet_core_service.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_util_lib.h"
+
+
+/**
+ * Start downloading hostlists from hostlist servers as necessary.
+ *
+ * @param c the configuration to use
+ * @param st hande for publishing statistics
+ * @param ch[OUT] set to handler for connect notifications
+ * @param dh[OUT] set to handler for disconnect notifications
+ * @param msgh[OUT] set to handler for message handler notifications
+ * @param learn set if client is learning new hostlists
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
+                              struct GNUNET_STATISTICS_Handle *st,
+                              GNUNET_CORE_ConnectEventHandler *ch,
+                              GNUNET_CORE_DisconnectEventHandler *dh,
+                              GNUNET_CORE_MessageCallback *msgh,
+                              int learn);
+
+
+/**
+ * Stop downloading hostlists from hostlist servers as necessary.
+ */
+void
+GNUNET_HOSTLIST_client_stop (void);
+
+
+#endif
+/* end of gnunet-daemon-hostlist_client.h */

Copied: gnunet/src/hostlist/gnunet-daemon-hostlist_server.c (from rev 33488, 
gnunet/src/hostlist/hostlist-server.c)
===================================================================
--- gnunet/src/hostlist/gnunet-daemon-hostlist_server.c                         
(rev 0)
+++ gnunet/src/hostlist/gnunet-daemon-hostlist_server.c 2014-06-03 08:41:00 UTC 
(rev 33489)
@@ -0,0 +1,888 @@
+/*
+     This file is part of GNUnet.
+     (C) 2008, 2009, 2010, 2014 Christian Grothoff (and other contributing 
authors)
+
+     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 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+
+/**
+ * @file hostlist/gnunet-daemon-hostlist_server.c
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ * @author David Barksdale
+ * @brief application to provide an integrated hostlist HTTP server
+ */
+#include "platform.h"
+#include <microhttpd.h>
+#include "gnunet-daemon-hostlist_server.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_peerinfo_service.h"
+#include "gnunet-daemon-hostlist.h"
+#include "gnunet_resolver_service.h"
+
+
+/**
+ * How long until our hostlist advertisment transmission via CORE should
+ * time out?
+ */
+#define GNUNET_ADV_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MINUTES, 5)
+
+
+/**
+ * Handle to the HTTP server as provided by libmicrohttpd for IPv6.
+ */
+static struct MHD_Daemon *daemon_handle_v6;
+
+/**
+ * Handle to the HTTP server as provided by libmicrohttpd for IPv4.
+ */
+static struct MHD_Daemon *daemon_handle_v4;
+
+/**
+ * Our configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * For keeping statistics.
+ */
+static struct GNUNET_STATISTICS_Handle *stats;
+
+/**
+ * Handle to the core service (NULL until we've connected to it).
+ */
+static struct GNUNET_CORE_Handle *core;
+
+/**
+ * Handle to the peerinfo notify service (NULL until we've connected to it).
+ */
+static struct GNUNET_PEERINFO_NotifyContext *notify;
+
+/**
+ * Our primary task for IPv4.
+ */
+static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v4;
+
+/**
+ * Our primary task for IPv6.
+ */
+static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v6;
+
+/**
+ * Our canonical response.
+ */
+static struct MHD_Response *response;
+
+/**
+ * Handle for accessing peerinfo service.
+ */
+static struct GNUNET_PEERINFO_Handle *peerinfo;
+
+/**
+ * Set if we are allowed to advertise our hostlist to others.
+ */
+static int advertising;
+
+/**
+ * Buffer for the hostlist address
+ */
+static char *hostlist_uri;
+
+
+/**
+ * Context for host processor.
+ */
+struct HostSet
+{
+  unsigned int size;
+
+  char *data;
+
+  struct GNUNET_PEERINFO_IteratorContext *pitr;
+};
+
+
+/**
+ * NULL if we are not currenlty iterating over peer information.
+ */
+static struct HostSet *builder;
+
+
+/**
+ * Function that assembles our response.
+ */
+static void
+finish_response ()
+{
+  if (NULL != response)
+    MHD_destroy_response (response);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Creating hostlist response with %u bytes\n",
+              (unsigned int) builder->size);
+  response =
+      MHD_create_response_from_data (builder->size, builder->data, MHD_YES,
+                                     MHD_NO);
+  if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6))
+  {
+    MHD_destroy_response (response);
+    response = NULL;
+  }
+  GNUNET_STATISTICS_set (stats, gettext_noop ("bytes in hostlist"),
+                         builder->size, GNUNET_YES);
+  GNUNET_free (builder);
+  builder = NULL;
+}
+
+
+/**
+ * Set @a cls to #GNUNET_YES (we have an address!).
+ *
+ * @param cls closure, an `int *`
+ * @param address the address (ignored)
+ * @param expiration expiration time (call is ignored if this is in the past)
+ * @return  #GNUNET_SYSERR to stop iterating (unless expiration has occured)
+ */
+static int
+check_has_addr (void *cls,
+                const struct GNUNET_HELLO_Address *address,
+                struct GNUNET_TIME_Absolute expiration)
+{
+  int *arg = cls;
+
+  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
+  {
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop ("expired addresses encountered"), 
1,
+                              GNUNET_YES);
+    return GNUNET_YES;          /* ignore this address */
+  }
+  *arg = GNUNET_YES;
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Callback that processes each of the known HELLOs for the
+ * hostlist response construction.
+ *
+ * @param cls closure, NULL
+ * @param peer id of the peer, NULL for last call
+ * @param hello hello message for the peer (can be NULL)
+ * @param error message
+ */
+static void
+host_processor (void *cls,
+                const struct GNUNET_PeerIdentity *peer,
+                const struct GNUNET_HELLO_Message *hello,
+                const char *err_msg)
+{
+  size_t old;
+  size_t s;
+  int has_addr;
+
+  if (NULL != err_msg)
+  {
+    GNUNET_assert (NULL == peer);
+    builder->pitr = NULL;
+    GNUNET_free_non_null (builder->data);
+    GNUNET_free (builder);
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Error in communication with PEERINFO service: %s\n"),
+                err_msg);
+    return;
+  }
+  if (NULL == peer)
+  {
+    builder->pitr = NULL;
+    finish_response ();
+    return;
+  }
+  if (NULL == hello)
+    return;
+  has_addr = GNUNET_NO;
+  GNUNET_HELLO_iterate_addresses (hello,
+                                  GNUNET_NO,
+                                  &check_has_addr,
+                                  &has_addr);
+  if (GNUNET_NO == has_addr)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "HELLO for peer `%4s' has no address, not suitable for 
hostlist!\n",
+                GNUNET_i2s (peer));
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop
+                              ("HELLOs without addresses encountered 
(ignored)"),
+                              1, GNUNET_NO);
+    return;
+  }
+  old = builder->size;
+  s = GNUNET_HELLO_size (hello);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
+              (unsigned int) s,
+              "HELLO",
+              GNUNET_i2s (peer));
+  if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) ||
+      (old + s >= MAX_BYTES_PER_HOSTLISTS))
+  {
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop
+                              ("bytes not included in hostlist (size limit)"),
+                              s, GNUNET_NO);
+    return;                     /* too large, skip! */
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Adding peer `%s' to hostlist (%u bytes)\n",
+              GNUNET_i2s (peer),
+              (unsigned int) s);
+  GNUNET_array_grow (builder->data, builder->size, old + s);
+  memcpy (&builder->data[old], hello, s);
+}
+
+
+/**
+ * Hostlist access policy (very permissive, allows everything).
+ * Returns #MHD_NO only if we are not yet ready to serve.
+ *
+ * @param cls closure
+ * @param addr address information from the client
+ * @param addrlen length of @a addr
+ * @return #MHD_YES if connection is allowed, #MHD_NO if not (we are not ready)
+ */
+static int
+accept_policy_callback (void *cls,
+                        const struct sockaddr *addr,
+                        socklen_t addrlen)
+{
+  if (NULL == response)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Received request for hostlist, but I am not yet ready; 
rejecting!\n");
+    return MHD_NO;
+  }
+  return MHD_YES;               /* accept all */
+}
+
+
+/**
+ * Add headers to a request indicating that we allow Cross-Origin Resource
+ * Sharing.
+ *
+ * @param response response to add headers to
+ */
+static void
+add_cors_headers (struct MHD_Response *response)
+{
+  MHD_add_response_header (response,
+                           "Access-Control-Allow-Origin",
+                           "*");
+  MHD_add_response_header (response,
+                           "Access-Control-Allow-Methods",
+                           "GET, OPTIONS");
+  MHD_add_response_header (response,
+                           "Access-Control-Max-Age",
+                           "86400");
+}
+
+
+/**
+ * Main request handler.
+ *
+ * @param cls argument given together with the function
+ *        pointer when the handler was registered with MHD
+ * @param url the requested url
+ * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
+ *        #MHD_HTTP_METHOD_PUT, etc.)
+ * @param version the HTTP version string (i.e.
+ *        #MHD_HTTP_VERSION_1_1)
+ * @param upload_data the data being uploaded (excluding HEADERS,
+ *        for a POST that fits into memory and that is encoded
+ *        with a supported encoding, the POST data will NOT be
+ *        given in upload_data and is instead available as
+ *        part of #MHD_get_connection_values; very large POST
+ *        data *will* be made available incrementally in
+ *        @a upload_data)
+ * @param upload_data_size set initially to the size of the
+ *        @a upload_data provided; the method must update this
+ *        value to the number of bytes NOT processed;
+ * @param con_cls pointer that the callback can set to some
+ *        address and that will be preserved by MHD for future
+ *        calls for this request; since the access handler may
+ *        be called many times (i.e., for a PUT/POST operation
+ *        with plenty of upload data) this allows the application
+ *        to easily associate some request-specific state.
+ *        If necessary, this state can be cleaned up in the
+ *        global #MHD_RequestCompletedCallback (which
+ *        can be set with the #MHD_OPTION_NOTIFY_COMPLETED).
+ *        Initially, `*con_cls` will be NULL.
+ * @return #MHD_YES if the connection was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serios
+ *         error while handling the request
+ */
+static int
+access_handler_callback (void *cls,
+                         struct MHD_Connection *connection,
+                         const char *url,
+                         const char *method,
+                         const char *version,
+                         const char *upload_data,
+                         size_t *upload_data_size,
+                         void **con_cls)
+{
+  static int dummy;
+
+  /* CORS pre-flight request */
+  if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method))
+  {
+    struct MHD_Response *options_response;
+    int rc;
+
+    options_response = MHD_create_response_from_buffer (0, NULL,
+                                                        
MHD_RESPMEM_PERSISTENT);
+    add_cors_headers(options_response);
+    rc = MHD_queue_response (connection, MHD_HTTP_OK, options_response);
+    MHD_destroy_response (options_response);
+    return rc;
+  }
+  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Refusing `%s' request to hostlist server\n"), method);
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop
+                              ("hostlist requests refused (not HTTP GET)"), 1,
+                              GNUNET_YES);
+    return MHD_NO;
+  }
+  if (NULL == *con_cls)
+  {
+    (*con_cls) = &dummy;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Sending 100 CONTINUE reply\n");
+    return MHD_YES;             /* send 100 continue */
+  }
+  if (0 != *upload_data_size)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Refusing `%s' request with %llu bytes of upload data\n"),
+                method, (unsigned long long) *upload_data_size);
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop
+                              ("hostlist requests refused (upload data)"), 1,
+                              GNUNET_YES);
+    return MHD_NO;              /* do not support upload data */
+  }
+  if (NULL == response)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Could not handle hostlist request since I do not have a 
response yet\n"));
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop
+                              ("hostlist requests refused (not ready)"), 1,
+                              GNUNET_YES);
+    return MHD_NO;              /* internal error, no response yet */
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              _("Received request for our hostlist\n"));
+  GNUNET_STATISTICS_update (stats,
+                            gettext_noop ("hostlist requests processed"),
+                            1, GNUNET_YES);
+  add_cors_headers (response);
+  return MHD_queue_response (connection, MHD_HTTP_OK, response);
+}
+
+
+/**
+ * Handler called by CORE when CORE is ready to transmit message
+ *
+ * @param cls closure
+ * @param size size of buffer to copy message to
+ * @param buf buffer to copy message to
+ * @return number of bytes copied to @a buf
+ */
+static size_t
+adv_transmit_ready (void *cls,
+                    size_t size,
+                    void *buf)
+{
+  static uint64_t hostlist_adv_count;
+  size_t transmission_size;
+  size_t uri_size;              /* Including \0 termination! */
+  struct GNUNET_MessageHeader header;
+  char *cbuf;
+
+  if (NULL == buf)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Transmission failed, buffer invalid!\n");
+    return 0;
+  }
+  uri_size = strlen (hostlist_uri) + 1;
+  transmission_size = sizeof (struct GNUNET_MessageHeader) + uri_size;
+  header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT);
+  header.size = htons (transmission_size);
+  GNUNET_assert (size >= transmission_size);
+  memcpy (buf, &header, sizeof (struct GNUNET_MessageHeader));
+  cbuf = buf;
+  memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], hostlist_uri, uri_size);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sent advertisement message: Copied %u bytes into buffer!\n",
+              (unsigned int) transmission_size);
+  hostlist_adv_count++;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " # Sent advertisement message: %u\n",
+              hostlist_adv_count);
+  GNUNET_STATISTICS_update (stats,
+                            gettext_noop ("# hostlist advertisements send"), 1,
+                            GNUNET_NO);
+  return transmission_size;
+}
+
+
+/**
+ * Method called whenever a given peer connects.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ */
+static void
+connect_handler (void *cls,
+                 const struct GNUNET_PeerIdentity *peer)
+{
+  size_t size;
+
+  if (!advertising)
+    return;
+  if (NULL == hostlist_uri)
+    return;
+  size = strlen (hostlist_uri) + 1;
+  if (size + sizeof (struct GNUNET_MessageHeader) >=
+      GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  size += sizeof (struct GNUNET_MessageHeader);
+  if (NULL == core)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Asked CORE to transmit advertisement message with a size of %u 
bytes to peer `%s'\n",
+              size,
+              GNUNET_i2s (peer));
+  if (NULL ==
+      GNUNET_CORE_notify_transmit_ready (core, GNUNET_YES,
+                                         GNUNET_CORE_PRIO_BEST_EFFORT,
+                                         GNUNET_ADV_TIMEOUT,
+                                         peer,
+                                         size,
+                                         &adv_transmit_ready, NULL))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Advertisement message could not be queued by core\n"));
+  }
+}
+
+
+/**
+ * Method called whenever a given peer disconnects.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ */
+static void
+disconnect_handler (void *cls,
+                    const struct GNUNET_PeerIdentity *peer)
+{
+  /* nothing to do */
+}
+
+
+/**
+ * PEERINFO calls this function to let us know about a possible peer
+ * that we might want to connect to.
+ *
+ * @param cls closure (not used)
+ * @param peer potential peer to connect to
+ * @param hello HELLO for this peer (or NULL)
+ * @param err_msg NULL if successful, otherwise contains error message
+ */
+static void
+process_notify (void *cls,
+                const struct GNUNET_PeerIdentity *peer,
+                const struct GNUNET_HELLO_Message *hello,
+                const char *err_msg)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Peerinfo is notifying us to rebuild our hostlist\n");
+  if (NULL != err_msg)
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Error in communication with PEERINFO service: %s\n"),
+               err_msg);
+  if (NULL != builder)
+  {
+    /* restart re-build already in progress ... */
+    GNUNET_PEERINFO_iterate_cancel (builder->pitr);
+    GNUNET_free_non_null (builder->data);
+    builder->size = 0;
+    builder->data = NULL;
+  }
+  else
+  {
+    builder = GNUNET_new (struct HostSet);
+  }
+  GNUNET_assert (NULL != peerinfo);
+  builder->pitr =
+      GNUNET_PEERINFO_iterate (peerinfo, GNUNET_NO, NULL, 
GNUNET_TIME_UNIT_MINUTES,
+                               &host_processor, NULL);
+}
+
+
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ */
+static GNUNET_SCHEDULER_TaskIdentifier
+prepare_daemon (struct MHD_Daemon *daemon_handle);
+
+
+/**
+ * Call MHD to process pending requests and then go back
+ * and schedule the next run.
+ *
+ * @param cls the `struct MHD_Daemon` of the HTTP server to run
+ * @param tc scheduler context
+ */
+static void
+run_daemon (void *cls,
+            const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct MHD_Daemon *daemon_handle = cls;
+
+  if (daemon_handle == daemon_handle_v4)
+    hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK;
+  else
+    hostlist_task_v6 = GNUNET_SCHEDULER_NO_TASK;
+
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+  GNUNET_assert (MHD_YES == MHD_run (daemon_handle));
+  if (daemon_handle == daemon_handle_v4)
+    hostlist_task_v4 = prepare_daemon (daemon_handle);
+  else
+    hostlist_task_v6 = prepare_daemon (daemon_handle);
+}
+
+
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ *
+ * @param daemon_handle HTTP server to prepare to run
+ */
+static GNUNET_SCHEDULER_TaskIdentifier
+prepare_daemon (struct MHD_Daemon *daemon_handle)
+{
+  GNUNET_SCHEDULER_TaskIdentifier ret;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  struct GNUNET_NETWORK_FDSet *wrs;
+  struct GNUNET_NETWORK_FDSet *wws;
+  int max;
+  MHD_UNSIGNED_LONG_LONG timeout;
+  int haveto;
+  struct GNUNET_TIME_Relative tv;
+
+  FD_ZERO (&rs);
+  FD_ZERO (&ws);
+  FD_ZERO (&es);
+  wrs = GNUNET_NETWORK_fdset_create ();
+  wws = GNUNET_NETWORK_fdset_create ();
+  max = -1;
+  GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, 
&max));
+  haveto = MHD_get_timeout (daemon_handle, &timeout);
+  if (haveto == MHD_YES)
+    tv.rel_value_us = (uint64_t) timeout * 1000LL;
+  else
+    tv = GNUNET_TIME_UNIT_FOREVER_REL;
+  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
+  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
+  ret =
+      GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                  tv, wrs, wws,
+                                   &run_daemon, daemon_handle);
+  GNUNET_NETWORK_fdset_destroy (wrs);
+  GNUNET_NETWORK_fdset_destroy (wws);
+  return ret;
+}
+
+
+/**
+ * Start server offering our hostlist.
+ *
+ * @param c configuration to use
+ * @param st statistics handle to use
+ * @param co core handle to use
+ * @param server_ch[OUT] set to handler for CORE connect events
+ * @param server_dh[OUT] set to handler for CORE disconnect events
+ * @param advertise #GNUNET_YES if we should advertise our hostlist
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
+                              struct GNUNET_STATISTICS_Handle *st,
+                              struct GNUNET_CORE_Handle *co,
+                              GNUNET_CORE_ConnectEventHandler *server_ch,
+                              GNUNET_CORE_DisconnectEventHandler *server_dh,
+                              int advertise)
+{
+  unsigned long long port;
+  char *hostname;
+  char *ipv4;
+  char *ipv6;
+  size_t size;
+  struct in_addr i4;
+  struct in6_addr i6;
+  struct sockaddr_in v4;
+  struct sockaddr_in6 v6;
+  const struct sockaddr *sa4;
+  const struct sockaddr *sa6;
+
+  advertising = advertise;
+  if (! advertising)
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Advertising not enabled on this hostlist server\n");
+  else
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Advertising enabled on this hostlist server\n");
+  cfg = c;
+  stats = st;
+  peerinfo = GNUNET_PEERINFO_connect (cfg);
+  if (NULL == peerinfo)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Could not access PEERINFO service.  Exiting.\n"));
+    return GNUNET_SYSERR;
+  }
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_number (cfg,
+                                             "HOSTLIST",
+                                             "HTTPPORT",
+                                             &port))
+    return GNUNET_SYSERR;
+  if ((0 == port) || (port > UINT16_MAX))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Invalid port number %llu.  Exiting.\n"),
+                port);
+    return GNUNET_SYSERR;
+  }
+
+  if (GNUNET_SYSERR ==
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "HOSTLIST",
+                                             "EXTERNAL_DNS_NAME",
+                                             &hostname))
+    hostname = GNUNET_RESOLVER_local_fqdn_get ();
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              _("Hostlist service starts on %s:%llu\n"),
+              hostname, port);
+  if (NULL != hostname)
+  {
+    size = strlen (hostname);
+    if (size + 15 > MAX_URL_LEN)
+    {
+      GNUNET_break (0);
+    }
+    else
+    {
+      GNUNET_asprintf (&hostlist_uri,
+                       "http://%s:%u/";, hostname,
+                       (unsigned int) port);
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  _("Address to obtain hostlist: `%s'\n"),
+                  hostlist_uri);
+    }
+    GNUNET_free (hostname);
+  }
+
+  if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV4"))
+  {
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST",
+                                                         "BINDTOIP", &ipv4));
+  }
+  else
+    ipv4 = NULL;
+  if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6"))
+  {
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST",
+                                                         "BINDTOIP", &ipv6));
+  }
+  else
+    ipv6 = NULL;
+  sa4 = NULL;
+  if (NULL != ipv4)
+  {
+    if (1 == inet_pton (AF_INET, ipv4, &i4))
+    {
+      memset (&v4, 0, sizeof (v4));
+      v4.sin_family = AF_INET;
+      v4.sin_addr = i4;
+      v4.sin_port = htons (port);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      v4.sin_len = sizeof (v4);
+#endif
+      sa4 = (const struct sockaddr *) &v4;
+    }
+    else
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _("`%s' is not a valid IPv4 address! Ignoring 
BINDTOIPV4.\n"),
+                  ipv4);
+    GNUNET_free (ipv4);
+  }
+  sa6 = NULL;
+  if (NULL != ipv6)
+  {
+    if (1 == inet_pton (AF_INET6, ipv6, &i6))
+    {
+      memset (&v6, 0, sizeof (v6));
+      v6.sin6_family = AF_INET6;
+      v6.sin6_addr = i6;
+      v6.sin6_port = htons (port);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      v6.sin6_len = sizeof (v6);
+#endif
+      sa6 = (const struct sockaddr *) &v6;
+    }
+    else
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _("`%s' is not a valid IPv6 address! Ignoring 
BINDTOIPV6.\n"),
+                  ipv6);
+    GNUNET_free (ipv6);
+  }
+
+  daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 | MHD_USE_DEBUG,
+                                       (uint16_t) port,
+                                       &accept_policy_callback, NULL,
+                                       &access_handler_callback, NULL,
+                                       MHD_OPTION_CONNECTION_LIMIT,
+                                       (unsigned int) 16,
+                                       MHD_OPTION_PER_IP_CONNECTION_LIMIT,
+                                       (unsigned int) 1,
+                                       MHD_OPTION_CONNECTION_TIMEOUT,
+                                       (unsigned int) 16,
+                                       MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+                                       (size_t) (16 * 1024),
+                                       MHD_OPTION_SOCK_ADDR,
+                                       sa6,
+                                       MHD_OPTION_END);
+  daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG | MHD_USE_DEBUG,
+                                      (uint16_t) port,
+                                       &accept_policy_callback, NULL,
+                                       &access_handler_callback, NULL,
+                                       MHD_OPTION_CONNECTION_LIMIT,
+                                       (unsigned int) 16,
+                                       MHD_OPTION_PER_IP_CONNECTION_LIMIT,
+                                       (unsigned int) 1,
+                                       MHD_OPTION_CONNECTION_TIMEOUT,
+                                       (unsigned int) 16,
+                                       MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+                                       (size_t) (16 * 1024),
+                                       MHD_OPTION_SOCK_ADDR,
+                                       sa4,
+                                       MHD_OPTION_END);
+
+  if ( (NULL == daemon_handle_v6) &&
+       (NULL == daemon_handle_v4) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Could not start hostlist HTTP server on port %u\n"),
+                (unsigned short) port);
+    return GNUNET_SYSERR;
+  }
+
+  core = co;
+  *server_ch = &connect_handler;
+  *server_dh = &disconnect_handler;
+  if (NULL != daemon_handle_v4)
+    hostlist_task_v4 = prepare_daemon (daemon_handle_v4);
+  if (NULL != daemon_handle_v6)
+    hostlist_task_v6 = prepare_daemon (daemon_handle_v6);
+  notify = GNUNET_PEERINFO_notify (cfg, GNUNET_NO,
+                                   &process_notify, NULL);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Stop server offering our hostlist.
+ */
+void
+GNUNET_HOSTLIST_server_stop ()
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n");
+  if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6)
+  {
+    GNUNET_SCHEDULER_cancel (hostlist_task_v6);
+    hostlist_task_v6 = GNUNET_SCHEDULER_NO_TASK;
+  }
+  if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v4)
+  {
+    GNUNET_SCHEDULER_cancel (hostlist_task_v4);
+    hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK;
+  }
+  if (NULL != daemon_handle_v4)
+  {
+    MHD_stop_daemon (daemon_handle_v4);
+    daemon_handle_v4 = NULL;
+  }
+  if (NULL != daemon_handle_v6)
+  {
+    MHD_stop_daemon (daemon_handle_v6);
+    daemon_handle_v6 = NULL;
+  }
+  if (NULL != response)
+  {
+    MHD_destroy_response (response);
+    response = NULL;
+  }
+  if (NULL != notify)
+  {
+    GNUNET_PEERINFO_notify_cancel (notify);
+    notify = NULL;
+  }
+  if (NULL != builder)
+  {
+    GNUNET_PEERINFO_iterate_cancel (builder->pitr);
+    builder->pitr = NULL;
+    GNUNET_free_non_null (builder->data);
+    GNUNET_free (builder);
+  }
+  if (NULL != peerinfo)
+  {
+    GNUNET_PEERINFO_disconnect (peerinfo);
+    peerinfo = NULL;
+  }
+  cfg = NULL;
+  stats = NULL;
+  core = NULL;
+}
+
+/* end of gnunet-daemon-hostlist_server.c */

Copied: gnunet/src/hostlist/gnunet-daemon-hostlist_server.h (from rev 33486, 
gnunet/src/hostlist/hostlist-server.h)
===================================================================
--- gnunet/src/hostlist/gnunet-daemon-hostlist_server.h                         
(rev 0)
+++ gnunet/src/hostlist/gnunet-daemon-hostlist_server.h 2014-06-03 08:41:00 UTC 
(rev 33489)
@@ -0,0 +1,63 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009 Christian Grothoff (and other contributing authors)
+
+     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 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+
+/**
+ * @file hostlist/gnunet-daemon-hostlist_server.h
+ * @brief hostlist support.  Downloads HELLOs via HTTP.
+ * @author Christian Grothoff
+ */
+
+#ifndef GNUNET_DAEMON_HOSTLIST_SERVER_H
+#define GNUNET_DAEMON_HOSTLIST_SERVER_H
+
+#include "gnunet_core_service.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_util_lib.h"
+
+
+/**
+ * Start server offering our hostlist.
+ *
+ * @param c configuration to use
+ * @param st statistics handle to use
+ * @param co core handle to use
+ * @param server_ch[OUT] set to handler for CORE connect events
+ * @param server_dh[OUT] set to handler for CORE disconnect events
+ * @param advertise #GNUNET_YES if we should advertise our hostlist
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
+                              struct GNUNET_STATISTICS_Handle *st,
+                              struct GNUNET_CORE_Handle *core,
+                              GNUNET_CORE_ConnectEventHandler *server_ch,
+                              GNUNET_CORE_DisconnectEventHandler *server_dh,
+                              int advertise);
+
+
+/**
+ * Stop server offering our hostlist.
+ */
+void
+GNUNET_HOSTLIST_server_stop (void);
+
+
+#endif
+/* end of gnunet-daemon-hostlist_server.h */

Deleted: gnunet/src/hostlist/hostlist-client.c
===================================================================
--- gnunet/src/hostlist/hostlist-client.c       2014-06-03 08:19:03 UTC (rev 
33488)
+++ gnunet/src/hostlist/hostlist-client.c       2014-06-03 08:41:00 UTC (rev 
33489)
@@ -1,1654 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 Christian Grothoff 
(and other contributing authors)
-
-     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 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file hostlist/hostlist-client.c
- * @brief hostlist support.  Downloads HELLOs via HTTP.
- * @author Christian Grothoff
- * @author Matthias Wachs
- */
-
-#include "platform.h"
-#include "hostlist-client.h"
-#include "gnunet_core_service.h"
-#include "gnunet_hello_lib.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet_transport_service.h"
-#include "gnunet-daemon-hostlist.h"
-#include <curl/curl.h>
-#include "gnunet_util_lib.h"
-
-
-/**
- * Number of connections that we must have to NOT download
- * hostlists anymore.
- */
-#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
- */
-struct Hostlist
-{
-  /**
-   * previous entry, used to manage entries in a double linked list
-   */
-  struct Hostlist *prev;
-
-  /**
-   * next entry, used to manage entries in a double linked list
-   */
-  struct Hostlist *next;
-
-  /**
-   * URI where hostlist can be obtained
-   */
-  const char *hostlist_uri;
-
-  /**
-   * Value describing the quality of the hostlist, the bigger the better but 
(should) never < 0
-   * used for deciding which hostlist is replaced if MAX_NUMBER_HOSTLISTS in 
data structure is reached
-   * intial value = HOSTLIST_INITIAL
-   * increased every successful download by HOSTLIST_SUCCESSFULL_DOWNLOAD
-   * increased every successful download by number of obtained HELLO messages
-   * decreased every failed download by HOSTLIST_SUCCESSFULL_DOWNLOAD
-   */
-  uint64_t quality;
-
-  /**
-   * Time the hostlist advertisement was recieved and the entry was created
-   */
-  struct GNUNET_TIME_Absolute time_creation;
-
-  /**
-   * Last time the hostlist was obtained
-   */
-  struct GNUNET_TIME_Absolute time_last_usage;
-
-  /**
-   * Number of HELLO messages obtained during last download
-   */
-  uint32_t hello_count;
-
-  /**
-   * Number of times the hostlist was successfully obtained
-   */
-  uint32_t times_used;
-
-};
-
-
-/**
- * Our configuration.
- */
-static const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-/**
- * Statistics handle.
- */
-static struct GNUNET_STATISTICS_Handle *stats;
-
-/**
- * Transport handle.
- */
-static struct GNUNET_TRANSPORT_Handle *transport;
-
-/**
- * Proxy hostname or ip we are using (can be NULL).
- */
-static char *proxy;
-
-/**
- * Proxy username we are using (can be NULL).
- */
-static char *proxy_username;
-
-/**
- * Proxy password we are using (can be NULL).
- */
-static char *proxy_password;
-
-/**
- * Proxy type we are using (can be NULL).
- */
-static curl_proxytype proxy_type;
-
-/**
- * Number of bytes valid in 'download_buffer'.
- */
-static size_t download_pos;
-
-/**
- * Current URL that we are using.
- */
-static char *current_url;
-
-/**
- * Current CURL handle.
- */
-static CURL *curl;
-
-/**
- * Current multi-CURL handle.
- */
-static CURLM *multi;
-
-/**
- * How many bytes did we download from the current hostlist URL?
- */
-static uint32_t stat_bytes_downloaded;
-
-/**
- * Amount of time we wait between hostlist downloads.
- */
-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;
-
-/**
- * ID of the task downloading the hostlist
- */
-static GNUNET_SCHEDULER_TaskIdentifier ti_download;
-
-/**
- * ID of the task saving the hostlsit in a regular intervall
- */
-static GNUNET_SCHEDULER_TaskIdentifier ti_saving_task;
-
-/**
- * ID of the task called to initiate a download
- */
-static GNUNET_SCHEDULER_TaskIdentifier ti_download_dispatcher_task;
-
-/**
- * ID of the task controlling the locking between two hostlist tests
- */
-static GNUNET_SCHEDULER_TaskIdentifier ti_testing_intervall_task;
-
-/**
- * At what time MUST the current hostlist request be done?
- */
-static struct GNUNET_TIME_Absolute end_time;
-
-/**
- * Head of the linked list used to store hostlists
- */
-static struct Hostlist *linked_list_head;
-
-/**
- *  Tail of the linked list used to store hostlists
- */
-static struct Hostlist *linked_list_tail;
-
-/**
- *  Current hostlist used for downloading
- */
-static struct Hostlist *current_hostlist;
-
-/**
- *  Size of the linke list  used to store hostlists
- */
-static unsigned int linked_list_size;
-
-/**
- * Head of the linked list used to store hostlists
- */
-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.
- */
-static int stat_bogus_url;
-
-/**
- * Value controlling if a hostlist is tested at the moment
- */
-static int stat_testing_hostlist;
-
-/**
- * Value controlling if a hostlist testing is allowed at the moment
- */
-static int stat_testing_allowed;
-
-/**
- * Value controlling if a hostlist download is running at the moment
- */
-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 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 stat_hellos_obtained;
-
-/**
- * Number of active connections (according to core service).
- */
-static unsigned int stat_connection_count;
-
-
-/**
- * Process downloaded bits by calling callback on each HELLO.
- *
- * @param ptr buffer with downloaded data
- * @param size size of a record
- * @param nmemb number of records downloaded
- * @param ctx unused
- * @return number of bytes that were processed (always size*nmemb)
- */
-static size_t
-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;
-  size_t cpy;
-  size_t left;
-  uint16_t msize;
-
-  total = size * nmemb;
-  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, GNUNET_NO);
-  left = total;
-  while ((left > 0) || (download_pos > 0))
-  {
-    cpy = GNUNET_MIN (left, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - download_pos);
-    memcpy (&download_buffer[download_pos], cbuf, cpy);
-    cbuf += cpy;
-    download_pos += cpy;
-    left -= cpy;
-    if (download_pos < sizeof (struct GNUNET_MessageHeader))
-    {
-      GNUNET_assert (0 == left);
-      break;
-    }
-    msg = (const struct GNUNET_MessageHeader *) download_buffer;
-    msize = ntohs (msg->size);
-    if (msize < sizeof (struct GNUNET_MessageHeader))
-    {
-      GNUNET_STATISTICS_update (stats,
-                                gettext_noop
-                                ("# invalid HELLOs downloaded from hostlist 
servers"),
-                                1, GNUNET_NO);
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  _("Invalid `%s' message received from hostlist at `%s'\n"),
-                  "HELLO", current_url);
-      stat_hellos_obtained++;
-      stat_bogus_url = 1;
-      return total;
-    }
-    if (download_pos < msize)
-    {
-      GNUNET_assert (left == 0);
-      break;
-    }
-    if (GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) msg) == msize)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "Received valid `%s' message from hostlist server.\n",
-                  "HELLO");
-      GNUNET_STATISTICS_update (stats,
-                                gettext_noop
-                                ("# valid HELLOs downloaded from hostlist 
servers"),
-                                1, GNUNET_NO);
-      stat_hellos_obtained++;
-      GNUNET_TRANSPORT_offer_hello (transport, msg, NULL, NULL);
-    }
-    else
-    {
-      GNUNET_STATISTICS_update (stats,
-                                gettext_noop
-                                ("# invalid HELLOs downloaded from hostlist 
servers"),
-                                1, GNUNET_NO);
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  _("Invalid `%s' message received from hostlist at `%s'\n"),
-                  "HELLO", current_url);
-      stat_bogus_url = GNUNET_YES;
-      stat_hellos_obtained++;
-      return total;
-    }
-    memmove (download_buffer, &download_buffer[msize], download_pos - msize);
-    download_pos -= msize;
-  }
-  return total;
-}
-
-
-/**
- * Obtain a hostlist URL that we should use.
- *
- * @return NULL if there is no URL available
- */
-static char *
-get_bootstrap_server ()
-{
-  char *servers;
-  char *ret;
-  size_t urls;
-  size_t pos;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "SERVERS",
-                                             &servers))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
-                              "hostlist", "SERVERS");
-    return NULL;
-  }
-
-  urls = 0;
-  if (strlen (servers) > 0)
-  {
-    urls++;
-    pos = strlen (servers) - 1;
-    while (pos > 0)
-    {
-      if (servers[pos] == ' ')
-        urls++;
-      pos--;
-    }
-  }
-  if (urls == 0)
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
-                              "hostlist", "SERVERS");
-    GNUNET_free (servers);
-    return NULL;
-  }
-
-  urls = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, urls) + 1;
-  pos = strlen (servers) - 1;
-  while (pos > 0)
-  {
-    if (servers[pos] == ' ')
-    {
-      urls--;
-      servers[pos] = '\0';
-    }
-    if (urls == 0)
-    {
-      pos++;
-      break;
-    }
-    pos--;
-  }
-  ret = GNUNET_strdup (&servers[pos]);
-  GNUNET_free (servers);
-  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
- */
-static char *
-download_get_url ()
-{
-  uint32_t index;
-  unsigned int counter;
-  struct Hostlist *pos;
-
-  if (GNUNET_NO == stat_learning)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Using preconfigured bootstrap server\n");
-    current_hostlist = NULL;
-    return get_bootstrap_server ();
-  }
-
-  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");
-    current_hostlist = hostlist_to_test;
-    return GNUNET_strdup (hostlist_to_test->hostlist_uri);
-  }
-
-  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_server ();
-  }
-  index =
-      GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, linked_list_size);
-  counter = 0;
-  pos = linked_list_head;
-  while (counter < index)
-  {
-    pos = pos->next;
-    counter++;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using learned hostlist `%s'\n",
-              pos->hostlist_uri);
-  current_hostlist = pos;
-  return GNUNET_strdup (pos->hostlist_uri);
-}
-
-
-#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);
-
-
-/**
- * add val2 to val1 with overflow check
- *
- * @param val1 value 1
- * @param val2 value 2
- * @return result
- */
-static uint64_t
-checked_add (uint64_t val1, uint64_t val2)
-{
-  static uint64_t temp;
-  static uint64_t maxv;
-
-  maxv = 0;
-  maxv--;
-
-  temp = val1 + val2;
-  if (temp < val1)
-    return maxv;
-  return temp;
-}
-
-
-/**
- * Subtract val2 from val1 with underflow check
- *
- * @param val1 value 1
- * @param val2 value 2
- * @return result
- */
-static uint64_t
-checked_sub (uint64_t val1, uint64_t val2)
-{
-  if (val1 <= val2)
-    return 0;
-  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
- */
-static int
-linked_list_contains (const char *uri)
-{
-  struct Hostlist *pos;
-
-  pos = linked_list_head;
-  while (pos != NULL)
-  {
-    if (0 == strcmp (pos->hostlist_uri, uri))
-      return GNUNET_YES;
-    pos = pos->next;
-  }
-  return GNUNET_NO;
-}
-
-
-/**
- * Method returning the hostlist element with the lowest quality in the 
datastore
- * @return hostlist with lowest quality
- */
-static struct Hostlist *
-linked_list_get_lowest_quality ()
-{
-  struct Hostlist *pos;
-  struct Hostlist *lowest;
-
-  if (linked_list_size == 0)
-    return NULL;
-  lowest = linked_list_head;
-  pos = linked_list_head->next;
-  while (pos != NULL)
-  {
-    if (pos->quality < lowest->quality)
-      lowest = pos;
-    pos = pos->next;
-  }
-  return lowest;
-}
-
-
-/**
- * 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 ()
-{
-  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);
-  stat_testing_hostlist = GNUNET_NO;
-}
-
-
-/**
- * Method updating hostlist statistics
- */
-static void
-update_hostlist ()
-{
-  char *stat;
-
-  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 = stat_hellos_obtained;
-    current_hostlist->time_last_usage = GNUNET_TIME_absolute_get ();
-    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);
-      GNUNET_asprintf (&stat, gettext_noop ("# advertised URI `%s' 
downloaded"),
-                       current_hostlist->hostlist_uri);
-
-      GNUNET_STATISTICS_update (stats, stat, 1, GNUNET_YES);
-      GNUNET_free (stat);
-    }
-    else
-      current_hostlist->quality =
-          checked_sub (current_hostlist->quality, HOSTLIST_FAILED_DOWNLOAD);
-  }
-  current_hostlist = NULL;
-  /* Alternating the usage of preconfigured and learned hostlists */
-
-  if (stat_testing_hostlist == GNUNET_YES)
-    return;
-
-  if (GNUNET_YES == stat_learning)
-  {
-    if (stat_use_bootstrap == GNUNET_YES)
-      stat_use_bootstrap = GNUNET_NO;
-    else
-      stat_use_bootstrap = GNUNET_YES;
-  }
-  else
-    stat_use_bootstrap = GNUNET_YES;
-}
-
-
-/**
- * Clean up the state from the task that downloaded the
- * hostlist and schedule the next task.
- */
-static void
-clean_up ()
-{
-  CURLMcode mret;
-
-  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 (stat_testing_hostlist == GNUNET_YES)
-  {
-    stat_testing_hostlist = GNUNET_NO;
-  }
-  if (NULL != hostlist_to_test)
-  {
-    GNUNET_free (hostlist_to_test);
-    hostlist_to_test = NULL;
-  }
-
-  if (multi != NULL)
-  {
-    mret = curl_multi_remove_handle (multi, curl);
-    if (mret != CURLM_OK)
-    {
-      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"),
-                  "curl_multi_cleanup", __FILE__, __LINE__,
-                  curl_multi_strerror (mret));
-    multi = NULL;
-  }
-  if (curl != NULL)
-  {
-    curl_easy_cleanup (curl);
-    curl = NULL;
-  }
-  GNUNET_free_non_null (current_url);
-  current_url = NULL;
-  stat_bytes_downloaded = 0;
-  stat_download_in_progress = GNUNET_NO;
-}
-
-
-/**
- * Task that is run when we are ready to receive more data from the hostlist
- * server.
- *
- * @param cls closure, unused
- * @param tc task context, unused
- */
-static void
-task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-/**
- * Ask CURL for the select set and then schedule the
- * receiving task with the scheduler.
- */
-static void
-download_prepare ()
-{
-  CURLMcode mret;
-  fd_set rs;
-  fd_set ws;
-  fd_set es;
-  int max;
-  struct GNUNET_NETWORK_FDSet *grs;
-  struct GNUNET_NETWORK_FDSet *gws;
-  long timeout;
-  struct GNUNET_TIME_Relative rtime;
-
-  max = -1;
-  FD_ZERO (&rs);
-  FD_ZERO (&ws);
-  FD_ZERO (&es);
-  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"),
-                "curl_multi_fdset", __FILE__, __LINE__,
-                curl_multi_strerror (mret));
-    clean_up ();
-    return;
-  }
-  mret = curl_multi_timeout (multi, &timeout);
-  if (mret != CURLM_OK)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
-                "curl_multi_timeout", __FILE__, __LINE__,
-                curl_multi_strerror (mret));
-    clean_up ();
-    return;
-  }
-  rtime =
-      GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining (end_time),
-                                GNUNET_TIME_relative_multiply
-                                (GNUNET_TIME_UNIT_MILLISECONDS, timeout));
-  grs = GNUNET_NETWORK_fdset_create ();
-  gws = GNUNET_NETWORK_fdset_create ();
-  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
-  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Scheduling task for hostlist download using cURL\n");
-  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);
-}
-
-
-/**
- * Task that is run when we are ready to receive more data from the hostlist
- * server.
- *
- * @param cls closure, unused
- * @param tc task context, unused
- */
-static void
-task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  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;
-  }
-  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"),
-                current_url);
-    update_hostlist ();
-    clean_up ();
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Ready for processing hostlist client request\n");
-  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);
-        GNUNET_break (msg != NULL);
-        if (msg == NULL)
-          break;
-        switch (msg->msg)
-        {
-        case CURLMSG_DONE:
-          if ((msg->data.result != CURLE_OK) &&
-              (msg->data.result != CURLE_GOT_NOTHING))
-            GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                        _("Download of hostlist from `%s' failed: `%s'\n"),
-                        current_url,
-                        curl_easy_strerror (msg->data.result));
-          else
-          {
-            GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                        _("Download of hostlist `%s' completed.\n"),
-                        current_url);
-            stat_download_successful = GNUNET_YES;
-            update_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;
-              stat_testing_hostlist = GNUNET_NO;
-            }
-          }
-          clean_up ();
-          return;
-        default:
-          break;
-        }
-
-      }
-      while ((running > 0));
-    }
-  }
-  while (mret == CURLM_CALL_MULTI_PERFORM);
-
-  if (mret != CURLM_OK)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("%s failed at %s:%d: `%s'\n"),
-                "curl_multi_perform", __FILE__, __LINE__,
-                curl_multi_strerror (mret));
-    clean_up ();
-  }
-  download_prepare ();
-}
-
-
-/**
- * Main function that will download a hostlist and process its
- * data.
- */
-static void
-download_hostlist ()
-{
-  CURLcode ret;
-  CURLMcode mret;
-
-
-  current_url = download_get_url ();
-  if (current_url == NULL)
-    return;
-  curl = curl_easy_init ();
-  multi = NULL;
-  if (curl == NULL)
-  {
-    GNUNET_break (0);
-    clean_up ();
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
-              _("Bootstrapping using hostlist at `%s'.\n"), current_url);
-
-  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"), 1,
-                            GNUNET_NO);
-  if (proxy != NULL)
-  {
-    CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
-    CURL_EASY_SETOPT (curl, CURLOPT_PROXYTYPE, proxy_type);
-    if (NULL != proxy_username)
-      CURL_EASY_SETOPT (curl, CURLOPT_PROXYUSERNAME, proxy_username);
-    if (NULL != proxy_password)
-      CURL_EASY_SETOPT (curl, CURLOPT_PROXYPASSWORD, proxy_password);
-  }
-  download_pos = 0;
-  stat_bogus_url = 0;
-  CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, &callback_download);
-  if (ret != CURLE_OK)
-  {
-    clean_up ();
-    return;
-  }
-  CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, NULL);
-  if (ret != CURLE_OK)
-  {
-    clean_up ();
-    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);
-  if (ret != CURLE_OK)
-  {
-    clean_up ();
-    return;
-  }
-  CURL_EASY_SETOPT (curl, CURLOPT_FAILONERROR, 1);
-#if 0
-  CURL_EASY_SETOPT (curl, CURLOPT_VERBOSE, 1);
-#endif
-  CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE);
-  if (0 == strncmp (current_url, "http", 4))
-    CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet");
-  CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 60L);
-  CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 60L);
-#if 0
-  /* this should no longer be needed; we're now single-threaded! */
-  CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1);
-#endif
-  multi = curl_multi_init ();
-  if (multi == NULL)
-  {
-    GNUNET_break (0);
-    /* clean_up (); */
-    return;
-  }
-  mret = curl_multi_add_handle (multi, curl);
-  if (mret != CURLM_OK)
-  {
-    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"),
-                  "curl_multi_cleanup", __FILE__, __LINE__,
-                  curl_multi_strerror (mret));
-    multi = NULL;
-    clean_up ();
-    return;
-  }
-  end_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
-  download_prepare ();
-}
-
-
-static void
-task_download_dispatcher (void *cls,
-                          const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download is initiated...\n");
-  if (GNUNET_NO == stat_download_in_progress)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download can start 
immediately...\n");
-    download_hostlist ();
-  }
-  else
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Download in progess, have to wait...\n");
-    ti_download_dispatcher_task =
-        GNUNET_SCHEDULER_add_delayed (WAITING_INTERVALL,
-                                      &task_download_dispatcher, NULL);
-  }
-}
-
-
-/**
- * Task that checks if we should try to download a hostlist.
- * If so, we initiate the download, otherwise we schedule
- * this task again for a later time.
- */
-static void
-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 (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 (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_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_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 %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);
-}
-
-
-/**
- * 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)
-{
-  ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
-  stat_testing_allowed = GNUNET_OK;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Testing new hostlist advertisements is allowed again\n");
-}
-
-
-/**
- * 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)
-{
-  ti_saving_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
-  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_INTERVALL, 
GNUNET_YES));
-  ti_saving_task =
-      GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL, &task_hostlist_saving,
-                                    NULL);
-}
-
-
-/**
- * Method called whenever a given peer connects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-static void
-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);
-}
-
-
-/**
- * Method called whenever a given peer disconnects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-static void
-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);
-}
-
-
-/**
- * Method called whenever an advertisement message arrives.
- *
- * @param cls closure (always NULL)
- * @param peer the peer sending the message
- * @param message the actual message
- * @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)
-{
-  size_t size;
-  size_t uri_size;
-  const struct GNUNET_MessageHeader *incoming;
-  const char *uri;
-  struct Hostlist *hostlist;
-
-  GNUNET_assert (ntohs (message->type) ==
-                 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT);
-  size = ntohs (message->size);
-  if (size <= sizeof (struct GNUNET_MessageHeader))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  incoming = (const struct GNUNET_MessageHeader *) message;
-  uri = (const char *) &incoming[1];
-  uri_size = size - sizeof (struct GNUNET_MessageHeader);
-  if (uri[uri_size - 1] != '\0')
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Hostlist client recieved advertisement from `%s' containing URI 
`%s'\n",
-              GNUNET_i2s (peer), uri);
-  if (GNUNET_NO != linked_list_contains (uri))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URI `%s' is already known\n", uri);
-    return GNUNET_OK;
-  }
-
-  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 == stat_testing_hostlist)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Currently not accepting new advertisements: we are already 
testing a hostlist\n");
-    return GNUNET_SYSERR;
-  }
-
-  hostlist = GNUNET_malloc (sizeof (struct Hostlist) + uri_size);
-  hostlist->hostlist_uri = (const char *) &hostlist[1];
-  memcpy (&hostlist[1], uri, uri_size);
-  hostlist->time_creation = GNUNET_TIME_absolute_get ();
-  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);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "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);
-
-  return GNUNET_OK;
-}
-
-
-/**
- * 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
-primary_task (void *cls, int success)
-{
-  sget = NULL;
-  GNUNET_assert (stats != NULL);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Statistics request done, scheduling hostlist download\n");
-  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)
-{
-  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
- */
-static void
-load_hostlist_file ()
-{
-  char *filename;
-  char *uri;
-  char *emsg;
-  struct Hostlist *hostlist;
-  uint32_t times_used;
-  uint32_t hellos_returned;
-  uint64_t quality;
-  uint64_t last_used;
-  uint64_t created;
-  uint32_t counter;
-
-  uri = NULL;
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE",
-                                               &filename))
-  {
-    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);
-  if (GNUNET_NO == GNUNET_DISK_file_test (filename))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Hostlist file `%s' does not exist\n"), filename);
-    GNUNET_free (filename);
-    return;
-  }
-
-  struct GNUNET_BIO_ReadHandle *rh = GNUNET_BIO_read_open (filename);
-
-  if (NULL == rh)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _
-                ("Could not open file `%s' for reading to load hostlists: 
%s\n"),
-                filename, STRERROR (errno));
-    GNUNET_free (filename);
-    return;
-  }
-
-  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)) &&
-         (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)))
-  {
-    hostlist = GNUNET_malloc (sizeof (struct Hostlist) + strlen (uri) + 1);
-    hostlist->hello_count = hellos_returned;
-    hostlist->hostlist_uri = (const char *) &hostlist[1];
-    memcpy (&hostlist[1], uri, strlen (uri) + 1);
-    hostlist->quality = quality;
-    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,
-                "Added hostlist entry eith URI `%s' \n",
-                hostlist->hostlist_uri);
-    GNUNET_free (uri);
-    uri = NULL;
-    counter++;
-    if (counter >= MAX_NUMBER_HOSTLISTS)
-      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"),
-                         counter, GNUNET_YES);
-  GNUNET_STATISTICS_set (stats, gettext_noop ("# advertised hostlist URIs"),
-                         linked_list_size, GNUNET_NO);
-
-  GNUNET_free_non_null (uri);
-  emsg = NULL;
-  (void) GNUNET_BIO_read_close (rh, &emsg);
-  if (emsg != NULL)
-    GNUNET_free (emsg);
-  GNUNET_free (filename);
-}
-
-
-/**
- * Method to save persistent hostlist 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)
-{
-  char *filename;
-  struct Hostlist *pos;
-  struct GNUNET_BIO_WriteHandle *wh;
-  int ok;
-  uint32_t counter;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE",
-                                               &filename))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
-                              "hostlist", "HOSTLISTFILE");
-    return;
-  }
-  if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
-  {
-    GNUNET_free (filename);
-    return;
-  }
-  wh = GNUNET_BIO_write_open (filename);
-  if (NULL == wh)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _
-                ("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"),
-              linked_list_size, filename);
-  /* add code to write hostlists to file using bio */
-  ok = GNUNET_YES;
-  counter = 0;
-  while (NULL != (pos = linked_list_head))
-  {
-    if (GNUNET_YES == shutdown)
-    {
-      GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail, pos);
-      linked_list_size--;
-    }
-    if (GNUNET_YES == ok)
-    {
-      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_int64 (wh, pos->time_last_usage.abs_value_us)) ||
-          (GNUNET_OK !=
-           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,
-                    _("Error writing hostlist URIs to file `%s'\n"), filename);
-        ok = GNUNET_NO;
-      }
-    }
-
-    if (GNUNET_YES == shutdown)
-      GNUNET_free (pos);
-    counter++;
-    if (counter >= MAX_NUMBER_HOSTLISTS)
-      break;
-  }
-  GNUNET_STATISTICS_set (stats,
-                         gettext_noop ("# hostlist URIs written to file"),
-                         counter, GNUNET_YES);
-
-  if (GNUNET_OK != GNUNET_BIO_write_close (wh))
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("Error writing hostlist URIs to file `%s'\n"), filename);
-  GNUNET_free (filename);
-}
-
-
-/**
- * Start downloading hostlists from hostlist servers as necessary.
- */
-int
-GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
-                              struct GNUNET_STATISTICS_Handle *st,
-                              GNUNET_CORE_ConnectEventHandler *ch,
-                              GNUNET_CORE_DisconnectEventHandler *dh,
-                              GNUNET_CORE_MessageCallback *msgh, int learn)
-{
-  char *filename;
-  char *proxytype_str;
-  int result;
-
-  GNUNET_assert (NULL != st);
-  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  transport = GNUNET_TRANSPORT_connect (c, NULL, NULL, NULL, NULL, NULL);
-  if (NULL == transport)
-  {
-    curl_global_cleanup ();
-    return GNUNET_SYSERR;
-  }
-  cfg = c;
-  stats = st;
-
-  /* Read proxy configuration */
-  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
-      "HOSTLIST", "PROXY", &proxy))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Found proxy host: `%s'\n",
-                     proxy);
-    /* proxy username */
-    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
-        "HOSTLIST", "PROXY_USERNAME", &proxy_username))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                       "Found proxy username name: `%s'\n",
-                       proxy_username);
-    }
-
-    /* proxy password */
-    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
-        "HOSTLIST", "PROXY_PASSWORD", &proxy_password))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                       "Found proxy password name: `%s'\n",
-                       proxy_password);
-    }
-
-    /* proxy type */
-    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
-        "HOSTLIST", "PROXY_TYPE", &proxytype_str))
-    {
-      GNUNET_STRINGS_utf8_toupper (proxytype_str, proxytype_str);
-
-      proxy_type = CURLPROXY_HTTP;
-      if (0 == strcmp(proxytype_str, "HTTP"))
-        proxy_type = CURLPROXY_HTTP;
-      else if (0 == strcmp(proxytype_str, "HTTP_1_0"))
-        proxy_type = CURLPROXY_HTTP_1_0;
-      else if (0 == strcmp(proxytype_str, "SOCKS4"))
-        proxy_type = CURLPROXY_SOCKS4;
-      else if (0 == strcmp(proxytype_str, "SOCKS5"))
-        proxy_type = CURLPROXY_SOCKS5;
-      else if (0 == strcmp(proxytype_str, "SOCKS4A"))
-        proxy_type = CURLPROXY_SOCKS4A;
-      else if (0 == strcmp(proxytype_str, "SOCKS5_HOSTNAME"))
-        proxy_type = CURLPROXY_SOCKS5_HOSTNAME ;
-      else
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-             _("Invalid proxy type: `%s', disabling proxy! Check 
configuration!\n"),
-             proxytype_str);
-        GNUNET_free (proxytype_str);
-
-        GNUNET_free (proxy);
-        proxy = NULL;
-        GNUNET_free_non_null (proxy_username);
-        proxy_username = NULL;
-        GNUNET_free_non_null (proxy_password);
-        proxy_password = NULL;
-
-        return GNUNET_SYSERR;
-      }
-    }
-    GNUNET_free_non_null (proxytype_str);
-  }
-
-  stat_learning = learn;
-  *ch = &handler_connect;
-  *dh = &handler_disconnect;
-  linked_list_head = NULL;
-  linked_list_tail = NULL;
-  stat_use_bootstrap = GNUNET_YES;
-  stat_testing_hostlist = GNUNET_NO;
-  stat_testing_allowed = GNUNET_YES;
-
-  if (GNUNET_YES == stat_learning)
-  {
-    *msgh = &handler_advertisement;
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Learning is enabled on this peer\n"));
-    load_hostlist_file ();
-    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_YES == GNUNET_DISK_file_test (filename))
-      {
-        result = remove (filename);
-        if (result == 0)
-          GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                      _
-                      ("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_free (filename);
-  }
-  sget = GNUNET_STATISTICS_get (stats, "hostlist",
-                               gettext_noop
-                               ("# milliseconds between hostlist downloads"),
-                               GNUNET_TIME_UNIT_MINUTES, &primary_task, 
&process_stat,
-                               NULL);
-  return GNUNET_OK;
-}
-
-
-/**
- * Stop downloading hostlists from hostlist servers as necessary.
- */
-void
-GNUNET_HOSTLIST_client_stop ()
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n");
-  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)
-  {
-    GNUNET_TRANSPORT_disconnect (transport);
-    transport = NULL;
-  }
-  GNUNET_free_non_null (proxy);
-  proxy = NULL;
-  GNUNET_free_non_null (proxy_username);
-  proxy_username = NULL;
-  GNUNET_free_non_null (proxy_password);
-  proxy_password = NULL;
-
-  cfg = NULL;
-}
-
-/* end of hostlist-client.c */

Deleted: gnunet/src/hostlist/hostlist-client.h
===================================================================
--- gnunet/src/hostlist/hostlist-client.h       2014-06-03 08:19:03 UTC (rev 
33488)
+++ gnunet/src/hostlist/hostlist-client.h       2014-06-03 08:41:00 UTC (rev 
33489)
@@ -1,108 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2009 Christian Grothoff (and other contributing authors)
-
-     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 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file hostlist/hostlist-client.h
- * @brief hostlist support.  Downloads HELLOs via HTTP.
- * @author Christian Grothoff
- */
-
-#ifndef HOSTLIST_CLIENT_H
-#define HOSTLIST_CLIENT_H
-
-#include "gnunet_core_service.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_time_lib.h"
-
-/**
- * Maximum number of hostlist that are saved
- */
-#define MAX_NUMBER_HOSTLISTS 30
-
-/**
- * Time intervall hostlists are saved to disk
- */
-#define SAVING_INTERVALL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MINUTES, 30)
-
-/**
- * Time interval between two hostlist tests
- */
-#define TESTING_INTERVALL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 3)
-
-/**
- * Time interval for download dispatcher before a download is re-scheduled
- */
-#define WAITING_INTERVALL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 1)
-
-/**
- * Defines concerning the hostlist quality metric
- */
-
-/**
- * Initial quality of a new created hostlist
- */
-#define HOSTLIST_INITIAL 10000
-
-/**
- * Value subtracted each time a hostlist download fails
- */
-#define HOSTLIST_FAILED_DOWNLOAD 100
-
-/**
- * Value added each time a hostlist download is successful
- */
-#define HOSTLIST_SUCCESSFUL_DOWNLOAD 100
-
-/**
- * Value added for each valid HELLO recived during a hostlist download
- */
-#define HOSTLIST_SUCCESSFUL_HELLO 1
-
-
-
-/**
- * Start downloading hostlists from hostlist servers as necessary.
- *
- * @param c the configuration to use
- * @param st hande for publishing statistics
- * @param ch set to handler for connect notifications
- * @param dh set to handler for disconnect notifications
- * @param msgh set to handler for message handler notifications
- * @param learn set if client is learning new hostlists
- * @return GNUNET_OK on success
- */
-int
-GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
-                              struct GNUNET_STATISTICS_Handle *st,
-                              GNUNET_CORE_ConnectEventHandler *ch,
-                              GNUNET_CORE_DisconnectEventHandler *dh,
-                              GNUNET_CORE_MessageCallback *msgh, int learn);
-
-
-/**
- * Stop downloading hostlists from hostlist servers as necessary.
- */
-void
-GNUNET_HOSTLIST_client_stop (void);
-
-
-#endif
-/* end of hostlist-client.h */

Deleted: gnunet/src/hostlist/hostlist-server.c
===================================================================
--- gnunet/src/hostlist/hostlist-server.c       2014-06-03 08:19:03 UTC (rev 
33488)
+++ gnunet/src/hostlist/hostlist-server.c       2014-06-03 08:41:00 UTC (rev 
33489)
@@ -1,802 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2008, 2009, 2010, 2014 Christian Grothoff (and other contributing 
authors)
-
-     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 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file hostlist/hostlist-server.c
- * @author Christian Grothoff, Matthias Wachs, David Barksdale
- * @brief application to provide an integrated hostlist HTTP server
- */
-
-#include "platform.h"
-#include <microhttpd.h>
-#include "hostlist-server.h"
-#include "gnunet_hello_lib.h"
-#include "gnunet_peerinfo_service.h"
-#include "gnunet-daemon-hostlist.h"
-#include "gnunet_resolver_service.h"
-
-
-/**
- * Handle to the HTTP server as provided by libmicrohttpd for IPv6.
- */
-static struct MHD_Daemon *daemon_handle_v6;
-
-/**
- * Handle to the HTTP server as provided by libmicrohttpd for IPv4.
- */
-static struct MHD_Daemon *daemon_handle_v4;
-
-/**
- * Our configuration.
- */
-static const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-/**
- * For keeping statistics.
- */
-static struct GNUNET_STATISTICS_Handle *stats;
-
-/**
- * Handle to the core service (NULL until we've connected to it).
- */
-static struct GNUNET_CORE_Handle *core;
-
-/**
- * Handle to the peerinfo notify service (NULL until we've connected to it).
- */
-static struct GNUNET_PEERINFO_NotifyContext *notify;
-
-/**
- * Our primary task for IPv4.
- */
-static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v4;
-
-/**
- * Our primary task for IPv6.
- */
-static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v6;
-
-/**
- * Our canonical response.
- */
-static struct MHD_Response *response;
-
-/**
- * Handle for accessing peerinfo service.
- */
-static struct GNUNET_PEERINFO_Handle *peerinfo;
-
-/**
- * Set if we are allowed to advertise our hostlist to others.
- */
-static int advertising;
-
-/**
- * Buffer for the hostlist address
- */
-static char *hostlist_uri;
-
-
-/**
- * Context for host processor.
- */
-struct HostSet
-{
-  unsigned int size;
-
-  char *data;
-
-  struct GNUNET_PEERINFO_IteratorContext *pitr;
-};
-
-
-/**
- * NULL if we are not currenlty iterating over peer information.
- */
-static struct HostSet *builder;
-
-
-/**
- * Function that assembles our response.
- */
-static void
-finish_response ()
-{
-  if (NULL != response)
-    MHD_destroy_response (response);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Creating hostlist response with %u bytes\n",
-              (unsigned int) builder->size);
-  response =
-      MHD_create_response_from_data (builder->size, builder->data, MHD_YES,
-                                     MHD_NO);
-  if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6))
-  {
-    MHD_destroy_response (response);
-    response = NULL;
-  }
-  GNUNET_STATISTICS_set (stats, gettext_noop ("bytes in hostlist"),
-                         builder->size, GNUNET_YES);
-  GNUNET_free (builder);
-  builder = NULL;
-}
-
-
-/**
- * Set @a cls to #GNUNET_YES (we have an address!).
- *
- * @param cls closure, an `int *`
- * @param address the address (ignored)
- * @param expiration expiration time (call is ignored if this is in the past)
- * @return  #GNUNET_SYSERR to stop iterating (unless expiration has occured)
- */
-static int
-check_has_addr (void *cls, const struct GNUNET_HELLO_Address *address,
-                struct GNUNET_TIME_Absolute expiration)
-{
-  int *arg = cls;
-
-  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
-  {
-    GNUNET_STATISTICS_update (stats,
-                              gettext_noop ("expired addresses encountered"), 
1,
-                              GNUNET_YES);
-    return GNUNET_YES;          /* ignore this address */
-  }
-  *arg = GNUNET_YES;
-  return GNUNET_SYSERR;
-}
-
-
-/**
- * Callback that processes each of the known HELLOs for the
- * hostlist response construction.
- */
-static void
-host_processor (void *cls,
-                const struct GNUNET_PeerIdentity *peer,
-                const struct GNUNET_HELLO_Message *hello,
-                const char *err_msg)
-{
-  size_t old;
-  size_t s;
-  int has_addr;
-
-  if (NULL != err_msg)
-  {
-    GNUNET_assert (NULL == peer);
-    builder->pitr = NULL;
-    GNUNET_free_non_null (builder->data);
-    GNUNET_free (builder);
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Error in communication with PEERINFO service: %s\n"),
-                err_msg);
-    return;
-  }
-  if (NULL == peer)
-  {
-    builder->pitr = NULL;
-    finish_response ();
-    return;
-  }
-  if (NULL == hello)
-    return;
-  has_addr = GNUNET_NO;
-  GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_has_addr, 
&has_addr);
-  if (GNUNET_NO == has_addr)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "HELLO for peer `%4s' has no address, not suitable for 
hostlist!\n",
-                GNUNET_i2s (peer));
-    GNUNET_STATISTICS_update (stats,
-                              gettext_noop
-                              ("HELLOs without addresses encountered 
(ignored)"),
-                              1, GNUNET_NO);
-    return;
-  }
-  old = builder->size;
-  s = GNUNET_HELLO_size (hello);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
-              (unsigned int) s, "HELLO", GNUNET_i2s (peer));
-  if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) ||
-      (old + s >= MAX_BYTES_PER_HOSTLISTS))
-  {
-    GNUNET_STATISTICS_update (stats,
-                              gettext_noop
-                              ("bytes not included in hostlist (size limit)"),
-                              s, GNUNET_NO);
-    return;                     /* too large, skip! */
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Adding peer `%s' to hostlist (%u bytes)\n", GNUNET_i2s (peer),
-              (unsigned int) s);
-  GNUNET_array_grow (builder->data, builder->size, old + s);
-  memcpy (&builder->data[old], hello, s);
-}
-
-
-
-/**
- * Hostlist access policy (very permissive, allows everything).
- */
-static int
-accept_policy_callback (void *cls, const struct sockaddr *addr,
-                        socklen_t addrlen)
-{
-  if (NULL == response)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Received request for hostlist, but I am not yet ready; 
rejecting!\n");
-    return MHD_NO;
-  }
-  return MHD_YES;               /* accept all */
-}
-
-
-/**
- * Add headers to a request indicating that we allow Cross-Origin Resource
- * Sharing.
- */
-static void
-add_cors_headers(struct MHD_Response *response)
-{
-  MHD_add_response_header (response,
-                           "Access-Control-Allow-Origin",
-                           "*");
-  MHD_add_response_header (response,
-                           "Access-Control-Allow-Methods",
-                           "GET, OPTIONS");
-  MHD_add_response_header (response,
-                           "Access-Control-Max-Age",
-                           "86400");
-}
-
-
-/**
- * Main request handler.
- */
-static int
-access_handler_callback (void *cls, struct MHD_Connection *connection,
-                         const char *url, const char *method,
-                         const char *version, const char *upload_data,
-                         size_t * upload_data_size, void **con_cls)
-{
-  static int dummy;
-
-  /* CORS pre-flight request */
-  if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method))
-  {
-    struct MHD_Response *options_response;
-    int rc;
-
-    options_response = MHD_create_response_from_buffer (0, NULL,
-                                                        
MHD_RESPMEM_PERSISTENT);
-    add_cors_headers(options_response);
-    rc = MHD_queue_response (connection, MHD_HTTP_OK, options_response);
-    MHD_destroy_response (options_response);
-    return rc;
-  }
-  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("Refusing `%s' request to hostlist server\n"), method);
-    GNUNET_STATISTICS_update (stats,
-                              gettext_noop
-                              ("hostlist requests refused (not HTTP GET)"), 1,
-                              GNUNET_YES);
-    return MHD_NO;
-  }
-  if (NULL == *con_cls)
-  {
-    (*con_cls) = &dummy;
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Sending 100 CONTINUE reply\n");
-    return MHD_YES;             /* send 100 continue */
-  }
-  if (0 != *upload_data_size)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("Refusing `%s' request with %llu bytes of upload data\n"),
-                method, (unsigned long long) *upload_data_size);
-    GNUNET_STATISTICS_update (stats,
-                              gettext_noop
-                              ("hostlist requests refused (upload data)"), 1,
-                              GNUNET_YES);
-    return MHD_NO;              /* do not support upload data */
-  }
-  if (NULL == response)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("Could not handle hostlist request since I do not have a 
response yet\n"));
-    GNUNET_STATISTICS_update (stats,
-                              gettext_noop
-                              ("hostlist requests refused (not ready)"), 1,
-                              GNUNET_YES);
-    return MHD_NO;              /* internal error, no response yet */
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Received request for our hostlist\n"));
-  GNUNET_STATISTICS_update (stats,
-                            gettext_noop ("hostlist requests processed"),
-                            1, GNUNET_YES);
-  add_cors_headers (response);
-  return MHD_queue_response (connection, MHD_HTTP_OK, response);
-}
-
-
-/**
- * Handler called by core when core is ready to transmit message
- * @param cls   closure
- * @param size  size of buffer to copy message to
- * @param buf   buffer to copy message to
- */
-static size_t
-adv_transmit_ready (void *cls, size_t size, void *buf)
-{
-  static uint64_t hostlist_adv_count;
-  size_t transmission_size;
-  size_t uri_size;              /* Including \0 termination! */
-  struct GNUNET_MessageHeader header;
-  char *cbuf;
-
-  if (NULL == buf)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Transmission failed, buffer invalid!\n");
-    return 0;
-  }
-  uri_size = strlen (hostlist_uri) + 1;
-  transmission_size = sizeof (struct GNUNET_MessageHeader) + uri_size;
-  header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT);
-  header.size = htons (transmission_size);
-  GNUNET_assert (size >= transmission_size);
-  memcpy (buf, &header, sizeof (struct GNUNET_MessageHeader));
-  cbuf = buf;
-  memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], hostlist_uri, uri_size);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sent advertisement message: Copied %u bytes into buffer!\n",
-              (unsigned int) transmission_size);
-  hostlist_adv_count++;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " # Sent advertisement message: %u\n",
-              hostlist_adv_count);
-  GNUNET_STATISTICS_update (stats,
-                            gettext_noop ("# hostlist advertisements send"), 1,
-                            GNUNET_NO);
-  return transmission_size;
-}
-
-
-/**
- * Method called whenever a given peer connects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-static void
-connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
-  size_t size;
-
-  if (!advertising)
-    return;
-  if (NULL == hostlist_uri)
-    return;
-  size = strlen (hostlist_uri) + 1;
-  if (size + sizeof (struct GNUNET_MessageHeader) >=
-      GNUNET_SERVER_MAX_MESSAGE_SIZE)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  size += sizeof (struct GNUNET_MessageHeader);
-  if (NULL == core)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Asked core to transmit advertisement message with a size of %u 
bytes to peer `%s'\n",
-              size, GNUNET_i2s (peer));
-  if (NULL ==
-      GNUNET_CORE_notify_transmit_ready (core, GNUNET_YES,
-                                         GNUNET_CORE_PRIO_BEST_EFFORT,
-                                         GNUNET_ADV_TIMEOUT, peer, size,
-                                         &adv_transmit_ready, NULL))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("Advertisement message could not be queued by core\n"));
-  }
-}
-
-
-/**
- * Method called whenever a given peer disconnects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-static void
-disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
-  /* nothing to do */
-}
-
-
-/**
- * PEERINFO calls this function to let us know about a possible peer
- * that we might want to connect to.
- *
- * @param cls closure (not used)
- * @param peer potential peer to connect to
- * @param hello HELLO for this peer (or NULL)
- * @param err_msg NULL if successful, otherwise contains error message
- */
-static void
-process_notify (void *cls, const struct GNUNET_PeerIdentity *peer,
-                const struct GNUNET_HELLO_Message *hello, const char *err_msg)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Peerinfo is notifying us to rebuild our hostlist\n");
-  if (NULL != err_msg)
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Error in communication with PEERINFO service: %s\n"),
-               err_msg);
-  if (NULL != builder)
-  {
-    /* restart re-build already in progress ... */
-    GNUNET_PEERINFO_iterate_cancel (builder->pitr);
-    GNUNET_free_non_null (builder->data);
-    builder->size = 0;
-    builder->data = NULL;
-  }
-  else
-  {
-    builder = GNUNET_new (struct HostSet);
-  }
-  GNUNET_assert (NULL != peerinfo);
-  builder->pitr =
-      GNUNET_PEERINFO_iterate (peerinfo, GNUNET_NO, NULL, 
GNUNET_TIME_UNIT_MINUTES,
-                               &host_processor, NULL);
-}
-
-
-/**
- * Function that queries MHD's select sets and
- * starts the task waiting for them.
- */
-static GNUNET_SCHEDULER_TaskIdentifier
-prepare_daemon (struct MHD_Daemon *daemon_handle);
-
-
-/**
- * Call MHD to process pending requests and then go back
- * and schedule the next run.
- */
-static void
-run_daemon (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct MHD_Daemon *daemon_handle = cls;
-
-  if (daemon_handle == daemon_handle_v4)
-    hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK;
-  else
-    hostlist_task_v6 = GNUNET_SCHEDULER_NO_TASK;
-
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
-  GNUNET_assert (MHD_YES == MHD_run (daemon_handle));
-  if (daemon_handle == daemon_handle_v4)
-    hostlist_task_v4 = prepare_daemon (daemon_handle);
-  else
-    hostlist_task_v6 = prepare_daemon (daemon_handle);
-}
-
-
-/**
- * Function that queries MHD's select sets and
- * starts the task waiting for them.
- */
-static GNUNET_SCHEDULER_TaskIdentifier
-prepare_daemon (struct MHD_Daemon *daemon_handle)
-{
-  GNUNET_SCHEDULER_TaskIdentifier ret;
-  fd_set rs;
-  fd_set ws;
-  fd_set es;
-  struct GNUNET_NETWORK_FDSet *wrs;
-  struct GNUNET_NETWORK_FDSet *wws;
-  int max;
-  MHD_UNSIGNED_LONG_LONG timeout;
-  int haveto;
-  struct GNUNET_TIME_Relative tv;
-
-  FD_ZERO (&rs);
-  FD_ZERO (&ws);
-  FD_ZERO (&es);
-  wrs = GNUNET_NETWORK_fdset_create ();
-  wws = GNUNET_NETWORK_fdset_create ();
-  max = -1;
-  GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, 
&max));
-  haveto = MHD_get_timeout (daemon_handle, &timeout);
-  if (haveto == MHD_YES)
-    tv.rel_value_us = (uint64_t) timeout * 1000LL;
-  else
-    tv = GNUNET_TIME_UNIT_FOREVER_REL;
-  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
-  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
-  ret =
-      GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                  tv, wrs, wws,
-                                   &run_daemon, daemon_handle);
-  GNUNET_NETWORK_fdset_destroy (wrs);
-  GNUNET_NETWORK_fdset_destroy (wws);
-  return ret;
-}
-
-
-/**
- * Start server offering our hostlist.
- *
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
-                              struct GNUNET_STATISTICS_Handle *st,
-                              struct GNUNET_CORE_Handle *co,
-                              GNUNET_CORE_ConnectEventHandler *server_ch,
-                              GNUNET_CORE_DisconnectEventHandler *server_dh,
-                              int advertise)
-{
-  unsigned long long port;
-  char *hostname;
-  char *ipv4;
-  char *ipv6;
-  size_t size;
-  struct in_addr i4;
-  struct in6_addr i6;
-  struct sockaddr_in v4;
-  struct sockaddr_in6 v6;
-  const struct sockaddr *sa4;
-  const struct sockaddr *sa6;
-
-  advertising = advertise;
-  if (! advertising)
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Advertising not enabled on this hostlist server\n");
-  else
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Advertising enabled on this hostlist server\n");
-  cfg = c;
-  stats = st;
-  peerinfo = GNUNET_PEERINFO_connect (cfg);
-  if (NULL == peerinfo)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Could not access PEERINFO service.  Exiting.\n"));
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_number (cfg,
-                                             "HOSTLIST",
-                                             "HTTPPORT",
-                                             &port))
-    return GNUNET_SYSERR;
-  if ((0 == port) || (port > UINT16_MAX))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Invalid port number %llu.  Exiting.\n"),
-                port);
-    return GNUNET_SYSERR;
-  }
-
-  if (GNUNET_SYSERR ==
-      GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "HOSTLIST",
-                                             "EXTERNAL_DNS_NAME",
-                                             &hostname))
-    hostname = GNUNET_RESOLVER_local_fqdn_get ();
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Hostlist service starts on %s:%llu\n"),
-              hostname, port);
-  if (NULL != hostname)
-  {
-    size = strlen (hostname);
-    if (size + 15 > MAX_URL_LEN)
-    {
-      GNUNET_break (0);
-    }
-    else
-    {
-      GNUNET_asprintf (&hostlist_uri,
-                       "http://%s:%u/";, hostname,
-                       (unsigned int) port);
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  _("Address to obtain hostlist: `%s'\n"),
-                  hostlist_uri);
-    }
-    GNUNET_free (hostname);
-  }
-
-  if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV4"))
-  {
-    GNUNET_break (GNUNET_OK ==
-                  GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST",
-                                                         "BINDTOIP", &ipv4));
-  }
-  else
-    ipv4 = NULL;
-  if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6"))
-  {
-    GNUNET_break (GNUNET_OK ==
-                  GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST",
-                                                         "BINDTOIP", &ipv6));
-  }
-  else
-    ipv6 = NULL;
-  sa4 = NULL;
-  if (NULL != ipv4)
-  {
-    if (1 == inet_pton (AF_INET, ipv4, &i4))
-    {
-      memset (&v4, 0, sizeof (v4));
-      v4.sin_family = AF_INET;
-      v4.sin_addr = i4;
-      v4.sin_port = htons (port);
-#if HAVE_SOCKADDR_IN_SIN_LEN
-      v4.sin_len = sizeof (v4);
-#endif
-      sa4 = (const struct sockaddr *) &v4;
-    }
-    else
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _("`%s' is not a valid IPv4 address! Ignoring 
BINDTOIPV4.\n"),
-                  ipv4);
-    GNUNET_free (ipv4);
-  }
-  sa6 = NULL;
-  if (NULL != ipv6)
-  {
-    if (1 == inet_pton (AF_INET6, ipv6, &i6))
-    {
-      memset (&v6, 0, sizeof (v6));
-      v6.sin6_family = AF_INET6;
-      v6.sin6_addr = i6;
-      v6.sin6_port = htons (port);
-#if HAVE_SOCKADDR_IN_SIN_LEN
-      v6.sin6_len = sizeof (v6);
-#endif
-      sa6 = (const struct sockaddr *) &v6;
-    }
-    else
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _("`%s' is not a valid IPv6 address! Ignoring 
BINDTOIPV6.\n"),
-                  ipv6);
-    GNUNET_free (ipv6);
-  }
-
-  daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 | MHD_USE_DEBUG,
-                                       (uint16_t) port,
-                                       &accept_policy_callback, NULL,
-                                       &access_handler_callback, NULL,
-                                       MHD_OPTION_CONNECTION_LIMIT,
-                                       (unsigned int) 16,
-                                       MHD_OPTION_PER_IP_CONNECTION_LIMIT,
-                                       (unsigned int) 1,
-                                       MHD_OPTION_CONNECTION_TIMEOUT,
-                                       (unsigned int) 16,
-                                       MHD_OPTION_CONNECTION_MEMORY_LIMIT,
-                                       (size_t) (16 * 1024),
-                                       MHD_OPTION_SOCK_ADDR,
-                                       sa6,
-                                       MHD_OPTION_END);
-  daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG | MHD_USE_DEBUG,
-                                      (uint16_t) port,
-                                       &accept_policy_callback, NULL,
-                                       &access_handler_callback, NULL,
-                                       MHD_OPTION_CONNECTION_LIMIT,
-                                       (unsigned int) 16,
-                                       MHD_OPTION_PER_IP_CONNECTION_LIMIT,
-                                       (unsigned int) 1,
-                                       MHD_OPTION_CONNECTION_TIMEOUT,
-                                       (unsigned int) 16,
-                                       MHD_OPTION_CONNECTION_MEMORY_LIMIT,
-                                       (size_t) (16 * 1024),
-                                       MHD_OPTION_SOCK_ADDR,
-                                       sa4,
-                                       MHD_OPTION_END);
-
-  if ( (NULL == daemon_handle_v6) &&
-       (NULL == daemon_handle_v4) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Could not start hostlist HTTP server on port %u\n"),
-                (unsigned short) port);
-    return GNUNET_SYSERR;
-  }
-
-  core = co;
-  *server_ch = &connect_handler;
-  *server_dh = &disconnect_handler;
-  if (NULL != daemon_handle_v4)
-    hostlist_task_v4 = prepare_daemon (daemon_handle_v4);
-  if (NULL != daemon_handle_v6)
-    hostlist_task_v6 = prepare_daemon (daemon_handle_v6);
-  notify = GNUNET_PEERINFO_notify (cfg, GNUNET_NO,
-                                   &process_notify, NULL);
-  return GNUNET_OK;
-}
-
-
-/**
- * Stop server offering our hostlist.
- */
-void
-GNUNET_HOSTLIST_server_stop ()
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n");
-  if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6)
-  {
-    GNUNET_SCHEDULER_cancel (hostlist_task_v6);
-    hostlist_task_v6 = GNUNET_SCHEDULER_NO_TASK;
-  }
-  if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v4)
-  {
-    GNUNET_SCHEDULER_cancel (hostlist_task_v4);
-    hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK;
-  }
-  if (NULL != daemon_handle_v4)
-  {
-    MHD_stop_daemon (daemon_handle_v4);
-    daemon_handle_v4 = NULL;
-  }
-  if (NULL != daemon_handle_v6)
-  {
-    MHD_stop_daemon (daemon_handle_v6);
-    daemon_handle_v6 = NULL;
-  }
-  if (NULL != response)
-  {
-    MHD_destroy_response (response);
-    response = NULL;
-  }
-  if (NULL != notify)
-  {
-    GNUNET_PEERINFO_notify_cancel (notify);
-    notify = NULL;
-  }
-  if (NULL != builder)
-  {
-    GNUNET_PEERINFO_iterate_cancel (builder->pitr);
-    builder->pitr = NULL;
-    GNUNET_free_non_null (builder->data);
-    GNUNET_free (builder);
-  }
-  if (NULL != peerinfo)
-  {
-    GNUNET_PEERINFO_disconnect (peerinfo);
-    peerinfo = NULL;
-  }
-  cfg = NULL;
-  stats = NULL;
-  core = NULL;
-}
-
-/* end of hostlist-server.c */

Deleted: gnunet/src/hostlist/hostlist-server.h
===================================================================
--- gnunet/src/hostlist/hostlist-server.h       2014-06-03 08:19:03 UTC (rev 
33488)
+++ gnunet/src/hostlist/hostlist-server.h       2014-06-03 08:41:00 UTC (rev 
33489)
@@ -1,58 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2009 Christian Grothoff (and other contributing authors)
-
-     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 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file hostlist/hostlist-server.h
- * @brief hostlist support.  Downloads HELLOs via HTTP.
- * @author Christian Grothoff
- */
-
-#ifndef HOSTLIST_SERVER_H
-#define HOSTLIST_SERVER_H
-
-#include "gnunet_core_service.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet_util_lib.h"
-
-#define GNUNET_ADV_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MINUTES, 5)
-
-/**
- * Start server offering our hostlist.
- *
- * @return GNUNET_OK on success
- */
-int
-GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
-                              struct GNUNET_STATISTICS_Handle *st,
-                              struct GNUNET_CORE_Handle *core,
-                              GNUNET_CORE_ConnectEventHandler *server_ch,
-                              GNUNET_CORE_DisconnectEventHandler *server_dh,
-                              int advertise);
-
-
-/**
- * Stop server offering our hostlist.
- */
-void
-GNUNET_HOSTLIST_server_stop (void);
-
-
-#endif
-/* end of hostlist-server.h */

Modified: gnunet/src/hostlist/test_gnunet_daemon_hostlist_learning.c
===================================================================
--- gnunet/src/hostlist/test_gnunet_daemon_hostlist_learning.c  2014-06-03 
08:19:03 UTC (rev 33488)
+++ gnunet/src/hostlist/test_gnunet_daemon_hostlist_learning.c  2014-06-03 
08:41:00 UTC (rev 33489)
@@ -37,7 +37,7 @@
  */
 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 180)
 
-#define CHECK_INTERVALL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 1)
+#define CHECK_INTERVAL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 1)
 
 
 struct PeerContext
@@ -304,7 +304,7 @@
                                &process_adv_sent, NULL);
   }
   check_task =
-      GNUNET_SCHEDULER_add_delayed (CHECK_INTERVALL, &check_statistics, NULL);
+      GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL, &check_statistics, NULL);
 }
 
 
@@ -452,7 +452,7 @@
   timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_error, NULL);
 
   check_task =
-      GNUNET_SCHEDULER_add_delayed (CHECK_INTERVALL, &check_statistics, NULL);
+      GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL, &check_statistics, NULL);
 }
 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]