-more rsa refactoring
[oweals/gnunet.git] / src / gns / gnunet-service-gns_resolver.c
index 846b4db5bf7146f1d5fa7b2ad4aa550248fa1b9f..964f798d0faf0790428c4d598c201878714f43b8 100644 (file)
 #include "gnunet_dnsparser_lib.h"
 #include "gns_protocol.h"
 #include "gnunet_gns_service.h"
+#include "gns_common.h"
 #include "block_gns.h"
 #include "gns.h"
 #include "gnunet-service-gns_resolver.h"
 
+/**
+ * Default DHT timeout
+ */
 #define DHT_LOOKUP_TIMEOUT DHT_OPERATION_TIMEOUT
+
+/**
+ * DHT replication level
+ */
 #define DHT_GNS_REPLICATION_LEVEL 5
+
+/**
+ * Maximum label length of DNS names
+ */
 #define MAX_DNS_LABEL_LENGTH 63
 
 
@@ -136,7 +148,6 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 /**
  * a resolution identifier pool variable
- * FIXME overflow?
  * This is a non critical identifier useful for debugging
  */
 static unsigned long long rid = 0;
@@ -176,38 +187,51 @@ is_srv (char* name)
 }
 
 /**
- * Determine if this name is canonical.
- * i.e.
- * a.b.gnunet  = not canonical
- * a           = canonical
+ * Determine if this name is canonical (is a legal name in a zone, without delegation);
+ * note that we do not test that the name does not contain illegal characters, we only
+ * test for delegation.  Note that service records (i.e. _foo._srv) are canonical names
+ * even though they consist of multiple labels.
+ *
+ * Examples:
+ * a.b.gads  = not canonical
+ * a         = canonical
+ * _foo._srv = canonical
+ * _f.bar    = not canonical
  *
  * @param name the name to test
  * @return GNUNET_YES if canonical
  */
 static int
-is_canonical (char* name)
+is_canonical (const char* name)
 {
-  char* ndup;
-  char* tok;
+  const char *pos;
+  const char *dot;
 
-  ndup = GNUNET_strdup (name);
-  strtok (ndup, ".");
-
-  for (tok = strtok (NULL, "."); tok != NULL; tok = strtok (NULL, "."))
-  {
-    /*
-     * probably srv
-     */
-    if (*tok == '_')
-      continue;
-    GNUNET_free (ndup);
+  if (NULL == strchr (name, '.'))
+    return GNUNET_YES;
+  if ('_' != name[0])
     return GNUNET_NO;
-  }
-  GNUNET_free (ndup);
+  pos = &name[1];
+  while (NULL != (dot = strchr (pos, '.')))    
+    if ('_' != dot[1])
+      return GNUNET_NO;
+    else
+      pos = dot + 1;
   return GNUNET_YES;
 }
 
 
+static void
+free_get_pseu_authority_handle (struct GetPseuAuthorityHandle *gph)
+{
+  gph->namestore_task = NULL;
+  GNUNET_free (gph->auth);
+  GNUNET_CRYPTO_rsa_key_free (gph->key);
+  GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph);
+  GNUNET_free (gph);
+}
+
+
 /**
  * Callback that shortens authorities
  *
@@ -228,13 +252,9 @@ static void
 create_pkey_cont (void* cls, int32_t success, const char* emsg)
 {
   //FIXME do sth with error
-  struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls;
+  struct GetPseuAuthorityHandle* gph = cls;
 
-  gph->namestore_task = NULL;
-  GNUNET_free (gph->auth);
-  GNUNET_CRYPTO_rsa_key_free (gph->key);
-  GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph);
-  GNUNET_free (gph);
+  free_get_pseu_authority_handle (gph);
 }
 
 
@@ -252,13 +272,13 @@ create_pkey_cont (void* cls, int32_t success, const char* emsg)
  */
 static void
 process_pseu_lookup_ns (void* cls,
-                      const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key,
-                      struct GNUNET_TIME_Absolute expiration,
-                      const char *name, unsigned int rd_count,
-                      const struct GNUNET_NAMESTORE_RecordData *rd,
-                      const struct GNUNET_CRYPTO_RsaSignature *signature)
+                       const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key,
+                       struct GNUNET_TIME_Absolute expiration,
+                       const char *name, unsigned int rd_count,
+                       const struct GNUNET_NAMESTORE_RecordData *rd,
+                       const struct GNUNET_CRYPTO_RsaSignature *signature)
 {
-  struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls;
+  struct GetPseuAuthorityHandle* gph = cls;
   struct GNUNET_NAMESTORE_RecordData new_pkey;
 
   gph->namestore_task = NULL;
@@ -266,10 +286,7 @@ process_pseu_lookup_ns (void* cls,
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
                "GNS_AUTO_PSEU: Name %s already taken in NS!\n", name);
-    GNUNET_free (gph->auth);
-    GNUNET_CRYPTO_rsa_key_free (gph->key);
-    GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph);
-    GNUNET_free (gph);
+    free_get_pseu_authority_handle (gph);
     return;
   }
 
