-fixing #2985
[oweals/gnunet.git] / src / gns / gnunet-service-gns_resolver.c
index 4eba4dae83abdba34b1b181943e6d331ae660624..d357a13125a90ae5de5e2033d689f232f011d61d 100644 (file)
@@ -39,9 +39,7 @@
 #include "gnunet_dns_service.h"
 #include "gnunet_resolver_service.h"
 #include "gnunet_dnsparser_lib.h"
-#include "gns_protocol.h"
 #include "gnunet_gns_service.h"
-#include "gns_common.h"
 #include "gns.h"
 #include "gnunet-service-gns_resolver.h"
 #include "gnunet_vpn_service.h"
@@ -370,6 +368,11 @@ struct GetPseuAuthorityHandle
    */
   char label[GNUNET_DNSPARSER_MAX_LABEL_LENGTH + 1];
 
+  /**
+   * Label we are currently trying out (during #perform_pseu_lookup).
+   */
+  char *current_label;
+
   /**
    * The zone for which we are trying to find the PSEU record.
    */
@@ -486,7 +489,7 @@ is_srv (const char *name)
  * even though they consist of multiple labels.
  *
  * Examples:
- * a.b.gads  = not canonical
+ * a.b.gnu  = not canonical
  * a         = canonical
  * _foo._srv = canonical
  * _f.bar    = not canonical
@@ -542,6 +545,7 @@ free_get_pseu_authority_handle (struct GetPseuAuthorityHandle *gph)
     gph->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   }
   GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph);
+  GNUNET_free_non_null (gph->current_label);
   GNUNET_free (gph);
 }
 
@@ -570,44 +574,110 @@ create_pkey_cont (void* cls,
  * (or with rd_count=0 to indicate no matches).
  *
  * @param cls the pending query
- * @param key the key of the zone we did the lookup
- * @param name the name for which we need an authority
  * @param rd_count the number of records with 'name'
  * @param rd the record data
  */
 static void
 process_pseu_lookup_ns (void *cls,
-                       const struct GNUNET_CRYPTO_EccPrivateKey *key,
-                       const char *name, 
+                       unsigned int rd_count,
+                       const struct GNUNET_NAMESTORE_RecordData *rd);
+
+
+/**
+ * We obtained a result for our query to the shorten zone from
+ * the namestore.  Try to decrypt.
+ *
+ * @param cls the handle to our shorten operation
+ * @param block resulting encrypted block
+ */
+static void
+process_pseu_block_ns (void *cls,
+                      const struct GNUNET_NAMESTORE_Block *block)
+{
+  struct GetPseuAuthorityHandle *gph = cls;
+  struct GNUNET_CRYPTO_EccPublicKey pub;
+
+  gph->namestore_task = NULL;
+  if (NULL == block)
+  {
+    process_pseu_lookup_ns (gph, 0, NULL);
+    return;
+  }
+  GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key,
+                                   &pub);
+  if (GNUNET_OK != 
+      GNUNET_NAMESTORE_block_decrypt (block,
+                                     &pub,
+                                     gph->current_label,
+                                     &process_pseu_lookup_ns,
+                                     gph))
+  {
+    GNUNET_break (0);
+    free_get_pseu_authority_handle (gph);
+    return;
+  }
+}
+
+
+/**
+ * Lookup in the namestore for the shorten zone the given label.
+ *
+ * @param gph the handle to our shorten operation
+ * @param label the label to lookup
+ */
+static void 
+perform_pseu_lookup (struct GetPseuAuthorityHandle *gph,
+                    const char *label)
+{ 
+  struct GNUNET_CRYPTO_EccPublicKey pub;
+  struct GNUNET_HashCode query;
+
+  GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key,
+                                   &pub);
+  GNUNET_free_non_null (gph->current_label);
+  gph->current_label = GNUNET_strdup (label);
+  GNUNET_NAMESTORE_query_from_public_key (&pub,
+                                         label,
+                                         &query);
+  gph->namestore_task = GNUNET_NAMESTORE_lookup_block (namestore_handle,
+                                                      &query,
+                                                      &process_pseu_block_ns,
+                                                      gph);
+}
+
+
+/**
+ * Namestore calls this function if we have record for this name.
+ * (or with rd_count=0 to indicate no matches).
+ *
+ * @param cls the pending query
+ * @param rd_count the number of records with 'name'
+ * @param rd the record data
+ */
+static void
+process_pseu_lookup_ns (void *cls,
                        unsigned int rd_count,
                        const struct GNUNET_NAMESTORE_RecordData *rd)
 {
   struct GetPseuAuthorityHandle *gph = cls;
   struct GNUNET_NAMESTORE_RecordData new_pkey;
-  struct GNUNET_CRYPTO_EccPublicKey pub;
 
   gph->namestore_task = NULL;
   if (rd_count > 0)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
                "Name `%s' already taken, cannot shorten.\n", 
-              name);
+              gph->current_label);
     /* if this was not yet the original label, try one more
        time, this time not using PSEU but the original label */
