gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] 06/06: misc fixes to gnunet-gns-proxy, in particul


From: gnunet
Subject: [GNUnet-SVN] [gnunet] 06/06: misc fixes to gnunet-gns-proxy, in particular avoiding MHD-busy waiting
Date: Thu, 08 Mar 2018 15:50:26 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

commit 310d0f559656343c4fd849fa517a054c31b24a4e
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Mar 8 15:50:18 2018 +0100

    misc fixes to gnunet-gns-proxy, in particular avoiding MHD-busy waiting
---
 src/gns/gns_tld_api.c            |  12 +-
 src/gns/gnunet-gns-proxy.c       | 298 ++++++++++++++++++++++++++++++---------
 src/gns/gnunet-gns.c             |   7 +-
 src/gns/plugin_rest_gns.c        |  25 ++--
 src/include/gnunet_gns_service.h |   2 +-
 5 files changed, 253 insertions(+), 91 deletions(-)

diff --git a/src/gns/gns_tld_api.c b/src/gns/gns_tld_api.c
index c78afa572..293e37140 100644
--- a/src/gns/gns_tld_api.c
+++ b/src/gns/gns_tld_api.c
@@ -57,9 +57,9 @@ struct GNUNET_GNS_LookupWithTldRequest
 
   /**
    * Domain name we are resolving.
-   */ 
+   */
   char *name;
-  
+
   /**
    * @e lookup_proc closure
    */
@@ -82,7 +82,7 @@ struct GNUNET_GNS_LookupWithTldRequest
 
   /**
    * Lookup options.
-   */ 
+   */
   enum GNUNET_GNS_LocalOptions options;
 };
 
