flip LSD0001 defines
[oweals/gnunet.git] / src / gns / gnunet-service-gns_resolver.c
index 0d04fc6b9c290db738e052c00c1d2374043e68a1..dac0ab16a5c63cd560335b376b6329370b3cce5a 100644 (file)
@@ -2,21 +2,21 @@
      This file is part of GNUnet.
      Copyright (C) 2011-2013 GNUnet e.V.
 
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     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.
+     Affero 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., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
 
 /**
  * @file gns/gnunet-service-gns_resolver.c
  * @author Christian Grothoff
  */
 #include "platform.h"
+#if HAVE_LIBIDN2
+#if HAVE_IDN2_H
+#include <idn2.h>
+#elif HAVE_IDN2_IDN2_H
+#include <idn2/idn2.h>
+#endif
+#elif HAVE_LIBIDN
+#if HAVE_IDNA_H
+#include <idna.h>
+#elif HAVE_IDN_IDNA_H
+#include <idn/idna.h>
+#endif
+#endif
 #include "gnunet_util_lib.h"
 #include "gnunet_dnsstub_lib.h"
 #include "gnunet_dht_service.h"
 /**
  * Default DHT timeout for lookups.
  */
-#define DHT_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
+#define DHT_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply ( \
+    GNUNET_TIME_UNIT_SECONDS, 60)
 
 /**
  * Default timeout for DNS lookups.
  */
-#define DNS_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
+#define DNS_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply ( \
+    GNUNET_TIME_UNIT_SECONDS, 15)
 
 /**
  * Default timeout for VPN redirections.
@@ -82,7 +97,6 @@ struct AuthorityChain;
  */
 struct Gns2DnsPending
 {
-
   /**
    * Kept in a DLL.
    */
@@ -161,7 +175,6 @@ struct AuthorityChain
    */
   union
   {
-
     /**
      * The zone of the GNS authority
      */
@@ -203,11 +216,8 @@ struct AuthorityChain
        * Did we start the recursive resolution via DNS?
        */
       int launched;
-
     } dns_authority;
-
   } authority_info;
-
 };
 
 
@@ -216,7 +226,6 @@ struct AuthorityChain
  */
 struct DnsResult
 {
-
   /**
    * Kept in DLL.
    */
@@ -247,7 +256,6 @@ struct DnsResult
    * Type of the GNS/DNS record.
    */
   uint32_t record_type;
-
 };
 
 
@@ -256,7 +264,6 @@ struct DnsResult
  */
 struct VpnContext
 {
-
   /**
    * Which resolution process are we processing.
    */
@@ -290,7 +297,6 @@ struct VpnContext
  */
 struct GNS_ResolverHandle
 {
-
   /**
    * DLL
    */
@@ -314,7 +320,7 @@ struct GNS_ResolverHandle
   /**
    * closure passed to @e proc
    */
-  void* proc_cls;
+  void*proc_cls;
 
   /**
    * Handle for DHT lookups. should be NULL if no lookups are in progress
@@ -372,6 +378,12 @@ struct GNS_ResolverHandle
    */
   char *name;
 
+  /**
+   * Legacy Hostname to use if we encountered GNS2DNS record
+   * and thus can deduct the LEHO from that transition.
+   */
+  char *leho;
+
   /**
    * DLL of results we got from DNS.
    */
@@ -420,7 +432,6 @@ struct GNS_ResolverHandle
    * 16 bit random ID we used in the @e dns_request.
    */
   uint16_t original_dns_id;
-
 };
 
 
@@ -429,7 +440,6 @@ struct GNS_ResolverHandle
  */
 struct CacheOps
 {
-
   /**
    * Organized in a DLL.
    */
@@ -444,7 +454,6 @@ struct CacheOps
    * Pending Namestore caching task.
    */
   struct GNUNET_NAMECACHE_QueueEntry *namecache_qe_cache;
-
 };
 
 
@@ -540,6 +549,7 @@ is_canonical (const char *name)
   return GNUNET_YES;
 }
 
+
 /* ************************** Resolution **************************** */
 
 /**
@@ -551,20 +561,21 @@ is_canonical (const char *name)
  */
 static char *
 translate_dot_plus (struct GNS_ResolverHandle *rh,
-                   char *name)
+                    char *name)
 {
   char *ret;
   size_t s_len = strlen (name);
 
   if (0 != strcmp (&name[s_len - 2],
-                  ".+"))
+                   ".+"))
     return name; /* did not end in ".+" */
   GNUNET_assert (GNUNET_YES == rh->ac_tail->gns_authority);
   GNUNET_asprintf (&ret,
-                  "%.*s.%s",
-                  (int) (s_len - 2),
-                  name,
-                  GNUNET_GNSRECORD_pkey_to_zkey (&rh->ac_tail->authority_info.gns_authority));
+                   "%.*s.%s",
+                   (int) (s_len - 2),
+                   name,
+                   GNUNET_GNSRECORD_pkey_to_zkey (
+                     &rh->ac_tail->authority_info.gns_authority));
   GNUNET_free (name);
   return ret;
 }
@@ -618,25 +629,6 @@ timeout_resolution (void *cls)
 }
 
 
-#if (defined WINDOWS) || (defined DARWIN)
-/* Don't have this on W32, here's a naive implementation
- * Was somehow removed on OS X ...  */
-static void *
-memrchr (const void *s,
-        int c,
-        size_t n)
-{
-  const unsigned char *ucs = s;
-  ssize_t i;
-
-  for (i = n - 1; i >= 0; i--)
-    if (c == (int) ucs[i])
-      return (void *) &ucs[i];
-  return NULL;
-}
-#endif
-
-
 /**
  * Get the next, rightmost label from the name that we are trying to resolve,
  * and update the resolution position accordingly.  Labels usually consist
@@ -692,25 +684,26 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle *rh)
    * the right (SRV/DANE/BOX case), determine port/protocol;
    * The format of `rh->name` must be "_PORT._PROTOCOL".
    */
-  if ( ('_' == rh->name[0]) &&
-       (NULL != (dot = memrchr (rh->name,
-                                (int) '.',
-                                rh->name_resolution_pos))) &&
-       ('_' == dot[1]) &&
-       (NULL == memrchr (rh->name,
-                         (int) '.',
-                         dot - rh->name)) )
+  if (('_' == rh->name[0]) &&
+      (NULL != (dot = memrchr (rh->name,
+                               (int) '.',
+                               rh->name_resolution_pos))) &&
+      ('_' == dot[1]) &&
+      (NULL == memrchr (rh->name,
+                        (int) '.',
+                        dot - rh->name)))
   {
     srv_name = GNUNET_strndup (&rh->name[1],
                                (dot - rh->name) - 1);
     proto_name = GNUNET_strndup (&dot[2],
-                                 rh->name_resolution_pos - (dot - rh->name) - 1);
+                                 rh->name_resolution_pos - (dot - rh->name)
+                                 - 1);
     rh->name_resolution_pos = 0;
     pe = getprotobyname (proto_name);
     if (NULL == pe)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _("Protocol `%s' unknown, skipping labels.\n"),
+                  _ ("Protocol `%s' unknown, skipping labels.\n"),
                   proto_name);
       GNUNET_free (proto_name);
       GNUNET_free (srv_name);
@@ -721,7 +714,8 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle *rh)
     if (NULL == se)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _("Service `%s' unknown for protocol `%s', skipping labels.\n"),
+                  _ (
+                    "Service `%s' unknown for protocol `%s', skipping labels.\n"),
                   srv_name,
                   proto_name);
       GNUNET_free (proto_name);
@@ -763,23 +757,23 @@ transmit_lookup_dns_result (struct GNS_ResolverHandle *rh)
       rd[i].record_type = pos->record_type;
       if (0 == pos->expiration_time)
       {
-       rd[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
-       rd[i].expiration_time = 0;
+        rd[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+        rd[i].expiration_time = 0;
       }
       else
       {
-       rd[i].flags = GNUNET_GNSRECORD_RF_NONE;
-       rd[i].expiration_time = pos->expiration_time;
+        rd[i].flags = GNUNET_GNSRECORD_RF_NONE;
+        rd[i].expiration_time = pos->expiration_time;
       }
       i++;
     }
     GNUNET_assert (i == n);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-               "Transmitting standard DNS result with %u records\n",
-               n);
+                "Transmitting standard DNS result with %u records\n",
+                n);
     rh->proc (rh->proc_cls,
-             n,
-             rd);
+              n,
+              rd);
   }
   GNS_resolver_lookup_cancel (rh);
 }
@@ -796,14 +790,14 @@ transmit_lookup_dns_result (struct GNS_ResolverHandle *rh)
  */
 static void
 add_dns_result (struct GNS_ResolverHandle *rh,
-               uint64_t expiration_time,
-               uint32_t record_type,
-               size_t data_size,
-               const void *data)
+                uint64_t expiration_time,
+                uint32_t record_type,
+                size_t data_size,
+                const void *data)
 {
   struct DnsResult *res;
 
-  res = GNUNET_malloc (sizeof (struct DnsResult) + data_size);
+  res = GNUNET_malloc (sizeof(struct DnsResult) + data_size);
   res->expiration_time = expiration_time;
   res->data_size = data_size;
   res->record_type = record_type;
@@ -812,8 +806,8 @@ add_dns_result (struct GNS_ResolverHandle *rh,
                  data,
                  data_size);
   GNUNET_CONTAINER_DLL_insert (rh->dns_result_head,
-                              rh->dns_result_tail,
-                              res);
+                               rh->dns_result_tail,
+                               res);
 }
 
 
