allow GNS clients to control recursion depth limit
authorChristian Grothoff <christian@grothoff.org>
Tue, 7 Jan 2020 08:44:59 +0000 (09:44 +0100)
committerChristian Grothoff <christian@grothoff.org>
Tue, 7 Jan 2020 08:45:52 +0000 (09:45 +0100)
src/gns/gns.h
src/gns/gns_api.c
src/gns/gnunet-service-gns.c
src/gns/gnunet-service-gns_interceptor.c
src/gns/gnunet-service-gns_resolver.c
src/gns/gnunet-service-gns_resolver.h
src/include/gnunet_gns_service.h

index 1fa812c23962fc12b7c624162cf9c02927093540..5f51b710843aaf222550045422c2e84d79279069 100644 (file)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      Copyright (C) 2012-2013 GNUnet e.V.
+      Copyright (C) 2012-2020 GNUnet e.V.
 
       GNUnet is free software: you can redistribute it and/or modify it
       under the terms of the GNU Affero General Public License as published
@@ -57,9 +57,11 @@ struct LookupMessage
   int16_t options GNUNET_PACKED;
 
   /**
-   * Always 0.
+   * Recursion depth limit, i.e. how many more 
+   * GNS zones may be traversed during the resolution
+   * of this name.
    */
-  int16_t reserved GNUNET_PACKED;
+  uint16_t recursion_depth_limit GNUNET_PACKED;
 
   /**
    * the type of record to look up
index 4a4003b2ac9d083569e3960e91b99265986a4633..0d99d822e8c4a1d6c04e1fec9c9ba67766caae0d 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009-2013, 2016, 2018 GNUnet e.V.
+     Copyright (C) 2009-2020 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
 
 #define LOG(kind, ...) GNUNET_log_from (kind, "gns-api", __VA_ARGS__)
 
+/**
+ * Default recursion depth limit to apply if
+ * the application does not specify any.
+ */
+#define DEFAULT_LIMIT 128
+
 /**
  * Handle to a lookup request
  */
@@ -325,21 +331,24 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr)
  *
  * @param handle handle to the GNS service
  * @param name the name to look up (in UTF-8 encoding)
- * @param zone the zone to start the resolution in
- * @param type the record type to look up
+ * @param zone zone to look in
+ * @param type the GNS record type to look for
  * @param options local options for the lookup
- * @param proc processor to call on result
+ * @param recursion_depth_limit maximum number of zones
+ *        that the lookup may (still) traverse
+ * @param proc function to call on result
  * @param proc_cls closure for @a proc
- * @return handle to the get request
+ * @return handle to the queued request
  */
-struct GNUNET_GNS_LookupRequest*
-GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
-                   const char *name,
-                   const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
-                   uint32_t type,
-                   enum GNUNET_GNS_LocalOptions options,
-                   GNUNET_GNS_LookupResultProcessor proc,
-                   void *proc_cls)
+struct GNUNET_GNS_LookupRequest *
+GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle,
+                           const char *name,
+                           const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
+                           uint32_t type,
+                           enum GNUNET_GNS_LocalOptions options,
+                           uint16_t recursion_depth_limit,
+                           GNUNET_GNS_LookupResultProcessor proc,
+                           void *proc_cls)
 {
   /* IPC to shorten gns names, return shorten_handle */
   struct LookupMessage *lookup_msg;
@@ -370,6 +379,8 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
                                  GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
   lookup_msg->id = htonl (lr->r_id);
   lookup_msg->options = htons ((uint16_t) options);
+  lookup_msg->recursion_depth_limit
+    = htons (recursion_depth_limit);
   lookup_msg->zone = *zone;
   lookup_msg->type = htonl (type);
   GNUNET_memcpy (&lookup_msg[1],
@@ -385,4 +396,35 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
 }
 
 
+/**
+ * Perform an asynchronous lookup operation on the GNS.
+ *
+ * @param handle handle to the GNS service
+ * @param name the name to look up (in UTF-8 encoding)
+ * @param zone the zone to start the resolution in
+ * @param type the record type to look up
+ * @param options local options for the lookup
+ * @param proc processor to call on result
+ * @param proc_cls closure for @a proc
+ * @return handle to the get request
+ */
+struct GNUNET_GNS_LookupRequest*
+GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
+                   const char *name,
+                   const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
+                   uint32_t type,
+                   enum GNUNET_GNS_LocalOptions options,
+                   GNUNET_GNS_LookupResultProcessor proc,
+                   void *proc_cls)
+{
+  return GNUNET_GNS_lookup_limited (handle,
+                                    name,
+                                    zone,
+                                    type,
+                                    options,
+                                    DEFAULT_LIMIT,
+                                    proc,
+                                    proc_cls);
+}
+
 /* end of gns_api.c */