@@ -285,11 +302,11 @@ process_pseu_lookup_ns (void* cls,
                  | GNUNET_NAMESTORE_RF_PRIVATE
                  | GNUNET_NAMESTORE_RF_PENDING;
   gph->namestore_task = GNUNET_NAMESTORE_record_create (namestore_handle,
-                                  gph->key,
-                                  gph->test_name,
-                                  &new_pkey,
-                                  &create_pkey_cont, //cont
-                                  gph); //cls
+                                                       gph->key,
+                                                       gph->test_name,
+                                                       &new_pkey,
+                                                       &create_pkey_cont, 
+                                                       gph);
 }
 
 /**
@@ -305,15 +322,11 @@ process_pseu_result (struct GetPseuAuthorityHandle* gph, char* name)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "GNS_AUTO_PSEU: No PSEU, no shorten. Finished.\n");
-    GNUNET_free (gph->auth);
-    GNUNET_CRYPTO_rsa_key_free (gph->key);
-    GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph);
-    GNUNET_free (gph);
+    free_get_pseu_authority_handle (gph);
     return;
   }
   
-  memcpy (gph->test_name, name, strlen(name)+1);
-
+  memcpy (gph->test_name, name, strlen(name) + 1);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "GNS_AUTO_PSEU: Checking %s for collision in NS\n",
               gph->test_name);
@@ -321,13 +334,14 @@ process_pseu_result (struct GetPseuAuthorityHandle* gph, char* name)
    * Check for collision
    */
   gph->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle,
-                                  &gph->our_zone,
-                                  gph->test_name,
-                                  GNUNET_NAMESTORE_TYPE_ANY,
-                                  &process_pseu_lookup_ns,
-                                  gph);
+                                                       &gph->our_zone,
+                                                       gph->test_name,
+                                                       GNUNET_NAMESTORE_TYPE_ANY,
+                                                       &process_pseu_lookup_ns,
+                                                       gph);
 }
 
+
 /**
  * Handle timeout for dht request
  *
@@ -347,6 +361,7 @@ handle_auth_discovery_timeout (void *cls,
   process_pseu_result (gph, NULL);
 }
 
+
 /**
  * Function called when we find a PSEU entry in the DHT
  *
@@ -375,7 +390,7 @@ process_auth_discovery_dht_result (void* cls,
 {
   struct GetPseuAuthorityHandle* gph = cls;
   struct GNSNameRecordBlock *nrb;
-  char* rd_data = (char*)data;
+  const char* rd_data = data;
   char* name;
   int num_records;
   size_t rd_size;
@@ -389,14 +404,11 @@ process_auth_discovery_dht_result (void* cls,
   gph->get_handle = NULL;
   GNUNET_SCHEDULER_cancel (gph->timeout);
   
-  if (data == NULL)
+  if (NULL == data)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "GNS_GET_AUTH: got dht result null!\n", size);
-    GNUNET_free (gph->auth);
-    GNUNET_CRYPTO_rsa_key_free (gph->key);
-    GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph);
-    GNUNET_free (gph);
+    free_get_pseu_authority_handle (gph);
     return;
   }
   
@@ -436,6 +448,7 @@ process_auth_discovery_dht_result (void* cls,
   process_pseu_result (gph, NULL);
 }
 
+
 /**
  * Process PSEU discovery for shorten via namestore
  *
@@ -457,30 +470,19 @@ process_auth_discovery_ns_result (void* cls,
                       const struct GNUNET_CRYPTO_RsaSignature *signature)
 {
   struct GetPseuAuthorityHandle* gph = cls;
-  struct GNUNET_CRYPTO_ShortHashCode name_hash;
   struct GNUNET_HashCode lookup_key;
-  struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string;
-  struct GNUNET_HashCode name_hash_double;
-  struct GNUNET_HashCode zone_hash_double;
-  int i;
+  unsigned int i;
   uint32_t xquery;
   
   gph->namestore_task = NULL;
   /* no pseu found */
   if (0 == rd_count)
   {
-    /**
-     * check dht
-     */
-    GNUNET_CRYPTO_short_hash ("+", strlen ("+"), &name_hash);
-    GNUNET_CRYPTO_short_hash_double (&name_hash, &name_hash_double);
-    GNUNET_CRYPTO_short_hash_double (&gph->auth->zone, &zone_hash_double);
-    GNUNET_CRYPTO_hash_xor (&name_hash_double, &zone_hash_double, &lookup_key);
-    GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string);
-
+    GNUNET_GNS_get_key_for_record (GNUNET_GNS_TLD_PLUS, &gph->auth->zone, &lookup_key);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_AUTO_PSEU: starting dht lookup for %s with key: %s\n",
-               "+", (char*)&lookup_key_string);
+               "GNS_AUTO_PSEU: starting dht lookup for %s with key: %s\n",
+               GNUNET_GNS_TLD_PLUS, 
+               GNUNET_h2s (&lookup_key));
 
     gph->timeout = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT,
                                          &handle_auth_discovery_timeout, gph);
@@ -503,7 +505,7 @@ process_auth_discovery_ns_result (void* cls,
 
   for (i=0; i < rd_count; i++)
   {
-    if (0 != (strcmp (name, "+")))
+    if (0 != (strcmp (name, GNUNET_GNS_TLD_PLUS)))
       continue;
 
     if (rd[i].record_type != GNUNET_GNS_RECORD_PSEU)
@@ -518,6 +520,7 @@ process_auth_discovery_ns_result (void* cls,
   process_pseu_result (gph, NULL);
 }
 
+
 /**
  * Callback called by namestore for a zone to name
  * result
@@ -553,12 +556,9 @@ process_zone_to_name_discover (void *cls,
     return;
   }
   /* we found a match in our own zone */
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_AUTO_PSEU: name for zone in our root %s\n", name);
-  GNUNET_free (gph->auth);
-  GNUNET_CRYPTO_rsa_key_free (gph->key);
-  GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph);
-  GNUNET_free (gph);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "GNS_AUTO_PSEU: name for zone in our root %s\n", name);
+  free_get_pseu_authority_handle (gph);
 }
 
 