@@ -827,8 +821,8 @@ add_dns_result (struct GNS_ResolverHandle *rh,
  */
 static void
 handle_dns_result (void *cls,
-                  const struct sockaddr *addr,
-                  socklen_t addrlen)
+                   const struct sockaddr *addr,
+                   socklen_t addrlen)
 {
   struct GNS_ResolverHandle *rh = cls;
   const struct sockaddr_in *sa4;
@@ -841,26 +835,28 @@ handle_dns_result (void *cls,
     return;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Received %u bytes of DNS IP data\n",
-             addrlen);
+              "Received %u bytes of DNS IP data\n",
+              addrlen);
   switch (addr->sa_family)
   {
   case AF_INET:
     sa4 = (const struct sockaddr_in *) addr;
     add_dns_result (rh,
-                   0 /* expiration time is unknown */,
-                   GNUNET_DNSPARSER_TYPE_A,
-                   sizeof (struct in_addr),
-                   &sa4->sin_addr);
+                    0 /* expiration time is unknown */,
+                    GNUNET_DNSPARSER_TYPE_A,
+                    sizeof(struct in_addr),
+                    &sa4->sin_addr);
     break;
+
   case AF_INET6:
     sa6 = (const struct sockaddr_in6 *) addr;
     add_dns_result (rh,
-                   0 /* expiration time is unknown */,
-                   GNUNET_DNSPARSER_TYPE_AAAA,
-                   sizeof (struct in6_addr),
-                   &sa6->sin6_addr);
+                    0 /* expiration time is unknown */,
+                    GNUNET_DNSPARSER_TYPE_AAAA,
+                    sizeof(struct in6_addr),
+                    &sa6->sin6_addr);
     break;
+
   default:
     GNUNET_break (0);
     break;
@@ -898,8 +894,8 @@ start_resolver_lookup (void *cls);
  */
 static void
 dns_result_parser (void *cls,
-                  const struct GNUNET_TUN_DnsHeader *dns,
-                  size_t dns_len)
+                   const struct GNUNET_TUN_DnsHeader *dns,
+                   size_t dns_len)
 {
   struct GNS_ResolverHandle *rh = cls;
   struct GNUNET_DNSPARSER_Packet *p;
@@ -920,22 +916,22 @@ dns_result_parser (void *cls,
     return;
   }
   p = GNUNET_DNSPARSER_parse ((const char *) dns,
-                             dns_len);
+                              dns_len);
   if (NULL == p)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               _("Failed to parse DNS response\n"));
+                _ ("Failed to parse DNS response\n"));
     return;
   }
 
   /* We got a result from DNS */
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Received DNS response for `%s' with %u answers\n",
-             rh->ac_tail->label,
-             (unsigned int) p->num_answers);
-  if ( (p->num_answers > 0) &&
-       (GNUNET_DNSPARSER_TYPE_CNAME == p->answers[0].type) &&
-       (GNUNET_DNSPARSER_TYPE_CNAME != rh->record_type) )
+              "Received DNS response for `%s' with %u answers\n",
+              rh->ac_tail->label,
+              (unsigned int) p->num_answers);
+  if ((p->num_answers > 0) &&
+      (GNUNET_DNSPARSER_TYPE_CNAME == p->answers[0].type) &&
+      (GNUNET_DNSPARSER_TYPE_CNAME != rh->record_type))
   {
     int af;
 
@@ -958,13 +954,21 @@ dns_result_parser (void *cls,
     case GNUNET_DNSPARSER_TYPE_A:
       af = AF_INET;
       break;
+
     case GNUNET_DNSPARSER_TYPE_AAAA:
       af = AF_INET6;
       break;
+
     default:
       af = AF_UNSPEC;
       break;
     }
+    if (NULL != rh->leho)
+      add_dns_result (rh,
+                      GNUNET_TIME_UNIT_HOURS.rel_value_us,
+                      GNUNET_GNSRECORD_TYPE_LEHO,
+                      strlen (rh->leho),
+                      rh->leho);
     rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name,
                                               af,
                                               DNS_LOOKUP_TIMEOUT,
@@ -977,10 +981,11 @@ dns_result_parser (void *cls,
   }
 
   /* convert from (parsed) DNS to (binary) GNS format! */
-  rd_count = p->num_answers + p->num_authority_records + p->num_additional_records;
+  rd_count = p->num_answers + p->num_authority_records
+             + p->num_additional_records;
   {
-    struct GNUNET_GNSRECORD_Data rd[rd_count];
-    unsigned int skip;
+    struct GNUNET_GNSRECORD_Data rd[rd_count + 1]; /* +1 for LEHO */
+    int skip;
     char buf[UINT16_MAX];
     size_t buf_off;
     size_t buf_start;
@@ -989,126 +994,145 @@ dns_result_parser (void *cls,
     skip = 0;
     memset (rd,
             0,
-            sizeof (rd));
-    for (unsigned int i=0;i<rd_count;i++)
+            sizeof(rd));
+    for (unsigned int i = 0; i < rd_count; i++)
     {
       if (i < p->num_answers)
-       rec = &p->answers[i];
+        rec = &p->answers[i];
       else if (i < p->num_answers + p->num_authority_records)
-       rec = &p->authority_records[i - p->num_answers];
+        rec = &p->authority_records[i - p->num_answers];
       else
-       rec = &p->additional_records[i - p->num_answers - p->num_authority_records];
+        rec = &p->additional_records[i - p->num_answers
+                                     - p->num_authority_records];
       /* As we copied the full DNS name to 'rh->ac_tail->label', this
-        should be the correct check to see if this record is actually
-        a record for our label... */
+         should be the correct check to see if this record is actually
+         a record for our label... */
       if (0 != strcmp (rec->name,
-                      rh->ac_tail->label))
+                       rh->ac_tail->label))
       {
-       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                   "Dropping record `%s', does not match desired name `%s'\n",
-                   rec->name,
-                   rh->ac_tail->label);
-       skip++;
-       continue;
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Dropping record `%s', does not match desired name `%s'\n",
+                    rec->name,
+                    rh->ac_tail->label);
+        skip++;
+        continue;
       }
       rd[i - skip].record_type = rec->type;
       rd[i - skip].expiration_time = rec->expiration_time.abs_value_us;
       switch (rec->type)
       {
       case GNUNET_DNSPARSER_TYPE_A:
-       if (rec->data.raw.data_len != sizeof (struct in_addr))
-       {
-         GNUNET_break_op (0);
-         skip++;
-         continue;
-       }
-       rd[i - skip].data_size = rec->data.raw.data_len;
-       rd[i - skip].data = rec->data.raw.data;
-       break;
+        if (rec->data.raw.data_len != sizeof(struct in_addr))
+        {
+          GNUNET_break_op (0);
+          skip++;
+          continue;
+        }
+        rd[i - skip].data_size = rec->data.raw.data_len;
+        rd[i - skip].data = rec->data.raw.data;
+        break;
+
       case GNUNET_DNSPARSER_TYPE_AAAA:
-       if (rec->data.raw.data_len != sizeof (struct in6_addr))
-       {
-         GNUNET_break_op (0);
-         skip++;
-         continue;
-       }
-       rd[i - skip].data_size = rec->data.raw.data_len;
-       rd[i - skip].data = rec->data.raw.data;
-       break;
+        if (rec->data.raw.data_len != sizeof(struct in6_addr))
+        {
+          GNUNET_break_op (0);
+          skip++;
+          continue;
+        }
+        rd[i - skip].data_size = rec->data.raw.data_len;
+        rd[i - skip].data = rec->data.raw.data;
+        break;
+
       case GNUNET_DNSPARSER_TYPE_CNAME:
       case GNUNET_DNSPARSER_TYPE_PTR:
       case GNUNET_DNSPARSER_TYPE_NS:
-       buf_start = buf_off;
-       if (GNUNET_OK !=
-           GNUNET_DNSPARSER_builder_add_name (buf,
-                                              sizeof (buf),
-                                              &buf_off,
-                                              rec->data.hostname))
-       {
-         GNUNET_break (0);
-         skip++;
-         continue;
-       }
-       rd[i - skip].data_size = buf_off - buf_start;
-       rd[i - skip].data = &buf[buf_start];
-       break;
+        buf_start = buf_off;
+        if (GNUNET_OK !=
+            GNUNET_DNSPARSER_builder_add_name (buf,
+                                               sizeof(buf),
+                                               &buf_off,
+                                               rec->data.hostname))
+        {
+          GNUNET_break (0);
+          skip++;
+          continue;
+        }
+        rd[i - skip].data_size = buf_off - buf_start;
+        rd[i - skip].data = &buf[buf_start];
+        break;
+
       case GNUNET_DNSPARSER_TYPE_SOA:
-       buf_start = buf_off;
-       if (GNUNET_OK !=
-           GNUNET_DNSPARSER_builder_add_soa (buf,
-                                              sizeof (buf),
+        buf_start = buf_off;
+        if (GNUNET_OK !=
+            GNUNET_DNSPARSER_builder_add_soa (buf,
+                                              sizeof(buf),
                                               &buf_off,
                                               rec->data.soa))
-       {
-         GNUNET_break (0);
-         skip++;
-         continue;
-       }
-       rd[i - skip].data_size = buf_off - buf_start;
-       rd[i - skip].data = &buf[buf_start];
-       break;
+        {
+          GNUNET_break (0);
+          skip++;
+          continue;
+        }
+        rd[i - skip].data_size = buf_off - buf_start;
+        rd[i - skip].data = &buf[buf_start];
+        break;
+
       case GNUNET_DNSPARSER_TYPE_MX:
-       buf_start = buf_off;
-       if (GNUNET_OK !=
-           GNUNET_DNSPARSER_builder_add_mx (buf,
-                                            sizeof (buf),
-                                            &buf_off,
-                                            rec->data.mx))
-       {
-         GNUNET_break (0);
-         skip++;
-         continue;
-       }
-       rd[i - skip].data_size = buf_off - buf_start;
-       rd[i - skip].data = &buf[buf_start];
-       break;
+        buf_start = buf_off;
+        if (GNUNET_OK !=
+            GNUNET_DNSPARSER_builder_add_mx (buf,
+                                             sizeof(buf),
+                                             &buf_off,
+                                             rec->data.mx))
+        {
+          GNUNET_break (0);
+          skip++;
+          continue;
+        }
+        rd[i - skip].data_size = buf_off - buf_start;
+        rd[i - skip].data = &buf[buf_start];
+        break;
+
       case GNUNET_DNSPARSER_TYPE_SRV:
-       buf_start = buf_off;
-       if (GNUNET_OK !=
-           GNUNET_DNSPARSER_builder_add_srv (buf,
-                                             sizeof (buf),
-                                             &buf_off,
-                                             rec->data.srv))
-       {
-         GNUNET_break (0);
-         skip++;
-         continue;
-       }
-       rd[i - skip].data_size = buf_off - buf_start;
-       rd[i - skip].data = &buf[buf_start];
-       break;
+        buf_start = buf_off;
+        if (GNUNET_OK !=
+            GNUNET_DNSPARSER_builder_add_srv (buf,
+                                              sizeof(buf),
+                                              &buf_off,
+                                              rec->data.srv))
+        {
+          GNUNET_break (0);
+          skip++;
+          continue;
+        }
+        rd[i - skip].data_size = buf_off - buf_start;
+        rd[i - skip].data = &buf[buf_start];
+        break;
+
       default:
-       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                   _("Skipping record of unsupported type %d\n"),
-                   rec->type);
-       skip++;
-       continue;
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    _ ("Skipping record of unsupported type %d\n"),
+                    rec->type);
+        skip++;
+        continue;
       }
