-cleanup
[oweals/gnunet.git] / src / gns / gnunet-service-gns_resolver.c
index f17ff7135160a0a5c305c4a34106b0689db315f5..7258f97a145db1d532cbae4ff7b4955ebdffe7c2 100644 (file)
@@ -19,8 +19,6 @@
 */
 
 /**
- *
- *
  * @file gns/gnunet-service-gns_resolver.c
  * @brief GNUnet GNS resolver logic
  * @author Martin Schanzenbach
@@ -131,6 +129,11 @@ static struct ResolverHandle *nah_head;
  */
 static struct ResolverHandle *nah_tail;
 
+/**
+ * Global configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
 /**
  * a resolution identifier pool variable
  * FIXME overflow?
@@ -138,28 +141,36 @@ static struct ResolverHandle *nah_tail;
  */
 static unsigned long long rid = 0;
 
+/*
+ * Check if name is in srv format (_x._y.xxx)
+ *
+ * @param name
+ * @return GNUNET_YES if true
+ */
 static int
 is_srv (char* name)
 {
   char* ndup;
-  int ret = 1;
+  int ret = GNUNET_YES;
 
   if (*name != '_')
-    return 0;
+    return GNUNET_NO;
   if (NULL == strstr (name, "._"))
-    return 0;
+    return GNUNET_NO;
 
   ndup = GNUNET_strdup (name);
   strtok (ndup, ".");
 
   if (NULL == strtok (NULL, "."))
-    ret = 0;
+    ret = GNUNET_NO;
 
   if (NULL == strtok (NULL, "."))
-    ret = 0;
+    ret = GNUNET_NO;
 
   if (NULL != strtok (NULL, "."))
-    ret = 0;
+    ret = GNUNET_NO;
+
+  GNUNET_free (ndup);
 
   return ret;
 }
@@ -171,16 +182,16 @@ is_srv (char* name)
  * a           = canonical
  *
  * @param name the name to test
- * @return 1 if canonical
+ * @return GNUNET_YES if canonical
  */
 static int
-is_canonical(char* name)
+is_canonical (char* name)
 {
   char* ndup;
   char* tok;
 
   ndup = GNUNET_strdup (name);
-  tok = strtok (ndup, ".");
+  strtok (ndup, ".");
 
   for (tok = strtok (NULL, "."); tok != NULL; tok = strtok (NULL, "."))
   {
@@ -190,10 +201,10 @@ is_canonical(char* name)
     if (*tok == '_')
       continue;
     GNUNET_free (ndup);
-    return 0;
+    return GNUNET_NO;
   }
   GNUNET_free (ndup);
-  return 1;
+  return GNUNET_YES;
 }
 
 
@@ -719,20 +730,21 @@ start_shorten (struct AuthorityChain *atail,
  * @param nh the namestore handle
  * @param dh the dht handle
  * @param lz the local zone's hash
- * @param cfg configuration handle
+ * @param c configuration handle
  * @param max_bg_queries maximum number of parallel background queries in dht
  * @param ignore_pending ignore records that still require user confirmation
  *        on lookup
  * @return GNUNET_OK on success
  */
 int
-gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh,
-                  struct GNUNET_DHT_Handle *dh,
-                  struct GNUNET_CRYPTO_ShortHashCode lz,
-                  const struct GNUNET_CONFIGURATION_Handle *cfg,
-                  unsigned long long max_bg_queries,
-                  int ignore_pending)
+gns_resolver_init (struct GNUNET_NAMESTORE_Handle *nh,
+                  struct GNUNET_DHT_Handle *dh,
+                  struct GNUNET_CRYPTO_ShortHashCode lz,
+                  const struct GNUNET_CONFIGURATION_Handle *c,
+                  unsigned long long max_bg_queries,
+                  int ignore_pending)
 {
+  cfg = c;
   namestore_handle = nh;
   dht_handle = dh;
   local_zone = lz;
@@ -756,17 +768,6 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh,
   
   GNUNET_RESOLVER_connect (cfg);
   
-  if (NULL == vpn_handle)
-  {
-    vpn_handle = GNUNET_VPN_connect (cfg);
-    if (NULL == vpn_handle)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "GNS_PHASE_INIT: Error connecting to VPN!\n");
-
-      return GNUNET_SYSERR;
-    }
-  }
 
   if ((namestore_handle != NULL) && (dht_handle != NULL))
   {
@@ -911,6 +912,9 @@ free_resolver_handle (struct ResolverHandle* rh)
     GNUNET_NETWORK_socket_close (rh->dns_sock);
   if (NULL != rh->dns_resolver_handle)
     GNUNET_RESOLVER_request_cancel (rh->dns_resolver_handle);
+
+  if (NULL != rh->rd.data)
+    GNUNET_free ((void*)(rh->rd.data));
   GNUNET_free(rh);
 }
 