-    if (0 == strcmp (name,
+    if (0 == strcmp (gph->current_label,
                     gph->label))
     {
       free_get_pseu_authority_handle (gph);
     }
     else
     {
-      GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key,
-                                       &pub);
-      gph->namestore_task = GNUNET_NAMESTORE_lookup (namestore_handle,
-                                                    &pub,
-                                                    gph->label,
-                                                    &process_pseu_lookup_ns,
-                                                    gph);
+      perform_pseu_lookup (gph, gph->label);
     }
     return;
   }
@@ -615,7 +685,7 @@ process_pseu_lookup_ns (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Shortening `%s' to `%s'\n", 
              GNUNET_NAMESTORE_z2s (&gph->target_zone),
-             name);
+             gph->current_label);
   new_pkey.expiration_time = UINT64_MAX;
   new_pkey.data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey);
   new_pkey.data = &gph->target_zone;
@@ -626,7 +696,7 @@ process_pseu_lookup_ns (void *cls,
   gph->namestore_task 
     = GNUNET_NAMESTORE_records_store (namestore_handle,
                                      &gph->shorten_zone_key,
-                                     name,
+                                     gph->current_label,
                                      1, &new_pkey,
                                      &create_pkey_cont, gph);
 }
@@ -642,30 +712,17 @@ static void
 process_pseu_result (struct GetPseuAuthorityHandle* gph, 
                     const char *pseu)
 {
-  struct GNUNET_CRYPTO_EccPublicKey pub;
-
-  GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key,
-                                   &pub);
   if (NULL == pseu)
   {
     /* no PSEU found, try original label */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "No PSEU found, trying original label `%s' instead.\n",
                gph->label);
-    gph->namestore_task = GNUNET_NAMESTORE_lookup (namestore_handle,
-                                                  &pub,
-                                                  gph->label,
-                                                  &process_pseu_lookup_ns,
-                                                  gph);
+    perform_pseu_lookup (gph, gph->label);
     return;
-  }
-  
+  }  
   /* check if 'pseu' is taken */
-  gph->namestore_task = GNUNET_NAMESTORE_lookup (namestore_handle,
-                                                &pub,
-                                                pseu,
-                                                &process_pseu_lookup_ns,
-                                                gph);
+  perform_pseu_lookup (gph, pseu);
 }
 
 