@@ -583,27 +583,32 @@ shorten_authority_chain (struct GetPseuAuthorityHandle *gph)
 
 }
 
+
+/**
+ * Start shortening algorithm using auth as
+ * authority chain
+ *
+ * @param auth the authorities that were resolved
+ * @param key the private key for PKEY import
+ */
 static void
 start_shorten (struct AuthorityChain *auth,
-               struct GNUNET_CRYPTO_RsaPrivateKey *key)
+               const struct GNUNET_CRYPTO_RsaPrivateKey *key)
 {
   struct GetPseuAuthorityHandle *gph;
   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
   struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pb_key;
   
   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
-  pb_key = GNUNET_CRYPTO_rsa_encode_key (key);
-
-  if (NULL == pb_key)
+  if (NULL == (pb_key = GNUNET_CRYPTO_rsa_encode_key (key)))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Failed to encode RSA key on shorten\n");
     return;
   }
-
   gph = GNUNET_malloc (sizeof (struct GetPseuAuthorityHandle));
-  gph->key = GNUNET_CRYPTO_rsa_decode_key ((char*)pb_key, ntohs (pb_key->len));
-
+  gph->key = GNUNET_CRYPTO_rsa_decode_key ((const char*) pb_key, ntohs (pb_key->len));
+  GNUNET_free (pb_key);
   if (NULL == gph->key)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -640,9 +645,8 @@ gns_resolver_init (struct GNUNET_NAMESTORE_Handle *nh,
                   unsigned long long max_bg_queries,
                   int ignore_pending)
 {
-  if (NULL == nh)
-    return GNUNET_SYSERR;
-  if (NULL == dh)
+  if ( (NULL == nh) ||
+       (NULL == dh) )
     return GNUNET_SYSERR;
   
   cfg = c;
@@ -655,16 +659,7 @@ gns_resolver_init (struct GNUNET_NAMESTORE_Handle *nh,
     GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
   max_allowed_background_queries = max_bg_queries;
   max_allowed_ns_tasks = GNUNET_GNS_MAX_NS_TASKS;
-  ignore_pending_records = ignore_pending;
-  gph_head = NULL;
-  gph_tail = NULL;
-  rlh_head = NULL;
-  rlh_tail = NULL;
-  nsh_head = NULL;
-  nsh_tail = NULL;
-  nah_head = NULL;
-  nah_tail = NULL;
-  
+  ignore_pending_records = ignore_pending; 
   GNUNET_RESOLVER_connect (cfg);
   return GNUNET_OK;
 }
@@ -686,17 +681,12 @@ cleanup_pending_ns_tasks (void* cls,
                           GNUNET_CONTAINER_HeapCostType cost)
 {
   struct NamestoreBGTask *nbg = element;
-  ResolverCleanupContinuation cont = cls;
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
              "GNS_CLEANUP: Terminating ns task\n");
   GNUNET_NAMESTORE_cancel (nbg->qe);
 
   GNUNET_CONTAINER_heap_remove_node (node);
-
-  if (0 == GNUNET_CONTAINER_heap_get_size (ns_task_heap))
-    cont ();
-
   return GNUNET_YES;
 }
 
@@ -733,7 +723,6 @@ cleanup_pending_background_queries (void* cls,
                                     GNUNET_CONTAINER_HeapCostType cost)
 {
   struct ResolverHandle *rh = element;
-  ResolverCleanupContinuation cont = cls;
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
              "GNS_CLEANUP-%llu: Terminating background lookup for %s\n",
@@ -741,17 +730,10 @@ cleanup_pending_background_queries (void* cls,
   GNUNET_CONTAINER_heap_remove_node (node);
   if (0 == GNUNET_CONTAINER_heap_get_size (dht_lookup_heap))
   {
-    if (GNUNET_CONTAINER_heap_get_size (ns_task_heap) == 0)
-      cont ();
-    else
-    {
-      GNUNET_CONTAINER_heap_iterate (ns_task_heap,
-                                     &cleanup_pending_ns_tasks,
-                                     cont);
-    }
+    GNUNET_CONTAINER_heap_iterate (ns_task_heap,
+                                  &cleanup_pending_ns_tasks,
+                                  NULL);    
   }
-
-
   return GNUNET_YES;
 }
 
@@ -815,6 +797,8 @@ free_resolver_handle (struct ResolverHandle* rh)
 static void
 finish_shorten (struct ResolverHandle *rh,
                 struct NameShortenHandle *nsh);
+
+
 /**
  * finish get auth
  *
@@ -824,33 +808,35 @@ finish_shorten (struct ResolverHandle *rh,
 static void
 finish_get_auth (struct ResolverHandle *rh,
                  struct GetNameAuthorityHandle* rlh);
+
+
 /**
  * Shutdown resolver
  */
 void
-gns_resolver_cleanup (ResolverCleanupContinuation cont)
+gns_resolver_cleanup ()
 {
   unsigned int s;
   struct GetPseuAuthorityHandle *tmp;
 
-  
-  tmp = gph_head;
-  for (tmp = gph_head; tmp != NULL; tmp = gph_head)
+  while (NULL != (tmp = gph_head))
   {
     if (tmp->get_handle != NULL)
+    {
       GNUNET_DHT_get_stop (tmp->get_handle);
-    tmp->get_handle = NULL;
+      tmp->get_handle = NULL;
+    }
     if (tmp->timeout != GNUNET_SCHEDULER_NO_TASK)
+    {
       GNUNET_SCHEDULER_cancel (tmp->timeout);
-    tmp->timeout = GNUNET_SCHEDULER_NO_TASK;
-
+      tmp->timeout = GNUNET_SCHEDULER_NO_TASK;
+    }
     if (NULL != tmp->namestore_task)
+    {
       GNUNET_NAMESTORE_cancel (tmp->namestore_task);
-    tmp->namestore_task = NULL;
-    GNUNET_free (tmp->auth);
-    GNUNET_CRYPTO_rsa_key_free (tmp->key);
-    GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, tmp);
-    GNUNET_free (tmp);
+      tmp->namestore_task = NULL;
+    }
+    free_get_pseu_authority_handle (tmp);
   }
 
   while (NULL != rlh_head)
@@ -872,20 +858,16 @@ gns_resolver_cleanup (ResolverCleanupContinuation cont)
   if (0 != s)
     GNUNET_CONTAINER_heap_iterate (dht_lookup_heap,
                                    &cleanup_pending_background_queries,
-                                   cont);
+                                   NULL);
   else if (0 != GNUNET_CONTAINER_heap_get_size (ns_task_heap))
   {
     GNUNET_CONTAINER_heap_iterate (ns_task_heap,
                                    &cleanup_pending_ns_tasks,
-                                   cont);
+                                   NULL);
   }