+    }   /* end of for all records in answer */
+    if (NULL != rh->leho)
+    {
+      rd[rd_count - skip].record_type = GNUNET_GNSRECORD_TYPE_LEHO;
+      rd[rd_count - skip].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+      rd[rd_count - skip].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us;
+      rd[rd_count - skip].data = rh->leho;
+      rd[rd_count - skip].data_size = strlen (rh->leho);
+      skip--;   /* skip one LESS */
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Adding LEHO %s\n",
+                  rh->leho);
     }
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Returning DNS response for `%s' with %u answers\n",
                 rh->ac_tail->label,
-                (unsigned int) p->num_answers);
+                (unsigned int) (rd_count - skip));
     rh->proc (rh->proc_cls,
               rd_count - skip,
               rd);
@@ -1144,8 +1168,8 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
   ac = rh->ac_tail;
   GNUNET_assert (NULL != ac);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Starting DNS lookup for `%s'\n",
-             ac->label);
+              "Starting DNS lookup for `%s'\n",
+              ac->label);
   GNUNET_assert (GNUNET_NO == ac->gns_authority);
   query = GNUNET_new (struct GNUNET_DNSPARSER_Query);
   query->name = GNUNET_strdup (ac->label);
@@ -1155,19 +1179,19 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
   p->queries = query;
   p->num_queries = 1;
   p->id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
-                                              UINT16_MAX);
+                                               UINT16_MAX);
   p->flags.opcode = GNUNET_TUN_DNS_OPCODE_QUERY;
   p->flags.recursion_desired = 1;
   ret = GNUNET_DNSPARSER_pack (p,
-                              1024,
-                              &dns_request,
-                              &dns_request_length);
+                               1024,
+                               &dns_request,
+                               &dns_request_length);
   if (GNUNET_OK != ret)
   {
     GNUNET_break (0);
     rh->proc (rh->proc_cls,
-             0,
-             NULL);
+              0,
+              NULL);
     GNUNET_assert (NULL == rh->task_id);
     rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_,
                                             rh);
@@ -1177,14 +1201,16 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
     rh->original_dns_id = p->id;
     GNUNET_assert (NULL != ac->authority_info.dns_authority.dns_handle);
     GNUNET_assert (NULL == rh->dns_request);
-    rh->dns_request = GNUNET_DNSSTUB_resolve (ac->authority_info.dns_authority.dns_handle,
-                                             dns_request,
-                                             dns_request_length,
-                                             &dns_result_parser,
-                                             rh);
+    rh->leho = GNUNET_strdup (ac->label);
+    rh->dns_request = GNUNET_DNSSTUB_resolve (
+      ac->authority_info.dns_authority.dns_handle,
+      dns_request,
+      dns_request_length,
+      &dns_result_parser,
+      rh);
     rh->task_id = GNUNET_SCHEDULER_add_delayed (DNS_LOOKUP_TIMEOUT,
-                                               &timeout_resolution,
-                                               rh);
+                                                &timeout_resolution,
+                                                rh);
   }
   if (GNUNET_SYSERR != ret)
     GNUNET_free (dns_request);
@@ -1202,17 +1228,18 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
  */
 static void
 handle_gns_cname_result (struct GNS_ResolverHandle *rh,
-                        const char *cname)
+                         const char *cname)
 {
   size_t nlen;
   char *res;
+  const char *tld;
   struct AuthorityChain *ac;
   int af;
+  struct GNUNET_CRYPTO_EcdsaPublicKey zone;
 
   nlen = strlen (cname);
-  if ( (nlen > 2) &&
-       (0 == strcmp (".+",
-                    &cname[nlen - 2])) )
+  tld = GNS_get_tld (cname);
+  if (0 == strcmp ("+", tld))
   {
     /* CNAME resolution continues relative to current domain */
     if (0 == rh->name_resolution_pos)
@@ -1223,11 +1250,11 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
     else
     {
       GNUNET_asprintf (&res,
-                      "%.*s.%.*s",
-                      (int) rh->name_resolution_pos,
-                      rh->name,
-                      (int) (nlen - 2),
-                      cname);
+                       "%.*s.%.*s",
+                       (int) rh->name_resolution_pos,
+                       rh->name,
+                       (int) (nlen - 2),
+                       cname);
       rh->name_resolution_pos = strlen (res);
     }
     GNUNET_free (rh->name);
@@ -1235,16 +1262,53 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
     ac = GNUNET_new (struct AuthorityChain);
     ac->rh = rh;
     ac->gns_authority = GNUNET_YES;
-    ac->authority_info.gns_authority = rh->ac_tail->authority_info.gns_authority;
+    ac->authority_info.gns_authority =
+      rh->ac_tail->authority_info.gns_authority;
+    ac->label = resolver_lookup_get_next_label (rh);
+    /* add AC to tail */
+    GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
+                                      rh->ac_tail,
+                                      ac);
+    rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution,
+                                            rh);
+    return;
+  }
+  if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone))
+  {
+    /* CNAME resolution continues relative to current domain */
+    if (0 == rh->name_resolution_pos)
+    {
+      GNUNET_asprintf (&res,
+                       "%.*s",
+                       strlen (cname) - (strlen (tld) + 1),
+                       cname);
+    }
+    else
+    {
+      GNUNET_asprintf (&res,
+                       "%.*s.%.*s",
+                       (int) rh->name_resolution_pos,
+                       rh->name,
+                       (int) strlen (cname) - (strlen (tld) + 1),
+                       cname);
+    }
+    rh->name_resolution_pos = strlen (res);
+    GNUNET_free (rh->name);
+    rh->name = res;
+    ac = GNUNET_new (struct AuthorityChain);
+    ac->rh = rh;
+    ac->gns_authority = GNUNET_YES;
+    ac->authority_info.gns_authority = zone;
     ac->label = resolver_lookup_get_next_label (rh);
     /* add AC to tail */
     GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
-                                     rh->ac_tail,
-                                     ac);
+                                      rh->ac_tail,
+                                      ac);
     rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution,
-                                           rh);
+                                            rh);
     return;
   }
+
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Got CNAME `%s' from GNS for `%s'\n",
               cname,
@@ -1252,7 +1316,7 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
   if (NULL != rh->std_resolve)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               "Multiple CNAME results from GNS resolving `%s'! Not really allowed...\n",
+                "Multiple CNAME results from GNS resolving `%s'! Not really allowed...\n",
                 rh->name);
     GNUNET_RESOLVER_request_cancel (rh->std_resolve);
   }
@@ -1265,9 +1329,11 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
   case GNUNET_DNSPARSER_TYPE_A:
     af = AF_INET;
     break;
+
   case GNUNET_DNSPARSER_TYPE_AAAA:
     af = AF_INET6;
     break;
+
   default:
     af = AF_UNSPEC;
     break;
@@ -1292,8 +1358,8 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
  */
 static void
 handle_gns_resolution_result (void *cls,
-                             unsigned int rd_count,
-                             const struct GNUNET_GNSRECORD_Data *rd);
+                              unsigned int rd_count,
+                              const struct GNUNET_GNSRECORD_Data *rd);
 
 
 /**
@@ -1312,8 +1378,8 @@ handle_gns_resolution_result (void *cls,
  */
 static void
 vpn_allocation_cb (void *cls,
-                  int af,
-                  const void *address)
+                   int af,
+                   const void *address)
 {
   struct VpnContext *vpn_ctx = cls;
   struct GNS_ResolverHandle *rh = vpn_ctx->rh;
@@ -1323,40 +1389,49 @@ vpn_allocation_cb (void *cls,
   vpn_ctx->vpn_request = NULL;
   rh->vpn_ctx = NULL;
   GNUNET_assert (GNUNET_OK ==
-                GNUNET_GNSRECORD_records_deserialize ((size_t) vpn_ctx->rd_data_size,
-                                                      vpn_ctx->rd_data,
-                                                      vpn_ctx->rd_count,
-                                                      rd));
-  for (i=0;i<vpn_ctx->rd_count;i++)
+                 GNUNET_GNSRECORD_records_deserialize (
+                   (size_t) vpn_ctx->rd_data_size,
+                   vpn_ctx->rd_data,
+                   vpn_ctx->rd_count,
+                   rd));
+  for (i = 0; i < vpn_ctx->rd_count; i++)
   {
     if (GNUNET_GNSRECORD_TYPE_VPN == rd[i].record_type)
     {
       switch (af)
       {
       case AF_INET:
-       rd[i].record_type = GNUNET_DNSPARSER_TYPE_A;
-       rd[i].data_size = sizeof (struct in_addr);
-       rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (VPN_TIMEOUT).abs_value_us;
-       rd[i].flags = 0;
-       rd[i].data = address;
-       break;
+        rd[i].record_type = GNUNET_DNSPARSER_TYPE_A;
+        rd[i].data_size = sizeof(struct in_addr);
+        rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
+          VPN_TIMEOUT).abs_value_us;
+        rd[i].flags = 0;
+        rd[i].data = address;
+        break;
+
       case AF_INET6:
-       rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
-       rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (VPN_TIMEOUT).abs_value_us;
-       rd[i].flags = 0;
-       rd[i].data = address;
-       rd[i].data_size = sizeof (struct in6_addr);
-       break;
+        rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
+        rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
+          VPN_TIMEOUT).abs_value_us;
+        rd[i].flags = 0;
+        rd[i].data = address;
+        rd[i].data_size = sizeof(struct in6_addr);
+        break;
+
       default:
-       GNUNET_assert (0);
+        GNUNET_assert (0);
       }
       break;
     }
   }
   GNUNET_assert (i < vpn_ctx->rd_count);