@@ -1109,7 +1166,7 @@ resolve_record_dns (struct ResolverHandle *rh,
   struct RecordLookupHandle *rlh = rh->proc_cls;
   struct GNUNET_DNSPARSER_Query query;
   struct GNUNET_DNSPARSER_Packet packet;
-  struct GNUNET_DNSPARSER_Flags flags;
+  struct GNUNET_TUN_DnsFlags flags;
   struct in_addr dnsip;
   struct sockaddr_in addr;
   struct sockaddr *sa;
@@ -1183,7 +1240,7 @@ resolve_record_dns (struct ResolverHandle *rh,
   }
   query.name = rh->dns_name;
   query.type = rlh->record_type;
-  query.class = GNUNET_DNSPARSER_CLASS_INTERNET;
+  query.class = GNUNET_TUN_DNS_CLASS_INTERNET;
   memset (&flags, 0, sizeof (flags));
   flags.recursion_desired = 1;
   flags.checking_disabled = 1;
@@ -1234,7 +1291,7 @@ resolve_record_vpn (struct ResolverHandle *rh,
 {
   struct RecordLookupHandle *rlh = rh->proc_cls;
   struct GNUNET_HashCode serv_desc;
-  struct vpn_data* vpn;
+  struct GNUNET_TUN_GnsVpnRecord* vpn;
   int af;
   
   /* We cancel here as to not include the ns lookup in the timeout */
@@ -1254,7 +1311,7 @@ resolve_record_vpn (struct ResolverHandle *rh,
                    rh->priv_key);
   }
 
-  vpn = (struct vpn_data*)rd->data;
+  vpn = (struct GNUNET_TUN_GnsVpnRecord*)rd->data;
   GNUNET_CRYPTO_hash ((char*)&vpn[1],
                       strlen ((char*)&vpn[1]) + 1,
                       &serv_desc);
@@ -1398,7 +1455,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, "+.gads", GNUNET_NAMESTORE_TYPE_REV);
+        rh->id, "+.gnu", GNUNET_NAMESTORE_TYPE_REV);
 
       gns_resolver_lookup_record(rh->authority,
                                  rh->private_local_zone,
@@ -1729,10 +1786,10 @@ finish_lookup (struct ResolverHandle *rh,
   char new_mx_data[MAX_MX_LENGTH];
   char new_soa_data[MAX_SOA_LENGTH];
   char new_srv_data[MAX_SRV_LENGTH];
-  struct srv_data *old_srv;
-  struct srv_data *new_srv;
-  struct soa_data *old_soa;
-  struct soa_data *new_soa;
+  struct GNUNET_TUN_DnsSrvRecord *old_srv;
+  struct GNUNET_TUN_DnsSrvRecord *new_srv;
+  struct GNUNET_TUN_DnsSoaRecord *old_soa;
+  struct GNUNET_TUN_DnsSoaRecord *new_soa;
   struct GNUNET_NAMESTORE_RecordData p_rd[rd_count];
   char* repl_string;
   char* pos;
@@ -1794,8 +1851,8 @@ finish_lookup (struct ResolverHandle *rh,
       /*
        * Prio, weight and port
        */
-      new_srv = (struct srv_data*)new_srv_data;
-      old_srv = (struct srv_data*)rd[i].data;
+      new_srv = (struct GNUNET_TUN_DnsSrvRecord*)new_srv_data;
+      old_srv = (struct GNUNET_TUN_DnsSrvRecord*)rd[i].data;
       new_srv->prio = old_srv->prio;
       new_srv->weight = old_srv->weight;
       new_srv->port = old_srv->port;
@@ -1803,14 +1860,14 @@ finish_lookup (struct ResolverHandle *rh,
       expand_plus((char*)&new_srv[1], (char*)&old_srv[1],
                   repl_string);
       p_rd[i].data = new_srv_data;
-      p_rd[i].data_size = sizeof (struct srv_data) + strlen ((char*)&new_srv[1]) + 1;
+      p_rd[i].data_size = sizeof (struct GNUNET_TUN_DnsSrvRecord) + strlen ((char*)&new_srv[1]) + 1;
     }
     else if (GNUNET_DNSPARSER_TYPE_SOA == rd[i].record_type)
     {
       /* expand mname and rname */
-      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));
+      old_soa = (struct GNUNET_TUN_DnsSoaRecord*)rd[i].data;
+      new_soa = (struct GNUNET_TUN_DnsSoaRecord*)new_soa_data;
+      memcpy (new_soa, old_soa, sizeof (struct GNUNET_TUN_DnsSoaRecord));
       // 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;
@@ -1818,7 +1875,7 @@ finish_lookup (struct ResolverHandle *rh,
       expand_plus((char*)&new_soa[1] + offset,
                   (char*)&old_soa[1] + strlen ((char*)&old_soa[1]) + 1,
                   repl_string);
-      p_rd[i].data_size = sizeof (struct soa_data)
+      p_rd[i].data_size = sizeof (struct GNUNET_TUN_DnsSoaRecord)
                           + offset
                           + strlen ((char*)&new_soa[1] + offset);
       p_rd[i].data = new_soa_data;
@@ -2830,13 +2887,13 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
   query = GNUNET_new (struct GNUNET_DNSPARSER_Query);
   query->name = GNUNET_strdup (ac->label);
   query->type = rh->record_type;
-  query->class = GNUNET_DNSPARSER_CLASS_INTERNET;
+  query->class = GNUNET_TUN_DNS_CLASS_INTERNET;
   p = GNUNET_new (struct GNUNET_DNSPARSER_Packet);
   p->queries = query;
   p->num_queries = 1;
   p->id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
                                               UINT16_MAX);
-  p->flags.opcode = GNUNET_DNSPARSER_OPCODE_QUERY;
+  p->flags.opcode = GNUNET_TUN_DNS_OPCODE_QUERY;
   p->flags.recursion_desired = 1;
   if (GNUNET_OK != 
       GNUNET_DNSPARSER_pack (p, 1024, &dns_request, &dns_request_length))
@@ -3142,7 +3199,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EccPublicKey *zone,
 
   if ( ( (GNUNET_YES == is_canonical (name)) &&
         (0 != strcmp (GNUNET_GNS_TLD, name)) ) ||
-       ( (GNUNET_YES != is_gads_tld (name)) &&
+       ( (GNUNET_YES != is_gnu_tld (name)) &&
         (GNUNET_YES != is_zkey_tld (name)) ) )
   {
     /* use standard DNS lookup */
@@ -3287,15 +3344,13 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
  * Initialize the resolver
  *
  * @param nh the namestore handle
- * @param dh the dht handle
+ * @param dht the dht 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
  */
 void
 GNS_resolver_init (struct GNUNET_NAMESTORE_Handle *nh,
-                  struct GNUNET_DHT_Handle *dh,
+                  struct GNUNET_DHT_Handle *dht,
                   const struct GNUNET_CONFIGURATION_Handle *c,
                   unsigned long long max_bg_queries)
 {
@@ -3303,7 +3358,7 @@ GNS_resolver_init (struct GNUNET_NAMESTORE_Handle *nh,
 
   cfg = c;
   namestore_handle = nh;
-  dht_handle = dh;
+  dht_handle = dht;
   dht_lookup_heap =
     GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
   max_allowed_background_queries = max_bg_queries;