-  else
-    cont ();
 }
 
 
-
-
 /**
  * Callback when record data is put into namestore
  *
@@ -921,6 +903,12 @@ on_namestore_record_put_result (void *cls,
 }
 
 
+/**
+ * Lookup timeout task
+ *
+ * @param cls the ResolverHandle for the task that timed out
+ * @param tc the task context
+ */
 static void
 handle_lookup_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
@@ -928,7 +916,6 @@ handle_lookup_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
   if (NULL != rh->timeout_cont)
     rh->timeout_cont (rh->timeout_cont_cls, tc);
-  /* FIXME: does this leak memory? */
 }
 
 
@@ -950,6 +937,7 @@ background_lookup_result_processor (void *cls,
               rd_count);
 }
 
+
 /**
  * Handle timeout for DHT requests
  *
@@ -975,7 +963,7 @@ dht_lookup_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "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,
@@ -985,6 +973,7 @@ dht_lookup_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                               GNUNET_NO,
                               &background_lookup_result_processor,
                               NULL);
+                              
   rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
 
   GNUNET_DHT_get_stop (rh->get_handle);
@@ -1150,25 +1139,15 @@ static void
 resolve_record_dht (struct ResolverHandle *rh)
 {
   uint32_t xquery;
-  struct GNUNET_CRYPTO_ShortHashCode name_hash;
   struct GNUNET_HashCode lookup_key;
-  struct GNUNET_HashCode name_hash_double;
-  struct GNUNET_HashCode zone_hash_double;
-  struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string;
   struct RecordLookupHandle *rlh = rh->proc_cls;
   struct ResolverHandle *rh_heap_root;
 
-  GNUNET_CRYPTO_short_hash (rh->name, strlen (rh->name), &name_hash);
-  GNUNET_CRYPTO_short_hash_double (&name_hash, &name_hash_double);
-  GNUNET_CRYPTO_short_hash_double (&rh->authority, &zone_hash_double);
-  GNUNET_CRYPTO_hash_xor (&name_hash_double, &zone_hash_double, &lookup_key);
-  GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string);
-
+  GNUNET_GNS_get_key_for_record (rh->name, &rh->authority, &lookup_key);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "GNS_PHASE_REC-%llu: starting dht lookup for %s with key: %s\n",
-              rh->id, rh->name, (char*)&lookup_key_string);
+              rh->id, rh->name, GNUNET_h2s (&lookup_key));
 
-  //rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   rh->dht_heap_node = NULL;
 
   if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value != rh->timeout.rel_value)
@@ -1416,8 +1395,6 @@ process_record_result_vpn (void* cls, int af, const void *address)
 }
 
 
-
-
 /**
  * Process VPN lookup result for record
  *
@@ -1461,6 +1438,13 @@ static void
 send_dns_packet (struct ResolverHandle *rh);
 
 
+/**
+ * Read DNS response
+ *
+ * @param cls the ResolverHandle for this lookup
+ * @param addr the sockaddr
+ * @param addrlen the socket address length
+ */
 static void
 handle_dns_resolver (void *cls,
                      const struct sockaddr *addr,
@@ -1694,6 +1678,7 @@ read_dns_response (void *cls,
   return;
 }
 
+
 /**
  * Sends a UDP dns query to a nameserver specified in the rh
  * 
@@ -1731,6 +1716,7 @@ send_dns_packet (struct ResolverHandle *rh)
 
 }
 
+
 /**
  * The final phase of resoution.
  * We found a NS RR and want to resolve via DNS
@@ -1754,6 +1740,7 @@ resolve_record_dns (struct ResolverHandle *rh,
   struct RecordLookupHandle *rlh = rh->proc_cls;
 
   memset (&packet, 0, sizeof (struct GNUNET_DNSPARSER_Packet));
+  memset (rh->dns_name, 0, sizeof (rh->dns_name));
   
   /* We cancel here as to not include the ns lookup in the timeout */
   if (GNUNET_SCHEDULER_NO_TASK != rh->timeout_task)
@@ -1933,9 +1920,9 @@ resolve_record_vpn (struct ResolverHandle *rh,
                                                GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME
                                                &process_record_result_vpn,
                                                rh);
-
 }
 