@@ -144,7 +144,7 @@ process_lookup_result (void *cls,
 {
   struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
 
-  ltr->lr = NULL;  
+  ltr->lr = NULL;
   ltr->lookup_proc (ltr->lookup_proc_cls,
                    GNUNET_YES,
                    rd_count,
@@ -291,10 +291,12 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle 
*handle,
   /* Final case: TLD matches one of our egos */
   eat_tld (ltr->name);
 
-  /* if the name is of the form 'label.gnu', never go to the DHT */
+  /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go 
to the DHT */
   if (NULL == strchr (ltr->name,
                       (unsigned char) '.'))
     ltr->options = GNUNET_GNS_LO_NO_DHT;
+  else
+    ltr->options = GNUNET_GNS_LO_LOCAL_MASTER;
   ltr->id_op = GNUNET_IDENTITY_ego_lookup (ltr->gns_handle->cfg,
                                           tld,
                                           &identity_zone_cb,
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 83518fcd7..ce06ccebe 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -485,17 +485,17 @@ struct Socks5Request
   /**
    * Client socket read task
    */
-  struct GNUNET_SCHEDULER_Task * rtask;
+  struct GNUNET_SCHEDULER_Task *rtask;
 
   /**
    * Client socket write task
    */
-  struct GNUNET_SCHEDULER_Task * wtask;
+  struct GNUNET_SCHEDULER_Task *wtask;
 
   /**
    * Timeout task
    */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
+  struct GNUNET_SCHEDULER_Task *timeout_task;
 
   /**
    * Read buffer
@@ -518,6 +518,11 @@ struct Socks5Request
   struct MhdHttpList *hd;
 
   /**
+   * MHD connection for this request.
+   */
+  struct MHD_Connection *con;
+
+  /**
    * MHD response object for this request.
    */
   struct MHD_Response *response;
@@ -611,6 +616,16 @@ struct Socks5Request
    * SSL Certificate status
    */
   int ssl_checked;
+
+  /**
+   * Was the hostname resolved via GNS?
+   */
+  int is_gns;
+
+  /**
+   * Did we suspend MHD processing?
+   */
+  int suspended;
 };
 
 
@@ -731,10 +746,16 @@ cleanup_s5r (struct Socks5Request *s5r)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Cleaning up cURL handle\n");
-    curl_multi_remove_handle (curl_multi, s5r->curl);
+    curl_multi_remove_handle (curl_multi,
+                              s5r->curl);
     curl_easy_cleanup (s5r->curl);
     s5r->curl = NULL;
   }
+  if (s5r->suspended)
+  {
+    s5r->suspended = GNUNET_NO;
+    MHD_resume_connection (s5r->con);
+  }
   curl_slist_free_all (s5r->headers);
   if (NULL != s5r->hosts)
   {
@@ -774,6 +795,7 @@ cleanup_s5r (struct Socks5Request *s5r)
 static void
 curl_download_prepare ();
 
+
 /**
  * Callback for MHD response generation.  This function is called from
  * MHD whenever MHD expects to get data back.  Copies data from the
@@ -813,9 +835,16 @@ mhd_content_cb (void *cls,
                "Pausing MHD download, no data available\n");
     if (NULL != s5r->curl)
     {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Continuing CURL interaction\n");
       curl_easy_pause (s5r->curl, CURLPAUSE_CONT);
       curl_download_prepare ();
     }
+    if (GNUNET_NO == s5r->suspended)
+    {
+      MHD_suspend_connection (s5r->con);
+      s5r->suspended = GNUNET_YES;
+    }
     return 0; /* more data later */
   }
   if ( (0 == bytes_to_copy) &&
@@ -826,14 +855,23 @@ mhd_content_cb (void *cls,
     return MHD_CONTENT_READER_END_OF_STREAM;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Writing %lu/%lu bytes\n", bytes_to_copy, s5r->io_len);
-  GNUNET_memcpy (buf, s5r->io_buf, bytes_to_copy);
+              "Writing %lu/%lu bytes\n",
+              bytes_to_copy,
+              s5r->io_len);
+  GNUNET_memcpy (buf,
+                 s5r->io_buf,
+                 bytes_to_copy);
   memmove (s5r->io_buf,
           &s5r->io_buf[bytes_to_copy],
           s5r->io_len - bytes_to_copy);
   s5r->io_len -= bytes_to_copy;
   if (NULL != s5r->curl)
-    curl_easy_pause (s5r->curl, CURLPAUSE_CONT);
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Continuing CURL interaction\n");
+    curl_easy_pause (s5r->curl,
+                     CURLPAUSE_CONT);
+  }
   return bytes_to_copy;
 }
 
@@ -1028,12 +1066,14 @@ curl_check_hdr (void *buffer,
   int domain_matched;
   char *tok;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Receiving HTTP response header from CURL\n");
   /* first, check SSL certificate */
-  if ((GNUNET_YES != s5r->ssl_checked) &&
-      (HTTPS_PORT == s5r->port))
+  if ( (GNUNET_YES != s5r->ssl_checked) &&
+       (HTTPS_PORT == s5r->port))
   {
-      if (GNUNET_OK != check_ssl_certificate (s5r))
-        return 0;
+    if (GNUNET_OK != check_ssl_certificate (s5r))
+      return 0;
   }
 
   ndup = GNUNET_strndup (buffer, bytes);
@@ -1181,8 +1221,11 @@ create_mhd_response_from_s5r (struct Socks5Request *s5r)
                                    CURLINFO_CONTENT_LENGTH_DOWNLOAD,
                                    &content_length));
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Creating MHD response with code %d and size %d\n",
-              (int) resp_code, (int) content_length);
+              "Creating MHD response with code %d and size %d for %s%s\n",
+              (int) resp_code,
+              (int) content_length,
+              s5r->domain,
+              s5r->url);
   s5r->response_code = resp_code;
   s5r->response = MHD_create_response_from_callback ((-1 == content_length) ? 
MHD_SIZE_UNKNOWN : content_length,
                                                      IO_BUFFERSIZE,
@@ -1221,6 +1264,8 @@ create_mhd_response_from_s5r (struct Socks5Request *s5r)
     MHD_add_response_header (s5r->response,
     MHD_HTTP_HEADER_CONNECTION,
     "close"));*/