+  if (0 == vpn_ctx->rd_count)
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _ ("VPN returned empty result for `%s'\n"),
+                rh->name);
   handle_gns_resolution_result (rh,
-                               vpn_ctx->rd_count,
-                               rd);
+                                vpn_ctx->rd_count,
+                                rd);
   GNUNET_free (vpn_ctx->rd_data);
   GNUNET_free (vpn_ctx);
 }
@@ -1374,8 +1449,8 @@ continue_with_gns2dns (struct AuthorityChain *ac)
 {
   struct GNS_ResolverHandle *rh = ac->rh;
 
-  if ( (NULL != ac->authority_info.dns_authority.gp_head) &&
-       (GNUNET_NO == ac->authority_info.dns_authority.found) )
+  if ((NULL != ac->authority_info.dns_authority.gp_head) &&
+      (GNUNET_NO == ac->authority_info.dns_authority.found))
     return; /* more pending and none found yet */
   if (GNUNET_NO == ac->authority_info.dns_authority.found)
   {
@@ -1395,7 +1470,6 @@ continue_with_gns2dns (struct AuthorityChain *ac)
   GNUNET_assert (NULL == rh->task_id);
   rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution,
                                           rh);
-
 }
 
 
@@ -1432,7 +1506,7 @@ handle_gns2dns_result (void *cls,
               "Received %u results for IP address of DNS server for GNS2DNS transition\n",
               rd_count);
   /* find suitable A/AAAA record */
-  for (unsigned int j=0;j<rd_count;j++)
+  for (unsigned int j = 0; j < rd_count; j++)
   {
     switch (rd[j].record_type)
     {
@@ -1440,33 +1514,35 @@ handle_gns2dns_result (void *cls,
       {
         struct sockaddr_in v4;
 
-        if (sizeof (struct in_addr) != rd[j].data_size)
+        if (sizeof(struct in_addr) != rd[j].data_size)
         {
           GNUNET_break_op (0);
           continue;
         }
         memset (&v4,
                 0,
-                sizeof (v4));
+                sizeof(v4));
         v4.sin_family = AF_INET;
         v4.sin_port = htons (53);
 #if HAVE_SOCKADDR_IN_SIN_LEN
-        v4.sin_len = (u_char) sizeof (v4);
+        v4.sin_len = (u_char) sizeof(v4);
 #endif
         GNUNET_memcpy (&v4.sin_addr,
                        rd[j].data,
-                       sizeof (struct in_addr));
+                       sizeof(struct in_addr));
         if (GNUNET_OK ==
-            GNUNET_DNSSTUB_add_dns_sa (ac->authority_info.dns_authority.dns_handle,
-                                       (const struct sockaddr *) &v4))
+            GNUNET_DNSSTUB_add_dns_sa (
+              ac->authority_info.dns_authority.dns_handle,
+              (const struct sockaddr *) &v4))
           ac->authority_info.dns_authority.found = GNUNET_YES;
         break;
       }
+
     case GNUNET_DNSPARSER_TYPE_AAAA:
       {
         struct sockaddr_in6 v6;
 
-        if (sizeof (struct in6_addr) != rd[j].data_size)
+        if (sizeof(struct in6_addr) != rd[j].data_size)
         {
           GNUNET_break_op (0);
           continue;
@@ -1475,21 +1551,23 @@ handle_gns2dns_result (void *cls,
            and otherwise skip this one and hope we find another */
         memset (&v6,
                 0,
-                sizeof (v6));
+                sizeof(v6));
         v6.sin6_family = AF_INET6;
         v6.sin6_port = htons (53);
 #if HAVE_SOCKADDR_IN_SIN_LEN
-        v6.sin6_len = (u_char) sizeof (v6);
+        v6.sin6_len = (u_char) sizeof(v6);
 #endif
         GNUNET_memcpy (&v6.sin6_addr,
                        rd[j].data,
-                       sizeof (struct in6_addr));
+                       sizeof(struct in6_addr));
         if (GNUNET_OK ==
-            GNUNET_DNSSTUB_add_dns_sa (ac->authority_info.dns_authority.dns_handle,
-                                       (const struct sockaddr *) &v6))
+            GNUNET_DNSSTUB_add_dns_sa (
+              ac->authority_info.dns_authority.dns_handle,
+              (const struct sockaddr *) &v6))
           ac->authority_info.dns_authority.found = GNUNET_YES;
         break;
       }
+
     default:
       break;
     }
@@ -1539,11 +1617,13 @@ handle_gns2dns_ip (void *cls,
     v4->sin_port = htons (53);
     gp->num_results++;
     break;
+
   case AF_INET6:
     v6 = (struct sockaddr_in6 *) &ss;
     v6->sin6_port = htons (53);
     gp->num_results++;
     break;
+
   default:
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Unsupported AF %d\n",
@@ -1574,10 +1654,10 @@ recursive_cname_resolution (struct GNS_ResolverHandle *rh,
   cname = GNUNET_DNSPARSER_parse_name (rd->data,
                                        rd->data_size,
                                        &off);
-  if ( (NULL == cname) ||
-       (off != rd->data_size) )
+  if ((NULL == cname) ||
+      (off != rd->data_size))
   {
-    GNUNET_break_op (0); /* record not well-formed */
+    GNUNET_break_op (0);  /* record not well-formed */
     GNUNET_free_non_null (cname);
     fail_resolution (rh);
     return;
@@ -1601,7 +1681,7 @@ recursive_pkey_resolution (struct GNS_ResolverHandle *rh,
   struct AuthorityChain *ac;
 
   /* delegation to another zone */
-  if (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) !=
+  if (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) !=
       rd->data_size)
   {
     GNUNET_break_op (0);
@@ -1614,7 +1694,7 @@ recursive_pkey_resolution (struct GNS_ResolverHandle *rh,
   ac->gns_authority = GNUNET_YES;
   GNUNET_memcpy (&ac->authority_info.gns_authority,
                  rd->data,
-                 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+                 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
   ac->label = resolver_lookup_get_next_label (rh);
   /* add AC to tail */
   GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
@@ -1651,7 +1731,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
   ac->rh = rh;
   ac->authority_info.dns_authority.dns_handle = GNUNET_DNSSTUB_start (4);
 
-  for (unsigned int i=0;i<rd_count;i++)
+  for (unsigned int i = 0; i < rd_count; i++)
   {
     char *ip;
     char *n;
@@ -1667,12 +1747,12 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
     n = GNUNET_DNSPARSER_parse_name (rd[i].data,
                                      rd[i].data_size,
                                      &off);
-    ip = GNUNET_DNSPARSER_parse_name (rd[i].data,
-                                      rd[i].data_size,
-                                      &off);
-    if ( (NULL == n) ||
-         (NULL == ip) ||
-         (off != rd[i].data_size) )
+    ip = GNUNET_strdup (&rd[i].data[off]);
+    off += strlen (ip) + 1;
+
+    if ((NULL == n) ||
+        (NULL == ip) ||
+        (off != rd[i].data_size))
     {
       GNUNET_break_op (0);
       GNUNET_free_non_null (n);
@@ -1701,23 +1781,24 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
     }
 
     /* check if 'ip' is already an IPv4/IPv6 address */
-    if ( (1 == inet_pton (AF_INET,
-                          ip,
-                          &v4)) ||
-         (1 == inet_pton (AF_INET6,
-                          ip,
-                          &v6)) )
+    if ((1 == inet_pton (AF_INET,
+                         ip,
+                         &v4)) ||
+        (1 == inet_pton (AF_INET6,
+                         ip,
+                         &v6)))
     {
       GNUNET_break (GNUNET_OK ==
-                    GNUNET_DNSSTUB_add_dns_ip (ac->authority_info.dns_authority.dns_handle,
-                                               ip));
+                    GNUNET_DNSSTUB_add_dns_ip (
+                      ac->authority_info.dns_authority.dns_handle,
+                      ip));
       ac->authority_info.dns_authority.found = GNUNET_YES;
       GNUNET_free (ip);
       continue;
     }
     tld = GNS_get_tld (ip);
-    if (0 != strcmp (tld,
-                     "+"))
+    if ((0 != strcmp (tld, "+")) &&
+        (GNUNET_OK != GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)))
     {
       /* 'ip' is a DNS name */
       gp = GNUNET_new (struct Gns2DnsPending);
@@ -1740,16 +1821,19 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
                                  ac->authority_info.dns_authority.gp_tail,
                                  gp);
     gp->rh = GNUNET_new (struct GNS_ResolverHandle);
-    ip = translate_dot_plus (rh,
-                             ip);
-    tld = GNS_get_tld (ip);
-    if (GNUNET_OK !=
-        GNUNET_GNSRECORD_zkey_to_pkey (tld,
-                                       &zone))
+    if (0 == strcmp (tld, "+"))
     {
-      GNUNET_break_op (0);
-      GNUNET_free (ip);
-      continue;
+      ip = translate_dot_plus (rh,
+                               ip);
+      tld = GNS_get_tld (ip);
+      if (GNUNET_OK !=
+          GNUNET_GNSRECORD_zkey_to_pkey (tld,
+                                         &zone))
+      {
+        GNUNET_break_op (0);
+        GNUNET_free (ip);
+        continue;
+      }
     }
     gp->rh->authority_zone = zone;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1766,7 +1850,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
     gp->rh->task_id
       = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
                                   gp->rh);
-  } /* end 'for all records' */
+  }   /* end 'for all records' */
 
   if (NULL == ns)
   {
@@ -1787,13 +1871,32 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
                    (0 != rh->name_resolution_pos) ? "." : "",
                    ns);
   GNUNET_free (ns);
+
+  {
+    /* the GNS name is UTF-8 and may include multibyte chars.
+     * We have to convert the combined name to a DNS-compatible IDNA.
+     */
+    char *tmp = ac->label;
+
+    if (IDNA_SUCCESS != idna_to_ascii_8z (tmp,
+                                          &ac->label,
+                                          IDNA_ALLOW_UNASSIGNED))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _ ("Name `%s' cannot be converted to IDNA."),
+                  tmp);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_free (tmp);
+  }
+
   GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
                                     rh->ac_tail,
                                     ac);
   if (strlen (ac->label) > GNUNET_DNSPARSER_MAX_NAME_LENGTH)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("GNS lookup resulted in DNS name that is too long (`%s')\n"),