+
 /**
  * The final phase of resolution.
  * rh->name is a name that is canonical and we do not have a delegation.
@@ -1980,7 +1967,6 @@ resolve_record_ns(struct ResolverHandle *rh)
 }
 
 
-
 /**
  * Handle timeout for DHT requests
  *
@@ -2036,23 +2022,33 @@ dht_authority_lookup_timeout(void *cls,
         "GNS_PHASE_DELEGATE_DHT-%llu: Starting background query for %s type %d\n",
         rh->id, rh->name, rlh->record_type);
 
-  gns_resolver_lookup_record(rh->authority,
-                             rh->private_local_zone,
-                             rlh->record_type,
-                             new_name,
-                             NULL,
-                             GNUNET_TIME_UNIT_FOREVER_REL,
-                             GNUNET_NO,
-                             &background_lookup_result_processor,
-                             NULL);
-
+  gns_resolver_lookup_record (rh->authority,
+                              rh->private_local_zone,
+                              rlh->record_type,
+                              new_name,
+                              NULL,
+                              GNUNET_TIME_UNIT_FOREVER_REL,
+                              GNUNET_NO,
+                              &background_lookup_result_processor,
+                              NULL);
   rh->proc(rh->proc_cls, rh, 0, NULL);
 }
 
-/* Prototype */
+
+/**
+ * Start DHT lookup for a name -> PKEY (compare NS) record in
+ * rh->authority's zone
+ *
+ * @param rh the pending gns query
+ */
 static void resolve_delegation_dht(struct ResolverHandle *rh);
 
-/* Prototype */
+
+/**
+ * Resolve the delegation chain for the request in our namestore
+ *
+ * @param rh the resolver handle
+ */
 static void resolve_delegation_ns(struct ResolverHandle *rh);
 
 
@@ -2121,7 +2117,7 @@ process_pkey_revocation_result_ns (void *cls,
     {
       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
         "GNS_PHASE_DELEGATE_REV-%llu: Starting background lookup for %s type %d\n",
-        rh->id, "+.gnunet", GNUNET_GNS_RECORD_REV);
+        rh->id, "+.gads", GNUNET_GNS_RECORD_REV);
 
       gns_resolver_lookup_record(rh->authority,
                                  rh->private_local_zone,
@@ -2182,6 +2178,7 @@ on_namestore_delegation_put_result(void *cls,
              "GNS_NS: Error putting records into namestore: %s\n", emsg);
 }
 
+
 /**
  * Function called when we get a result from the dht
  * for our query. Recursively tries to resolve authorities
@@ -2214,10 +2211,9 @@ process_delegation_result_dht(void* cls,
   uint32_t num_records;
   char* name = NULL;
   char* rd_data = (char*) data;
-  int i;
+  uint32_t i;
   int rd_size;
-  struct GNUNET_CRYPTO_ShortHashCode zone, name_hash;
-  struct GNUNET_HashCode zone_hash_double, name_hash_double;
+  struct GNUNET_CRYPTO_ShortHashCode zone;
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
              "GNS_PHASE_DELEGATE_DHT-%llu: Got DHT result\n", rh->id);
@@ -2324,13 +2320,9 @@ process_delegation_result_dht(void* cls,
       }
 
     }
+    GNUNET_GNS_get_zone_from_key (name, key, &zone);
 
 
-    GNUNET_CRYPTO_short_hash(name, strlen(name), &name_hash);
-    GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double);
-    GNUNET_CRYPTO_hash_xor(key, &name_hash_double, &zone_hash_double);
-    GNUNET_CRYPTO_short_hash_from_truncation (&zone_hash_double, &zone);
-
     /* Save to namestore
     if (0 != GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
                                           &zone))
@@ -2432,43 +2424,55 @@ process_delegation_result_dht(void* cls,
 #define MAX_SRV_LENGTH (sizeof(uint16_t)*3)+MAX_DNS_NAME_LENGTH
 
 
+/**
+ * Exands a name ending in .+ with the zone of origin.
+ * FIXME: funky api: 'dest' must be large enough to hold
+ * the result; this is a bit yucky...
+ *
+ * @param dest destination buffer
+ * @param src the .+ name
+ * @param repl the string to replace the + with
+ */
 static void
-expand_plus(char* dest, char* src, char* repl)
+expand_plus (char* dest, 
+            const char* src, 
+            const char* repl)
 {
   char* pos;
-  unsigned int s_len = strlen(src)+1;
+  size_t s_len = strlen (src) + 1;
 
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_POSTPROCESS: Got %s to expand with %s\n", src, repl);
   //Eh? I guess this is at least strlen ('x.+') == 3 FIXME
   if (3 > s_len)
   {
+    /* no postprocessing */
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
                "GNS_POSTPROCESS: %s too short\n", src);
-
-    /* no postprocessing */
-    memcpy(dest, src, s_len+1);
+    memcpy (dest, src, s_len);
     return;
   }
-  
-  if (0 == strcmp(src+s_len-3, ".+"))
+  if (0 == strcmp (src + s_len - 3, ".+"))
   {
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_POSTPROCESS: Expanding .+ in %s\n", src);
-    memset(dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD));
-    strcpy(dest, src);
-    pos = dest+s_len-2;
-    strcpy(pos, repl);
-    pos += strlen(repl);
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "GNS_POSTPROCESS: Expanded to %s\n", dest);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "GNS_POSTPROCESS: Expanding .+ in %s\n", 
+               src);
+    memset (dest, 0, s_len + strlen (repl) + strlen(GNUNET_GNS_TLD));
+    strcpy (dest, src);
+    pos = dest + s_len - 2;
+    strcpy (pos, repl);
+    pos += strlen (repl);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "GNS_POSTPROCESS: Expanded to %s\n", 
+               dest);
   }
   else
   {
-    memcpy(dest, src, s_len+1);
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+               "GNS_POSTPROCESS: No postprocessing for %s\n", src);
+    memcpy (dest, src, s_len);
   }
 }
 
