aboutsummaryrefslogtreecommitdiff
path: root/src/gns
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns')
-rw-r--r--src/gns/Makefile.am26
-rw-r--r--src/gns/gnunet-bcd.c2
-rw-r--r--src/gns/gnunet-dns2gns.c209
-rw-r--r--src/gns/gnunet-service-gns.c8
-rw-r--r--src/gns/gnunet-service-gns_resolver.c348
-rw-r--r--src/gns/plugin_block_gns.c132
-rw-r--r--src/gns/plugin_gnsrecord_gns.c40
-rwxr-xr-xsrc/gns/test_gns_cname_lookup.sh99
-rwxr-xr-xsrc/gns/test_gns_gns2dns_cname_lookup.sh9
-rwxr-xr-xsrc/gns/test_gns_gns2dns_lookup.sh14
-rwxr-xr-xsrc/gns/test_gns_gns2dns_zkey_lookup.sh14
-rwxr-xr-xsrc/gns/test_gns_redirect_lookup.sh100
12 files changed, 542 insertions, 459 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index 315b4dbf3..d49e0c5c8 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -155,6 +155,7 @@ gnunet_dns2gns_LDADD = \
155 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ 155 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
156 libgnunetgns.la \ 156 libgnunetgns.la \
157 $(top_builddir)/src/util/libgnunetutil.la \ 157 $(top_builddir)/src/util/libgnunetutil.la \
158 $(USE_VPN) \
158 $(top_builddir)/src/identity/libgnunetidentity.la \ 159 $(top_builddir)/src/identity/libgnunetidentity.la \
159 $(GN_LIBINTL) 160 $(GN_LIBINTL)
160 161
@@ -218,7 +219,6 @@ gnunet_service_gns_LDADD = \
218 $(top_builddir)/src/dht/libgnunetdht.la \ 219 $(top_builddir)/src/dht/libgnunetdht.la \
219 $(top_builddir)/src/namecache/libgnunetnamecache.la \ 220 $(top_builddir)/src/namecache/libgnunetnamecache.la \
220 $(LIBIDN) $(LIBIDN2) \ 221 $(LIBIDN) $(LIBIDN2) \
221 $(USE_VPN) \
222 $(GN_LIBINTL) 222 $(GN_LIBINTL)
223 223
224 224
@@ -270,8 +270,7 @@ check_SCRIPTS = \
270 test_gns_rel_expiration.sh\ 270 test_gns_rel_expiration.sh\
271 test_gns_soa_lookup.sh\ 271 test_gns_soa_lookup.sh\
272 test_gns_revocation.sh\ 272 test_gns_revocation.sh\
273 test_gns_cname_lookup.sh\ 273 test_gns_redirect_lookup.sh
274 test_proxy.sh
275 274
276if HAVE_GNUTLS 275if HAVE_GNUTLS
277if HAVE_LIBGNURL 276if HAVE_LIBGNURL
@@ -292,7 +291,26 @@ EXTRA_DIST = \
292 zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \ 291 zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \
293 zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \ 292 zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \
294 zonefiles/test_zonekey \ 293 zonefiles/test_zonekey \
295 $(check_SCRIPTS) \ 294 test_gns_lookup.sh \
295 test_gns_config_lookup.sh \
296 test_gns_ipv6_lookup.sh\
297 test_gns_txt_lookup.sh\
298 test_gns_caa_lookup.sh\
299 test_gns_mx_lookup.sh \
300 test_gns_gns2dns_lookup.sh \
301 test_gns_gns2dns_zkey_lookup.sh \
302 test_gns_gns2dns_cname_lookup.sh \
303 test_gns_dht_lookup.sh\
304 test_gns_delegated_lookup.sh \
305 test_gns_at_lookup.sh\
306 test_gns_zkey_lookup.sh\
307 test_gns_rel_expiration.sh\
308 test_gns_soa_lookup.sh\
309 test_gns_revocation.sh\
310 test_gns_redirect_lookup.sh\
311 test_proxy.sh\
312 test_plugin_rest_gns.sh\
313 test_proxy.sh \
296 $(pkgdata_DATA) \ 314 $(pkgdata_DATA) \
297 test_gnunet_gns.sh.in 315 test_gnunet_gns.sh.in
298 316
diff --git a/src/gns/gnunet-bcd.c b/src/gns/gnunet-bcd.c
index 83efcfba5..60fe25945 100644
--- a/src/gns/gnunet-bcd.c
+++ b/src/gns/gnunet-bcd.c
@@ -419,6 +419,8 @@ create_response (void *cls,
419 "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n", 419 "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n",
420 line1, 420 line1,
421 line2); 421 line2);
422 GNUNET_free (line1);
423 GNUNET_free (line2);
422 } 424 }
423 425
424 fprintf (deffile, 426 fprintf (deffile,
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c
index 06f4c9841..46659cdda 100644
--- a/src/gns/gnunet-dns2gns.c
+++ b/src/gns/gnunet-dns2gns.c
@@ -27,6 +27,7 @@
27#include <gnunet_dnsparser_lib.h> 27#include <gnunet_dnsparser_lib.h>
28#include <gnunet_gns_service.h> 28#include <gnunet_gns_service.h>
29#include <gnunet_dnsstub_lib.h> 29#include <gnunet_dnsstub_lib.h>
30#include "gnunet_vpn_service.h"
30#include "gns.h" 31#include "gns.h"
31 32
32/** 33/**
@@ -35,6 +36,46 @@
35#define TIMEOUT GNUNET_TIME_UNIT_MINUTES 36#define TIMEOUT GNUNET_TIME_UNIT_MINUTES
36 37
37/** 38/**
39 * Default timeout for VPN redirections.
40 */
41#define VPN_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
42
43
44struct Request;
45
46/**
47 * Closure for #vpn_allocation_cb.
48 */
49struct VpnContext
50{
51 /**
52 * Which resolution process are we processing.
53 */
54 struct Request *request;
55
56 /**
57 * Handle to the VPN request that we were performing.
58 */
59 struct GNUNET_VPN_RedirectionRequest *vpn_request;
60
61 /**
62 * Number of records serialized in @e rd_data.
63 */
64 unsigned int rd_count;
65
66 /**
67 * Serialized records.
68 */
69 char *rd_data;
70
71 /**
72 * Number of bytes in @e rd_data.
73 */
74 ssize_t rd_data_size;
75};
76
77
78/**
38 * Data kept per request. 79 * Data kept per request.
39 */ 80 */
40struct Request 81struct Request
@@ -72,6 +113,11 @@ struct Request
72 struct GNUNET_SCHEDULER_Task *timeout_task; 113 struct GNUNET_SCHEDULER_Task *timeout_task;
73 114
74 /** 115 /**
116 * Vpn resulution context
117 */
118 struct VpnContext *vpn_ctx;
119
120 /**
75 * Original UDP request message. 121 * Original UDP request message.
76 */ 122 */
77 char *udp_msg; 123 char *udp_msg;
@@ -90,6 +136,7 @@ struct Request
90 * ID of the original request. 136 * ID of the original request.
91 */ 137 */
92 uint16_t original_request_id; 138 uint16_t original_request_id;
139
93}; 140};
94 141
95/** 142/**
@@ -109,6 +156,11 @@ static struct in6_addr address6;
109struct GNUNET_GNS_Handle *gns; 156struct GNUNET_GNS_Handle *gns;
110 157
111/** 158/**
159 * Our handle to the vpn service
160 */
161static struct GNUNET_VPN_Handle *vpn_handle;
162
163/**
112 * Stub resolver 164 * Stub resolver
113 */ 165 */
114struct GNUNET_DNSSTUB_Context *dns_stub; 166struct GNUNET_DNSSTUB_Context *dns_stub;
@@ -183,6 +235,11 @@ do_shutdown (void *cls)
183 GNUNET_GNS_disconnect (gns); 235 GNUNET_GNS_disconnect (gns);
184 gns = NULL; 236 gns = NULL;
185 } 237 }
238 if (NULL != vpn_handle)
239 {
240 GNUNET_VPN_disconnect (vpn_handle);
241 vpn_handle = NULL;
242 }
186 if (NULL != dns_stub) 243 if (NULL != dns_stub)
187 { 244 {
188 GNUNET_DNSSTUB_stop (dns_stub); 245 GNUNET_DNSSTUB_stop (dns_stub);
@@ -269,6 +326,7 @@ static void
269do_timeout (void *cls) 326do_timeout (void *cls)
270{ 327{
271 struct Request *request = cls; 328 struct Request *request = cls;
329 struct VpnContext *vpn_ctx;
272 330
273 if (NULL != request->packet) 331 if (NULL != request->packet)
274 GNUNET_DNSPARSER_free_packet (request->packet); 332 GNUNET_DNSPARSER_free_packet (request->packet);
@@ -277,6 +335,12 @@ do_timeout (void *cls)
277 if (NULL != request->dns_lookup) 335 if (NULL != request->dns_lookup)
278 GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup); 336 GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup);
279 GNUNET_free (request->udp_msg); 337 GNUNET_free (request->udp_msg);
338 if (NULL != (vpn_ctx = request->vpn_ctx))
339 {
340 GNUNET_VPN_cancel_request (vpn_ctx->vpn_request);
341 GNUNET_free (vpn_ctx->rd_data);
342 GNUNET_free (vpn_ctx);
343 }
280 GNUNET_free (request); 344 GNUNET_free (request);
281} 345}
282 346
@@ -321,6 +385,79 @@ dns_result_processor (void *cls,
321 send_response (request); 385 send_response (request);
322} 386}
323 387
388/**
389 * Callback invoked from the VPN service once a redirection is
390 * available. Provides the IP address that can now be used to
391 * reach the requested destination. Replaces the "VPN" record
392 * with the respective A/AAAA record and continues processing.
393 *
394 * @param cls closure
395 * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error;
396 * will match 'result_af' from the request
397 * @param address IP address (struct in_addr or struct in_addr6, depending on 'af')
398 * that the VPN allocated for the redirection;
399 * traffic to this IP will now be redirected to the
400 * specified target peer; NULL on error
401 */
402static void
403vpn_allocation_cb (void *cls,
404 int af,
405 const void *address)
406{
407 struct VpnContext *vpn_ctx = cls;
408 struct Request *request = vpn_ctx->request;
409 struct GNUNET_GNSRECORD_Data rd[vpn_ctx->rd_count];
410 unsigned int i;
411
412 vpn_ctx->vpn_request = NULL;
413 request->vpn_ctx = NULL;
414 GNUNET_assert (GNUNET_OK ==
415 GNUNET_GNSRECORD_records_deserialize (
416 (size_t) vpn_ctx->rd_data_size,
417 vpn_ctx->rd_data,
418 vpn_ctx->rd_count,
419 rd));
420 for (i = 0; i < vpn_ctx->rd_count; i++)
421 {
422 if (GNUNET_GNSRECORD_TYPE_VPN == rd[i].record_type)
423 {
424 switch (af)
425 {
426 case AF_INET:
427 rd[i].record_type = GNUNET_DNSPARSER_TYPE_A;
428 rd[i].data_size = sizeof(struct in_addr);
429 rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
430 VPN_TIMEOUT).abs_value_us;
431 rd[i].flags = 0;
432 rd[i].data = address;
433 break;
434
435 case AF_INET6:
436 rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
437 rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
438 VPN_TIMEOUT).abs_value_us;
439 rd[i].flags = 0;
440 rd[i].data = address;
441 rd[i].data_size = sizeof(struct in6_addr);
442 break;
443
444 default:
445 GNUNET_assert (0);
446 }
447 break;
448 }
449 }
450 GNUNET_assert (i < vpn_ctx->rd_count);
451 if (0 == vpn_ctx->rd_count)
452 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
453 _ ("VPN returned empty result for `%s'\n"),
454 request->packet->queries[0].name);
455 send_response (request);
456 GNUNET_free (vpn_ctx->rd_data);
457 GNUNET_free (vpn_ctx);
458}
459
460
324 461
325/** 462/**
326 * Iterator called on obtained result for a GNS lookup. 463 * Iterator called on obtained result for a GNS lookup.
@@ -339,6 +476,11 @@ result_processor (void *cls,
339 struct Request *request = cls; 476 struct Request *request = cls;
340 struct GNUNET_DNSPARSER_Packet *packet; 477 struct GNUNET_DNSPARSER_Packet *packet;
341 struct GNUNET_DNSPARSER_Record rec; 478 struct GNUNET_DNSPARSER_Record rec;
479 struct VpnContext *vpn_ctx;
480 const struct GNUNET_TUN_GnsVpnRecord *vpn;
481 const char *vname;
482 struct GNUNET_HashCode vhash;
483 int af;
342 484
343 request->lookup = NULL; 485 request->lookup = NULL;
344 if (GNUNET_NO == was_gns) 486 if (GNUNET_NO == was_gns)
@@ -415,6 +557,67 @@ result_processor (void *cls,
415 packet->num_answers, 557 packet->num_answers,
416 rec); 558 rec);
417 break; 559 break;
560 case GNUNET_GNSRECORD_TYPE_VPN:
561 if ((GNUNET_DNSPARSER_TYPE_A != request->packet->queries[0].type) &&
562 (GNUNET_DNSPARSER_TYPE_AAAA != request->packet->queries[0].type))
563 break;
564 af = (GNUNET_DNSPARSER_TYPE_A == request->packet->queries[0].type) ? AF_INET :
565 AF_INET6;
566 if (sizeof(struct GNUNET_TUN_GnsVpnRecord) >
567 rd[i].data_size)
568 {
569 GNUNET_break_op (0);
570 break;
571 }
572 vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data;
573 vname = (const char *) &vpn[1];
574 if ('\0' != vname[rd[i].data_size - 1 - sizeof(struct
575 GNUNET_TUN_GnsVpnRecord)
576 ])
577 {
578 GNUNET_break_op (0);
579 break;
580 }
581 GNUNET_TUN_service_name_to_hash (vname,
582 &vhash);
583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
584 "Attempting VPN allocation for %s-%s (AF: %d, proto %d)\n",
585 GNUNET_i2s (&vpn->peer),
586 vname,
587 (int) af,
588 (int) ntohs (vpn->proto));
589 vpn_ctx = GNUNET_new (struct VpnContext);
590 request->vpn_ctx = vpn_ctx;
591 vpn_ctx->request = request;
592 vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
593 rd);
594 if (vpn_ctx->rd_data_size < 0)
595 {
596 GNUNET_break_op (0);
597 GNUNET_free (vpn_ctx);
598 break;
599 }
600 vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size);
601 vpn_ctx->rd_count = rd_count;
602 GNUNET_assert (vpn_ctx->rd_data_size ==
603 GNUNET_GNSRECORD_records_serialize (rd_count,
604 rd,
605 (size_t) vpn_ctx
606 ->rd_data_size,
607 vpn_ctx->rd_data));
608 vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle,
609 af,
610 ntohs (
611 vpn->proto),
612 &vpn->peer,
613 &vhash,
614 GNUNET_TIME_relative_to_absolute (
615 VPN_TIMEOUT),
616 &
617 vpn_allocation_cb,
618 vpn_ctx);
619 return;
620
418 621
419 default: 622 default:
420 /* skip */ 623 /* skip */
@@ -641,6 +844,8 @@ run (void *cls,
641 NULL); 844 NULL);
642 if (NULL == (gns = GNUNET_GNS_connect (cfg))) 845 if (NULL == (gns = GNUNET_GNS_connect (cfg)))
643 return; 846 return;
847 if (NULL == (vpn_handle = GNUNET_VPN_connect (cfg)))
848 return;
644 GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128))); 849 GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128)));
645 if (GNUNET_OK != 850 if (GNUNET_OK !=
646 GNUNET_DNSSTUB_add_dns_ip (dns_stub, 851 GNUNET_DNSSTUB_add_dns_ip (dns_stub,
@@ -649,6 +854,8 @@ run (void *cls,
649 GNUNET_DNSSTUB_stop (dns_stub); 854 GNUNET_DNSSTUB_stop (dns_stub);
650 GNUNET_GNS_disconnect (gns); 855 GNUNET_GNS_disconnect (gns);
651 gns = NULL; 856 gns = NULL;
857 GNUNET_VPN_disconnect (vpn_handle);
858 vpn_handle = NULL;
652 return; 859 return;
653 } 860 }
654 861
@@ -750,6 +957,8 @@ run (void *cls,
750 { 957 {
751 GNUNET_GNS_disconnect (gns); 958 GNUNET_GNS_disconnect (gns);
752 gns = NULL; 959 gns = NULL;
960 GNUNET_VPN_disconnect (vpn_handle);
961 vpn_handle = NULL;
753 GNUNET_DNSSTUB_stop (dns_stub); 962 GNUNET_DNSSTUB_stop (dns_stub);
754 dns_stub = NULL; 963 dns_stub = NULL;
755 return; 964 return;
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c
index 5833f4d0b..b28236fed 100644
--- a/src/gns/gnunet-service-gns.c
+++ b/src/gns/gnunet-service-gns.c
@@ -420,15 +420,11 @@ handle_lookup (void *cls,
420 const struct LookupMessage *sh_msg) 420 const struct LookupMessage *sh_msg)
421{ 421{
422 struct GnsClient *gc = cls; 422 struct GnsClient *gc = cls;
423 char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 1];
424 struct ClientLookupHandle *clh; 423 struct ClientLookupHandle *clh;
425 char *nameptr = name; 424 const char *name;
426 const char *utf_in;
427 425
428 GNUNET_SERVICE_client_continue (gc->client); 426 GNUNET_SERVICE_client_continue (gc->client);
429 utf_in = (const char *) &sh_msg[1]; 427 name = (const char *) &sh_msg[1];
430 GNUNET_STRINGS_utf8_tolower (utf_in,
431 nameptr);
432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
433 "Received LOOKUP `%s' message\n", 429 "Received LOOKUP `%s' message\n",
434 name); 430 name);
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c
index 51e650b4f..72b228f33 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -52,7 +52,6 @@
52#include "gns.h" 52#include "gns.h"
53#include "gnunet-service-gns.h" 53#include "gnunet-service-gns.h"
54#include "gnunet-service-gns_resolver.h" 54#include "gnunet-service-gns_resolver.h"
55#include "gnunet_vpn_service.h"
56 55
57 56
58/** 57/**
@@ -68,11 +67,6 @@
68 GNUNET_TIME_UNIT_SECONDS, 15) 67 GNUNET_TIME_UNIT_SECONDS, 15)
69 68
70/** 69/**
71 * Default timeout for VPN redirections.
72 */
73#define VPN_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
74
75/**
76 * DHT replication level 70 * DHT replication level
77 */ 71 */
78#define DHT_GNS_REPLICATION_LEVEL 10 72#define DHT_GNS_REPLICATION_LEVEL 10
@@ -255,38 +249,6 @@ struct DnsResult
255 249
256 250
257/** 251/**
258 * Closure for #vpn_allocation_cb.
259 */
260struct VpnContext
261{
262 /**
263 * Which resolution process are we processing.
264 */
265 struct GNS_ResolverHandle *rh;
266
267 /**
268 * Handle to the VPN request that we were performing.
269 */
270 struct GNUNET_VPN_RedirectionRequest *vpn_request;
271
272 /**
273 * Number of records serialized in @e rd_data.
274 */
275 unsigned int rd_count;
276
277 /**
278 * Serialized records.
279 */
280 char *rd_data;
281
282 /**
283 * Number of bytes in @e rd_data.
284 */
285 ssize_t rd_data_size;
286};
287
288
289/**
290 * Handle to a currently pending resolution. On result (positive or 252 * Handle to a currently pending resolution. On result (positive or
291 * negative) the #GNS_ResultProcessor is called. 253 * negative) the #GNS_ResultProcessor is called.
292 */ 254 */
@@ -322,10 +284,6 @@ struct GNS_ResolverHandle
322 */ 284 */
323 struct GNUNET_DHT_GetHandle *get_handle; 285 struct GNUNET_DHT_GetHandle *get_handle;
324 286
325 /**
326 * Handle to a VPN request, NULL if none is active.
327 */
328 struct VpnContext *vpn_ctx;
329 287
330 /** 288 /**
331 * Socket for a DNS request, NULL if none is active. 289 * Socket for a DNS request, NULL if none is active.
@@ -463,11 +421,6 @@ struct CacheOps
463static struct GNUNET_NAMECACHE_Handle *namecache_handle; 421static struct GNUNET_NAMECACHE_Handle *namecache_handle;
464 422
465/** 423/**
466 * Our handle to the vpn service
467 */
468static struct GNUNET_VPN_Handle *vpn_handle;
469
470/**
471 * Resolver handle to the dht 424 * Resolver handle to the dht
472 */ 425 */
473static struct GNUNET_DHT_Handle *dht_handle; 426static struct GNUNET_DHT_Handle *dht_handle;
@@ -1235,16 +1188,16 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
1235 1188
1236 1189
1237/** 1190/**
1238 * We encountered a CNAME record during our resolution. 1191 * We encountered a REDIRECT record during our resolution.
1239 * Merge it into our chain. 1192 * Merge it into our chain.
1240 * 1193 *
1241 * @param rh resolution we are performing 1194 * @param rh resolution we are performing
1242 * @param cname value of the cname record we got for the current 1195 * @param rname value of the redirect record we got for the current
1243 * authority chain tail 1196 * authority chain tail
1244 */ 1197 */
1245static void 1198static void
1246handle_gns_cname_result (struct GNS_ResolverHandle *rh, 1199handle_gns_redirect_result (struct GNS_ResolverHandle *rh,
1247 const char *cname) 1200 const char *rname)
1248{ 1201{
1249 size_t nlen; 1202 size_t nlen;
1250 char *res; 1203 char *res;
@@ -1253,14 +1206,17 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
1253 int af; 1206 int af;
1254 struct GNUNET_IDENTITY_PublicKey zone; 1207 struct GNUNET_IDENTITY_PublicKey zone;
1255 1208
1256 nlen = strlen (cname); 1209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1257 tld = GNS_get_tld (cname); 1210 "Handling GNS REDIRECT result `%s'\n",
1211 rname);
1212 nlen = strlen (rname);
1213 tld = GNS_get_tld (rname);
1258 if (0 == strcmp ("+", tld)) 1214 if (0 == strcmp ("+", tld))
1259 { 1215 {
1260 /* CNAME resolution continues relative to current domain */ 1216 /* REDIRECT resolution continues relative to current domain */
1261 if (0 == rh->name_resolution_pos) 1217 if (0 == rh->name_resolution_pos)
1262 { 1218 {
1263 res = GNUNET_strndup (cname, nlen - 2); 1219 res = GNUNET_strndup (rname, nlen - 2);
1264 rh->name_resolution_pos = nlen - 2; 1220 rh->name_resolution_pos = nlen - 2;
1265 } 1221 }
1266 else 1222 else
@@ -1270,7 +1226,7 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
1270 (int) rh->name_resolution_pos, 1226 (int) rh->name_resolution_pos,
1271 rh->name, 1227 rh->name,
1272 (int) (nlen - 2), 1228 (int) (nlen - 2),
1273 cname); 1229 rname);
1274 rh->name_resolution_pos = strlen (res); 1230 rh->name_resolution_pos = strlen (res);
1275 } 1231 }
1276 GNUNET_free (rh->name); 1232 GNUNET_free (rh->name);
@@ -1291,13 +1247,13 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
1291 } 1247 }
1292 if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)) 1248 if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone))
1293 { 1249 {
1294 /* CNAME resolution continues relative to current domain */ 1250 /* REDIRECT resolution continues relative to current domain */
1295 if (0 == rh->name_resolution_pos) 1251 if (0 == rh->name_resolution_pos)
1296 { 1252 {
1297 GNUNET_asprintf (&res, 1253 GNUNET_asprintf (&res,
1298 "%.*s", 1254 "%.*s",
1299 (int) (strlen (cname) - (strlen (tld) + 1)), 1255 (int) (strlen (rname) - (strlen (tld) + 1)),
1300 cname); 1256 rname);
1301 } 1257 }
1302 else 1258 else
1303 { 1259 {
@@ -1305,8 +1261,8 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
1305 "%.*s.%.*s", 1261 "%.*s.%.*s",
1306 (int) rh->name_resolution_pos, 1262 (int) rh->name_resolution_pos,
1307 rh->name, 1263 rh->name,
1308 (int) (strlen (cname) - (strlen (tld) + 1)), 1264 (int) (strlen (rname) - (strlen (tld) + 1)),
1309 cname); 1265 rname);
1310 } 1266 }
1311 rh->name_resolution_pos = strlen (res); 1267 rh->name_resolution_pos = strlen (res);
1312 GNUNET_free (rh->name); 1268 GNUNET_free (rh->name);
@@ -1326,18 +1282,62 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
1326 } 1282 }
1327 1283
1328 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1284 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1329 "Got CNAME `%s' from GNS for `%s'\n", 1285 "Got REDIRECT `%s' from GNS for `%s'\n",
1330 cname, 1286 rname,
1331 rh->name); 1287 rh->name);
1332 if (NULL != rh->std_resolve) 1288 if (NULL != rh->std_resolve)
1333 { 1289 {
1334 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1290 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1335 "Multiple CNAME results from GNS resolving `%s'! Not really allowed...\n", 1291 "Multiple REDIRECT results from GNS resolving `%s'! Not really allowed...\n",
1336 rh->name); 1292 rh->name);
1337 GNUNET_RESOLVER_request_cancel (rh->std_resolve); 1293 GNUNET_RESOLVER_request_cancel (rh->std_resolve);
1338 } 1294 }
1339 /* name is absolute, go to DNS */ 1295 /* name is absolute, go to DNS */
1340 GNUNET_free (rh->name); 1296 GNUNET_free (rh->name);
1297 rh->name = GNUNET_strdup (rname);
1298 rh->name_resolution_pos = strlen (rh->name);
1299 switch (rh->record_type)
1300 {
1301 case GNUNET_DNSPARSER_TYPE_A:
1302 af = AF_INET;
1303 break;
1304
1305 case GNUNET_DNSPARSER_TYPE_AAAA:
1306 af = AF_INET6;
1307 break;
1308
1309 default:
1310 af = AF_UNSPEC;
1311 break;
1312 }
1313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1314 "Doing standard DNS lookup for `%s'\n",
1315 rh->name);
1316
1317 rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name,
1318 af,
1319 DNS_LOOKUP_TIMEOUT,
1320 &handle_dns_result,
1321 rh);
1322}
1323
1324
1325
1326/**
1327 * We encountered a CNAME record during our resolution.
1328 * Merge it into our chain.
1329 *
1330 * @param rh resolution we are performing
1331 * @param cname value of the cname record we got for the current
1332 * authority chain tail
1333 */
1334static void
1335handle_gns_cname_result (struct GNS_ResolverHandle *rh,
1336 const char *cname)
1337{
1338 int af;
1339
1340 GNUNET_free (rh->name);
1341 rh->name = GNUNET_strdup (cname); 1341 rh->name = GNUNET_strdup (cname);
1342 rh->name_resolution_pos = strlen (rh->name); 1342 rh->name_resolution_pos = strlen (rh->name);
1343 switch (rh->record_type) 1343 switch (rh->record_type)
@@ -1379,80 +1379,6 @@ handle_gns_resolution_result (void *cls,
1379 const struct GNUNET_GNSRECORD_Data *rd); 1379 const struct GNUNET_GNSRECORD_Data *rd);
1380 1380
1381 1381
1382/**
1383 * Callback invoked from the VPN service once a redirection is
1384 * available. Provides the IP address that can now be used to
1385 * reach the requested destination. Replaces the "VPN" record
1386 * with the respective A/AAAA record and continues processing.
1387 *
1388 * @param cls closure
1389 * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error;
1390 * will match 'result_af' from the request
1391 * @param address IP address (struct in_addr or struct in_addr6, depending on 'af')
1392 * that the VPN allocated for the redirection;
1393 * traffic to this IP will now be redirected to the
1394 * specified target peer; NULL on error
1395 */
1396static void
1397vpn_allocation_cb (void *cls,
1398 int af,
1399 const void *address)
1400{
1401 struct VpnContext *vpn_ctx = cls;
1402 struct GNS_ResolverHandle *rh = vpn_ctx->rh;
1403 struct GNUNET_GNSRECORD_Data rd[vpn_ctx->rd_count];
1404 unsigned int i;
1405
1406 vpn_ctx->vpn_request = NULL;
1407 rh->vpn_ctx = NULL;
1408 GNUNET_assert (GNUNET_OK ==
1409 GNUNET_GNSRECORD_records_deserialize (
1410 (size_t) vpn_ctx->rd_data_size,
1411 vpn_ctx->rd_data,
1412 vpn_ctx->rd_count,
1413 rd));
1414 for (i = 0; i < vpn_ctx->rd_count; i++)
1415 {
1416 if (GNUNET_GNSRECORD_TYPE_VPN == rd[i].record_type)
1417 {
1418 switch (af)
1419 {
1420 case AF_INET:
1421 rd[i].record_type = GNUNET_DNSPARSER_TYPE_A;
1422 rd[i].data_size = sizeof(struct in_addr);
1423 rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
1424 VPN_TIMEOUT).abs_value_us;
1425 rd[i].flags = 0;
1426 rd[i].data = address;
1427 break;
1428
1429 case AF_INET6:
1430 rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
1431 rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
1432 VPN_TIMEOUT).abs_value_us;
1433 rd[i].flags = 0;
1434 rd[i].data = address;
1435 rd[i].data_size = sizeof(struct in6_addr);
1436 break;
1437
1438 default:
1439 GNUNET_assert (0);
1440 }
1441 break;
1442 }
1443 }
1444 GNUNET_assert (i < vpn_ctx->rd_count);
1445 if (0 == vpn_ctx->rd_count)
1446 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1447 _ ("VPN returned empty result for `%s'\n"),
1448 rh->name);
1449 handle_gns_resolution_result (rh,
1450 vpn_ctx->rd_count,
1451 rd);
1452 GNUNET_free (vpn_ctx->rd_data);
1453 GNUNET_free (vpn_ctx);
1454}
1455
1456 1382
1457/** 1383/**
1458 * We have resolved one or more of the nameservers for a 1384 * We have resolved one or more of the nameservers for a
@@ -1653,6 +1579,20 @@ handle_gns2dns_ip (void *cls,
1653 ac->authority_info.dns_authority.found = GNUNET_YES; 1579 ac->authority_info.dns_authority.found = GNUNET_YES;
1654} 1580}
1655 1581
1582/**
1583 * We found a REDIRECT record, perform recursive resolution on it.
1584 *
1585 * @param rh resolution handle
1586 * @param rd record with CNAME to resolve recursively
1587 */
1588static void
1589recursive_redirect_resolution (struct GNS_ResolverHandle *rh,
1590 const struct GNUNET_GNSRECORD_Data *rd)
1591{
1592 handle_gns_redirect_result (rh,
1593 rd->data);
1594}
1595
1656 1596
1657/** 1597/**
1658 * We found a CNAME record, perform recursive resolution on it. 1598 * We found a CNAME record, perform recursive resolution on it.
@@ -1956,11 +1896,6 @@ handle_gns_resolution_result (void *cls,
1956{ 1896{
1957 struct GNS_ResolverHandle *rh = cls; 1897 struct GNS_ResolverHandle *rh = cls;
1958 char *cname; 1898 char *cname;
1959 struct VpnContext *vpn_ctx;
1960 const struct GNUNET_TUN_GnsVpnRecord *vpn;
1961 const char *vname;
1962 struct GNUNET_HashCode vhash;
1963 int af;
1964 char scratch[UINT16_MAX]; 1899 char scratch[UINT16_MAX];
1965 size_t scratch_off; 1900 size_t scratch_off;
1966 size_t scratch_start; 1901 size_t scratch_start;
@@ -2006,8 +1941,18 @@ handle_gns_resolution_result (void *cls,
2006 GNUNET_free (cname); 1941 GNUNET_free (cname);
2007 return; 1942 return;
2008 } 1943 }
2009 /* If A/AAAA was requested, but we got a VPN 1944 if ((rd_count > 0) &&
2010 record, we convert it to A/AAAA using GNUnet VPN */ 1945 (GNUNET_GNSRECORD_TYPE_REDIRECT == rd[0].record_type) &&
1946 (GNUNET_GNSRECORD_TYPE_REDIRECT != rh->record_type))
1947 {
1948 handle_gns_redirect_result (rh,
1949 rd[0].data);
1950 return;
1951 }
1952
1953
1954 /* If A/AAAA was requested,
1955 * but we got a GNS2DNS record */
2011 if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) || 1956 if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) ||
2012 (GNUNET_DNSPARSER_TYPE_AAAA == rh->record_type)) 1957 (GNUNET_DNSPARSER_TYPE_AAAA == rh->record_type))
2013 { 1958 {
@@ -2015,69 +1960,6 @@ handle_gns_resolution_result (void *cls,
2015 { 1960 {
2016 switch (rd[i].record_type) 1961 switch (rd[i].record_type)
2017 { 1962 {
2018 case GNUNET_GNSRECORD_TYPE_VPN:
2019 {
2020 af = (GNUNET_DNSPARSER_TYPE_A == rh->record_type) ? AF_INET :
2021 AF_INET6;
2022 if (sizeof(struct GNUNET_TUN_GnsVpnRecord) >
2023 rd[i].data_size)
2024 {
2025 GNUNET_break_op (0);
2026 fail_resolution (rh);
2027 return;
2028 }
2029 vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data;
2030 vname = (const char *) &vpn[1];
2031 if ('\0' != vname[rd[i].data_size - 1 - sizeof(struct
2032 GNUNET_TUN_GnsVpnRecord)
2033 ])
2034 {
2035 GNUNET_break_op (0);
2036 fail_resolution (rh);
2037 return;
2038 }
2039 GNUNET_TUN_service_name_to_hash (vname,
2040 &vhash);
2041 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2042 "Attempting VPN allocation for %s-%s (AF: %d, proto %d)\n",
2043 GNUNET_i2s (&vpn->peer),
2044 vname,
2045 (int) af,
2046 (int) ntohs (vpn->proto));
2047 vpn_ctx = GNUNET_new (struct VpnContext);
2048 rh->vpn_ctx = vpn_ctx;
2049 vpn_ctx->rh = rh;
2050 vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
2051 rd);
2052 if (vpn_ctx->rd_data_size < 0)
2053 {
2054 GNUNET_break_op (0);
2055 GNUNET_free (vpn_ctx);
2056 fail_resolution (rh);
2057 return;
2058 }
2059 vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size);
2060 vpn_ctx->rd_count = rd_count;
2061 GNUNET_assert (vpn_ctx->rd_data_size ==
2062 GNUNET_GNSRECORD_records_serialize (rd_count,
2063 rd,
2064 (size_t) vpn_ctx
2065 ->rd_data_size,
2066 vpn_ctx->rd_data));
2067 vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle,
2068 af,
2069 ntohs (
2070 vpn->proto),
2071 &vpn->peer,
2072 &vhash,
2073 GNUNET_TIME_relative_to_absolute (
2074 VPN_TIMEOUT),
2075 &
2076 vpn_allocation_cb,
2077 vpn_ctx);
2078 return;
2079 }
2080
2081 case GNUNET_GNSRECORD_TYPE_GNS2DNS: 1963 case GNUNET_GNSRECORD_TYPE_GNS2DNS:
2082 { 1964 {
2083 /* delegation to DNS */ 1965 /* delegation to DNS */
@@ -2117,6 +1999,23 @@ handle_gns_resolution_result (void *cls,
2117 so we can free it afterwards. */ 1999 so we can free it afterwards. */
2118 switch (rd[i].record_type) 2000 switch (rd[i].record_type)
2119 { 2001 {
2002 case GNUNET_GNSRECORD_TYPE_REDIRECT:
2003 {
2004 char *rname;
2005 rname = GNUNET_strndup (rd[i].data, rd[i].data_size);
2006 rname = translate_dot_plus (rh, rname);
2007 GNUNET_break (NULL != rname);
2008 scratch_start = scratch_off;
2009 memcpy (&scratch[scratch_start], rname, strlen (rname) + 1);
2010 scratch_off += strlen (rname) + 1;
2011 GNUNET_assert (rd_off < rd_count);
2012 rd_new[rd_off].data = &scratch[scratch_start];
2013 rd_new[rd_off].data_size = scratch_off - scratch_start;
2014 rd_off++;
2015 GNUNET_free (rname);
2016 }
2017 break;
2018
2120 case GNUNET_DNSPARSER_TYPE_CNAME: 2019 case GNUNET_DNSPARSER_TYPE_CNAME:
2121 { 2020 {
2122 char *cname; 2021 char *cname;
@@ -2380,6 +2279,12 @@ handle_gns_resolution_result (void *cls,
2380 2279
2381 switch (rd[0].record_type) 2280 switch (rd[0].record_type)
2382 { 2281 {
2282 case GNUNET_GNSRECORD_TYPE_REDIRECT:
2283 GNUNET_break_op (1 == rd_count); /* REDIRECT should be unique */
2284 recursive_redirect_resolution (rh,
2285 &rd[0]);
2286 return;
2287
2383 case GNUNET_DNSPARSER_TYPE_CNAME: 2288 case GNUNET_DNSPARSER_TYPE_CNAME:
2384 GNUNET_break_op (1 == rd_count); /* CNAME should be unique */ 2289 GNUNET_break_op (1 == rd_count); /* CNAME should be unique */
2385 recursive_cname_resolution (rh, 2290 recursive_cname_resolution (rh,
@@ -2393,15 +2298,21 @@ handle_gns_resolution_result (void *cls,
2393 &rd[0]); 2298 &rd[0]);
2394 return; 2299 return;
2395 2300
2396 default: 2301 case GNUNET_GNSRECORD_TYPE_GNS2DNS:
2397 if (GNUNET_OK == 2302 if (GNUNET_OK ==
2398 recursive_gns2dns_resolution (rh, 2303 recursive_gns2dns_resolution (rh,
2399 rd_count, 2304 rd_count,
2400 rd)) 2305 rd))
2401 return; 2306 return;
2402 break; 2307 break;
2308 default:
2309 if (GNUNET_YES != GNUNET_GNSRECORD_is_critical (rd[0].record_type))
2310 return;
2311 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2312 _ ("Unable to process critical delegation record\n"));
2313 break;
2403 } 2314 }
2404fail: 2315 fail:
2405 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2316 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2406 _ ("GNS lookup recursion failed (no delegation record found)\n")); 2317 _ ("GNS lookup recursion failed (no delegation record found)\n"));
2407 fail_resolution (rh); 2318 fail_resolution (rh);
@@ -2618,6 +2529,13 @@ handle_namecache_block_response (void *cls,
2618 2529
2619 GNUNET_assert (NULL != rh->namecache_qe); 2530 GNUNET_assert (NULL != rh->namecache_qe);
2620 rh->namecache_qe = NULL; 2531 rh->namecache_qe = NULL;
2532 if (NULL == block)
2533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2534 "No block found\n");
2535 else
2536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2537 "Got block with expiration %s\n",
2538 GNUNET_STRINGS_absolute_time_to_string (GNUNET_GNSRECORD_block_get_expiration (block)));
2621 if (((GNUNET_GNS_LO_DEFAULT == rh->options) || 2539 if (((GNUNET_GNS_LO_DEFAULT == rh->options) ||
2622 ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) && 2540 ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) &&
2623 (ac != rh->ac_head))) && 2541 (ac != rh->ac_head))) &&
@@ -2916,7 +2834,6 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
2916{ 2834{
2917 struct DnsResult *dr; 2835 struct DnsResult *dr;
2918 struct AuthorityChain *ac; 2836 struct AuthorityChain *ac;
2919 struct VpnContext *vpn_ctx;
2920 2837
2921 GNUNET_CONTAINER_DLL_remove (rlh_head, 2838 GNUNET_CONTAINER_DLL_remove (rlh_head,
2922 rlh_tail, 2839 rlh_tail,
@@ -2981,12 +2898,6 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
2981 GNUNET_CONTAINER_heap_remove_node (rh->dht_heap_node); 2898 GNUNET_CONTAINER_heap_remove_node (rh->dht_heap_node);
2982 rh->dht_heap_node = NULL; 2899 rh->dht_heap_node = NULL;
2983 } 2900 }
2984 if (NULL != (vpn_ctx = rh->vpn_ctx))
2985 {
2986 GNUNET_VPN_cancel_request (vpn_ctx->vpn_request);
2987 GNUNET_free (vpn_ctx->rd_data);
2988 GNUNET_free (vpn_ctx);
2989 }
2990 if (NULL != rh->namecache_qe) 2901 if (NULL != rh->namecache_qe)
2991 { 2902 {
2992 GNUNET_NAMECACHE_cancel (rh->namecache_qe); 2903 GNUNET_NAMECACHE_cancel (rh->namecache_qe);
@@ -3046,7 +2957,6 @@ GNS_resolver_init (struct GNUNET_NAMECACHE_Handle *nc,
3046 if (GNUNET_YES == disable_cache) 2957 if (GNUNET_YES == disable_cache)
3047 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2958 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3048 "Namecache disabled\n"); 2959 "Namecache disabled\n");
3049 vpn_handle = GNUNET_VPN_connect (cfg);
3050} 2960}
3051 2961
3052 2962
@@ -3077,8 +2987,6 @@ GNS_resolver_done ()
3077 } 2987 }
3078 GNUNET_CONTAINER_heap_destroy (dht_lookup_heap); 2988 GNUNET_CONTAINER_heap_destroy (dht_lookup_heap);
3079 dht_lookup_heap = NULL; 2989 dht_lookup_heap = NULL;
3080 GNUNET_VPN_disconnect (vpn_handle);
3081 vpn_handle = NULL;
3082 dht_handle = NULL; 2990 dht_handle = NULL;
3083 namecache_handle = NULL; 2991 namecache_handle = NULL;
3084} 2992}
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c
index 407754a8c..fd9c99cb4 100644
--- a/src/gns/plugin_block_gns.c
+++ b/src/gns/plugin_block_gns.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2010-2013 GNUnet e.V. 3 Copyright (C) 2010-2013, 2021, 2022 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
@@ -92,98 +92,16 @@ block_plugin_gns_create_group (void *cls,
92 92
93 93
94/** 94/**
95 * Function called to validate a reply or a request. For
96 * request evaluation, simply pass "NULL" for the reply_block.
97 * Note that it is assumed that the reply has already been
98 * matched to the key (and signatures checked) as it would
99 * be done with the "get_key" function.
100 *
101 * @param cls closure
102 * @param ctx block context
103 * @param type block type
104 * @param bg block group to use for evaluation
105 * @param eo control flags
106 * @param query original query (hash)
107 * @param xquery extrended query data (can be NULL, depending on @a type)
108 * @param xquery_size number of bytes in @a xquery
109 * @param reply_block response to validate
110 * @param reply_block_size number of bytes in @a reply_block
111 * @return characterization of result
112 */
113static enum GNUNET_BLOCK_EvaluationResult
114block_plugin_gns_evaluate (void *cls,
115 struct GNUNET_BLOCK_Context *ctx,
116 enum GNUNET_BLOCK_Type type,
117 struct GNUNET_BLOCK_Group *bg,
118 enum GNUNET_BLOCK_EvaluationOptions eo,
119 const struct GNUNET_HashCode *query,
120 const void *xquery,
121 size_t xquery_size,
122 const void *reply_block,
123 size_t reply_block_size)
124{
125 const struct GNUNET_GNSRECORD_Block *block;
126 struct GNUNET_HashCode h;
127 struct GNUNET_HashCode chash;
128
129 if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD)
130 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
131 if (NULL == reply_block)
132 {
133 if (0 != xquery_size)
134 {
135 GNUNET_break_op (0);
136 return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
137 }
138 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
139 }
140
141 /* this is a reply */
142 if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block))
143 {
144 GNUNET_break_op (0);
145 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
146 }
147 block = reply_block;
148 if (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size)
149 {
150 GNUNET_break_op (0);
151 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
152 }
153 GNUNET_GNSRECORD_query_from_block (block,
154 &h);
155 if (0 != GNUNET_memcmp (&h, query))
156 {
157 GNUNET_break_op (0);
158 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
159 }
160 if (GNUNET_OK !=
161 GNUNET_GNSRECORD_block_verify (block))
162 {
163 GNUNET_break_op (0);
164 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
165 }
166 GNUNET_CRYPTO_hash (reply_block,
167 reply_block_size,
168 &chash);
169 if (GNUNET_YES ==
170 GNUNET_BLOCK_GROUP_bf_test_and_set (bg,
171 &chash))
172 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
173 return GNUNET_BLOCK_EVALUATION_OK_MORE;
174}
175
176
177/**
178 * Function called to obtain the key for a block. 95 * Function called to obtain the key for a block.
96 * If the @a block is malformed, the function should
97 * zero-out @a key and return #GNUNET_OK.
179 * 98 *
180 * @param cls closure 99 * @param cls closure
181 * @param type block type 100 * @param type block type
182 * @param reply_block block to get the key for 101 * @param reply_block block to get the key for
183 * @param reply_block_size number of bytes in @a reply_block 102 * @param reply_block_size number of bytes in @a reply_block
184 * @param key set to the key (query) for the given block 103 * @param key set to the key (query) for the given block
185 * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported 104 * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported, #GNUNET_NO if extracting a key from a block of this type does not work
186 * (or if extracting a key from a block of this type does not work)
187 */ 105 */
188static enum GNUNET_GenericReturnValue 106static enum GNUNET_GenericReturnValue
189block_plugin_gns_get_key (void *cls, 107block_plugin_gns_get_key (void *cls,
@@ -194,12 +112,18 @@ block_plugin_gns_get_key (void *cls,
194{ 112{
195 const struct GNUNET_GNSRECORD_Block *block; 113 const struct GNUNET_GNSRECORD_Block *block;
196 114
197 if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) 115 if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type)
116 {
117 GNUNET_break (0);
198 return GNUNET_SYSERR; 118 return GNUNET_SYSERR;
119 }
199 if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block)) 120 if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block))
200 { 121 {
201 GNUNET_break_op (0); 122 GNUNET_break_op (0);
202 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 123 memset (key,
124 0,
125 sizeof (*key));
126 return GNUNET_OK;
203 } 127 }
204 block = reply_block; 128 block = reply_block;
205 GNUNET_GNSRECORD_query_from_block (block, 129 GNUNET_GNSRECORD_query_from_block (block,
@@ -227,8 +151,11 @@ block_plugin_gns_check_query (void *cls,
227 const void *xquery, 151 const void *xquery,
228 size_t xquery_size) 152 size_t xquery_size)
229{ 153{
230 if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) 154 if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type)
155 {
156 GNUNET_break (0);
231 return GNUNET_SYSERR; 157 return GNUNET_SYSERR;
158 }
232 if (0 != xquery_size) 159 if (0 != xquery_size)
233 { 160 {
234 GNUNET_break_op (0); 161 GNUNET_break_op (0);
@@ -243,7 +170,6 @@ block_plugin_gns_check_query (void *cls,
243 * 170 *
244 * @param cls closure 171 * @param cls closure
245 * @param type block type 172 * @param type block type
246 * @param query key for the block (hash), must match exactly
247 * @param block block data to validate 173 * @param block block data to validate
248 * @param block_size number of bytes in @a block 174 * @param block_size number of bytes in @a block
249 * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not 175 * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not
@@ -251,14 +177,16 @@ block_plugin_gns_check_query (void *cls,
251static enum GNUNET_GenericReturnValue 177static enum GNUNET_GenericReturnValue
252block_plugin_gns_check_block (void *cls, 178block_plugin_gns_check_block (void *cls,
253 enum GNUNET_BLOCK_Type type, 179 enum GNUNET_BLOCK_Type type,
254 const struct GNUNET_HashCode *query,
255 const void *block, 180 const void *block,
256 size_t block_size) 181 size_t block_size)
257{ 182{
258 const struct GNUNET_GNSRECORD_Block *gblock; 183 const struct GNUNET_GNSRECORD_Block *gblock;
259 184
260 if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) 185 if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type)
186 {
187 GNUNET_break (0);
261 return GNUNET_SYSERR; 188 return GNUNET_SYSERR;
189 }
262 if (block_size < sizeof(struct GNUNET_GNSRECORD_Block)) 190 if (block_size < sizeof(struct GNUNET_GNSRECORD_Block))
263 { 191 {
264 GNUNET_break_op (0); 192 GNUNET_break_op (0);
@@ -306,23 +234,16 @@ block_plugin_gns_check_reply (void *cls,
306 const void *reply_block, 234 const void *reply_block,
307 size_t reply_block_size) 235 size_t reply_block_size)
308{ 236{
309 const struct GNUNET_GNSRECORD_Block *block; 237 const struct GNUNET_GNSRECORD_Block *block = reply_block;
310 struct GNUNET_HashCode chash; 238 struct GNUNET_HashCode chash;
311 239
312 if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) 240 if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type)
313 return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED;
314 /* this is a reply */
315 if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block))
316 { 241 {
317 GNUNET_break_op (0); 242 GNUNET_break (0);
318 return GNUNET_BLOCK_REPLY_INVALID; 243 return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED;
319 }
320 block = reply_block;
321 if (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size)
322 {
323 GNUNET_break_op (0);
324 return GNUNET_BLOCK_REPLY_INVALID;
325 } 244 }
245 GNUNET_assert (reply_block_size >= sizeof(struct GNUNET_GNSRECORD_Block));
246 GNUNET_assert (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size);
326 GNUNET_CRYPTO_hash (reply_block, 247 GNUNET_CRYPTO_hash (reply_block,
327 reply_block_size, 248 reply_block_size,
328 &chash); 249 &chash);
@@ -347,7 +268,6 @@ libgnunet_plugin_block_gns_init (void *cls)
347 struct GNUNET_BLOCK_PluginFunctions *api; 268 struct GNUNET_BLOCK_PluginFunctions *api;
348 269
349 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); 270 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
350 api->evaluate = &block_plugin_gns_evaluate;
351 api->get_key = &block_plugin_gns_get_key; 271 api->get_key = &block_plugin_gns_get_key;
352 api->create_group = &block_plugin_gns_create_group; 272 api->create_group = &block_plugin_gns_create_group;
353 api->check_query = &block_plugin_gns_check_query; 273 api->check_query = &block_plugin_gns_check_query;
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c
index 391144925..dc7ffa9b2 100644
--- a/src/gns/plugin_gnsrecord_gns.c
+++ b/src/gns/plugin_gnsrecord_gns.c
@@ -64,8 +64,7 @@ gns_value_to_string (void *cls,
64 return GNUNET_IDENTITY_public_key_to_string (&pk); 64 return GNUNET_IDENTITY_public_key_to_string (&pk);
65 65
66 case GNUNET_GNSRECORD_TYPE_NICK: 66 case GNUNET_GNSRECORD_TYPE_NICK:
67 return GNUNET_strndup (data, data_size); 67 case GNUNET_GNSRECORD_TYPE_REDIRECT:
68
69 case GNUNET_GNSRECORD_TYPE_LEHO: 68 case GNUNET_GNSRECORD_TYPE_LEHO:
70 return GNUNET_strndup (data, data_size); 69 return GNUNET_strndup (data, data_size);
71 70
@@ -133,7 +132,9 @@ gns_value_to_string (void *cls,
133 GNUNET_free (ival); 132 GNUNET_free (ival);
134 return box_str; 133 return box_str;
135 } 134 }
136 135 case GNUNET_GNSRECORD_TYPE_TOMBSTONE: {
136 return GNUNET_strdup (_("This is a memento of an older block for internal maintenance."));
137 }
137 default: 138 default:
138 return NULL; 139 return NULL;
139 } 140 }
@@ -184,16 +185,13 @@ gns_string_to_value (void *cls,
184 if (record_type != type) 185 if (record_type != type)
185 { 186 {
186 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 187 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
187 _("Record type does not match parsed record type\n")); 188 _ ("Record type does not match parsed record type\n"));
188 return GNUNET_SYSERR; 189 return GNUNET_SYSERR;
189 } 190 }
190 return GNUNET_OK; 191 return GNUNET_OK;
191 192
192 case GNUNET_GNSRECORD_TYPE_NICK: 193 case GNUNET_GNSRECORD_TYPE_NICK:
193 *data = GNUNET_strdup (s); 194 case GNUNET_GNSRECORD_TYPE_REDIRECT:
194 *data_size = strlen (s);
195 return GNUNET_OK;
196
197 case GNUNET_GNSRECORD_TYPE_LEHO: 195 case GNUNET_GNSRECORD_TYPE_LEHO:
198 *data = GNUNET_strdup (s); 196 *data = GNUNET_strdup (s);
199 *data_size = strlen (s); 197 *data_size = strlen (s);
@@ -301,6 +299,12 @@ gns_string_to_value (void *cls,
301 GNUNET_free (bval); 299 GNUNET_free (bval);
302 return GNUNET_OK; 300 return GNUNET_OK;
303 } 301 }
302 case GNUNET_GNSRECORD_TYPE_TOMBSTONE: {
303 *data_size = 0;
304 *data = NULL;
305 return GNUNET_OK;
306 }
307
304 308
305 default: 309 default:
306 return GNUNET_SYSERR; 310 return GNUNET_SYSERR;
@@ -317,12 +321,16 @@ static struct
317 const char *name; 321 const char *name;
318 uint32_t number; 322 uint32_t number;
319} gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY }, 323} gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY },
320 { "EDKEY", GNUNET_GNSRECORD_TYPE_PKEY }, 324 { "EDKEY", GNUNET_GNSRECORD_TYPE_EDKEY },
321 { "NICK", GNUNET_GNSRECORD_TYPE_NICK }, 325 { "NICK", GNUNET_GNSRECORD_TYPE_NICK },
322 { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO }, 326 { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
323 { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, 327 { "VPN", GNUNET_GNSRECORD_TYPE_VPN },
324 { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, 328 { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
325 { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, 329 { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
330 { "REDIRECT", GNUNET_GNSRECORD_TYPE_REDIRECT },
331 /* Tombstones should never be added manually
332 * so this makes sense, kind of */
333 { "\u271E", GNUNET_GNSRECORD_TYPE_TOMBSTONE },
326 { NULL, UINT32_MAX } }; 334 { NULL, UINT32_MAX } };
327 335
328 336
@@ -365,6 +373,19 @@ gns_number_to_typename (void *cls, uint32_t type)
365} 373}
366 374
367 375
376static enum GNUNET_GenericReturnValue
377gns_is_critical (void *cls, uint32_t type)
378{
379 return ((type == GNUNET_GNSRECORD_TYPE_PKEY) ||
380 (type == GNUNET_GNSRECORD_TYPE_EDKEY) ||
381 (type == GNUNET_GNSRECORD_TYPE_GNS2DNS) ||
382 (type == GNUNET_GNSRECORD_TYPE_REDIRECT) ?
383 GNUNET_YES : GNUNET_NO);
384}
385
386
387
388
368/** 389/**
369 * Entry point for the plugin. 390 * Entry point for the plugin.
370 * 391 *
@@ -381,6 +402,7 @@ libgnunet_plugin_gnsrecord_gns_init (void *cls)
381 api->string_to_value = &gns_string_to_value; 402 api->string_to_value = &gns_string_to_value;
382 api->typename_to_number = &gns_typename_to_number; 403 api->typename_to_number = &gns_typename_to_number;
383 api->number_to_typename = &gns_number_to_typename; 404 api->number_to_typename = &gns_number_to_typename;
405 api->is_critical = &gns_is_critical;
384 return api; 406 return api;
385} 407}
386 408
diff --git a/src/gns/test_gns_cname_lookup.sh b/src/gns/test_gns_cname_lookup.sh
deleted file mode 100755
index 3a189e1e2..000000000
--- a/src/gns/test_gns_cname_lookup.sh
+++ /dev/null
@@ -1,99 +0,0 @@
1#!/bin/sh
2# This file is in the public domain.
3trap "gnunet-arm -e -c test_gns_lookup.conf" INT
4
5LOCATION=$(which gnunet-config)
6if [ -z $LOCATION ]
7then
8 LOCATION="gnunet-config"
9fi
10$LOCATION --version 1> /dev/null
11if test $? != 0
12then
13 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
14 exit 77
15fi
16
17# permissive DNS resolver we will use for the test
18DNS_RESOLVER="8.8.8.8"
19if ! nslookup gnunet.org $DNS_RESOLVER > /dev/null 2>&1
20then
21 echo "Cannot reach DNS, skipping test"
22 exit 77
23fi
24
25
26rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
27
28TEST_IP_PLUS="127.0.0.1"
29TEST_IP_DNS="131.159.74.67"
30TEST_RECORD_CNAME_SERVER="server"
31TEST_RECORD_CNAME_PLUS="server.+"
32TEST_RECORD_CNAME_DNS="gnunet.org"
33TEST_RECORD_NAME_SERVER="server"
34TEST_RECORD_NAME_PLUS="www"
35TEST_RECORD_NAME_ZKEY="www2"
36TEST_RECORD_NAME_DNS="www3"
37MY_EGO="myego"
38TEST_DOMAIN_PLUS="www.$MY_EGO"
39TEST_DOMAIN_ZKEY="www2.$MY_EGO"
40TEST_DOMAIN_DNS="www3.$MY_EGO"
41which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
42
43gnunet-arm -s -c test_gns_lookup.conf
44gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
45MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}')
46TEST_RECORD_CNAME_ZKEY="server.${MY_EGO_PKEY}"
47gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_DNS -t CNAME -V $TEST_RECORD_CNAME_DNS -e never -c test_gns_lookup.conf
48gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_PLUS -t CNAME -V $TEST_RECORD_CNAME_PLUS -e never -c test_gns_lookup.conf
49gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_ZKEY -t CNAME -V $TEST_RECORD_CNAME_ZKEY -e never -c test_gns_lookup.conf
50gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
51RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf`
52RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf`
53RES_CNAME_ZKEY=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ZKEY -t A -c test_gns_lookup.conf`
54RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS`
55
56TESTEGOZONE=`gnunet-identity -c test_gns_lookup.conf -d | awk '{print $3}'`
57gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_DNS -t CNAME -V $TEST_RECORD_CNAME_DNS -e never -c test_gns_lookup.conf
58gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_PLUS -t CNAME -V $TEST_RECORD_CNAME_PLUS -e never -c test_gns_lookup.conf
59gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_ZKEY -t CNAME -V $TEST_RECORD_CNAME_ZKEY -e never -c test_gns_lookup.conf
60gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
61gnunet-identity -D $MY_EGO -c test_gns_lookup.conf
62gnunet-arm -e -c test_gns_lookup.conf
63rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
64
65# make cmp case-insensitive by converting to lower case first
66RES_CNAME_RAW=`echo $RES_CNAME_RAW | tr [A-Z] [a-z]`
67TESTEGOZONE=`echo $TESTEGOZONE | tr [A-Z] [a-z]`
68if [ "$RES_CNAME_RAW" = "server.$TESTEGOZONE" ]
69then
70 echo "PASS: CNAME resolution from GNS"
71else
72 echo "FAIL: CNAME resolution from GNS, got $RES_CNAME_RAW, expected server.$TESTEGOZONE."
73 exit 1
74fi
75
76if [ "$RES_CNAME" = "$TEST_IP_PLUS" ]
77then
78 echo "PASS: IP resolution from GNS (.+)"
79else
80 echo "FAIL: IP resolution from GNS (.+), got $RES_CNAME, expected $TEST_IP_PLUS."
81 exit 1
82fi
83
84if [ "$RES_CNAME_ZKEY" = "$TEST_IP_PLUS" ]
85then
86 echo "PASS: IP resolution from GNS (.zkey)"
87else
88 echo "FAIL: IP resolution from GNS (.zkey), got $RES_CNAME, expected $TEST_IP_PLUS."
89 exit 1
90fi
91
92if echo "$RES_CNAME_DNS" | grep "$TEST_IP_DNS" > /dev/null
93then
94 echo "PASS: IP resolution from DNS"
95 exit 0
96else
97 echo "FAIL: IP resolution from DNS, got $RES_CNAME_DNS, expected $TEST_IP_DNS."
98 exit 1
99fi
diff --git a/src/gns/test_gns_gns2dns_cname_lookup.sh b/src/gns/test_gns_gns2dns_cname_lookup.sh
index ce1afacf4..9315f6b2f 100755
--- a/src/gns/test_gns_gns2dns_cname_lookup.sh
+++ b/src/gns/test_gns_gns2dns_cname_lookup.sh
@@ -16,9 +16,11 @@ fi
16 16
17rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` 17rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
18# IP address of 'www.gnunet.org' 18# IP address of 'www.gnunet.org'
19TEST_IP="131.159.74.67" 19TEST_IP="147.87.255.218"
20# IP address of 'gnunet.org'
21TEST_IPALT="131.159.74.67"
20# IPv6 address of 'gnunet.org' 22# IPv6 address of 'gnunet.org'
21TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60" 23TEST_IP6="2a07:6b47:100:464::9357:ffdb"
22 24
23# main label used during resolution 25# main label used during resolution
24TEST_RECORD_NAME="homepage" 26TEST_RECORD_NAME="homepage"
@@ -46,7 +48,7 @@ TEST_DOMAIN="www.${TEST_RECORD_NAME}.$MY_EGO"
46which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" 48which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
47 49
48gnunet-arm -s -c test_gns_lookup.conf 50gnunet-arm -s -c test_gns_lookup.conf
49OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org` 51OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf www.gnunet.org`
50echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } 52echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; }
51echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } 53echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; }
52 54
@@ -59,6 +61,7 @@ gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECOR
59gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS2 -e never -c test_gns_lookup.conf 61gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS2 -e never -c test_gns_lookup.conf
60gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS3 -e never -c test_gns_lookup.conf 62gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS3 -e never -c test_gns_lookup.conf
61 63
64gnunet-namestore -z $MY_EGO -D -c test_gns_lookup.conf
62 65
63echo "EGOs:" 66echo "EGOs:"
64gnunet-identity -d 67gnunet-identity -d
diff --git a/src/gns/test_gns_gns2dns_lookup.sh b/src/gns/test_gns_gns2dns_lookup.sh
index dcad594b3..240e441a4 100755
--- a/src/gns/test_gns_gns2dns_lookup.sh
+++ b/src/gns/test_gns_gns2dns_lookup.sh
@@ -17,9 +17,11 @@ rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
17# IP address of 'docs.gnunet.org' 17# IP address of 'docs.gnunet.org'
18TEST_IP_ALT2="147.87.255.218" 18TEST_IP_ALT2="147.87.255.218"
19# IP address of 'www.gnunet.org' 19# IP address of 'www.gnunet.org'
20TEST_IP="131.159.74.67" 20TEST_IP="147.87.255.218"
21# IP address of 'gnunet.org'
22TEST_IP_ALT="131.159.74.67"
21# IPv6 address of 'gnunet.org' 23# IPv6 address of 'gnunet.org'
22TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60" 24TEST_IP6="2a07:6b47:100:464::9357:ffdb"
23# permissive DNS resolver we will use for the test 25# permissive DNS resolver we will use for the test
24TEST_IP_GNS2DNS="8.8.8.8" 26TEST_IP_GNS2DNS="8.8.8.8"
25 27
@@ -49,7 +51,7 @@ which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
49 51
50gnunet-arm -s -c test_gns_lookup.conf 52gnunet-arm -s -c test_gns_lookup.conf
51 53
52OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org` 54OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf www.gnunet.org`
53echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } 55echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; }
54echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } 56echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; }
55 57
@@ -69,7 +71,7 @@ gnunet-identity -d
69# lookup 'www.gnunet.org', IPv4 71# lookup 'www.gnunet.org', IPv4
70RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf` 72RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf`
71# lookup 'www.gnunet.org', IPv6 73# lookup 'www.gnunet.org', IPv6
72RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf` 74RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf | head -n1`
73# lookup 'gnunet.org', IPv4 75# lookup 'gnunet.org', IPv4
74RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf` 76RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf`
75# lookup 'docs.gnunet.org', IPv4 77# lookup 'docs.gnunet.org', IPv4
@@ -91,7 +93,7 @@ else
91 ret=1 93 ret=1
92fi 94fi
93 95
94if [ "$RES_IP6" = "$TEST_IP6" ] 96if [ "${RES_IP6%?}" = "${TEST_IP6%?}" ]
95then 97then
96 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." 98 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6."
97else 99else
@@ -99,7 +101,7 @@ else
99 ret=1 101 ret=1
100fi 102fi
101 103
102if echo "$RES_IP_ALT" | grep "$TEST_IP" > /dev/null 104if echo "$RES_IP_ALT" | grep "$TEST_IP_ALT" > /dev/null
103then 105then
104 echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT." 106 echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT."
105else 107else
diff --git a/src/gns/test_gns_gns2dns_zkey_lookup.sh b/src/gns/test_gns_gns2dns_zkey_lookup.sh
index 1f8e34c42..a299c34b6 100755
--- a/src/gns/test_gns_gns2dns_zkey_lookup.sh
+++ b/src/gns/test_gns_gns2dns_zkey_lookup.sh
@@ -17,9 +17,11 @@ rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
17# IP address of 'docs.gnunet.org' 17# IP address of 'docs.gnunet.org'
18TEST_IP_ALT2="147.87.255.218" 18TEST_IP_ALT2="147.87.255.218"
19# IP address of 'www.gnunet.org' 19# IP address of 'www.gnunet.org'
20TEST_IP="131.159.74.67" 20TEST_IP="147.87.255.218"
21# IP address of 'www.gnunet.org'
22TEST_IP_ALT="131.159.74.67"
21# IPv6 address of 'gnunet.org' 23# IPv6 address of 'gnunet.org'
22TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60" 24TEST_IP6="2a07:6b47:100:464::9357:ffdb"
23# permissive DNS resolver we will use for the test 25# permissive DNS resolver we will use for the test
24TEST_IP_GNS2DNS="8.8.8.8" 26TEST_IP_GNS2DNS="8.8.8.8"
25 27
@@ -46,7 +48,7 @@ which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
46 48
47gnunet-arm -s -c test_gns_lookup.conf 49gnunet-arm -s -c test_gns_lookup.conf
48 50
49OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org` 51OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf www.gnunet.org`
50echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } 52echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; }
51echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } 53echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; }
52 54
@@ -66,7 +68,7 @@ gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECOR
66# lookup 'www.gnunet.org', IPv4 68# lookup 'www.gnunet.org', IPv4
67RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf` 69RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf`
68# lookup 'www.gnunet.org', IPv6 70# lookup 'www.gnunet.org', IPv6
69RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf` 71RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf | head -n1`
70# lookup 'gnunet.org', IPv4 72# lookup 'gnunet.org', IPv4
71RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf` 73RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf`
72# lookup 'docs.gnunet.org', IPv4 74# lookup 'docs.gnunet.org', IPv4
@@ -88,7 +90,7 @@ else
88 ret=1 90 ret=1
89fi 91fi
90 92
91if [ "$RES_IP6" = "$TEST_IP6" ] 93if [ "${RES_IP6%?}" = "${TEST_IP6%?}" ]
92then 94then
93 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." 95 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6."
94else 96else
@@ -96,7 +98,7 @@ else
96 ret=1 98 ret=1
97fi 99fi
98 100
99if echo "$RES_IP_ALT" | grep "$TEST_IP" > /dev/null 101if echo "$RES_IP_ALT" | grep "$TEST_IP_ALT" > /dev/null
100then 102then
101 echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT." 103 echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT."
102else 104else
diff --git a/src/gns/test_gns_redirect_lookup.sh b/src/gns/test_gns_redirect_lookup.sh
new file mode 100755
index 000000000..dfe5087ef
--- /dev/null
+++ b/src/gns/test_gns_redirect_lookup.sh
@@ -0,0 +1,100 @@
1#!/bin/sh
2# This file is in the public domain.
3trap "gnunet-arm -e -c test_gns_lookup.conf" INT
4
5LOCATION=$(which gnunet-config)
6if [ -z $LOCATION ]
7then
8 LOCATION="gnunet-config"
9fi
10$LOCATION --version 1> /dev/null
11if test $? != 0
12then
13 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
14 exit 77
15fi
16
17# permissive DNS resolver we will use for the test
18DNS_RESOLVER="8.8.8.8"
19if ! nslookup gnunet.org $DNS_RESOLVER > /dev/null 2>&1
20then
21 echo "Cannot reach DNS, skipping test"
22 exit 77
23fi
24
25
26rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
27
28TEST_IP_PLUS="127.0.0.1"
29TEST_IP_DNS="131.159.74.67"
30TEST_RECORD_REDIRECT_SERVER="server"
31TEST_RECORD_REDIRECT_PLUS="server.+"
32TEST_RECORD_REDIRECT_DNS="gnunet.org"
33TEST_RECORD_NAME_SERVER="server"
34TEST_RECORD_NAME_PLUS="www"
35TEST_RECORD_NAME_ZKEY="www2"
36TEST_RECORD_NAME_DNS="www3"
37MY_EGO="myego"
38TEST_DOMAIN_PLUS="www.$MY_EGO"
39TEST_DOMAIN_ZKEY="www2.$MY_EGO"
40TEST_DOMAIN_DNS="www3.$MY_EGO"
41which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
42
43gnunet-arm -s -c test_gns_lookup.conf
44gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
45MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}')
46TEST_RECORD_REDIRECT_ZKEY="server.${MY_EGO_PKEY}"
47gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_DNS -t REDIRECT -V $TEST_RECORD_REDIRECT_DNS -e never -c test_gns_lookup.conf
48gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_PLUS -t REDIRECT -V $TEST_RECORD_REDIRECT_PLUS -e never -c test_gns_lookup.conf
49gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_ZKEY -t REDIRECT -V $TEST_RECORD_REDIRECT_ZKEY -e never -c test_gns_lookup.conf
50gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_REDIRECT_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
51gnunet-namestore -D -z $MY_EGO
52RES_REDIRECT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf`
53RES_REDIRECT_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t REDIRECT -c test_gns_lookup.conf`
54RES_REDIRECT_ZKEY=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ZKEY -t A -c test_gns_lookup.conf`
55RES_REDIRECT_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS`
56
57TESTEGOZONE=`gnunet-identity -c test_gns_lookup.conf -d | awk '{print $3}'`
58gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_DNS -t REDIRECT -V $TEST_RECORD_REDIRECT_DNS -e never -c test_gns_lookup.conf
59gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_PLUS -t REDIRECT -V $TEST_RECORD_REDIRECT_PLUS -e never -c test_gns_lookup.conf
60gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_ZKEY -t REDIRECT -V $TEST_RECORD_REDIRECT_ZKEY -e never -c test_gns_lookup.conf
61gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_REDIRECT_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
62gnunet-identity -D $MY_EGO -c test_gns_lookup.conf
63gnunet-arm -e -c test_gns_lookup.conf
64rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
65
66# make cmp case-insensitive by converting to lower case first
67RES_REDIRECT_RAW=`echo $RES_REDIRECT_RAW | tr [A-Z] [a-z]`
68TESTEGOZONE=`echo $TESTEGOZONE | tr [A-Z] [a-z]`
69if [ "$RES_REDIRECT_RAW" = "server.$TESTEGOZONE" ]
70then
71 echo "PASS: REDIRECT resolution from GNS"
72else
73 echo "FAIL: REDIRECT resolution from GNS, got $RES_REDIRECT_RAW, expected server.$TESTEGOZONE."
74 exit 1
75fi
76
77if [ "$RES_REDIRECT" = "$TEST_IP_PLUS" ]
78then
79 echo "PASS: IP resolution from GNS (.+)"
80else
81 echo "FAIL: IP resolution from GNS (.+), got $RES_REDIRECT, expected $TEST_IP_PLUS."
82 exit 1
83fi
84
85if [ "$RES_REDIRECT_ZKEY" = "$TEST_IP_PLUS" ]
86then
87 echo "PASS: IP resolution from GNS (.zkey)"
88else
89 echo "FAIL: IP resolution from GNS (.zkey), got $RES_REDIRECT, expected $TEST_IP_PLUS."
90 exit 1
91fi
92
93if echo "$RES_REDIRECT_DNS" | grep "$TEST_IP_DNS" > /dev/null
94then
95 echo "PASS: IP resolution from DNS"
96 exit 0
97else
98 echo "FAIL: IP resolution from DNS, got $RES_REDIRECT_DNS, expected $TEST_IP_DNS."
99 exit 1
100fi