+                _ ("GNS lookup resulted in DNS name that is too long (`%s')\n"),
                 ac->label);
     return GNUNET_SYSERR;
   }
@@ -1811,8 +1914,8 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
  */
 static void
 handle_gns_resolution_result (void *cls,
-                             unsigned int rd_count,
-                             const struct GNUNET_GNSRECORD_Data *rd)
+                              unsigned int rd_count,
+                              const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct GNS_ResolverHandle *rh = cls;
   char *cname;
@@ -1829,14 +1932,15 @@ handle_gns_resolution_result (void *cls,
   unsigned int rd_off;
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-             "Resolution succeeded for `%s' in zone %s, got %u records\n",
-             rh->ac_tail->label,
-             GNUNET_GNSRECORD_z2s (&rh->ac_tail->authority_info.gns_authority),
-             rd_count);
+              "Resolution succeeded for `%s' in zone %s, got %u records\n",
+              rh->ac_tail->label,
+              GNUNET_GNSRECORD_z2s (&rh->ac_tail->authority_info.gns_authority),
+              rd_count);
   if (0 == rd_count)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("GNS lookup failed (zero records found)\n"));
+                _ ("GNS lookup failed (zero records found for `%s')\n"),
+                rh->name);
     fail_resolution (rh);
     return;
   }
@@ -1844,55 +1948,58 @@ handle_gns_resolution_result (void *cls,
   if (0 == rh->name_resolution_pos)
   {
     /* top-level match, are we done yet? */
-    if ( (rd_count > 0) &&
-        (GNUNET_DNSPARSER_TYPE_CNAME == rd[0].record_type) &&
-        (GNUNET_DNSPARSER_TYPE_CNAME != rh->record_type) )
+    if ((rd_count > 0) &&
+        (GNUNET_DNSPARSER_TYPE_CNAME == rd[0].record_type) &&
+        (GNUNET_DNSPARSER_TYPE_CNAME != rh->record_type))
     {
       off = 0;
       cname = GNUNET_DNSPARSER_parse_name (rd[0].data,
-                                          rd[0].data_size,
-                                          &off);
-      if ( (NULL == cname) ||
-          (off != rd[0].data_size) )
+                                           rd[0].data_size,
+                                           &off);
+      if ((NULL == cname) ||
+          (off != rd[0].data_size))
       {
-       GNUNET_break_op (0);
+        GNUNET_break_op (0);
         GNUNET_free_non_null (cname);
         fail_resolution (rh);
-       return;
+        return;
       }
       handle_gns_cname_result (rh,
-                              cname);
+                               cname);
       GNUNET_free (cname);
       return;
     }
     /* If A/AAAA was requested, but we got a VPN
        record, we convert it to A/AAAA using GNUnet VPN */
-    if ( (GNUNET_DNSPARSER_TYPE_A == rh->record_type) ||
-        (GNUNET_DNSPARSER_TYPE_AAAA == rh->record_type) )
+    if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) ||
+        (GNUNET_DNSPARSER_TYPE_AAAA == rh->record_type))
     {
-      for (unsigned int i=0;i<rd_count;i++)
+      for (unsigned int i = 0; i < rd_count; i++)
       {
-       switch (rd[i].record_type)
-       {
-       case GNUNET_GNSRECORD_TYPE_VPN:
-         {
-           af = (GNUNET_DNSPARSER_TYPE_A == rh->record_type) ? AF_INET : AF_INET6;
-           if (sizeof (struct GNUNET_TUN_GnsVpnRecord) >
-               rd[i].data_size)
-           {
-             GNUNET_break_op (0);
+        switch (rd[i].record_type)
+        {
+        case GNUNET_GNSRECORD_TYPE_VPN:
+          {
+            af = (GNUNET_DNSPARSER_TYPE_A == rh->record_type) ? AF_INET :
+                 AF_INET6;
+            if (sizeof(struct GNUNET_TUN_GnsVpnRecord) >
+                rd[i].data_size)
+            {
+              GNUNET_break_op (0);
               fail_resolution (rh);
-             return;
-           }
-           vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data;
-           vname = (const char *) &vpn[1];
-           if ('\0' != vname[rd[i].data_size - 1 - sizeof (struct GNUNET_TUN_GnsVpnRecord)])
-           {
-             GNUNET_break_op (0);
+              return;
+            }
+            vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data;
+            vname = (const char *) &vpn[1];
+            if ('\0' != vname[rd[i].data_size - 1 - sizeof(struct
+                                                           GNUNET_TUN_GnsVpnRecord)
+                ])
+            {
+              GNUNET_break_op (0);
               fail_resolution (rh);
-             return;
-           }
-           GNUNET_TUN_service_name_to_hash (vname,
+              return;
+            }
+            GNUNET_TUN_service_name_to_hash (vname,
                                              &vhash);
             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                         "Attempting VPN allocation for %s-%s (AF: %d, proto %d)\n",
@@ -1900,38 +2007,43 @@ handle_gns_resolution_result (void *cls,
                         vname,
                         (int) af,
                         (int) ntohs (vpn->proto));
-           vpn_ctx = GNUNET_new (struct VpnContext);
-           rh->vpn_ctx = vpn_ctx;
-           vpn_ctx->rh = rh;
-           vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
-                                                                      rd);
+            vpn_ctx = GNUNET_new (struct VpnContext);
+            rh->vpn_ctx = vpn_ctx;
+            vpn_ctx->rh = rh;
+            vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
+                                                                       rd);
             if (vpn_ctx->rd_data_size < 0)
             {
-             GNUNET_break_op (0);
+              GNUNET_break_op (0);
               GNUNET_free (vpn_ctx);
               fail_resolution (rh);
-             return;
+              return;
             }
-           vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size);
+            vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size);
             vpn_ctx->rd_count = rd_count;
-           GNUNET_assert (vpn_ctx->rd_data_size ==
+            GNUNET_assert (vpn_ctx->rd_data_size ==
                            GNUNET_GNSRECORD_records_serialize (rd_count,
                                                                rd,
-                                                               (size_t) vpn_ctx->rd_data_size,
+                                                               (size_t) vpn_ctx
+                                                               ->rd_data_size,
                                                                vpn_ctx->rd_data));
-           vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle,
-                                                               af,
-                                                               ntohs (vpn->proto),
-                                                               &vpn->peer,
-                                                               &vhash,
-                                                               GNUNET_TIME_relative_to_absolute (VPN_TIMEOUT),
-                                                               &vpn_allocation_cb,
-                                                               vpn_ctx);
-           return;
-         }
-       case GNUNET_GNSRECORD_TYPE_GNS2DNS:
-         {
-           /* delegation to DNS */
+            vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle,
+                                                                af,
+                                                                ntohs (
+                                                                  vpn->proto),
+                                                                &vpn->peer,
+                                                                &vhash,
+                                                                GNUNET_TIME_relative_to_absolute (
+                                                                  VPN_TIMEOUT),
+                                                                &
+                                                                vpn_allocation_cb,
+                                                                vpn_ctx);
+            return;
+          }
+
+        case GNUNET_GNSRECORD_TYPE_GNS2DNS:
+          {
+            /* delegation to DNS */
             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                         "Found GNS2DNS record, delegating to DNS!\n");
             if (GNUNET_OK ==
@@ -1941,205 +2053,200 @@ handle_gns_resolution_result (void *cls,
               return;
             else
               goto fail;
-         }
-       default:
-         break;
-       } /* end: switch */
-      } /* end: for rd */
-    } /* end: name_resolution_pos */
+          }
+
+        default:
+          break;
+        }         /* end: switch */
+      }       /* end: for rd */
+    }     /* end: name_resolution_pos */
     /* convert relative names in record values to absolute names,
        using 'scratch' array for memory allocations */
     scratch_off = 0;
     rd_off = 0;