+
 /**
  * finish lookup
  */
@@ -2534,11 +2538,12 @@ finish_lookup (struct ResolverHandle *rh,
     if (GNUNET_GNS_RECORD_MX == rd[i].record_type)
     {
       memcpy (new_mx_data, (char*)rd[i].data, sizeof(uint16_t));
-      offset = sizeof(uint16_t);
-      pos = new_mx_data+offset;
-      expand_plus(pos, (char*)rd[i].data+sizeof(uint16_t),
-                  repl_string);
-      offset += strlen(new_mx_data+sizeof(uint16_t))+1;
+      offset = sizeof (uint16_t);
+      pos = new_mx_data + offset;
+      // FIXME: how do we know that 'pos' has enough space for the new name?
+      expand_plus (pos, (char*)rd[i].data+sizeof(uint16_t),
+                  repl_string);
+      offset += strlen(new_mx_data+sizeof(uint16_t)) + 1;
       p_rd[i].data = new_mx_data;
       p_rd[i].data_size = offset;
     }
@@ -2552,6 +2557,7 @@ finish_lookup (struct ResolverHandle *rh,
       new_srv->prio = old_srv->prio;
       new_srv->weight = old_srv->weight;
       new_srv->port = old_srv->port;
+      // FIXME: how do we know that '&new_srv[1]' has enough space for the new name?
       expand_plus((char*)&new_srv[1], (char*)&old_srv[1],
                   repl_string);
       p_rd[i].data = new_srv_data;
@@ -2563,8 +2569,10 @@ finish_lookup (struct ResolverHandle *rh,
       old_soa = (struct soa_data*)rd[i].data;
       new_soa = (struct soa_data*)new_soa_data;
       memcpy (new_soa, old_soa, sizeof (struct soa_data));
+      // FIXME: how do we know that 'new_soa[1]' has enough space for the new name?
       expand_plus((char*)&new_soa[1], (char*)&old_soa[1], repl_string);
       offset = strlen ((char*)&new_soa[1]) + 1;
+      // FIXME: how do we know that 'new_soa[1]' has enough space for the new name?
       expand_plus((char*)&new_soa[1] + offset,
                   (char*)&old_soa[1] + strlen ((char*)&old_soa[1]) + 1,
                   repl_string);
@@ -2576,6 +2584,7 @@ finish_lookup (struct ResolverHandle *rh,
     else
     {
       pos = new_rr_data;
+      // FIXME: how do we know that 'rd[i].data' has enough space for the new name?
       expand_plus(pos, (char*)rd[i].data, repl_string);
       p_rd[i].data_size = strlen(new_rr_data)+1;
       p_rd[i].data = new_rr_data;
@@ -2588,6 +2597,7 @@ finish_lookup (struct ResolverHandle *rh,
   free_resolver_handle (rh);
 }
 
+
 /**
  * Process DHT lookup result for record.
  *
@@ -2605,22 +2615,20 @@ handle_record_dht(void* cls, struct ResolverHandle *rh,
 
   if (0 == rd_count)
   {
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "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);
+    finish_lookup (rh, rlh, 0, NULL);
     return;
   }
   /* results found yay */
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "GNS_PHASE_REC-%llu: Record resolved from DHT!", rh->id);
-  finish_lookup(rh, rlh, rd_count, rd);
+  finish_lookup (rh, rlh, rd_count, rd);
 }
 
 
-
-
 /**
  * Process namestore lookup result for record.
  *
@@ -2640,16 +2648,16 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
   if (0 != rd_count)
   {
     /* results found yay */
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "GNS_PHASE_REC-%llu: Record resolved from namestore!\n", rh->id);
-    finish_lookup(rh, rlh, rd_count, rd);
+    finish_lookup (rh, rlh, rd_count, rd);
     return;
   }
   
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_PHASE_REC-%llu: NS returned no records. (status: %d)!\n",
-             rh->id,
-             rh->status);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "GNS_PHASE_REC-%llu: NS returned no records. (status: %d)!\n",
+              rh->id,
+              rh->status);
   /**
    * There are 5 conditions that have to met for us to consult the DHT:
    * 1. The entry in the DHT is RSL_RECORD_EXPIRED OR
@@ -2663,11 +2671,23 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
    */
   if ((0 != (rh->status & RSL_RECORD_EXPIRED)) &&
       (0 == (rh->status & RSL_RECORD_EXISTS)) )
+  {
+    
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "GNS_PHASE_REC-%llu: Not expired and exists!\n",
+              rh->id);
     check_dht = GNUNET_NO;
+  }
   
-  if (0 != GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+  if (0 == GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
                                         &rh->private_local_zone))
+  {
+
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "GNS_PHASE_REC-%llu: Our zone!\n",
+              rh->id);
     check_dht = GNUNET_NO;
+  }
   
   if ((0 != strcmp (rh->name, "+")) && (GNUNET_YES == is_srv (rh->name)))
       check_dht = GNUNET_NO;
@@ -2682,7 +2702,7 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
     return;
   }
   /* give up, cannot resolve */
-  finish_lookup(rh, rlh, 0, NULL);
+  finish_lookup (rh, rlh, 0, NULL);
 }
 
 
@@ -2720,6 +2740,7 @@ pop_tld(char* name, char* dest)
   strcpy(dest, (name+len+1));
 }
 