@@ -1081,7 +1085,7 @@ dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   char new_name[MAX_DNS_NAME_LENGTH];
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%d: dht lookup for query %s (%ds)timed out.\n",
+             "GNS_PHASE_REC-%llu: dht lookup for query %s (%llus)timed out.\n",
              rh->id, rh->name, rh->timeout.rel_value);
   /**
    * Start resolution in bg
@@ -1092,14 +1096,14 @@ dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                   rh->name, GNUNET_GNS_TLD);
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%d: Starting background lookup for %s type %d\n",
+             "GNS_PHASE_REC-%llu: Starting background lookup for %s type %d\n",
              rh->id, new_name, rlh->record_type);
 
   gns_resolver_lookup_record(rh->authority,
                              rh->private_local_zone,
                              rlh->record_type,
                              new_name,
-                             rh->priv_key,
+                             NULL,
                              GNUNET_TIME_UNIT_FOREVER_REL,
                              GNUNET_NO,
                              &background_lookup_result_processor,
@@ -1149,7 +1153,7 @@ process_record_result_dht(void* cls,
 
   rh = (struct ResolverHandle *)cls;
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%d: got dht result (size=%d)\n", rh->id, size);
+             "GNS_PHASE_REC-%llu: got dht result (size=%d)\n", rh->id, size);
 
   //FIXME maybe check expiration here, check block type
 
@@ -1190,23 +1194,23 @@ process_record_result_dht(void* cls,
                                                                rd))
     {
       GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
-                 "GNS_PHASE_REC-%d: Error deserializing data!\n", rh->id);
+                 "GNS_PHASE_REC-%llu: Error deserializing data!\n", rh->id);
       return;
     }
 
     for (i=0; i<num_records; i++)
     {
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Got name: %s (wanted %s)\n",
+                 "GNS_PHASE_REC-%llu: Got name: %s (wanted %s)\n",
                  rh->id, name, rh->name);
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Got type: %d (wanted %d)\n",
+                 "GNS_PHASE_REC-%llu: Got type: %d (wanted %d)\n",
                  rh->id, rd[i].record_type, rlh->record_type);
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Got data length: %d\n",
+                 "GNS_PHASE_REC-%llu: Got data length: %d\n",
                  rh->id, rd[i].data_size);
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Got flag %d\n",
+                 "GNS_PHASE_REC-%llu: Got flag %d\n",
                  rh->id, rd[i].flags);
 
       if ((strcmp(name, rh->name) == 0) &&
@@ -1228,7 +1232,7 @@ process_record_result_dht(void* cls,
       GNUNET_NAMESTORE_cancel (ns_heap_root->qe);
 
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Replacing oldest background ns task\n",
+                 "GNS_PHASE_REC-%llu: Replacing oldest background ns task\n",
                  rh->id);
     }
     
@@ -1283,7 +1287,7 @@ resolve_record_dht (struct ResolverHandle *rh)
   GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string);
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%d: starting dht lookup for %s with key: %s\n",
+             "GNS_PHASE_REC-%llu: starting dht lookup for %s with key: %s\n",
              rh->id, rh->name, (char*)&lookup_key_string);
 
   //rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
@@ -1298,7 +1302,7 @@ resolve_record_dht (struct ResolverHandle *rh)
     {
 
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Adjusting timeout\n", rh->id);
+                 "GNS_PHASE_REC-%llu: Adjusting timeout\n", rh->id);
       /*
        * Set timeout for authority lookup phase to 1/2
        */
