-hope springs eternal
[oweals/gnunet.git] / src / gns / gnunet-service-gns_resolver.c
index 17e45bbf80cf6c23e3649160dcf12814c481d134..1a22e624dd9d1c01362bbd6ab7c69d81dd26f3d8 100644 (file)
@@ -176,34 +176,36 @@ is_srv (char* name)
 }
 
 /**
- * Determine if this name is canonical.
- * i.e.
+ * 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
+ * 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;
-
-  ndup = GNUNET_strdup (name);
-  strtok (ndup, ".");
+  const char *pos;
+  const char *dot;
 
-  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;
 }
 
@@ -228,7 +230,7 @@ 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);
@@ -258,7 +260,7 @@ process_pseu_lookup_ns (void* cls,
                       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;
@@ -375,7 +377,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,7 +391,7 @@ 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);
@@ -583,18 +585,17 @@ shorten_authority_chain (struct GetPseuAuthorityHandle *gph)
 
 }
 
+
 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");
@@ -602,7 +603,7 @@ start_shorten (struct AuthorityChain *auth,
   }
 
   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));
 
   if (NULL == gph->key)
   {
@@ -640,9 +641,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 +655,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;
 }
@@ -975,7 +966,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 +976,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);
@@ -1754,6 +1746,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)
@@ -2036,16 +2029,15 @@ 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);
 }
 
@@ -2605,17 +2597,17 @@ 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);
 }
 
 
@@ -2640,16 +2632,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 +2655,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 +2686,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);
 }
 
 
@@ -3677,8 +3681,11 @@ process_zone_to_name_shorten_shorten (void *cls,
   }
   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,
@@ -3787,8 +3794,11 @@ process_zone_to_name_shorten_private (void *cls,
     }
     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,
@@ -3906,8 +3916,11 @@ process_zone_to_name_shorten_root (void *cls,
     }
     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 +3961,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,8 +3973,8 @@ 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 .gads unless name is empty
@@ -4053,9 +4066,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 +4080,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;
@@ -4257,10 +4269,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);
 }
 
 /**
@@ -4313,7 +4325,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);
   }