+
 /**
  * Checks if name is in tld
  *
@@ -2745,6 +2766,7 @@ is_tld(const char* name, const char* tld)
   return GNUNET_YES;
 }
 
+
 /**
  * DHT resolution for delegation finished. Processing result.
  *
@@ -2813,21 +2835,12 @@ static void
 resolve_delegation_dht(struct ResolverHandle *rh)
 {
   uint32_t xquery;
-  struct GNUNET_CRYPTO_ShortHashCode name_hash;
-  struct GNUNET_HashCode name_hash_double;
-  struct GNUNET_HashCode zone_hash_double;
   struct GNUNET_HashCode lookup_key;
   struct ResolverHandle *rh_heap_root;
   
   pop_tld(rh->name, rh->authority_name);
 
-  //FIXME handle return values here
-  GNUNET_CRYPTO_short_hash(rh->authority_name,
-                     strlen(rh->authority_name),
-                     &name_hash);
-  GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double);
-  GNUNET_CRYPTO_short_hash_double(&rh->authority, &zone_hash_double);
-  GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key);
+  GNUNET_GNS_get_key_for_record (rh->authority_name, &rh->authority, &lookup_key);
   
   rh->dht_heap_node = NULL;
 
@@ -3428,10 +3441,8 @@ gns_resolver_lookup_record (struct GNUNET_CRYPTO_ShortHashCode zone,
   GNUNET_CONTAINER_DLL_insert (rlh_head, rlh_tail, rh);
   
   if (NULL == key)
-  {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "No shorten key for resolution\n");
-  }
 
   if (timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
   {
@@ -3645,7 +3656,7 @@ process_zone_to_name_shorten_shorten (void *cls,
                                         nsh->shorten_zone) == 0)
   {
     /**
-     * This is our zone append .gnunet unless name is empty
+     * This is our zone append .gads unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
@@ -3670,15 +3681,18 @@ process_zone_to_name_shorten_shorten (void *cls,
    * No PSEU found.
    * continue with next authority if exists
    */
-  if ((rh->authority_chain_head->next == NULL))
+  if (NULL == rh->authority_chain_head->next)
   {
     finish_shorten (rh, nsh);
     return;
   }
   next_authority = rh->authority_chain_head;
   
-  GNUNET_snprintf(tmp_name, MAX_DNS_NAME_LENGTH,
-                  "%s.%s", rh->name, next_authority->name);
+  if (0 == strcmp (rh->name, ""))
+    strcpy (tmp_name, next_authority->name);
+  else
+    GNUNET_snprintf(tmp_name, MAX_DNS_NAME_LENGTH,
+                    "%s.%s", rh->name, next_authority->name);
   
   strcpy(rh->name, tmp_name);
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
@@ -3698,6 +3712,7 @@ process_zone_to_name_shorten_shorten (void *cls,
                                  rh);
 }
 
+
 /**
  * Callback calles by namestore for a zone to name
  * result
@@ -3752,7 +3767,7 @@ process_zone_to_name_shorten_private (void *cls,
                                         nsh->private_zone) == 0)
   {
     /**
-     * This is our zone append .gnunet unless name is empty
+     * This is our zone append .gads unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
@@ -3780,15 +3795,18 @@ process_zone_to_name_shorten_private (void *cls,
      * No PSEU found.
      * continue with next authority if exists
      */
-    if ((rh->authority_chain_head->next == NULL))
+    if (NULL == rh->authority_chain_head->next)
     {
       finish_shorten (rh, nsh);
       return;
     }
     next_authority = rh->authority_chain_head;
     
-    GNUNET_snprintf(tmp_name, MAX_DNS_NAME_LENGTH,
-                    "%s.%s", rh->name, next_authority->name);
+    if (0 == strcmp (rh->name, ""))
+      strcpy (tmp_name, next_authority->name);
+    else
+      GNUNET_snprintf(tmp_name, MAX_DNS_NAME_LENGTH,
+                      "%s.%s", rh->name, next_authority->name);
     
     strcpy(rh->name, tmp_name);
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
@@ -3809,6 +3827,7 @@ process_zone_to_name_shorten_private (void *cls,
   }
 }
 
+
 /**
  * Callback calles by namestore for a zone to name
  * result
@@ -3863,7 +3882,7 @@ process_zone_to_name_shorten_root (void *cls,
                                         nsh->root_zone) == 0)
   {
     /**
-     * This is our zone append .gnunet unless name is empty
+     * This is our zone append .gads unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
@@ -3899,15 +3918,18 @@ process_zone_to_name_shorten_root (void *cls,
      * No PSEU found.
      * continue with next authority if exists
      */
-    if ((rh->authority_chain_head->next == NULL))
+    if (NULL == rh->authority_chain_head->next)
     {
       finish_shorten (rh, nsh);
       return;
     }
     next_authority = rh->authority_chain_head;
     