@@ -1324,7 +1328,7 @@ resolve_record_dht (struct ResolverHandle *rh)
       rh_heap_root->dht_heap_node = NULL;
 
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Replacing oldest background query for %s\n",
+                 "GNS_PHASE_REC-%llu: Replacing oldest background query for %s\n",
                  rh->id, rh_heap_root->name);
       rh_heap_root->proc(rh_heap_root->proc_cls,
                          rh_heap_root,
@@ -1408,11 +1412,11 @@ process_record_result_ns (void* cls,
      * Lookup terminated and no results
      */
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: Namestore lookup for %s terminated without results\n",
+               "GNS_PHASE_REC-%llu: Namestore lookup for %s terminated without results\n",
                rh->id, name);
 
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: Record %s unknown in namestore\n",
+               "GNS_PHASE_REC-%llu: Record %s unknown in namestore\n",
                rh->id, rh->name);
     /**
      * Our zone and no result? Cannot resolve TT
@@ -1424,7 +1428,7 @@ process_record_result_ns (void* cls,
   else
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: Processing additional result %s from namestore\n",
+               "GNS_PHASE_REC-%llu: Processing additional result %s from namestore\n",
                rh->id, name);
     for (i=0; i<rd_count;i++)
     {
@@ -1435,7 +1439,7 @@ process_record_result_ns (void* cls,
           (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING))
       {
         GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                   "GNS_PHASE_REC-%d: Record %s is awaiting user confirmation. Skipping\n",
+                   "GNS_PHASE_REC-%llu: Record %s is awaiting user confirmation. Skipping\n",
                    rh->id, name);
         continue;
       }
@@ -1446,7 +1450,7 @@ process_record_result_ns (void* cls,
           == 0)
       {
         GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                   "GNS_PHASE_REC-%d: This record is expired. Skipping\n",
+                   "GNS_PHASE_REC-%llu: This record is expired. Skipping\n",
                    rh->id);
         continue;
       }
@@ -1459,13 +1463,13 @@ process_record_result_ns (void* cls,
     if (rh->answered == 0)
     {
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 
-                 "GNS_PHASE_REC-%d: No answers found. This is odd!\n", rh->id);
+                 "GNS_PHASE_REC-%llu: No answers found. This is odd!\n", rh->id);
       rh->proc(rh->proc_cls, rh, 0, NULL);
       return;
     }
 
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: Found %d answer(s) to query in %d records!\n",
+               "GNS_PHASE_REC-%llu: Found %d answer(s) to query in %d records!\n",
                rh->id, rh->answered, rd_count);
 
     rh->proc(rh->proc_cls, rh, rd_count, rd);
@@ -1490,17 +1494,17 @@ process_record_result_vpn (void* cls, int af, const void *address)
   rlh = (struct RecordLookupHandle *)rh->proc_cls;
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC_VPN-%d: Got answer from VPN to query!\n",
+             "GNS_PHASE_REC_VPN-%llu: Got answer from VPN to query!\n",
              rh->id);
   if (af == AF_INET)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: Answer is IPv4!\n",
+               "GNS_PHASE_REC-%llu: Answer is IPv4!\n",
                rh->id);
     if (rlh->record_type != GNUNET_GNS_RECORD_A)
     {
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Requested record is not IPv4!\n",
+                 "GNS_PHASE_REC-%llu: Requested record is not IPv4!\n",
                  rh->id);
       rh->proc (rh->proc_cls, rh, 0, NULL);
       return;
@@ -1516,12 +1520,12 @@ process_record_result_vpn (void* cls, int af, const void *address)
   else if (af == AF_INET6)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: Answer is IPv6!\n",
+               "GNS_PHASE_REC-%llu: Answer is IPv6!\n",
                rh->id);
     if (rlh->record_type != GNUNET_GNS_RECORD_AAAA)
     {
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                 "GNS_PHASE_REC-%d: Requested record is not IPv6!\n",
+                 "GNS_PHASE_REC-%llu: Requested record is not IPv6!\n",
                  rh->id);
       rh->proc (rh->proc_cls, rh, 0, NULL);
       return;
@@ -1536,7 +1540,7 @@ process_record_result_vpn (void* cls, int af, const void *address)
   }
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%d: Got garbage from VPN!\n",
+             "GNS_PHASE_REC-%llu: Got garbage from VPN!\n",
              rh->id);
   rh->proc (rh->proc_cls, rh, 0, NULL);
 }
@@ -1562,7 +1566,7 @@ handle_record_vpn (void* cls, struct ResolverHandle *rh,
   if (rd_count == 0)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC_VPN-%d: VPN returned no records. (status: %d)!\n",
+               "GNS_PHASE_REC_VPN-%llu: VPN returned no records. (status: %d)!\n",
                rh->id,
                rh->status);
     /* give up, cannot resolve */