-    for (unsigned int i=0;i<rd_count;i++)
+    for (unsigned int i = 0; i < rd_count; i++)
     {
       GNUNET_assert (rd_off <= i);
-      if ( (0 != rh->protocol) &&
-           (0 != rh->service) &&
-           (GNUNET_GNSRECORD_TYPE_BOX != rd[i].record_type) )
-        continue; /* we _only_ care about boxed records */
+      if ((0 != rh->protocol) &&
+          (0 != rh->service) &&
+          (GNUNET_GNSRECORD_TYPE_BOX != rd[i].record_type))
+        continue;     /* we _only_ care about boxed records */
 
       GNUNET_assert (rd_off < rd_count);
       rd_new[rd_off] = rd[i];
       /* Check if the embedded name(s) end in "+", and if so,
-        replace the "+" with the zone at "ac_tail", changing the name
-        to a ".ZONEKEY".  The name is allocated on the 'scratch' array,
-        so we can free it afterwards. */
+         replace the "+" with the zone at "ac_tail", changing the name
+         to a ".ZONEKEY".  The name is allocated on the 'scratch' array,
+         so we can free it afterwards. */
       switch (rd[i].record_type)
       {
       case GNUNET_DNSPARSER_TYPE_CNAME:
-       {
-         char *cname;
-
-         off = 0;
-         cname = GNUNET_DNSPARSER_parse_name (rd[i].data,
-                                              rd[i].data_size,
-                                              &off);
-         if ( (NULL == cname) ||
-              (off != rd[i].data_size) )
-         {
-           GNUNET_break_op (0); /* record not well-formed */
-         }
-         else
-         {
-           cname = translate_dot_plus (rh, cname);
+        {
+          char *cname;
+
+          off = 0;
+          cname = GNUNET_DNSPARSER_parse_name (rd[i].data,
+                                               rd[i].data_size,
+                                               &off);
+          if ((NULL == cname) ||
+              (off != rd[i].data_size))
+          {
+            GNUNET_break_op (0);      /* record not well-formed */
+          }
+          else
+          {
+            cname = translate_dot_plus (rh, cname);
             GNUNET_break (NULL != cname);
-           scratch_start = scratch_off;
-           if (GNUNET_OK !=
-               GNUNET_DNSPARSER_builder_add_name (scratch,
-                                                  sizeof (scratch),
-                                                  &scratch_off,
-                                                  cname))
-           {
-             GNUNET_break (0);
-           }
-           else
-           {
+            scratch_start = scratch_off;
+            if (GNUNET_OK !=
+                GNUNET_DNSPARSER_builder_add_name (scratch,
+                                                   sizeof(scratch),
+                                                   &scratch_off,
+                                                   cname))
+            {
+              GNUNET_break (0);
+            }
+            else
+            {
               GNUNET_assert (rd_off < rd_count);
-             rd_new[rd_off].data = &scratch[scratch_start];
-             rd_new[rd_off].data_size = scratch_off - scratch_start;
-             rd_off++;
-           }
-         }
-         GNUNET_free_non_null (cname);
-       }
-       break;
+              rd_new[rd_off].data = &scratch[scratch_start];
+              rd_new[rd_off].data_size = scratch_off - scratch_start;
+              rd_off++;
+            }
+          }
+          GNUNET_free_non_null (cname);
+        }
+        break;
+
       case GNUNET_DNSPARSER_TYPE_SOA:
-       {
-         struct GNUNET_DNSPARSER_SoaRecord *soa;
-
-         off = 0;
-         soa = GNUNET_DNSPARSER_parse_soa (rd[i].data,
-                                           rd[i].data_size,
-                                           &off);
-         if ( (NULL == soa) ||
-              (off != rd[i].data_size) )
-         {
-           GNUNET_break_op (0); /* record not well-formed */
-         }
-         else
-         {
-           soa->mname = translate_dot_plus (rh, soa->mname);
-           soa->rname = translate_dot_plus (rh, soa->rname);
-           scratch_start = scratch_off;
-           if (GNUNET_OK !=
-               GNUNET_DNSPARSER_builder_add_soa (scratch,
-                                                 sizeof (scratch),
-                                                 &scratch_off,
-                                                 soa))
-           {
-             GNUNET_break (0);
-           }
-           else
-           {
+        {
+          struct GNUNET_DNSPARSER_SoaRecord *soa;
+
+          off = 0;
+          soa = GNUNET_DNSPARSER_parse_soa (rd[i].data,
+                                            rd[i].data_size,
+                                            &off);
+          if ((NULL == soa) ||
+              (off != rd[i].data_size))
+          {
+            GNUNET_break_op (0);      /* record not well-formed */
+          }
+          else
+          {
+            soa->mname = translate_dot_plus (rh, soa->mname);
+            soa->rname = translate_dot_plus (rh, soa->rname);
+            scratch_start = scratch_off;
+            if (GNUNET_OK !=
+                GNUNET_DNSPARSER_builder_add_soa (scratch,
+                                                  sizeof(scratch),
+                                                  &scratch_off,
+                                                  soa))
+            {
+              GNUNET_break (0);
+            }
+            else
+            {
               GNUNET_assert (rd_off < rd_count);
-             rd_new[rd_off].data = &scratch[scratch_start];
-             rd_new[rd_off].data_size = scratch_off - scratch_start;
-             rd_off++;
-           }
-         }
-         if (NULL != soa)
-           GNUNET_DNSPARSER_free_soa (soa);
-       }
-       break;
+              rd_new[rd_off].data = &scratch[scratch_start];
+              rd_new[rd_off].data_size = scratch_off - scratch_start;
+              rd_off++;
+            }
+          }
+          if (NULL != soa)
+            GNUNET_DNSPARSER_free_soa (soa);
+        }
+        break;
+
       case GNUNET_DNSPARSER_TYPE_MX:
-       {
-         struct GNUNET_DNSPARSER_MxRecord *mx;
-
-         off = 0;
-         mx = GNUNET_DNSPARSER_parse_mx (rd[i].data,
-                                         rd[i].data_size,
-                                         &off);
-         if ( (NULL == mx) ||
-              (off != rd[i].data_size) )
-         {
-           GNUNET_break_op (0); /* record not well-formed */
-         }
-         else
-         {
-           mx->mxhost = translate_dot_plus (rh, mx->mxhost);
-           scratch_start = scratch_off;
-           if (GNUNET_OK !=
-               GNUNET_DNSPARSER_builder_add_mx (scratch,
-                                                sizeof (scratch),
-                                                &scratch_off,
-                                                mx))
-           {
-             GNUNET_break (0);
-           }
-           else
-           {
+        {
+          struct GNUNET_DNSPARSER_MxRecord *mx;
+
+          off = 0;
+          mx = GNUNET_DNSPARSER_parse_mx (rd[i].data,
+                                          rd[i].data_size,
+                                          &off);
+          if ((NULL == mx) ||
+              (off != rd[i].data_size))
+          {
+            GNUNET_break_op (0);      /* record not well-formed */
+          }
+          else
+          {
+            mx->mxhost = translate_dot_plus (rh, mx->mxhost);
+            scratch_start = scratch_off;
+            if (GNUNET_OK !=
+                GNUNET_DNSPARSER_builder_add_mx (scratch,
+                                                 sizeof(scratch),
+                                                 &scratch_off,
+                                                 mx))
+            {
+              GNUNET_break (0);
+            }
+            else
+            {
               GNUNET_assert (rd_off < rd_count);
-             rd_new[rd_off].data = &scratch[scratch_start];
-             rd_new[rd_off].data_size = scratch_off - scratch_start;
-             rd_off++;
-           }
-         }
-         if (NULL != mx)
-           GNUNET_DNSPARSER_free_mx (mx);
-       }
-       break;
+              rd_new[rd_off].data = &scratch[scratch_start];
+              rd_new[rd_off].data_size = scratch_off - scratch_start;
+              rd_off++;
+            }
+          }
+          if (NULL != mx)
+            GNUNET_DNSPARSER_free_mx (mx);
+        }
+        break;
+
       case GNUNET_DNSPARSER_TYPE_SRV:
-       {
-         struct GNUNET_DNSPARSER_SrvRecord *srv;
-
-         off = 0;
-         srv = GNUNET_DNSPARSER_parse_srv (rd[i].data,
-                                           rd[i].data_size,
-                                           &off);
-         if ( (NULL == srv) ||
-              (off != rd[i].data_size) )
-         {
-           GNUNET_break_op (0); /* record not well-formed */
-         }
-         else
-         {
-           srv->target = translate_dot_plus (rh, srv->target);
-           scratch_start = scratch_off;
-           if (GNUNET_OK !=
-               GNUNET_DNSPARSER_builder_add_srv (scratch,
-                                                 sizeof (scratch),
-                                                 &scratch_off,
-                                                 srv))
-           {
-             GNUNET_break (0);
-           }
-           else
-           {
+        {
+          struct GNUNET_DNSPARSER_SrvRecord *srv;
+
+          off = 0;
+          srv = GNUNET_DNSPARSER_parse_srv (rd[i].data,
+                                            rd[i].data_size,
+                                            &off);
+          if ((NULL == srv) ||
+              (off != rd[i].data_size))
+          {
+            GNUNET_break_op (0);      /* record not well-formed */
+          }
+          else
+          {
+            srv->target = translate_dot_plus (rh, srv->target);
+            scratch_start = scratch_off;
+            if (GNUNET_OK !=
+                GNUNET_DNSPARSER_builder_add_srv (scratch,
+                                                  sizeof(scratch),
+                                                  &scratch_off,
+                                                  srv))
+            {
+              GNUNET_break (0);
+            }
+            else
+            {
               GNUNET_assert (rd_off < rd_count);
-             rd_new[rd_off].data = &scratch[scratch_start];
-             rd_new[rd_off].data_size = scratch_off - scratch_start;
-             rd_off++;
-           }
-         }
-         if (NULL != srv)
-           GNUNET_DNSPARSER_free_srv (srv);
-       }
-       break;
+              rd_new[rd_off].data = &scratch[scratch_start];
+              rd_new[rd_off].data_size = scratch_off - scratch_start;
+              rd_off++;
+            }
+          }
+          if (NULL != srv)
+            GNUNET_DNSPARSER_free_srv (srv);
+        }
+        break;
 
       case GNUNET_GNSRECORD_TYPE_NICK:
+        /* ignore */
+        break;
+
+      case GNUNET_GNSRECORD_TYPE_PKEY:
         {
-          const char *nick;
+          struct GNUNET_CRYPTO_EcdsaPublicKey pub;
 
-          nick = rd[i].data;
-          if ((rd[i].data_size > 0) &&
-              (nick[rd[i].data_size -1] != '\0'))
+          if (rd[i].data_size != sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))
           {
             GNUNET_break_op (0);
             break;
           }
-          break;
-        }
-      case GNUNET_GNSRECORD_TYPE_PKEY:
-        {
-         struct GNUNET_CRYPTO_EcdsaPublicKey pub;
-
-         if (rd[i].data_size != sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))
-         {
-           GNUNET_break_op (0);
-           break;
-         }
-         GNUNET_memcpy (&pub,
+          GNUNET_memcpy (&pub,
                          rd[i].data,
                          rd[i].data_size);
           rd_off++;
@@ -2161,14 +2268,15 @@ handle_gns_resolution_result (void *cls,
             return;
           }
         }
-       break;
+        break;
+
       case GNUNET_GNSRECORD_TYPE_GNS2DNS:
         {
           /* delegation to DNS */
           if (GNUNET_GNSRECORD_TYPE_GNS2DNS == rh->record_type)
           {
             rd_off++;
-            break; /* do not follow to DNS, we wanted the GNS2DNS record! */
+            break;       /* do not follow to DNS, we wanted the GNS2DNS record! */
           }
           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                       "Found GNS2DNS record, delegating to DNS!\n");
@@ -2180,23 +2288,25 @@ handle_gns_resolution_result (void *cls,
           else
             goto fail;
         }
+
       case GNUNET_GNSRECORD_TYPE_BOX:
         {
           /* unbox SRV/TLSA records if a specific one was requested */
-          if ( (0 != rh->protocol) &&
-               (0 != rh->service) &&
-               (rd[i].data_size >= sizeof (struct GNUNET_GNSRECORD_BoxRecord)) )
+          if ((0 != rh->protocol) &&
+              (0 != rh->service) &&
+              (rd[i].data_size >= sizeof(struct GNUNET_GNSRECORD_BoxRecord)))
           {
             const struct GNUNET_GNSRECORD_BoxRecord *box;
 
             box = rd[i].data;
-            if ( (ntohs (box->protocol) == rh->protocol) &&
-                 (ntohs (box->service) == rh->service) )
+            if ((ntohs (box->protocol) == rh->protocol) &&
+                (ntohs (box->service) == rh->service))
             {
               /* Box matches, unbox! */
               GNUNET_assert (rd_off < rd_count);
               rd_new[rd_off].record_type = ntohl (box->record_type);
-              rd_new[rd_off].data_size -= sizeof (struct GNUNET_GNSRECORD_BoxRecord);
+              rd_new[rd_off].data_size -= sizeof(struct
+                                                 GNUNET_GNSRECORD_BoxRecord);
               rd_new[rd_off].data = &box[1];
               rd_off++;
             }
@@ -2209,11 +2319,12 @@ handle_gns_resolution_result (void *cls,
           }
           break;
         }
+
       default:
-       rd_off++;
-       break;
-      } /* end: switch */
-    } /* end: for rd_count */
+        rd_off++;
+        break;
+      }       /* end: switch */
+    }     /* end: for rd_count */
 
     /* yes, we are done, return result */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2231,15 +2342,17 @@ handle_gns_resolution_result (void *cls,
   switch (rd[0].record_type)
   {
   case GNUNET_DNSPARSER_TYPE_CNAME:
-    GNUNET_break_op (1 == rd_count); /* CNAME should be unique */
+    GNUNET_break_op (1 == rd_count);  /* CNAME should be unique */
     recursive_cname_resolution (rh,
                                 &rd[0]);
     return;
+
   case GNUNET_GNSRECORD_TYPE_PKEY:
-    GNUNET_break_op (1 == rd_count); /* PKEY should be unique */
+    GNUNET_break_op (1 == rd_count);  /* PKEY should be unique */
     recursive_pkey_resolution (rh,
                                &rd[0]);
     return;
+
   default:
     if (GNUNET_OK ==
         recursive_gns2dns_resolution (rh,
@@ -2248,9 +2361,9 @@ handle_gns_resolution_result (void *cls,
       return;
     break;
   }
- fail:
+fail:
   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-             _("GNS lookup recursion failed (no delegation record found)\n"));
+              _ ("GNS lookup recursion failed (no delegation record found)\n"));
   fail_resolution (rh);
 }
 
@@ -2265,19 +2378,19 @@ handle_gns_resolution_result (void *cls,
  */
 static void
 namecache_cache_continuation (void *cls,
-                             int32_t success,
-                             const char *emsg)
+                              int32_t success,
+                              const char *emsg)
 {
   struct CacheOps *co = cls;
 
   co->namecache_qe_cache = NULL;
   if (GNUNET_OK != success)
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               _("Failed to cache GNS resolution: %s\n"),
-               emsg);
+                _ ("Failed to cache GNS resolution: %s\n"),
+                emsg);
   GNUNET_CONTAINER_DLL_remove (co_head,
-                              co_tail,
-                              co);
+                               co_tail,
+                               co);
   GNUNET_free (co);
 }
 