-    GNUNET_snprintf(tmp_name, MAX_DNS_NAME_LENGTH,
-                    "%s.%s", rh->name, next_authority->name);
+    if (0 == strcmp (rh->name, ""))
+      strcpy (tmp_name, next_authority->name);
+    else
+      GNUNET_snprintf(tmp_name, MAX_DNS_NAME_LENGTH,
+                      "%s.%s", rh->name, next_authority->name);
     
     strcpy(rh->name, tmp_name);
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
@@ -3948,7 +3970,7 @@ handle_delegation_ns_shorten (void* cls,
   char result[MAX_DNS_NAME_LENGTH];
 
   nsh = (struct NameShortenHandle *)cls;
-  
+  rh->namestore_task = NULL;
   /**
    * At this point rh->name contains the part of the name
    * that we do not have a PKEY in our namestore to resolve.
@@ -3960,11 +3982,11 @@ handle_delegation_ns_shorten (void* cls,
              "PKEY resolved as far as possible in ns up to %s!\n", rh->name);
   memset(result, 0, sizeof (result));
 
-  if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
-                                   nsh->root_zone) == 0)
+  if (0 == GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+                                   nsh->root_zone))
   {
     /**
-     * This is our zone append .gnunet unless name is empty
+     * This is our zone append .gads unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
@@ -3980,7 +4002,7 @@ handle_delegation_ns_shorten (void* cls,
   else if (NULL != nsh->private_zone)
   {
     /**
-     * This is our zone append .gnunet unless name is empty
+     * This is our zone append .gads unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
@@ -4001,7 +4023,7 @@ handle_delegation_ns_shorten (void* cls,
   else if (NULL != nsh->shorten_zone)
   {
     /**
-     * This is our zone append .gnunet unless name is empty
+     * This is our zone append .gads unless name is empty
      * (it shouldn't be, usually FIXME what happens if we
      * shorten to our zone to a "" record??)
      */
@@ -4053,9 +4075,10 @@ process_zone_to_name_zkey(void *cls,
 {
   struct ResolverHandle *rh = cls;
   struct NameShortenHandle *nsh = rh->proc_cls;
-  struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
   char new_name[MAX_DNS_NAME_LENGTH];
 
+  rh->namestore_task = NULL;
+
   /* zkey not in our zone */
   if (name == NULL)
   {
@@ -4066,18 +4089,16 @@ process_zone_to_name_zkey(void *cls,
      * because PKEY import will happen if the user follows the zkey
      * link.
      */
-    GNUNET_CRYPTO_short_hash_to_enc ((struct GNUNET_CRYPTO_ShortHashCode*)rd,
-                                     &enc);
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-               "No name found for zkey %s returning verbatim!\n", enc);
-    if (strcmp(rh->name, "") != 0)
+               "No name found for zkey %s returning verbatim!\n", nsh->result);
+    /*if (strcmp(rh->name, "") != 0)
       GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s.%s",
                       rh->name, enc, GNUNET_GNS_TLD_ZKEY);
     else
       GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s",
                       enc, GNUNET_GNS_TLD_ZKEY);
 
-    strcpy (nsh->result, new_name);
+    strcpy (nsh->result, new_name);*/
 
     finish_shorten (rh, nsh);
     return;
@@ -4146,7 +4167,6 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
   }
 
   nsh = GNUNET_malloc (sizeof (struct NameShortenHandle));
-
   nsh->proc = proc;
   nsh->proc_cls = proc_cls;
   nsh->root_zone = zone;
@@ -4156,7 +4176,6 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
   strcpy (nsh->shorten_zone_name, shorten_zone_name);
   strcpy (nsh->result, name);
   
-
   rh = GNUNET_malloc (sizeof (struct ResolverHandle));
   rh->authority = *zone;
   rh->id = rid++;
@@ -4168,9 +4187,8 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
   rh->private_local_zone = *zone;
 
   GNUNET_CONTAINER_DLL_insert (nsh_head, nsh_tail, rh);
-  
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Checking for TLD...\n");
+              "Checking for TLD...\n");
   if (is_zkey_tld (name) == GNUNET_YES)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -4196,13 +4214,12 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Cannot convert ZKEY %s to hash!\n", nzkey);
+      GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh);
       GNUNET_free (rh);
       GNUNET_free (nsh);
-      GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh);
       proc (proc_cls, name);
       return;
     }
-
     rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle,
                                    zone, //ours
                                    &zkey,
@@ -4226,9 +4243,9 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone,
   else
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown TLD in %s\n", name);
+    GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh);
     GNUNET_free (rh);
     GNUNET_free (nsh);
-    GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh);
     proc (proc_cls, name);
     return;
   }
@@ -4257,10 +4274,10 @@ finish_get_auth (struct ResolverHandle *rh,
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
              "Got authority result %s\n", nah->result);
   
-  nah->proc(nah->proc_cls, nah->result);
+  nah->proc (nah->proc_cls, nah->result);
   GNUNET_CONTAINER_DLL_remove (nah_head, nah_tail, rh);
-  GNUNET_free(nah);
-  free_resolver_handle(rh);
+  GNUNET_free (nah);
+  free_resolver_handle (rh);
 }
 
 /**
@@ -4278,11 +4295,9 @@ handle_delegation_result_ns_get_auth(void* cls,
                       uint32_t rd_count,
                       const struct GNUNET_NAMESTORE_RecordData *rd)
 {
-  struct GetNameAuthorityHandle* nah;
+  struct GetNameAuthorityHandle* nah = rh->proc_cls;
   size_t answer_len;
 
-  nah = (struct GetNameAuthorityHandle*) rh->proc_cls;
-  
   /**
    * At this point rh->name contains the part of the name
    * that we do not have a PKEY in our namestore to resolve.
@@ -4313,7 +4328,10 @@ handle_delegation_result_ns_get_auth(void* cls,
     answer_len = strlen(nah->name) - strlen(rh->name)
       + strlen(GNUNET_GNS_TLD) + 1;
     memset(nah->result, 0, answer_len);
-    strcpy(nah->result, nah->name + strlen(rh->name) + 1);
+    if (0 != strcmp (rh->name, ""))
+      strcpy(nah->result, nah->name + strlen(rh->name) + 1);
+    else
+      strcpy(nah->result, nah->name);
 
     finish_get_auth (rh, nah);
   }