-fixes
[oweals/gnunet.git] / src / gns / gnunet-service-gns_resolver.c
index d1cc4ccd317b616f7469798b2a114477452b593a..9959c43d57405e1acb2ed7ef6a95b3b243109c2e 100644 (file)
@@ -38,7 +38,6 @@
 #include "gns.h"
 #include "gnunet-service-gns_resolver.h"
 
-#define DHT_OPERATION_TIMEOUT  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
 #define DHT_LOOKUP_TIMEOUT DHT_OPERATION_TIMEOUT
 #define DHT_GNS_REPLICATION_LEVEL 5
 #define MAX_DNS_LABEL_LENGTH 63
@@ -64,11 +63,21 @@ static struct GNUNET_CONTAINER_Heap *dht_lookup_heap;
  */
 static unsigned long long max_allowed_background_queries;
 
+/**
+ * Wheather or not to ignore pending records
+ */
+static int ignore_pending_records;
+
 /**
  * Our local zone
  */
 static struct GNUNET_CRYPTO_ShortHashCode local_zone;
 
+/**
+ * a resolution identifier pool variable
+ * FIXME overflow?
+ * This is a non critical identifier useful for debugging
+ */
 static unsigned long long rid = 0;
 
 /**
@@ -113,7 +122,7 @@ process_pseu_lookup_ns(void* cls,
     GNUNET_NAMESTORE_lookup_record(namestore_handle,
                                    &gph->zone,
                                    gph->new_name,
-                                   GNUNET_GNS_RECORD_PSEU,
+                                   GNUNET_NAMESTORE_TYPE_ANY,
                                    &process_pseu_lookup_ns,
                                    gph);
     return;
@@ -127,6 +136,9 @@ process_pseu_lookup_ns(void* cls,
   new_pkey.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
   new_pkey.data = &gph->new_zone;
   new_pkey.record_type = GNUNET_GNS_RECORD_PKEY;
+  new_pkey.flags = GNUNET_NAMESTORE_RF_AUTHORITY
+                 | GNUNET_NAMESTORE_RF_PRIVATE
+                 | GNUNET_NAMESTORE_RF_PENDING;
   GNUNET_NAMESTORE_record_create (namestore_handle,
                                   gph->key,
                                   gph->new_name,
@@ -164,7 +176,7 @@ process_pseu_result(struct GetPseuAuthorityHandle* gph, char* name)
   GNUNET_NAMESTORE_lookup_record(namestore_handle,
                                  &gph->zone,
                                  gph->new_name,
-                                 GNUNET_GNS_RECORD_PSEU,
+                                 GNUNET_NAMESTORE_TYPE_ANY,
                                  &process_pseu_lookup_ns,
                                  gph);
 }
@@ -431,13 +443,16 @@ static void process_discovered_authority(char* name,
  * @param dh the dht handle
  * @param lz the local zone's hash
  * @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,
-                  unsigned long long max_bg_queries)
+                  unsigned long long max_bg_queries,
+                  int ignore_pending)
 {
   namestore_handle = nh;
   dht_handle = dh;
@@ -445,6 +460,7 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh,
   dht_lookup_heap =
     GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
   max_allowed_background_queries = max_bg_queries;
+  ignore_pending_records = ignore_pending;
 
   if ((namestore_handle != NULL) && (dht_handle != NULL))
   {
@@ -472,7 +488,7 @@ cleanup_pending_background_queries(void* cls,
   ResolverCleanupContinuation cont = cls;
   
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "GNS_CLEANUP-%d: Terminating background lookup for %s\n",
+             "GNS_CLEANUP-%llu: Terminating background lookup for %s\n",
              rh->id, rh->name);
   GNUNET_DHT_get_stop(rh->get_handle);
   rh->get_handle = NULL;
@@ -897,12 +913,12 @@ process_record_result_ns(void* cls,
   
   if (name != NULL)
   {
-    rh->status |= EXISTS;
+    rh->status |= RSL_RECORD_EXISTS;
   }
   
   if (remaining_time.rel_value == 0)
   {
-    rh->status |= EXPIRED;
+    rh->status |= RSL_RECORD_EXPIRED;
   }
   
   if (rd_count == 0)
@@ -936,6 +952,15 @@ process_record_result_ns(void* cls,
 
       if (rd[i].record_type != rlh->record_type)
         continue;
+
+      if (ignore_pending_records &&
+          (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",
+        rh->id, name);
+        continue;
+      }
       
       if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value
           == 0)
@@ -1023,7 +1048,7 @@ dht_authority_lookup_timeout(void *cls,
          "GNS_PHASE_DELEGATE_DHT-%llu: dht lookup for query %s (%ds)timed out.\n",
          rh->id, rh->authority_name, rh->timeout.rel_value);
 
-  rh->status |= TIMED_OUT;
+  rh->status |= RSL_TIMED_OUT;
 
   rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   
@@ -1469,7 +1494,7 @@ handle_record_ns(void* cls, struct ResolverHandle *rh,
     
     /**
      * There are 4 conditions that have to met for us to consult the DHT:
-     * 1. The entry in the DHT is EXPIRED AND
+     * 1. The entry in the DHT is RSL_RECORD_EXPIRED AND
      * 2. No entry in the NS existed AND
      * 3. The zone queried is not the local resolver's zone AND
      * 4. The name that was looked up is '+'
@@ -1477,7 +1502,7 @@ handle_record_ns(void* cls, struct ResolverHandle *rh,
      *    the DHT for the authority in the authority lookup phase (and thus
      *    would already have an entry in the NS for the record)
      */