@@ -2301,15 +2414,15 @@ namecache_cache_continuation (void *cls,
  */
 static void
 handle_dht_response (void *cls,
-                    struct GNUNET_TIME_Absolute exp,
-                    const struct GNUNET_HashCode *key,
-                    const struct GNUNET_PeerIdentity *get_path,
-                    unsigned int get_path_length,
-                    const struct GNUNET_PeerIdentity *put_path,
-                    unsigned int put_path_length,
-                    enum GNUNET_BLOCK_Type type,
-                    size_t size,
-                    const void *data)
+                     struct GNUNET_TIME_Absolute exp,
+                     const struct GNUNET_HashCode *key,
+                     const struct GNUNET_PeerIdentity *get_path,
+                     unsigned int get_path_length,
+                     const struct GNUNET_PeerIdentity *put_path,
+                     unsigned int put_path_length,
+                     enum GNUNET_BLOCK_Type type,
+                     size_t size,
+                     const void *data)
 {
   struct GNS_ResolverHandle *rh = cls;
   struct AuthorityChain *ac = rh->ac_tail;
@@ -2328,8 +2441,8 @@ handle_dht_response (void *cls,
   GNUNET_CONTAINER_heap_remove_node (rh->dht_heap_node);
   rh->dht_heap_node = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Handling response from the DHT\n");
-  if (size < sizeof (struct GNUNET_GNSRECORD_Block))
+              "Handling response from the DHT\n");
+  if (size < sizeof(struct GNUNET_GNSRECORD_Block))
   {
     /* how did this pass DHT block validation!? */
     GNUNET_break (0);
@@ -2338,43 +2451,53 @@ handle_dht_response (void *cls,
   }
   block = data;
   if (size !=
-      ntohl (block->purpose.size) +
-      sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
-      sizeof (struct GNUNET_CRYPTO_EcdsaSignature))
+      ntohl (block->purpose.size)
+      + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
+      + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
   {
     /* how did this pass DHT block validation!? */
     GNUNET_break (0);
     fail_resolution (rh);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Decrypting DHT block of size %u for `%s', expires %s\n",
+              ntohl (block->purpose.size),
+              rh->name,
+              GNUNET_STRINGS_absolute_time_to_string (exp));
   if (GNUNET_OK !=
       GNUNET_GNSRECORD_block_decrypt (block,
-                                     &ac->authority_info.gns_authority,
-                                     ac->label,
-                                     &handle_gns_resolution_result,
-                                     rh))
+                                      &ac->authority_info.gns_authority,
+                                      ac->label,
+                                      &handle_gns_resolution_result,
+                                      rh))
   {
-    GNUNET_break_op (0); /* block was ill-formed */
+    GNUNET_break_op (0);  /* block was ill-formed */
     fail_resolution (rh);
     return;
   }
-  if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (block->expiration_time)).rel_value_us)
+  if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (
+                                                 block->expiration_time)).
+      rel_value_us)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Received expired block from the DHT, will not cache it.\n");
     return;
   }
+  if (GNUNET_YES == disable_cache)
+    return;
   /* Cache well-formed blocks */
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Caching response from the DHT in namecache\n");
+              "Caching response from the DHT in namecache\n");
   co = GNUNET_new (struct CacheOps);
   co->namecache_qe_cache = GNUNET_NAMECACHE_block_cache (namecache_handle,
-                                                        block,
-                                                        &namecache_cache_continuation,
-                                                        co);
+                                                         block,
+                                                         &
+                                                         namecache_cache_continuation,
+                                                         co);
   GNUNET_CONTAINER_DLL_insert (co_head,
-                              co_tail,
-                              co);
+                               co_tail,
+                               co);
 }
 
 
@@ -2400,8 +2523,10 @@ start_dht_request (struct GNS_ResolverHandle *rh,
                                          &handle_dht_response, rh);
   rh->dht_heap_node = GNUNET_CONTAINER_heap_insert (dht_lookup_heap,
                                                     rh,
-                                                    GNUNET_TIME_absolute_get ().abs_value_us);
-  if (GNUNET_CONTAINER_heap_get_size (dht_lookup_heap) > max_allowed_background_queries)
+                                                    GNUNET_TIME_absolute_get ().
+                                                    abs_value_us);
+  if (GNUNET_CONTAINER_heap_get_size (dht_lookup_heap) >
+      max_allowed_background_queries)
   {
     /* fail longest-standing DHT request */
     rx = GNUNET_CONTAINER_heap_remove_root (dht_lookup_heap);
@@ -2427,6 +2552,10 @@ handle_gns_namecache_resolution_result (void *cls,
 {
   struct GNS_ResolverHandle *rh = cls;
 
+  if (0 == rd_count)
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _ ("GNS namecache returned empty result for `%s'\n"),
+                rh->name);
   handle_gns_resolution_result (rh,
                                 rd_count,
                                 rd);
@@ -2441,21 +2570,24 @@ handle_gns_namecache_resolution_result (void *cls,
  */
 static void
 handle_namecache_block_response (void *cls,
-                                const struct GNUNET_GNSRECORD_Block *block)
+                                 const struct GNUNET_GNSRECORD_Block *block)
 {
   struct GNS_ResolverHandle *rh = cls;
   struct AuthorityChain *ac = rh->ac_tail;
   const char *label = ac->label;
-  const struct GNUNET_CRYPTO_EcdsaPublicKey *auth = &ac->authority_info.gns_authority;
+  const struct GNUNET_CRYPTO_EcdsaPublicKey *auth =
+    &ac->authority_info.gns_authority;
   struct GNUNET_HashCode query;
 
   GNUNET_assert (NULL != rh->namecache_qe);
   rh->namecache_qe = NULL;
-  if ( ( (GNUNET_GNS_LO_DEFAULT == rh->options) ||
-        ( (GNUNET_GNS_LO_LOCAL_MASTER == rh->options) &&
-          (ac != rh->ac_head) ) ) &&
-       ( (NULL == block) ||
-        (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (block->expiration_time)).rel_value_us) ) )
+  if (((GNUNET_GNS_LO_DEFAULT == rh->options) ||
+       ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) &&
+        (ac != rh->ac_head))) &&
+      ((NULL == block) ||
+       (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (
+                                                   block->expiration_time)).
+        rel_value_us)))
   {
     /* namecache knows nothing; try DHT lookup */
     GNUNET_GNSRECORD_query_from_public_key (auth,
@@ -2470,14 +2602,16 @@ handle_namecache_block_response (void *cls,
     return;
   }
 
-  if ( (NULL == block) ||
-       (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (block->expiration_time)).rel_value_us) )
+  if ((NULL == block) ||
+      (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (
+                                                  block->expiration_time)).
+       rel_value_us))
   {
     /* DHT not permitted and no local result, fail */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-               "Resolution failed for `%s' in zone %s (DHT lookup not permitted by configuration)\n",
-               ac->label,
-               GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
+                "Resolution failed for `%s' in zone %s (DHT lookup not permitted by configuration)\n",
+                ac->label,
+                GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
     fail_resolution (rh);
     return;
   }
