REST: nothing triggers rest
[oweals/gnunet.git] / src / gns / gnunet-service-gns_resolver.c
index d3c07e9977695d29d97cf23f5abff173bd5e2da7..703a0f6522a3b2ead18df499d8d5fa1c2b128bf6 100644 (file)
@@ -2,20 +2,20 @@
      This file is part of GNUnet.
      Copyright (C) 2011-2013 GNUnet e.V.
 
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
+     Affero General Public License for more details.
 
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 
 /**
@@ -60,7 +60,7 @@
 /**
  * DHT replication level
  */
-#define DHT_GNS_REPLICATION_LEVEL 5
+#define DHT_GNS_REPLICATION_LEVEL 10
 
 /**
  * How deep do we allow recursions to go before we abort?
@@ -372,6 +372,12 @@ struct GNS_ResolverHandle
    */
   char *name;
 
+  /**
+   * Legacy Hostname to use if we encountered GNS2DNS record
+   * and thus can deduct the LEHO from that transition.
+   */
+  char *leho;
+
   /**
    * DLL of results we got from DNS.
    */
@@ -618,25 +624,6 @@ timeout_resolution (void *cls)
 }
 
 
-#if (defined WINDOWS) || (defined DARWIN)
-/* Don't have this on W32, here's a naive implementation
- * Was somehow removed on OS X ...  */
-static void *
-memrchr (const void *s,
-        int c,
-        size_t n)
-{
-  const unsigned char *ucs = s;
-  ssize_t i;
-
-  for (i = n - 1; i >= 0; i--)
-    if (c == (int) ucs[i])
-      return (void *) &ucs[i];
-  return NULL;
-}
-#endif
-
-
 /**
  * Get the next, rightmost label from the name that we are trying to resolve,
  * and update the resolution position accordingly.  Labels usually consist
@@ -965,20 +952,28 @@ dns_result_parser (void *cls,
       af = AF_UNSPEC;
       break;
     }
+    if (NULL != rh->leho)
+      add_dns_result (rh,
+                     GNUNET_TIME_UNIT_HOURS.rel_value_us,
+                     GNUNET_GNSRECORD_TYPE_LEHO,
+                     strlen (rh->leho),
+                     rh->leho);
     rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name,
                                               af,
                                               DNS_LOOKUP_TIMEOUT,
                                               &handle_dns_result,
                                               rh);
     GNUNET_DNSPARSER_free_packet (p);
+    GNUNET_DNSSTUB_resolve_cancel (rh->dns_request);
+    rh->dns_request = NULL;
     return;
   }
 
   /* convert from (parsed) DNS to (binary) GNS format! */
   rd_count = p->num_answers + p->num_authority_records + p->num_additional_records;
   {
-    struct GNUNET_GNSRECORD_Data rd[rd_count];
-    unsigned int skip;
+    struct GNUNET_GNSRECORD_Data rd[rd_count + 1]; /* +1 for LEHO */
+    int skip;
     char buf[UINT16_MAX];
     size_t buf_off;
     size_t buf_start;
@@ -1102,14 +1097,28 @@ dns_result_parser (void *cls,
        skip++;
        continue;
       }
+    } /* end of for all records in answer */
+    if (NULL != rh->leho)
+    {
+      rd[rd_count - skip].record_type = GNUNET_GNSRECORD_TYPE_LEHO;
+      rd[rd_count - skip].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+      rd[rd_count - skip].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us;
+      rd[rd_count - skip].data = rh->leho;
+      rd[rd_count - skip].data_size = strlen (rh->leho);
+      skip--; /* skip one LESS */
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Adding LEHO %s\n",
+                 rh->leho);
     }
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Returning DNS response for `%s' with %u answers\n",
                 rh->ac_tail->label,
-                (unsigned int) p->num_answers);
+                (unsigned int) (rd_count - skip));
     rh->proc (rh->proc_cls,
               rd_count - skip,
               rd);
+    GNUNET_DNSSTUB_resolve_cancel (rh->dns_request);
+    rh->dns_request = NULL;
   }
   GNUNET_DNSPARSER_free_packet (p);
   if (NULL != rh->task_id)
@@ -1173,6 +1182,7 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
     rh->original_dns_id = p->id;
     GNUNET_assert (NULL != ac->authority_info.dns_authority.dns_handle);
     GNUNET_assert (NULL == rh->dns_request);
+    rh->leho = GNUNET_strdup (ac->label);
     rh->dns_request = GNUNET_DNSSTUB_resolve (ac->authority_info.dns_authority.dns_handle,
                                              dns_request,
                                              dns_request_length,
@@ -1350,6 +1360,10 @@ vpn_allocation_cb (void *cls,
     }
   }
   GNUNET_assert (i < vpn_ctx->rd_count);
+  if (0 == vpn_ctx->rd_count)
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("VPN returned empty result for `%s'\n"),
+               rh->name);
   handle_gns_resolution_result (rh,
                                vpn_ctx->rd_count,
                                rd);
@@ -1832,7 +1846,8 @@ handle_gns_resolution_result (void *cls,
   if (0 == rd_count)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("GNS lookup failed (zero records found)\n"));
+                _("GNS lookup failed (zero records found for `%s')\n"),
+               rh->name);
     fail_resolution (rh);
     return;
   }
@@ -2343,6 +2358,11 @@ handle_dht_response (void *cls,
     fail_resolution (rh);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Decrypting DHT block of size %u for `%s', expires %s\n",
+             ntohl (block->purpose.size),
+             rh->name,
+             GNUNET_STRINGS_absolute_time_to_string (exp));
   if (GNUNET_OK !=
       GNUNET_GNSRECORD_block_decrypt (block,
                                      &ac->authority_info.gns_authority,
@@ -2360,6 +2380,8 @@ handle_dht_response (void *cls,
                 "Received expired block from the DHT, will not cache it.\n");
     return;
   }
+  if (GNUNET_YES == disable_cache)
+    return;
   /* Cache well-formed blocks */
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Caching response from the DHT in namecache\n");
@@ -2423,6 +2445,10 @@ handle_gns_namecache_resolution_result (void *cls,
 {
   struct GNS_ResolverHandle *rh = cls;
 
+  if (0 == rd_count)
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("GNS namecache returned empty result for `%s'\n"),
+               rh->name);
   handle_gns_resolution_result (rh,
                                 rd_count,
                                 rd);
@@ -2831,6 +2857,7 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
                                 dr);
     GNUNET_free (dr);
   }
+  GNUNET_free_non_null (rh->leho);
   GNUNET_free (rh->name);
   GNUNET_free (rh);
 }