@@ -1572,7 +1576,7 @@ handle_record_vpn (void* cls, struct ResolverHandle *rh,
 
   /* results found yay */
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC_VPN-%d: Record resolved from VPN!", rh->id);
+             "GNS_PHASE_REC_VPN-%llu: Record resolved from VPN!", rh->id);
 
   finish_lookup(rh, rlh, rd_count, rd);
 }
@@ -1883,7 +1887,8 @@ resolve_record_dns (struct ResolverHandle *rh,
     rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   }
   /* Start shortening */
-  if ((rh->priv_key != NULL) && is_canonical (rh->name))
+  if ((rh->priv_key != NULL) &&
+      (is_canonical (rh->name) == GNUNET_YES))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "GNS_PHASE_REC_DNS-%llu: Trying to shorten authority chain\n",
@@ -2002,7 +2007,8 @@ resolve_record_vpn (struct ResolverHandle *rh,
     rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   }
   /* Start shortening */
-  if ((rh->priv_key != NULL) && is_canonical (rh->name))
+  if ((rh->priv_key != NULL) &&
+      (is_canonical (rh->name) == GNUNET_YES))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "GNS_PHASE_REC_VPN-%llu: Trying to shorten authority chain\n",
@@ -2045,14 +2051,27 @@ resolve_record_vpn (struct ResolverHandle *rh,
     af = AF_INET6;
   
   //FIXME timeout??
+  if (NULL == vpn_handle)
+  {
+    vpn_handle = GNUNET_VPN_connect (cfg);
+    if (NULL == vpn_handle)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "GNS_PHASE_INIT: Error connecting to VPN!\n");
+      finish_lookup (rh, rh->proc_cls, 0, NULL);
+      return;
+    }
+  }
+
+
   rh->vpn_handle = GNUNET_VPN_redirect_to_peer (vpn_handle,
-                                          af, ntohs (vpn->proto),
-                                          (struct GNUNET_PeerIdentity *)&vpn->peer,
-                                          &serv_desc,
-                                          GNUNET_NO, //nac
-                                          GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME
-                                          &process_record_result_vpn,
-                                          rh);
+                                               af, ntohs (vpn->proto),
+                                               (struct GNUNET_PeerIdentity *)&vpn->peer,
+                                               &serv_desc,
+                                               GNUNET_NO, //nac
+                                               GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME
+                                               &process_record_result_vpn,
+                                               rh);
 
 }
 
@@ -2075,7 +2094,8 @@ resolve_record_ns(struct ResolverHandle *rh)
     rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   }
   /* Start shortening */
