diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-01-07 09:44:59 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-01-07 09:45:52 +0100 |
commit | c0a6838a1b8a3ca2c73af04b8829d6736521cba1 (patch) | |
tree | 076148fca0a229738510bd023a3271127963383f | |
parent | e8533c8a41e3fb29e51200d643382c8d5f882e5e (diff) | |
download | gnunet-c0a6838a1b8a3ca2c73af04b8829d6736521cba1.tar.gz gnunet-c0a6838a1b8a3ca2c73af04b8829d6736521cba1.zip |
allow GNS clients to control recursion depth limit
-rw-r--r-- | src/gns/gns.h | 8 | ||||
-rw-r--r-- | src/gns/gns_api.c | 68 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns.c | 1 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_interceptor.c | 7 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.c | 23 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.h | 5 | ||||
-rw-r--r-- | src/include/gnunet_gns_service.h | 25 |
7 files changed, 111 insertions, 26 deletions
diff --git a/src/gns/gns.h b/src/gns/gns.h index 1fa812c23..5f51b7108 100644 --- a/src/gns/gns.h +++ b/src/gns/gns.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2012-2013 GNUnet e.V. | 3 | Copyright (C) 2012-2020 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -57,9 +57,11 @@ struct LookupMessage | |||
57 | int16_t options GNUNET_PACKED; | 57 | int16_t options GNUNET_PACKED; |
58 | 58 | ||
59 | /** | 59 | /** |
60 | * Always 0. | 60 | * Recursion depth limit, i.e. how many more |
61 | * GNS zones may be traversed during the resolution | ||
62 | * of this name. | ||
61 | */ | 63 | */ |
62 | int16_t reserved GNUNET_PACKED; | 64 | uint16_t recursion_depth_limit GNUNET_PACKED; |
63 | 65 | ||
64 | /** | 66 | /** |
65 | * the type of record to look up | 67 | * the type of record to look up |
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index 4a4003b2a..0d99d822e 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009-2013, 2016, 2018 GNUnet e.V. | 3 | Copyright (C) 2009-2020 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -37,6 +37,12 @@ | |||
37 | #define LOG(kind, ...) GNUNET_log_from (kind, "gns-api", __VA_ARGS__) | 37 | #define LOG(kind, ...) GNUNET_log_from (kind, "gns-api", __VA_ARGS__) |
38 | 38 | ||
39 | /** | 39 | /** |
40 | * Default recursion depth limit to apply if | ||
41 | * the application does not specify any. | ||
42 | */ | ||
43 | #define DEFAULT_LIMIT 128 | ||
44 | |||
45 | /** | ||
40 | * Handle to a lookup request | 46 | * Handle to a lookup request |
41 | */ | 47 | */ |
42 | struct GNUNET_GNS_LookupRequest | 48 | struct GNUNET_GNS_LookupRequest |
@@ -325,21 +331,24 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr) | |||
325 | * | 331 | * |
326 | * @param handle handle to the GNS service | 332 | * @param handle handle to the GNS service |
327 | * @param name the name to look up (in UTF-8 encoding) | 333 | * @param name the name to look up (in UTF-8 encoding) |
328 | * @param zone the zone to start the resolution in | 334 | * @param zone zone to look in |
329 | * @param type the record type to look up | 335 | * @param type the GNS record type to look for |
330 | * @param options local options for the lookup | 336 | * @param options local options for the lookup |
331 | * @param proc processor to call on result | 337 | * @param recursion_depth_limit maximum number of zones |
338 | * that the lookup may (still) traverse | ||
339 | * @param proc function to call on result | ||
332 | * @param proc_cls closure for @a proc | 340 | * @param proc_cls closure for @a proc |
333 | * @return handle to the get request | 341 | * @return handle to the queued request |
334 | */ | 342 | */ |
335 | struct GNUNET_GNS_LookupRequest* | 343 | struct GNUNET_GNS_LookupRequest * |
336 | GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | 344 | GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle, |
337 | const char *name, | 345 | const char *name, |
338 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | 346 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, |
339 | uint32_t type, | 347 | uint32_t type, |
340 | enum GNUNET_GNS_LocalOptions options, | 348 | enum GNUNET_GNS_LocalOptions options, |
341 | GNUNET_GNS_LookupResultProcessor proc, | 349 | uint16_t recursion_depth_limit, |
342 | void *proc_cls) | 350 | GNUNET_GNS_LookupResultProcessor proc, |
351 | void *proc_cls) | ||
343 | { | 352 | { |
344 | /* IPC to shorten gns names, return shorten_handle */ | 353 | /* IPC to shorten gns names, return shorten_handle */ |
345 | struct LookupMessage *lookup_msg; | 354 | struct LookupMessage *lookup_msg; |
@@ -370,6 +379,8 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
370 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP); | 379 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP); |
371 | lookup_msg->id = htonl (lr->r_id); | 380 | lookup_msg->id = htonl (lr->r_id); |
372 | lookup_msg->options = htons ((uint16_t) options); | 381 | lookup_msg->options = htons ((uint16_t) options); |
382 | lookup_msg->recursion_depth_limit | ||
383 | = htons (recursion_depth_limit); | ||
373 | lookup_msg->zone = *zone; | 384 | lookup_msg->zone = *zone; |
374 | lookup_msg->type = htonl (type); | 385 | lookup_msg->type = htonl (type); |
375 | GNUNET_memcpy (&lookup_msg[1], | 386 | GNUNET_memcpy (&lookup_msg[1], |
@@ -385,4 +396,35 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
385 | } | 396 | } |
386 | 397 | ||
387 | 398 | ||
399 | /** | ||
400 | * Perform an asynchronous lookup operation on the GNS. | ||
401 | * | ||
402 | * @param handle handle to the GNS service | ||
403 | * @param name the name to look up (in UTF-8 encoding) | ||
404 | * @param zone the zone to start the resolution in | ||
405 | * @param type the record type to look up | ||
406 | * @param options local options for the lookup | ||
407 | * @param proc processor to call on result | ||
408 | * @param proc_cls closure for @a proc | ||
409 | * @return handle to the get request | ||
410 | */ | ||
411 | struct GNUNET_GNS_LookupRequest* | ||
412 | GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | ||
413 | const char *name, | ||
414 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | ||
415 | uint32_t type, | ||
416 | enum GNUNET_GNS_LocalOptions options, | ||
417 | GNUNET_GNS_LookupResultProcessor proc, | ||
418 | void *proc_cls) | ||
419 | { | ||
420 | return GNUNET_GNS_lookup_limited (handle, | ||
421 | name, | ||
422 | zone, | ||
423 | type, | ||
424 | options, | ||
425 | DEFAULT_LIMIT, | ||
426 | proc, | ||
427 | proc_cls); | ||
428 | } | ||
429 | |||
388 | /* end of gns_api.c */ | 430 | /* end of gns_api.c */ |
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 99cdbfe4e..8c5b2d6c4 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -463,6 +463,7 @@ handle_lookup (void *cls, | |||
463 | name, | 463 | name, |
464 | (enum GNUNET_GNS_LocalOptions) ntohs ( | 464 | (enum GNUNET_GNS_LocalOptions) ntohs ( |
465 | sh_msg->options), | 465 | sh_msg->options), |
466 | ntohs (sh_msg->recursion_depth_limit), | ||
466 | &send_lookup_response, clh); | 467 | &send_lookup_response, clh); |
467 | GNUNET_STATISTICS_update (statistics, | 468 | GNUNET_STATISTICS_update (statistics, |
468 | "Lookup attempts", | 469 | "Lookup attempts", |
diff --git a/src/gns/gnunet-service-gns_interceptor.c b/src/gns/gnunet-service-gns_interceptor.c index dd97782ae..9d6636e84 100644 --- a/src/gns/gnunet-service-gns_interceptor.c +++ b/src/gns/gnunet-service-gns_interceptor.c | |||
@@ -34,6 +34,12 @@ | |||
34 | 34 | ||
35 | 35 | ||
36 | /** | 36 | /** |
37 | * How deep do we allow recursions to go before we abort? | ||
38 | */ | ||
39 | #define MAX_RECURSION 256 | ||
40 | |||
41 | |||
42 | /** | ||
37 | * Handle to a DNS intercepted | 43 | * Handle to a DNS intercepted |
38 | * reslution request | 44 | * reslution request |
39 | */ | 45 | */ |
@@ -347,6 +353,7 @@ handle_dns_request (void *cls, | |||
347 | p->queries[0].type, | 353 | p->queries[0].type, |
348 | p->queries[0].name, | 354 | p->queries[0].name, |
349 | GNUNET_NO, | 355 | GNUNET_NO, |
356 | MAX_RECURSION, | ||
350 | &reply_to_dns, ilh); | 357 | &reply_to_dns, ilh); |
351 | return; | 358 | return; |
352 | } | 359 | } |
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 2c2263e58..735742283 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -77,11 +77,6 @@ | |||
77 | */ | 77 | */ |
78 | #define DHT_GNS_REPLICATION_LEVEL 10 | 78 | #define DHT_GNS_REPLICATION_LEVEL 10 |
79 | 79 | ||
80 | /** | ||
81 | * How deep do we allow recursions to go before we abort? | ||
82 | */ | ||
83 | #define MAX_RECURSION 256 | ||
84 | |||
85 | 80 | ||
86 | /** | 81 | /** |
87 | * DLL to hold the authority chain we had to pass in the resolution | 82 | * DLL to hold the authority chain we had to pass in the resolution |
@@ -320,7 +315,7 @@ struct GNS_ResolverHandle | |||
320 | /** | 315 | /** |
321 | * closure passed to @e proc | 316 | * closure passed to @e proc |
322 | */ | 317 | */ |
323 | void*proc_cls; | 318 | void *proc_cls; |
324 | 319 | ||
325 | /** | 320 | /** |
326 | * Handle for DHT lookups. should be NULL if no lookups are in progress | 321 | * Handle for DHT lookups. should be NULL if no lookups are in progress |
@@ -395,7 +390,7 @@ struct GNS_ResolverHandle | |||
395 | struct DnsResult *dns_result_tail; | 390 | struct DnsResult *dns_result_tail; |
396 | 391 | ||
397 | /** | 392 | /** |
398 | * Current offset in 'name' where we are resolving. | 393 | * Current offset in @e name where we are resolving. |
399 | */ | 394 | */ |
400 | size_t name_resolution_pos; | 395 | size_t name_resolution_pos; |
401 | 396 | ||
@@ -423,12 +418,17 @@ struct GNS_ResolverHandle | |||
423 | 418 | ||
424 | /** | 419 | /** |
425 | * We increment the loop limiter for each step in a recursive | 420 | * We increment the loop limiter for each step in a recursive |
426 | * resolution. If it passes our threshold (i.e. due to | 421 | * resolution. If it passes our @e loop_threshold (i.e. due to |
427 | * self-recursion in the resolution, i.e CNAME fun), we stop. | 422 | * self-recursion in the resolution, i.e CNAME fun), we stop. |
428 | */ | 423 | */ |
429 | unsigned int loop_limiter; | 424 | unsigned int loop_limiter; |
430 | 425 | ||
431 | /** | 426 | /** |
427 | * Maximum value of @e loop_limiter allowed by client. | ||
428 | */ | ||
429 | unsigned int loop_threshold; | ||
430 | |||
431 | /** | ||
432 | * 16 bit random ID we used in the @e dns_request. | 432 | * 16 bit random ID we used in the @e dns_request. |
433 | */ | 433 | */ |
434 | uint16_t original_dns_id; | 434 | uint16_t original_dns_id; |
@@ -1856,6 +1856,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh, | |||
1856 | gp->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY; | 1856 | gp->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY; |
1857 | gp->rh->options = GNUNET_GNS_LO_DEFAULT; | 1857 | gp->rh->options = GNUNET_GNS_LO_DEFAULT; |
1858 | gp->rh->loop_limiter = rh->loop_limiter + 1; | 1858 | gp->rh->loop_limiter = rh->loop_limiter + 1; |
1859 | gp->rh->loop_threshold = rh->loop_threshold; | ||
1859 | gp->rh->task_id | 1860 | gp->rh->task_id |
1860 | = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, | 1861 | = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, |
1861 | gp->rh); | 1862 | gp->rh); |
@@ -2744,7 +2745,7 @@ recursive_resolution (void *cls) | |||
2744 | struct GNS_ResolverHandle *rh = cls; | 2745 | struct GNS_ResolverHandle *rh = cls; |
2745 | 2746 | ||
2746 | rh->task_id = NULL; | 2747 | rh->task_id = NULL; |
2747 | if (MAX_RECURSION < rh->loop_limiter++) | 2748 | if (rh->loop_threshold < rh->loop_limiter++) |
2748 | { | 2749 | { |
2749 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2750 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2750 | "Encountered unbounded recursion resolving `%s'\n", | 2751 | "Encountered unbounded recursion resolving `%s'\n", |
@@ -2840,6 +2841,8 @@ start_resolver_lookup (void *cls) | |||
2840 | * @param record_type the record type to look up | 2841 | * @param record_type the record type to look up |
2841 | * @param name the name to look up | 2842 | * @param name the name to look up |
2842 | * @param options local options to control local lookup | 2843 | * @param options local options to control local lookup |
2844 | * @param recursion_depth_limit how many zones to traverse | ||
2845 | * at most | ||
2843 | * @param proc the processor to call on result | 2846 | * @param proc the processor to call on result |
2844 | * @param proc_cls the closure to pass to @a proc | 2847 | * @param proc_cls the closure to pass to @a proc |
2845 | * @return handle to cancel operation | 2848 | * @return handle to cancel operation |
@@ -2849,6 +2852,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | |||
2849 | uint32_t record_type, | 2852 | uint32_t record_type, |
2850 | const char *name, | 2853 | const char *name, |
2851 | enum GNUNET_GNS_LocalOptions options, | 2854 | enum GNUNET_GNS_LocalOptions options, |
2855 | uint16_t recursion_depth_limit, | ||
2852 | GNS_ResultProcessor proc, | 2856 | GNS_ResultProcessor proc, |
2853 | void *proc_cls) | 2857 | void *proc_cls) |
2854 | { | 2858 | { |
@@ -2868,6 +2872,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | |||
2868 | rh->record_type = record_type; | 2872 | rh->record_type = record_type; |
2869 | rh->name = GNUNET_strdup (name); | 2873 | rh->name = GNUNET_strdup (name); |
2870 | rh->name_resolution_pos = strlen (name); | 2874 | rh->name_resolution_pos = strlen (name); |
2875 | rh->loop_threshold = recursion_depth_limit; | ||
2871 | rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, | 2876 | rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, |
2872 | rh); | 2877 | rh); |
2873 | return rh; | 2878 | return rh; |
diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h index cc918fd90..3dab3c91a 100644 --- a/src/gns/gnunet-service-gns_resolver.h +++ b/src/gns/gnunet-service-gns_resolver.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009-2013 GNUnet e.V. | 3 | Copyright (C) 2009-2020 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -79,6 +79,8 @@ typedef void | |||
79 | * @param record_type the record type to look up | 79 | * @param record_type the record type to look up |
80 | * @param name the name to look up | 80 | * @param name the name to look up |
81 | * @param options options set to control local lookup | 81 | * @param options options set to control local lookup |
82 | * @param recursion_depth_limit how many zones to traverse | ||
83 | * at most | ||
82 | * @param proc the processor to call | 84 | * @param proc the processor to call |
83 | * @param proc_cls the closure to pass to @a proc | 85 | * @param proc_cls the closure to pass to @a proc |
84 | * @return handle to cancel operation | 86 | * @return handle to cancel operation |
@@ -88,6 +90,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | |||
88 | uint32_t record_type, | 90 | uint32_t record_type, |
89 | const char *name, | 91 | const char *name, |
90 | enum GNUNET_GNS_LocalOptions options, | 92 | enum GNUNET_GNS_LocalOptions options, |
93 | uint16_t recursion_depth_limit, | ||
91 | GNS_ResultProcessor proc, | 94 | GNS_ResultProcessor proc, |
92 | void *proc_cls); | 95 | void *proc_cls); |
93 | 96 | ||
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index 5d2b7246a..ef81e9a88 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h | |||
@@ -147,6 +147,31 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
147 | 147 | ||
148 | 148 | ||
149 | /** | 149 | /** |
150 | * Perform an asynchronous lookup operation on the GNS. | ||
151 | * | ||
152 | * @param handle handle to the GNS service | ||
153 | * @param name the name to look up (in UTF-8 encoding) | ||
154 | * @param zone zone to look in | ||
155 | * @param type the GNS record type to look for | ||
156 | * @param options local options for the lookup | ||
157 | * @param recursion_depth_limit maximum number of zones | ||
158 | * that the lookup may (still) traverse | ||
159 | * @param proc function to call on result | ||
160 | * @param proc_cls closure for @a proc | ||
161 | * @return handle to the queued request | ||
162 | */ | ||
163 | struct GNUNET_GNS_LookupRequest * | ||
164 | GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle, | ||
165 | const char *name, | ||
166 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | ||
167 | uint32_t type, | ||
168 | enum GNUNET_GNS_LocalOptions options, | ||
169 | uint16_t recursion_depth_limit, | ||
170 | GNUNET_GNS_LookupResultProcessor proc, | ||
171 | void *proc_cls); | ||
172 | |||
173 | |||
174 | /** | ||
150 | * Cancel pending lookup request | 175 | * Cancel pending lookup request |
151 | * | 176 | * |
152 | * @param lr the lookup request to cancel | 177 | * @param lr the lookup request to cancel |