+  MHD_resume_connection (s5r->con);
+  s5r->suspended = GNUNET_NO;
   return GNUNET_OK;
 }
 
@@ -1244,7 +1289,8 @@ curl_download_cb (void *ptr,
   size_t total = size * nmemb;
 
   if (NULL == s5r->response)
-    GNUNET_assert (GNUNET_OK == create_mhd_response_from_s5r (s5r));
+    GNUNET_assert (GNUNET_OK ==
+                   create_mhd_response_from_s5r (s5r));
 
   if ( (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) ||
        (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) )
@@ -1253,20 +1299,35 @@ curl_download_cb (void *ptr,
        start the download, the IO buffer is still full
        with upload data. */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Pausing CURL download, waiting for UPLOAD to finish\n");
+                "Pausing CURL download `%s%s', waiting for UPLOAD to finish\n",
+                s5r->domain,
+                s5r->url);
     return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */
   }
   if (sizeof (s5r->io_buf) - s5r->io_len < total)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Pausing CURL download, not enough space %lu %lu %lu\n", 
sizeof (s5r->io_buf),
-                s5r->io_len, total);
+                "Pausing CURL `%s%s' download, not enough space %lu %lu %lu\n",
+                s5r->domain,
+                s5r->url,
+                sizeof (s5r->io_buf),
+                s5r->io_len,
+                total);
     return CURL_WRITEFUNC_PAUSE; /* not enough space */
   }
   GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
                  ptr,
                  total);
   s5r->io_len += total;
+  if (GNUNET_YES == s5r->suspended)
+  {
+    MHD_resume_connection (s5r->con);
+    s5r->suspended = GNUNET_NO;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received %llu bytes of payload via cURL from %s\n",
+              (unsigned long long) total,
+              s5r->domain);
   if (s5r->io_len == total)
     run_mhd_now (s5r->hd);
   return total;