-  if ((rh->priv_key != NULL) && is_canonical (rh->name))
+  if ((rh->priv_key != NULL) &&
+     (is_canonical (rh->name) == GNUNET_YES))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "GNS_PHASE_REC-%llu: Trying to shorten authority chain\n",
@@ -2115,14 +2135,16 @@ dht_authority_lookup_timeout(void *cls,
   char new_name[MAX_DNS_NAME_LENGTH];
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-         "GNS_PHASE_DELEGATE_DHT-%llu: dht lookup for query %s (%ds)timed out.\n",
+         "GNS_PHASE_DELEGATE_DHT-%llu: dht lookup for query %s (%llus)timed out.\n",
          rh->id, rh->authority_name, rh->timeout.rel_value);
 
   rh->status |= RSL_TIMED_OUT;
 
   rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   
-  GNUNET_DHT_get_stop (rh->get_handle);
+  if (NULL != rh->get_handle)
+    GNUNET_DHT_get_stop (rh->get_handle);
+
   rh->get_handle = NULL;
   
   if (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
@@ -2163,7 +2185,7 @@ dht_authority_lookup_timeout(void *cls,
                              rh->private_local_zone,
                              rlh->record_type,
                              new_name,
-                             rh->priv_key,
+                             NULL,
                              GNUNET_TIME_UNIT_FOREVER_REL,
                              GNUNET_NO,
                              &background_lookup_result_processor,
@@ -2243,14 +2265,14 @@ process_pkey_revocation_result_ns (void *cls,
     if (rh->timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
     {
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-        "GNS_PHASE_DELEGATE_REV-%d: Starting background lookup for %s type %d\n",
+        "GNS_PHASE_DELEGATE_REV-%llu: Starting background lookup for %s type %d\n",
         rh->id, "+.gnunet", GNUNET_GNS_RECORD_REV);
 
       gns_resolver_lookup_record(rh->authority,
                                  rh->private_local_zone,
                                  GNUNET_GNS_RECORD_REV,
                                  GNUNET_GNS_TLD,
-                                 rh->priv_key,
+                                 NULL,
                                  GNUNET_TIME_UNIT_FOREVER_REL,
                                  GNUNET_NO,
                                  &background_lookup_result_processor,
@@ -2258,16 +2280,17 @@ process_pkey_revocation_result_ns (void *cls,
     }
   }
  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_DELEGATE_REV-%llu: Revocation checkpassed\n",
+             "GNS_PHASE_DELEGATE_REV-%llu: Revocation check passed\n",
              rh->id);
   /**
    * We are done with PKEY resolution if name is empty
    * else resolve again with new authority
    */
   if (strcmp (rh->name, "") == 0)
-    rh->proc (rh->proc_cls, rh, 0, NULL);
+    rh->proc (rh->proc_cls, rh, rh->rd_count, &rh->rd);
   else
     resolve_delegation_ns (rh);
+
   return;
 }
 
@@ -2437,6 +2460,14 @@ process_delegation_result_dht(void* cls,
                                      rh->authority_chain_tail,
                                      auth);
 
+        if (NULL != rh->rd.data)
+          GNUNET_free ((void*)rh->rd.data);
+        
+        memcpy (&rh->rd, &rd[i], sizeof (struct GNUNET_NAMESTORE_RecordData));
+        rh->rd.data = GNUNET_malloc (rd[i].data_size);
+        memcpy ((void*)(rh->rd.data), rd[i].data, rd[i].data_size);
+        rh->rd_count = 1;
+
         /** try to import pkey if private key available */
         //if (rh->priv_key && is_canonical (rh->name))
         //  process_discovered_authority(name, auth->zone,
@@ -2463,7 +2494,7 @@ process_delegation_result_dht(void* cls,
         GNUNET_NAMESTORE_cancel (ns_heap_root->qe);
 
         GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-                   "GNS_PHASE_REC-%d: Replacing oldest background ns task\n",
+                   "GNS_PHASE_REC-%llu: Replacing oldest background ns task\n",
                    rh->id);
       }
       
@@ -2498,7 +2529,8 @@ process_delegation_result_dht(void* cls,
     if (strcmp(rh->name, "") == 0)
     {
       /* Start shortening */
-      if ((rh->priv_key != NULL) && is_canonical (rh->name))
+      if ((rh->priv_key != NULL) &&
+          (is_canonical (rh->name) == GNUNET_YES))
       {
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "GNS_PHASE_DELEGATE_DHT-%llu: Trying to shorten authority chain\n",
@@ -2510,6 +2542,7 @@ process_delegation_result_dht(void* cls,
     else
       rh->proc = &handle_delegation_ns;
 
+
     /* Check for key revocation and delegate */
     rh->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle,
                                     &rh->authority,
@@ -2724,7 +2757,7 @@ handle_record_dht(void* cls, struct ResolverHandle *rh,
   if (rd_count == 0)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: No records for %s found in DHT. Aborting\n",
+               "GNS_PHASE_REC-%llu: No records for %s found in DHT. Aborting\n",
                rh->id, rh->name);
     /* give up, cannot resolve */
     finish_lookup(rh, rlh, 0, NULL);
@@ -2733,7 +2766,7 @@ handle_record_dht(void* cls, struct ResolverHandle *rh,
 
   /* results found yay */
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%d: Record resolved from DHT!", rh->id);
+             "GNS_PHASE_REC-%llu: Record resolved from DHT!", rh->id);
 
   finish_lookup(rh, rlh, rd_count, rd);
 
@@ -2762,7 +2795,7 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
   if (rd_count == 0)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_REC-%d: NS returned no records. (status: %d)!\n",
+               "GNS_PHASE_REC-%llu: NS returned no records. (status: %d)!\n",
                rh->id,
                rh->status);
     
@@ -2785,7 +2818,7 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
                                           &rh->private_local_zone))
       check_dht = GNUNET_NO;
     
-    if ((strcmp (rh->name, "+") != 0) && (is_srv (rh->name) != 0))
+    if ((strcmp (rh->name, "+") != 0) && (is_srv (rh->name) == GNUNET_YES))
         check_dht = GNUNET_NO;
 
 
@@ -2805,7 +2838,7 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
 
   /* results found yay */
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%d: Record resolved from namestore!\n", rh->id);
+             "GNS_PHASE_REC-%llu: Record resolved from namestore!\n", rh->id);
 
   finish_lookup(rh, rlh, rd_count, rd);
 
@@ -2825,7 +2858,7 @@ pop_tld(char* name, char* dest)
 {
   uint32_t len;
 
-  if (is_canonical (name))
+  if (is_canonical (name) == GNUNET_YES)
   {
     strcpy(dest, name);
     strcpy(name, "");
@@ -2914,7 +2947,7 @@ handle_delegation_dht(void* cls, struct ResolverHandle *rh,
   /**
    * we still have some left
    **/
-  if (is_canonical(rh->name))
+  if (is_canonical (rh->name) == GNUNET_YES)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
              "GNS_PHASE_DELEGATE_DHT-%llu: Resolving canonical record %s in ns\n",
@@ -3137,7 +3170,6 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh,
       }
       else if (rlh->record_type == GNUNET_GNS_RECORD_PKEY)
       {
-        GNUNET_assert(rd_count == 1);
         GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
                    "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried PKEY in NS.\n",
                    rh->id);
@@ -3194,7 +3226,7 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh,
 
   if (check_dht == GNUNET_NO)
   {
-    if (is_canonical(rh->name))
+    if (is_canonical (rh->name) == GNUNET_YES)
     {
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
                  "GNS_PHASE_DELEGATE_NS-%llu: Resolving canonical record %s\n",
@@ -3422,7 +3454,13 @@ process_delegation_result_ns (void* cls,
     GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head,
                                  rh->authority_chain_tail,
                                  auth);
+    if (NULL != rh->rd.data)
+      GNUNET_free ((void*)(rh->rd.data));
     
+    memcpy (&rh->rd, &rd[i], sizeof (struct GNUNET_NAMESTORE_RecordData));
+    rh->rd.data = GNUNET_malloc (rd[i].data_size);
+    memcpy ((void*)rh->rd.data, rd[i].data, rd[i].data_size);
+    rh->rd_count = 1;
     /* Check for key revocation and delegate */
     rh->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle,
                                     &rh->authority,
@@ -3443,10 +3481,11 @@ process_delegation_result_ns (void* cls,
    * If we have found some records for the LAST label
    * we return the results. Else null.
    */
-  if (strcmp(rh->name, "") == 0)
+  if (strcmp (rh->name, "") == 0)
   {
     /* Start shortening */
-    if ((rh->priv_key != NULL) && is_canonical (rh->name))
+    if ((rh->priv_key != NULL) &&
+        (is_canonical (rh->name) == GNUNET_YES))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "GNS_PHASE_DELEGATE_NS-%llu: Trying to shorten authority chain\n",
@@ -3455,15 +3494,18 @@ process_delegation_result_ns (void* cls,
                     rh->priv_key);
     }
     /* simply promote back */
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n",
-               rh->id, rh->authority_name);
-    strcpy(rh->name, rh->authority_name);
-    rh->proc(rh->proc_cls, rh, rd_count, rd);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n",
+                rh->id, rh->authority_name);
+    strcpy (rh->name, rh->authority_name);
+    rh->proc (rh->proc_cls, rh, rd_count, rd);
   }
   else
   {
-    rh->proc(rh->proc_cls, rh, 0, NULL);
+    GNUNET_snprintf (new_name, MAX_DNS_NAME_LENGTH,
+                     "%s.%s", rh->name, rh->authority_name);
+    strcpy (rh->name, new_name);
+    rh->proc (rh->proc_cls, rh, 0, NULL);
   }
 }
 
@@ -3526,7 +3568,8 @@ gns_resolver_lookup_record (struct GNUNET_CRYPTO_ShortHashCode zone,
               name, record_type);
 
   
-  if (is_canonical((char*)name) && (strcmp(GNUNET_GNS_TLD, name) != 0))
+  if ((is_canonical ((char*)name) == GNUNET_YES) &&
+      (strcmp(GNUNET_GNS_TLD, name) != 0))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "%s is canonical and not gnunet -> cannot resolve!\n", name);
@@ -3547,6 +3590,7 @@ gns_resolver_lookup_record (struct GNUNET_CRYPTO_ShortHashCode zone,
   rh->private_local_zone = pzone;
   rh->only_cached = only_cached;
   rh->namestore_task = NULL;
+  rh->rd.data = NULL;
 
   GNUNET_CONTAINER_DLL_insert (rlh_head, rlh_tail, rh);
   
@@ -3620,7 +3664,7 @@ gns_resolver_lookup_record (struct GNUNET_CRYPTO_ShortHashCode zone,
       }
 
     }
-    else
+    else if (is_gnunet_tld (name) == GNUNET_YES)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "TLD is gnunet\n");
@@ -3632,6 +3676,19 @@ gns_resolver_lookup_record (struct GNUNET_CRYPTO_ShortHashCode zone,
       memcpy (rh->name, name,
               strlen(name)-strlen(GNUNET_GNS_TLD) - 1);
     }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Cannot handle this TLD %s\n", string_hash);