index 99cdbfe4ed2854a08f0b633ee26c2e1f8e2f0575..8c5b2d6c432d8172dfbd698e987778b73e243893 100644 (file)
@@ -463,6 +463,7 @@ handle_lookup (void *cls,
                                      name,
                                      (enum GNUNET_GNS_LocalOptions) ntohs (
                                        sh_msg->options),
+                                     ntohs (sh_msg->recursion_depth_limit),
                                      &send_lookup_response, clh);
   GNUNET_STATISTICS_update (statistics,
                             "Lookup attempts",
index dd97782ae993e4fb132875e09d5a7724414e77ea..9d6636e84e8ccb53f30654fbba535e2f643357e8 100644 (file)
 #include "gns.h"
 
 
+/**
+ * How deep do we allow recursions to go before we abort?
+ */
+#define MAX_RECURSION 256
+
+
 /**
  * Handle to a DNS intercepted
  * reslution request
@@ -347,6 +353,7 @@ handle_dns_request (void *cls,
                                        p->queries[0].type,
                                        p->queries[0].name,
                                        GNUNET_NO,
+                                       MAX_RECURSION,
                                        &reply_to_dns, ilh);
     return;
   }
index 2c2263e585465b46f39ca3039e5f7c3264b4ab67..735742283587d14133e47f3772a57e497e9d53a9 100644 (file)
  */
 #define DHT_GNS_REPLICATION_LEVEL 10
 
-/**
- * How deep do we allow recursions to go before we abort?
- */
-#define MAX_RECURSION 256
-
 
 /**
  * DLL to hold the authority chain we had to pass in the resolution
@@ -320,7 +315,7 @@ struct GNS_ResolverHandle
   /**
    * closure passed to @e proc
    */
-  void*proc_cls;
+  void *proc_cls;
 
   /**
    * Handle for DHT lookups. should be NULL if no lookups are in progress
@@ -395,7 +390,7 @@ struct GNS_ResolverHandle
   struct DnsResult *dns_result_tail;
 
   /**
-   * Current offset in 'name' where we are resolving.
+   * Current offset in @e name where we are resolving.
    */
   size_t name_resolution_pos;
 
@@ -423,11 +418,16 @@ struct GNS_ResolverHandle
 
   /**
    * We increment the loop limiter for each step in a recursive
-   * resolution.  If it passes our threshold (i.e. due to
+   * resolution.  If it passes our @e loop_threshold (i.e. due to
    * self-recursion in the resolution, i.e CNAME fun), we stop.
    */
   unsigned int loop_limiter;
 
+  /**
+   * Maximum value of @e loop_limiter allowed by client.
+   */
+  unsigned int loop_threshold;
+
   /**
    * 16 bit random ID we used in the @e dns_request.
    */
@@ -1856,6 +1856,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
     gp->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY;
     gp->rh->options = GNUNET_GNS_LO_DEFAULT;
     gp->rh->loop_limiter = rh->loop_limiter + 1;
+    gp->rh->loop_threshold = rh->loop_threshold;
     gp->rh->task_id
       = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
                                   gp->rh);
@@ -2744,7 +2745,7 @@ recursive_resolution (void *cls)
   struct GNS_ResolverHandle *rh = cls;
 
   rh->task_id = NULL;
-  if (MAX_RECURSION < rh->loop_limiter++)
+  if (rh->loop_threshold < rh->loop_limiter++)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Encountered unbounded recursion resolving `%s'\n",
@@ -2840,6 +2841,8 @@ start_resolver_lookup (void *cls)
  * @param record_type the record type to look up
  * @param name the name to look up
  * @param options local options to control local lookup
+ * @param recursion_depth_limit how many zones to traverse
+ *        at most
  * @param proc the processor to call on result
  * @param proc_cls the closure to pass to @a proc
  * @return handle to cancel operation
@@ -2849,6 +2852,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
                      uint32_t record_type,
                      const char *name,
                      enum GNUNET_GNS_LocalOptions options,
+                     uint16_t recursion_depth_limit,
                      GNS_ResultProcessor proc,
                      void *proc_cls)
 {
@@ -2868,6 +2872,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
   rh->record_type = record_type;
   rh->name = GNUNET_strdup (name);
   rh->name_resolution_pos = strlen (name);
+  rh->loop_threshold = recursion_depth_limit;
   rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
                                           rh);
   return rh;
index cc918fd901e0a631caffca4072b89aa0f5b15588..3dab3c91ae1ecadfa464e7bfd09e91608846fe2c 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009-2013 GNUnet e.V.
+     Copyright (C) 2009-2020 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -79,6 +79,8 @@ typedef void
  * @param record_type the record type to look up
  * @param name the name to look up
  * @param options options set to control local lookup
+ * @param recursion_depth_limit how many zones to traverse
+ *        at most
  * @param proc the processor to call
  * @param proc_cls the closure to pass to @a proc
  * @return handle to cancel operation
@@ -88,6 +90,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
                      uint32_t record_type,
                      const char *name,
                      enum GNUNET_GNS_LocalOptions options,
+                     uint16_t recursion_depth_limit,
                      GNS_ResultProcessor proc,
                      void *proc_cls);
 
index 5d2b7246a2bbda93f536d0baee01aecd52bcb46f..ef81e9a8831145d13479a4eea655c2d3e9ee5650 100644 (file)
@@ -146,6 +146,31 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
                    void *proc_cls);
 
 
+/**
+ * Perform an asynchronous lookup operation on the GNS.
+ *
+ * @param handle handle to the GNS service
+ * @param name the name to look up (in UTF-8 encoding)
+ * @param zone zone to look in
+ * @param type the GNS record type to look for
+ * @param options local options for the lookup
+ * @param recursion_depth_limit maximum number of zones
+ *        that the lookup may (still) traverse
+ * @param proc function to call on result
+ * @param proc_cls closure for @a proc
+ * @return handle to the queued request
+ */
+struct GNUNET_GNS_LookupRequest *
+GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle,
+                           const char *name,
+                           const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
+                           uint32_t type,
+                           enum GNUNET_GNS_LocalOptions options,
+                           uint16_t recursion_depth_limit,
+                           GNUNET_GNS_LookupResultProcessor proc,
+                           void *proc_cls);
+
+
 /**
  * Cancel pending lookup request
  *