@@ -1297,7 +1358,9 @@ curl_upload_cb (void *buf,
        (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Pausing CURL UPLOAD, need more data\n");
+                "Pausing CURL UPLOAD %s%s, need more data\n",
+                s5r->domain,
+                s5r->url);
     return CURL_READFUNC_PAUSE;
   }
   if ( (0 == s5r->io_len) &&
@@ -1305,7 +1368,9 @@ curl_upload_cb (void *buf,
   {
     s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Completed CURL UPLOAD\n");
+                "Completed CURL UPLOAD %s%s\n",
+                s5r->domain,
+                s5r->url);
     return 0; /* upload finished, can now download */
   }
   if ( (SOCKS5_SOCKET_UPLOAD_STARTED != s5r->state) &&
@@ -1356,6 +1421,8 @@ curl_download_prepare ()
   long to;
   struct GNUNET_TIME_Relative rtime;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Scheduling CURL interaction\n");
   if (NULL != curl_download_task)
   {
     GNUNET_SCHEDULER_cancel (curl_download_task);
@@ -1365,7 +1432,11 @@ curl_download_prepare ()
   FD_ZERO (&rs);
   FD_ZERO (&ws);
   FD_ZERO (&es);
-  if (CURLM_OK != (mret = curl_multi_fdset (curl_multi, &rs, &ws, &es, &max)))
+  if (CURLM_OK != (mret = curl_multi_fdset (curl_multi,
+                                            &rs,
+                                            &ws,
+                                            &es,
+                                            &max)))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "%s failed at %s:%d: `%s'\n",
@@ -1388,7 +1459,8 @@ curl_download_prepare ()
     curl_download_task = GNUNET_SCHEDULER_add_select 
(GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                                                       rtime,
                                                       grs, gws,
-                                                      &curl_task_download, 
curl_multi);
+                                                      &curl_task_download,
+                                                      curl_multi);
     GNUNET_NETWORK_fdset_destroy (gws);
     GNUNET_NETWORK_fdset_destroy (grs);
   }
@@ -1416,11 +1488,15 @@ curl_task_download (void *cls)
   struct Socks5Request *s5r;
 
   curl_download_task = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Running CURL interaction\n");
   do
   {
     running = 0;
-    mret = curl_multi_perform (curl_multi, &running);
-    while (NULL != (msg = curl_multi_info_read (curl_multi, &msgnum)))
+    mret = curl_multi_perform (curl_multi,
+                               &running);
+    while (NULL != (msg = curl_multi_info_read (curl_multi,
+                                                &msgnum)))
     {
       GNUNET_break (CURLE_OK ==
                     curl_easy_getinfo (msg->easy_handle,
@@ -1443,15 +1519,22 @@ curl_task_download (void *cls)
             case CURLE_OK:
             case CURLE_GOT_NOTHING:
               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                          "CURL download completed.\n");
+                          "CURL download %s%s completed.\n",
+                          s5r->domain,
+                          s5r->url);
               if (NULL == s5r->response)
-                GNUNET_assert (GNUNET_OK == create_mhd_response_from_s5r 
(s5r));
+              {
+                GNUNET_assert (GNUNET_OK ==
+                               create_mhd_response_from_s5r (s5r));
+              }
               s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
               run_mhd_now (s5r->hd);
               break;
             default:
               GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                          "Download curl failed: %s\n",
+                          "Download curl %s%s failed: %s\n",
+                          s5r->domain,
+                          s5r->url,
                           curl_easy_strerror (msg->data.result));
               /* FIXME: indicate error somehow? close MHD connection badly as 
well? */
               s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
@@ -1481,6 +1564,11 @@ curl_task_download (void *cls)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Suspending cURL multi loop, no more events pending\n");
+    if (NULL != curl_download_task)
+    {
+      GNUNET_SCHEDULER_cancel (curl_download_task);
+      curl_download_task = NULL;
+    }
     return; /* nothing more in progress */
   }
   curl_download_prepare ();
@@ -1568,7 +1656,6 @@ create_response (void *cls,
 {
   struct Socks5Request *s5r = *con_cls;
   char *curlurl;
-  char *curl_hosts;
   char ipstring[INET6_ADDRSTRLEN];
   char ipaddr[INET6_ADDRSTRLEN + 2];
   const struct sockaddr *sa;
@@ -1582,13 +1669,16 @@ create_response (void *cls,
     GNUNET_break (0);
     return MHD_NO;
   }
+  s5r->con = con;
   //Fresh connection.
   if (SOCKS5_SOCKET_WITH_MHD == s5r->state)
   {
     /* first time here, initialize curl handle */
-    sa = (const struct sockaddr *) &s5r->destination_address;
-    switch (sa->sa_family)
+    if (s5r->is_gns)
     {
+      sa = (const struct sockaddr *) &s5r->destination_address;
+      switch (sa->sa_family)
+      {
       case AF_INET:
         s4 = (const struct sockaddr_in *) &s5r->destination_address;
         if (NULL == inet_ntop (AF_INET,
@@ -1624,6 +1714,11 @@ create_response (void *cls,
       default:
         GNUNET_break (0);
         return MHD_NO;
+      }
+    }
+    else
+    {
+      port = s5r->port;
     }
     if (NULL == s5r->curl)
       s5r->curl = curl_easy_init ();
@@ -1634,7 +1729,10 @@ create_response (void *cls,
     curl_easy_setopt (s5r->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr);
     curl_easy_setopt (s5r->curl, CURLOPT_HEADERDATA, s5r);
     curl_easy_setopt (s5r->curl, CURLOPT_FOLLOWLOCATION, 0);
-    curl_easy_setopt (s5r->curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+    if (s5r->is_gns)
+      curl_easy_setopt (s5r->curl,
+                        CURLOPT_IPRESOLVE,
+                        CURL_IPRESOLVE_V4);
     curl_easy_setopt (s5r->curl, CURLOPT_CONNECTTIMEOUT, 600L);
     curl_easy_setopt (s5r->curl, CURLOPT_TIMEOUT, 600L);
     curl_easy_setopt (s5r->curl, CURLOPT_NOSIGNAL, 1L);
@@ -1642,7 +1740,7 @@ create_response (void *cls,
     curl_easy_setopt (s5r->curl, CURLOPT_HTTP_TRANSFER_DECODING, 0);
     curl_easy_setopt (s5r->curl, CURLOPT_NOSIGNAL, 1L);
     curl_easy_setopt (s5r->curl, CURLOPT_PRIVATE, s5r);
-    curl_easy_setopt (s5r->curl, CURLOPT_VERBOSE, 0);
+    curl_easy_setopt (s5r->curl, CURLOPT_VERBOSE, 0L);
     /**
      * Pre-populate cache to resolve Hostname.
      * This is necessary as the DNS name in the CURLOPT_URL is used
@@ -1650,32 +1748,55 @@ create_response (void *cls,
      */
     if (NULL != s5r->leho)
     {
+      char *curl_hosts;
+
       GNUNET_asprintf (&curl_hosts,
                        "%s:%d:%s",
                        s5r->leho,
                        port,
                        ipaddr);
-      s5r->hosts = curl_slist_append(NULL, curl_hosts);
-      curl_easy_setopt(s5r->curl, CURLOPT_RESOLVE, s5r->hosts);
+      s5r->hosts = curl_slist_append (NULL,
+                                      curl_hosts);
+      curl_easy_setopt (s5r->curl,
+                        CURLOPT_RESOLVE,
+                        s5r->hosts);
       GNUNET_free (curl_hosts);
     }
-    GNUNET_asprintf (&curlurl,
-                     (HTTPS_PORT != s5r->port)
-                     ? "http://%s:%d%s";
-                     : "https://%s:%d%s";,
-                     (NULL != s5r->leho)
-                     ? s5r->leho
-                     : ipaddr,
-                     port,
-                     s5r->url);
+    if (s5r->is_gns)
+    {
+      GNUNET_asprintf (&curlurl,
+                       (HTTPS_PORT != s5r->port)
+                       ? "http://%s:%d%s";
+                       : "https://%s:%d%s";,
+                       (NULL != s5r->leho)
+                       ? s5r->leho
+                       : ipaddr,
+                       port,
+                       s5r->url);
+    }
+    else
+    {
+      GNUNET_asprintf (&curlurl,
+                       (HTTPS_PORT != s5r->port)
+                       ? "http://%s:%d%s";
+                       : "https://%s:%d%s";,
+                       s5r->domain,
+                       port,
+                       s5r->url);
+    }
     curl_easy_setopt (s5r->curl,
                       CURLOPT_URL,
                       curlurl);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Launching %s CURL interaction, fetching `%s'\n",
+                (s5r->is_gns) ? "GNS" : "DNS",
+                curlurl);
     GNUNET_free (curlurl);
-    if (0 == strcasecmp (meth, MHD_HTTP_METHOD_PUT))
+    if (0 == strcasecmp (meth,
+                         MHD_HTTP_METHOD_PUT))
     {
       s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
-      curl_easy_setopt (s5r->curl, CURLOPT_UPLOAD, 1);
+      curl_easy_setopt (s5r->curl, CURLOPT_UPLOAD, 1L);
       curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb);
       curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r);
       curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb);
@@ -1685,7 +1806,7 @@ create_response (void *cls,
     {
       s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
       curl_easy_setopt (s5r->curl, CURLOPT_POST, 1L);
-            curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, 
&curl_download_cb);
+      curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb);
       curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r);
       curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb);
       curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r);
@@ -1693,7 +1814,7 @@ create_response (void *cls,
     else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_HEAD))
     {
       s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
-      curl_easy_setopt (s5r->curl, CURLOPT_NOBODY, 1);
+      curl_easy_setopt (s5r->curl, CURLOPT_NOBODY, 1L);
     }
     else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_OPTIONS))
     {
@@ -1703,7 +1824,7 @@ create_response (void *cls,
     else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_GET))
     {
       s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
-      curl_easy_setopt (s5r->curl, CURLOPT_HTTPGET, 1);
+      curl_easy_setopt (s5r->curl, CURLOPT_HTTPGET, 1L);
       curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb);
       curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r);
     }
@@ -1746,7 +1867,9 @@ create_response (void *cls,
       curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_NONE);
     }
 
-    if (CURLM_OK != curl_multi_add_handle (curl_multi, s5r->curl))
+    if (CURLM_OK !=
+        curl_multi_add_handle (curl_multi,
+                               s5r->curl))
     {
       GNUNET_break (0);
       curl_easy_cleanup (s5r->curl);
@@ -1755,8 +1878,11 @@ create_response (void *cls,
     }
     MHD_get_connection_values (con,
                                MHD_HEADER_KIND,
-                               &con_val_iter, s5r);
-    curl_easy_setopt (s5r->curl, CURLOPT_HTTPHEADER, s5r->headers);
+                               &con_val_iter,
+                               s5r);
+    curl_easy_setopt (s5r->curl,
+                      CURLOPT_HTTPHEADER,
+                      s5r->headers);
     curl_download_prepare ();
     return MHD_YES;
   }
@@ -1764,7 +1890,6 @@ create_response (void *cls,
   /* continuing to process request */
   if (0 != *upload_data_size)
   {
-
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Processing %u bytes UPLOAD\n",
                (unsigned int) *upload_data_size);
@@ -1782,7 +1907,8 @@ create_response (void *cls,
     s5r->io_len += left;
     *upload_data_size -= left;
     GNUNET_assert (NULL != s5r->curl);
-    curl_easy_pause (s5r->curl, CURLPAUSE_CONT);
+    curl_easy_pause (s5r->curl,
+                     CURLPAUSE_CONT);
     return MHD_YES;
   }
   if (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state)
@@ -1792,9 +1918,19 @@ create_response (void *cls,
     s5r->state = SOCKS5_SOCKET_UPLOAD_DONE;
   }
   if (NULL == s5r->response)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Waiting for HTTP response for %s%s...\n",
+                s5r->domain,
+                s5r->url);
+    MHD_suspend_connection (con);
+    s5r->suspended = GNUNET_YES;
     return MHD_YES;
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Queueing response with MHD\n");
+              "Queueing response for %s%s with MHD\n",
+              s5r->domain,
+              s5r->url);
   run_mhd_now (s5r->hd);
   return MHD_queue_response (con,
                              s5r->response_code,
@@ -1821,7 +1957,6 @@ mhd_completed_cb (void *cls,
                   enum MHD_RequestTerminationCode toe)
 {
   struct Socks5Request *s5r = *con_cls;
-  struct HttpResponseHeader *header;
 
   if (NULL == s5r)
     return;
@@ -1832,19 +1967,23 @@ mhd_completed_cb (void *cls,
   if (NULL != s5r->curl)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Resetting cURL handle\n");
-    curl_multi_remove_handle (curl_multi, s5r->curl);
+                "Removing cURL handle (MHD interaction complete)\n");
+    curl_multi_remove_handle (curl_multi,
+                              s5r->curl);
     curl_slist_free_all (s5r->headers);
     s5r->headers = NULL;
     curl_easy_reset (s5r->curl);
     s5r->rbuf_len = 0;
     s5r->wbuf_len = 0;
     s5r->io_len = 0;
+    curl_download_prepare ();
   }
   if ( (NULL != s5r->response) &&
        (curl_failure_response != s5r->response) )
     MHD_destroy_response (s5r->response);
-  for (header = s5r->header_head; header != NULL; header = s5r->header_head)
+  for (struct HttpResponseHeader *header = s5r->header_head;
+       NULL != header;
+       header = s5r->header_head)
   {
     GNUNET_CONTAINER_DLL_remove (s5r->header_head,
                                  s5r->header_tail,
@@ -1853,7 +1992,9 @@ mhd_completed_cb (void *cls,
     GNUNET_free (header->value);
     GNUNET_free (header);
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished request for %s\n", s5r->url);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Finished request for %s\n",
+              s5r->url);
   GNUNET_free (s5r->url);
   s5r->state = SOCKS5_SOCKET_WITH_MHD;
   s5r->url = NULL;
@@ -2043,12 +2184,18 @@ schedule_httpd (struct MhdHttpList *hd)
   FD_ZERO (&ws);
   FD_ZERO (&es);
   max = -1;
-  if (MHD_YES != MHD_get_fdset (hd->daemon, &rs, &ws, &es, &max))
+  if (MHD_YES !=
+      MHD_get_fdset (hd->daemon,
+                     &rs,
+                     &ws,
+                     &es,
+                     &max))
   {
     kill_httpd (hd);
     return;
   }
-  haveto = MHD_get_timeout (hd->daemon, &timeout);
+  haveto = MHD_get_timeout (hd->daemon,
+                            &timeout);
   if (MHD_YES == haveto)
     tv.rel_value_us = (uint64_t) timeout * 1000LL;
   else
@@ -2146,7 +2293,10 @@ load_file (const char* filename,
     return NULL;
   *size = (unsigned int) fsize;
   buffer = GNUNET_malloc (*size);
-  if (fsize != GNUNET_DISK_fn_read (filename, buffer, (size_t) fsize))
+  if (fsize !=
+      GNUNET_DISK_fn_read (filename,
+                           buffer,
+                           (size_t) fsize))
   {
     GNUNET_free (buffer);
     return NULL;
@@ -2317,7 +2467,7 @@ lookup_ssl_httpd (const char* domain)
   hd->is_ssl = GNUNET_YES;
   hd->domain = GNUNET_strdup (domain);
   hd->proxy_cert = pgc;
-  hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | 
MHD_USE_NO_LISTEN_SOCKET,
+  hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | 
MHD_USE_NO_LISTEN_SOCKET | MHD_ALLOW_SUSPEND_RESUME,
                                  0,
                                  NULL, NULL,
                                  &create_response, hd,
@@ -2546,6 +2696,7 @@ signal_socks_success (struct Socks5Request *s5r)
  * Process GNS results for target domain.
  *
  * @param cls the `struct Socks5Request *`
+ * @param tld #GNUNET_YES if this was a GNS TLD.
  * @param rd_count number of records returned
  * @param rd record data
  */
@@ -2556,13 +2707,13 @@ handle_gns_result (void *cls,
                    const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct Socks5Request *s5r = cls;
-  uint32_t i;
   const struct GNUNET_GNSRECORD_Data *r;
   int got_ip;
 
   s5r->gns_lookup = NULL;
+  s5r->is_gns = tld;
   got_ip = GNUNET_NO;
-  for (i=0;i<rd_count;i++)
+  for (uint32_t i=0;i<rd_count;i++)
   {
     r = &rd[i];
     switch (r->record_type)
@@ -2655,7 +2806,8 @@ handle_gns_result (void *cls,
         break;
     }
   }
-  if (GNUNET_YES != got_ip)
+  if ( (GNUNET_YES != got_ip) &&
+       (GNUNET_YES == tld) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Name resolution failed to yield useful IP address.\n");
@@ -2844,7 +2996,8 @@ do_s5r_read (void *cls)
               return; /* need more data */
             dom_name = (const char *) &dom_len[1];
             port = (const uint16_t*) &dom_name[*dom_len];
-            s5r->domain = GNUNET_strndup (dom_name, *dom_len);
+            s5r->domain = GNUNET_strndup (dom_name,
+                                          *dom_len);
             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                         "Requested connection is to %s:%d\n",
                         s5r->domain,
@@ -2957,6 +3110,17 @@ do_shutdown (void *cls)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Shutting down...\n");
+  /* MHD requires resuming before destroying the daemons */
+  for (struct Socks5Request *s5r = s5r_head;
+       NULL != s5r;
+       s5r = s5r->next)
+  {
+    if (s5r->suspended)
+    {
+      s5r->suspended = GNUNET_NO;
+      MHD_resume_connection (s5r->con);
+    }
+  }
   while (NULL != mhd_httpd_head)
     kill_httpd (mhd_httpd_head);
   while (NULL != s5r_head)
@@ -3222,7 +3386,7 @@ run (void *cls,
 
   /* start MHD daemon for HTTP */
   hd = GNUNET_new (struct MhdHttpList);
-  hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET,
+  hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET | 
MHD_ALLOW_SUSPEND_RESUME,
                                  0,
                                  NULL, NULL,
                                  &create_response, hd,
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c
index 771a7dcc8..34f6e2c82 100644
--- a/src/gns/gnunet-gns.c
+++ b/src/gns/gnunet-gns.c
@@ -50,11 +50,6 @@ static char *lookup_name;
 static char *lookup_type;
 
 /**
- * Set to GNUNET_GNS_LO_LOCAL_MASTER if we are looking up in the master zone.
- */
-static enum GNUNET_GNS_LocalOptions local_options;
-
-/**
  * raw output
  */
 static int raw;
@@ -207,7 +202,7 @@ run (void *cls,
   lr = GNUNET_GNS_lookup_with_tld (gns,
                                   lookup_name,
                                   rtype,
-                                  local_options,
+                                  GNUNET_GNS_LO_DEFAULT,
                                   &process_lookup_result,
                                   lookup_name);
   if (NULL == lr)
diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c
index b7775e4ea..1d215b6a4 100644
--- a/src/gns/plugin_rest_gns.c
+++ b/src/gns/plugin_rest_gns.c
@@ -423,7 +423,8 @@ identity_master_cb (void *cls,
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_IDENTITY_ego_get_public_key (ego, &handle->pkey);
+  GNUNET_IDENTITY_ego_get_public_key (ego,
+                                      &handle->pkey);
   /* main name is our own master zone, do no look for that in the DHT */
   handle->options = GNUNET_GNS_LO_LOCAL_MASTER;
   /* if the name is of the form 'label.gnu', never go to the DHT */
@@ -465,6 +466,7 @@ parse_url (const char *url, struct LookupHandle *handle)
   return GNUNET_OK;
 }
 
+
 static void
 get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
               const char* url,
@@ -610,14 +612,19 @@ options_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
  * @param data body of the HTTP request (optional)
  * @param data_size length of the body
  * @param proc callback function for the result
- * @param proc_cls closure for callback function
- * @return GNUNET_OK if request accepted
+ * @param proc_cls closure for @a proc
+ * @return #GNUNET_OK if request accepted
  */
 static void
-rest_gns_process_request(struct GNUNET_REST_RequestHandle *conndata_handle,
-                         GNUNET_REST_ResultProcessor proc,
-                         void *proc_cls)
+rest_gns_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
+                          GNUNET_REST_ResultProcessor proc,
+                          void *proc_cls)
 {
+  static const struct GNUNET_REST_RequestHandler handlers[] = {
+    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont},
+    {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont},
+    GNUNET_REST_HANDLER_END
+  };
   struct LookupHandle *handle = GNUNET_new (struct LookupHandle);
   struct GNUNET_REST_RequestHandlerError err;
 
@@ -626,12 +633,6 @@ rest_gns_process_request(struct GNUNET_REST_RequestHandle 
*conndata_handle,
   handle->proc = proc;
   handle->rest_handle = conndata_handle;
 
-  static const struct GNUNET_REST_RequestHandler handlers[] = {
-    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont},
-    {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont},
-    GNUNET_REST_HANDLER_END
-  };
-
   if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle,
                                                   handlers,
                                                   &err,
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h
index 1eb67ed50..8c1f64783 100644
--- a/src/include/gnunet_gns_service.h
+++ b/src/include/gnunet_gns_service.h
@@ -122,7 +122,7 @@ enum GNUNET_GNS_LocalOptions
 
   /**
    * For the rightmost label, only look in the cache (it
-   * is our master zone), for the others, the DHT is OK.
+   * is our local namestore), for the others, the DHT is OK.
    */
   GNUNET_GNS_LO_LOCAL_MASTER = 2
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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