+      
+      if (GNUNET_SCHEDULER_NO_TASK != rh->timeout_task)
+        GNUNET_SCHEDULER_cancel (rh->timeout_task);
+      GNUNET_CONTAINER_DLL_remove (rlh_head, rlh_tail, rh);
+      GNUNET_free (rh);
+      GNUNET_free (rlh);
+      proc (cls, 0, NULL);
+      return;
+    }
   }
   
   /**
@@ -3642,6 +3699,7 @@ gns_resolver_lookup_record (struct GNUNET_CRYPTO_ShortHashCode zone,
   rh->authority_chain_head->next = NULL;
   rh->authority_chain_tail = rh->authority_chain_head;
   rh->authority_chain_head->zone = rh->authority;
+  strcpy (rh->authority_chain_head->name, "");
   
   /**
    * Copy original query into lookup handle
@@ -3982,7 +4040,7 @@ process_zone_to_name_shorten_root (void *cls,
       strcpy (nsh->result, result);
   }
   
-  if (0 != strcmp (nsh->private_zone_name, ""))
+  if (NULL != nsh->private_zone)
   {
     /* backtrack authorities for names in priv zone */
     rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle,
@@ -3991,7 +4049,7 @@ process_zone_to_name_shorten_root (void *cls,
                                    &process_zone_to_name_shorten_private,
                                    rh);
   }