-    if (rh->status & (EXPIRED | !EXISTS) &&
+    if (rh->status & (RSL_RECORD_EXPIRED | !RSL_RECORD_EXISTS) &&
         GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
                                      &local_zone) &&
         (strcmp(rh->name, "+") == 0))
@@ -1737,6 +1762,10 @@ handle_delegation_ns(void* cls, struct ResolverHandle *rh,
 {
   struct RecordLookupHandle* rlh;
   rlh = (struct RecordLookupHandle*) cls;
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+             "GNS_PHASE_DELEGATE_NS-%llu: Resolution status: %d.\n",
+             rh->id, rh->status);
   
   if (strcmp(rh->name, "") == 0)
   {
@@ -1766,9 +1795,9 @@ handle_delegation_ns(void* cls, struct ResolverHandle *rh,
    * and exists
    * or we are authority
    **/
-  if ((rh->status & (EXISTS | !EXPIRED)) ||
-      !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
-                             &rh->authority_chain_tail->zone))
+  if (((rh->status & RSL_RECORD_EXISTS) && (!(rh->status & RSL_RECORD_EXPIRED)))
+      || !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+                                       &local_zone))
   {
     if (is_canonical(rh->name))
     {
@@ -1843,12 +1872,18 @@ process_delegation_result_ns(void* cls,
   
   if (name != NULL)
   {
-    rh->status |= EXISTS;
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+               "GNS_PHASE_DELEGATE_NS-%llu: Records with name %s exist.\n",
+               rh->id, name);
+    rh->status |= RSL_RECORD_EXISTS;
   }
   
   if (remaining_time.rel_value == 0)
   {
-    rh->status |= EXPIRED;
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+               "GNS_PHASE_DELEGATE_NS-%llu: Record set %s expired.\n",
+               rh->id, name);
+    rh->status |= RSL_RECORD_EXPIRED;
   }
   
   /**
@@ -1904,6 +1939,16 @@ process_delegation_result_ns(void* cls,
   
     if (rd[i].record_type != GNUNET_GNS_RECORD_PKEY)
       continue;
+
+    if (ignore_pending_records &&
+        (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING))
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+      "GNS_PHASE_DELEGATE_NS-%llu: PKEY for %s is pending user confirmation.\n",
+        name,
+        rh->id);
+      continue;
+    }
     
     if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value
          == 0)
@@ -1959,7 +2004,23 @@ process_delegation_result_ns(void* cls,
    */
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
     "GNS_PHASE_DELEGATE_NS-%llu: Authority lookup and no PKEY...\n", rh->id);
-  rh->proc(rh->proc_cls, rh, 0, NULL);
+  /**
+   * If we have found some records for the LAST label
+   * we return the results. Else null.
+   */
+  if (strcmp(rh->name, "") == 0)
+  {
+    /* 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);
+  }
+  else
+  {
+    rh->proc(rh->proc_cls, rh, 0, NULL);
+  }
 }
 
 
@@ -1978,7 +2039,7 @@ resolve_delegation_ns(struct ResolverHandle *rh)
   GNUNET_NAMESTORE_lookup_record(namestore_handle,
                                  &rh->authority,
                                  rh->authority_name,
-                                 GNUNET_GNS_RECORD_PKEY,
+                                 GNUNET_GNS_RECORD_ANY,
                                  &process_delegation_result_ns,
                                  rh);