@@ -2487,12 +2621,12 @@ handle_namecache_block_response (void *cls,
 
   if (GNUNET_OK !=
       GNUNET_GNSRECORD_block_decrypt (block,
-                                     auth,
-                                     label,
-                                     &handle_gns_namecache_resolution_result,
-                                     rh))
+                                      auth,
+                                      label,
+                                      &handle_gns_namecache_resolution_result,
+                                      rh))
   {
-    GNUNET_break_op (0); /* block was ill-formed */
+    GNUNET_break_op (0);  /* block was ill-formed */
     /* try DHT instead */
     GNUNET_GNSRECORD_query_from_public_key (auth,
                                             label,
@@ -2520,12 +2654,12 @@ recursive_gns_resolution_namecache (struct GNS_ResolverHandle *rh)
   struct GNUNET_HashCode query;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Starting GNS resolution for `%s' in zone %s\n",
-             ac->label,
-             GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
+              "Starting GNS resolution for `%s' in zone %s\n",
+              ac->label,
+              GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
   GNUNET_GNSRECORD_query_from_public_key (&ac->authority_info.gns_authority,
-                                         ac->label,
-                                         &query);
+                                          ac->label,
+                                          &query);
   if (GNUNET_YES != disable_cache)
   {
     rh->namecache_qe
@@ -2538,7 +2672,7 @@ recursive_gns_resolution_namecache (struct GNS_ResolverHandle *rh)
   else
   {
     start_dht_request (rh,
-                      &query);
+                       &query);
   }
 }
 
@@ -2560,7 +2694,7 @@ handle_revocation_result (void *cls,
   if (GNUNET_YES != is_valid)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("Zone %s was revoked, resolution fails\n"),
+                _ ("Zone %s was revoked, resolution fails\n"),
                 GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
     fail_resolution (rh);
     return;
@@ -2580,8 +2714,8 @@ recursive_gns_resolution_revocation (struct GNS_ResolverHandle *rh)
   struct AuthorityChain *ac = rh->ac_tail;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Starting revocation check for zone %s\n",
-             GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
+              "Starting revocation check for zone %s\n",
+              GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
   rh->rev_check = GNUNET_REVOCATION_query (cfg,
                                            &ac->authority_info.gns_authority,
                                            &handle_revocation_result,
@@ -2604,8 +2738,8 @@ recursive_resolution (void *cls)
   if (MAX_RECURSION < rh->loop_limiter++)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               "Encountered unbounded recursion resolving `%s'\n",
-               rh->name);
+                "Encountered unbounded recursion resolving `%s'\n",
+                rh->name);
     fail_resolution (rh);
     return;
   }
@@ -2639,7 +2773,7 @@ start_resolver_lookup (void *cls)
     struct GNUNET_GNSRECORD_Data rd;
 
     rd.data = &v4;
-    rd.data_size = sizeof (v4);
+    rd.data_size = sizeof(v4);
     rd.expiration_time = UINT64_MAX;
     rd.record_type = GNUNET_DNSPARSER_TYPE_A;
     rd.flags = 0;
@@ -2659,7 +2793,7 @@ start_resolver_lookup (void *cls)
     struct GNUNET_GNSRECORD_Data rd;
 
     rd.data = &v6;
-    rd.data_size = sizeof (v6);
+    rd.data_size = sizeof(v6);
     rd.expiration_time = UINT64_MAX;
     rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA;
     rd.flags = 0;
@@ -2677,15 +2811,15 @@ start_resolver_lookup (void *cls)
   ac->label = resolver_lookup_get_next_label (rh);
   if (NULL == ac->label)
     /* name was just the "TLD", so we default to label
-       #GNUNET_GNS_EMPTY_LABEL_AT */
+     #GNUNET_GNS_EMPTY_LABEL_AT */
     ac->label = GNUNET_strdup (GNUNET_GNS_EMPTY_LABEL_AT);
   ac->gns_authority = GNUNET_YES;
   ac->authority_info.gns_authority = rh->authority_zone;
   GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
-                                   rh->ac_tail,
-                                   ac);
+                                    rh->ac_tail,
+                                    ac);
   rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution,
-                                         rh);
+                                          rh);
 }
 
 
@@ -2703,21 +2837,21 @@ start_resolver_lookup (void *cls)
  */
 struct GNS_ResolverHandle *
 GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
-                    uint32_t record_type,
-                    const char *name,
-                    enum GNUNET_GNS_LocalOptions options,
-                    GNS_ResultProcessor proc,
-                    void *proc_cls)
+                     uint32_t record_type,
+                     const char *name,
+                     enum GNUNET_GNS_LocalOptions options,
+                     GNS_ResultProcessor proc,
+                     void *proc_cls)
 {
   struct GNS_ResolverHandle *rh;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Starting lookup for `%s'\n",
-             name);
+              name);
   rh = GNUNET_new (struct GNS_ResolverHandle);
   GNUNET_CONTAINER_DLL_insert (rlh_head,
-                              rlh_tail,
-                              rh);
+                               rlh_tail,
+                               rh);
   rh->authority_zone = *zone;
   rh->proc = proc;
   rh->proc_cls = proc_cls;
@@ -2726,7 +2860,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
   rh->name = GNUNET_strdup (name);
   rh->name_resolution_pos = strlen (name);
   rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
-                                         rh);
+                                          rh);
   return rh;
 }
 
@@ -2744,8 +2878,8 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
   struct VpnContext *vpn_ctx;
 
   GNUNET_CONTAINER_DLL_remove (rlh_head,
-                              rlh_tail,
-                              rh);
+                               rlh_tail,
+                               rh);
   if (NULL != rh->dns_request)
   {
     GNUNET_DNSSTUB_resolve_cancel (rh->dns_request);
@@ -2754,8 +2888,8 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
   while (NULL != (ac = rh->ac_head))
   {
     GNUNET_CONTAINER_DLL_remove (rh->ac_head,
-                                rh->ac_tail,
-                                ac);
+                                 rh->ac_tail,
+                                 ac);
     if (GNUNET_NO == ac->gns_authority)
     {
       struct Gns2DnsPending *gp;
@@ -2774,8 +2908,9 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
                                        rlh_tail,
                                        gp->rh);
           GNUNET_assert (NULL == gp->rh->task_id);
-          gp->rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_,
-                                                      gp->rh);
+          gp->rh->task_id = GNUNET_SCHEDULER_add_now (
+            &GNS_resolver_lookup_cancel_,
+            gp->rh);
           gp->rh = NULL;
         }
         if (NULL != gp->dns_rh)
@@ -2824,17 +2959,18 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
   if (NULL != rh->std_resolve)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-               "Canceling standard DNS resolution\n");
+                "Canceling standard DNS resolution\n");
     GNUNET_RESOLVER_request_cancel (rh->std_resolve);
     rh->std_resolve = NULL;
   }
   while (NULL != (dr = rh->dns_result_head))
   {
     GNUNET_CONTAINER_DLL_remove (rh->dns_result_head,
-                                rh->dns_result_tail,
-                                dr);
+                                 rh->dns_result_tail,
+                                 dr);
     GNUNET_free (dr);
   }
+  GNUNET_free_non_null (rh->leho);
   GNUNET_free (rh->name);
   GNUNET_free (rh);
 }
@@ -2853,9 +2989,9 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
  */
 void
 GNS_resolver_init (struct GNUNET_NAMECACHE_Handle *nc,
-                  struct GNUNET_DHT_Handle *dht,
-                  const struct GNUNET_CONFIGURATION_Handle *c,
-                  unsigned long long max_bg_queries)
+                   struct GNUNET_DHT_Handle *dht,
+                   const struct GNUNET_CONFIGURATION_Handle *c,
+                   unsigned long long max_bg_queries)
 {
   cfg = c;
   namecache_handle = nc;
@@ -2864,8 +3000,8 @@ GNS_resolver_init (struct GNUNET_NAMECACHE_Handle *nc,
     GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
   max_allowed_background_queries = max_bg_queries;
   disable_cache = GNUNET_CONFIGURATION_get_value_yesno (cfg,
-                                                       "namecache",
-                                                       "DISABLE");
+                                                        "namecache",
+                                                        "DISABLE");
   if (GNUNET_YES == disable_cache)
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Namecache disabled\n");
@@ -2893,8 +3029,8 @@ GNS_resolver_done ()
   while (NULL != (co = co_head))
   {
     GNUNET_CONTAINER_DLL_remove (co_head,
-                                co_tail,
-                                co);
+                                 co_tail,
+                                 co);
     GNUNET_NAMECACHE_cancel (co->namecache_qe_cache);
     GNUNET_free (co);
   }