-  else if (0 != strcmp (nsh->shorten_zone_name, ""))
+  else if (NULL != nsh->shorten_zone)
   {
     /* backtrack authorities for names in shorten zone */
     rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle,
@@ -4084,15 +4142,15 @@ handle_delegation_ns_shorten (void* cls,
       strcpy (nsh->result, result);
 
   }
-  else if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
-                                        nsh->private_zone) == 0)
+  else if (NULL != nsh->private_zone)
   {
     /**
      * This is our zone append .gnunet unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
-    if (0 != strcmp (nsh->private_zone_name, ""))
+    if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+                                     nsh->private_zone) == 0)
     {
     
       sprintf (result, "%s.%s.%s",
@@ -4105,15 +4163,15 @@ handle_delegation_ns_shorten (void* cls,
         strcpy (nsh->result, result);
     }
   }
-  else if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
-                                        nsh->shorten_zone) == 0)
+  else if (NULL != nsh->shorten_zone)
   {
     /**
      * This is our zone append .gnunet unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
-    if (0 != strcmp (nsh->shorten_zone_name, ""))
+    if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+                                     nsh->shorten_zone) == 0)
     {
       sprintf (result, "%s.%s.%s",
                rh->name, nsh->private_zone_name, GNUNET_GNS_TLD);
@@ -4244,7 +4302,7 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Starting shorten for %s!\n", name);
   
-  if (is_canonical ((char*)name))
+  if (is_canonical ((char*)name) == GNUNET_YES)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "%s is canonical. Returning verbatim\n", name);
@@ -4318,7 +4376,7 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
     return;
 
   }
-  else
+  else if (is_gnunet_tld (name) == GNUNET_YES)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "TLD is gnunet\n");
@@ -4330,6 +4388,15 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
     memcpy (rh->name, name,
             strlen (name)-strlen (GNUNET_GNS_TLD) - 1);
   }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown TLD in %s\n", name);
+    GNUNET_free (rh);
+    GNUNET_free (nsh);
+    GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh);
+    proc (proc_cls, name);
+    return;
+  }
 
   rh->authority_chain_head = GNUNET_malloc (sizeof (struct AuthorityChain));
   rh->authority_chain_tail = rh->authority_chain_head;
@@ -4342,6 +4409,12 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
 
 /*********** END NAME SHORTEN ********************/
 
+/**
+ * Conclude get authority lookup
+ *
+ * @param rh resolver handle
+ * @param nah get authority lookup handle
+ */
 static void
 finish_get_auth (struct ResolverHandle *rh,
                  struct GetNameAuthorityHandle *nah)
@@ -4387,7 +4460,7 @@ handle_delegation_result_ns_get_auth(void* cls,
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
              "Building response!\n");
-  if (is_canonical(rh->name))
+  if (is_canonical (rh->name) == GNUNET_YES)
   {
     /**
      * We successfully resolved the authority in the ns