diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-06-06 11:06:15 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-06-06 11:06:15 +0000 |
commit | 552c240a850306b1ef4fc9cd831eedaf59995ddd (patch) | |
tree | 8610f11055354c793456753d1220c7eb83211463 /src/gns | |
parent | 2429173f65538442ae3d4fb58cc7a24a1d39f35f (diff) | |
download | gnunet-552c240a850306b1ef4fc9cd831eedaf59995ddd.tar.gz gnunet-552c240a850306b1ef4fc9cd831eedaf59995ddd.zip |
-preliminary support for BOX records
Diffstat (limited to 'src/gns')
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.c | 138 | ||||
-rw-r--r-- | src/gns/plugin_gnsrecord_gns.c | 9 |
2 files changed, 105 insertions, 42 deletions
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index e6b231459..9db5b1b99 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -362,6 +362,18 @@ struct GNS_ResolverHandle | |||
362 | enum GNUNET_GNS_LocalOptions options; | 362 | enum GNUNET_GNS_LocalOptions options; |
363 | 363 | ||
364 | /** | 364 | /** |
365 | * For SRV and TLSA records, the number of the | ||
366 | * protocol specified in the name. 0 if no protocol was given. | ||
367 | */ | ||
368 | int protocol; | ||
369 | |||
370 | /** | ||
371 | * For SRV and TLSA records, the number of the | ||
372 | * service specified in the name. 0 if no service was given. | ||
373 | */ | ||
374 | int service; | ||
375 | |||
376 | /** | ||
365 | * Desired type for the resolution. | 377 | * Desired type for the resolution. |
366 | */ | 378 | */ |
367 | int record_type; | 379 | int record_type; |
@@ -460,37 +472,6 @@ static int use_cache; | |||
460 | */ | 472 | */ |
461 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 473 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
462 | 474 | ||
463 | #if 0 | ||
464 | /** | ||
465 | * Check if name is in srv format (_x._y.xxx) | ||
466 | * | ||
467 | * @param name | ||
468 | * @return #GNUNET_YES if true | ||
469 | */ | ||
470 | static int | ||
471 | is_srv (const char *name) | ||
472 | { | ||
473 | char *ndup; | ||
474 | int ret; | ||
475 | |||
476 | if (*name != '_') | ||
477 | return GNUNET_NO; | ||
478 | if (NULL == strstr (name, "._")) | ||
479 | return GNUNET_NO; | ||
480 | ret = GNUNET_YES; | ||
481 | ndup = GNUNET_strdup (name); | ||
482 | strtok (ndup, "."); | ||
483 | if (NULL == strtok (NULL, ".")) | ||
484 | ret = GNUNET_NO; | ||
485 | if (NULL == strtok (NULL, ".")) | ||
486 | ret = GNUNET_NO; | ||
487 | if (NULL != strtok (NULL, ".")) | ||
488 | ret = GNUNET_NO; | ||
489 | GNUNET_free (ndup); | ||
490 | return ret; | ||
491 | } | ||
492 | #endif | ||
493 | |||
494 | 475 | ||
495 | /** | 476 | /** |
496 | * Determine if this name is canonical (is a legal name in a zone, without delegation); | 477 | * Determine if this name is canonical (is a legal name in a zone, without delegation); |
@@ -577,7 +558,7 @@ fail_resolution (void *cls, | |||
577 | #if (defined WINDOWS) || (defined DARWIN) | 558 | #if (defined WINDOWS) || (defined DARWIN) |
578 | /* Don't have this on W32, here's a naive implementation | 559 | /* Don't have this on W32, here's a naive implementation |
579 | * Was somehow removed on OS X ... */ | 560 | * Was somehow removed on OS X ... */ |
580 | void * | 561 | static void * |
581 | memrchr (const void *s, | 562 | memrchr (const void *s, |
582 | int c, | 563 | int c, |
583 | size_t n) | 564 | size_t n) |
@@ -616,6 +597,11 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle *rh) | |||
616 | const char *rp; | 597 | const char *rp; |
617 | const char *dot; | 598 | const char *dot; |
618 | size_t len; | 599 | size_t len; |
600 | char *ret; | ||
601 | char *srv_name; | ||
602 | char *proto_name; | ||
603 | struct protoent *pe; | ||
604 | struct servent *se; | ||
619 | 605 | ||
620 | if (0 == rh->name_resolution_pos) | 606 | if (0 == rh->name_resolution_pos) |
621 | return NULL; | 607 | return NULL; |
@@ -636,17 +622,53 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle *rh) | |||
636 | rp = dot + 1; | 622 | rp = dot + 1; |
637 | rh->name_resolution_pos = dot - rh->name; | 623 | rh->name_resolution_pos = dot - rh->name; |
638 | } | 624 | } |
639 | /* merge labels starting with underscore with label on the right (SRV/DANE case) */ | 625 | rh->protocol = 0; |
640 | while ( (NULL != (dot = memrchr (rh->name, | 626 | rh->service = 0; |
641 | (int) '.', | 627 | ret = GNUNET_strndup (rp, len); |
642 | rh->name_resolution_pos))) && | 628 | /* If we have labels starting with underscore with label on |
643 | ('_' == dot[1]) ) | 629 | * the right (SRV/DANE/BOX case), determine port/protocol; |
630 | * The format of `rh->name` must be "_PORT._PROTOCOL". | ||
631 | */ | ||
632 | if ( ('_' == rh->name[0]) && | ||
633 | (NULL != (dot = memrchr (rh->name, | ||
634 | (int) '.', | ||
635 | rh->name_resolution_pos))) && | ||
636 | ('_' == dot[1]) && | ||
637 | (NULL == memrchr (rh->name, | ||
638 | (int) '.', | ||
639 | dot - rh->name)) ) | ||
644 | { | 640 | { |
645 | len += rh->name_resolution_pos - (dot - rh->name) - 1; | 641 | srv_name = GNUNET_strndup (&rh->name[1], |
646 | rp = dot + 1; | 642 | (dot - rh->name) - 1); |
647 | rh->name_resolution_pos = dot - rh->name; | 643 | proto_name = GNUNET_strndup (&dot[2], |
644 | rh->name_resolution_pos - (dot - rh->name) - 1); | ||
645 | rh->name_resolution_pos = 0; | ||
646 | pe = getprotobyname (proto_name); | ||
647 | if (NULL == pe) | ||
648 | { | ||
649 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
650 | _("Protocol `%s' unknown, skipping labels.\n"), | ||
651 | proto_name); | ||
652 | GNUNET_free (proto_name); | ||
653 | GNUNET_free (srv_name); | ||
654 | return ret; | ||
655 | } | ||
656 | se = getservbyname (srv_name, | ||
657 | proto_name); | ||
658 | if (NULL == se) | ||
659 | { | ||
660 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
661 | _("Service `%s' unknown for protocol `%s', skipping labels.\n"), | ||
662 | srv_name, | ||
663 | proto_name); | ||
664 | GNUNET_free (proto_name); | ||
665 | GNUNET_free (srv_name); | ||
666 | return ret; | ||
667 | } | ||
668 | rh->protocol = pe->p_proto; | ||
669 | rh->service = se->s_port; | ||
648 | } | 670 | } |
649 | return GNUNET_strndup (rp, len); | 671 | return ret; |
650 | } | 672 | } |
651 | 673 | ||
652 | 674 | ||
@@ -849,7 +871,6 @@ dns_result_parser (void *cls, | |||
849 | GNUNET_DNSPARSER_free_packet (p); | 871 | GNUNET_DNSPARSER_free_packet (p); |
850 | return; | 872 | return; |
851 | } | 873 | } |
852 | /* FIXME: add DNAME support */ | ||
853 | 874 | ||
854 | /* convert from (parsed) DNS to (binary) GNS format! */ | 875 | /* convert from (parsed) DNS to (binary) GNS format! */ |
855 | rd_count = p->num_answers + p->num_authority_records + p->num_additional_records; | 876 | rd_count = p->num_answers + p->num_authority_records + p->num_additional_records; |
@@ -1481,6 +1502,11 @@ handle_gns_resolution_result (void *cls, | |||
1481 | shorten_ac = rh->ac_tail; | 1502 | shorten_ac = rh->ac_tail; |
1482 | for (i=0;i<rd_count;i++) | 1503 | for (i=0;i<rd_count;i++) |
1483 | { | 1504 | { |
1505 | if ( (0 != rh->protocol) && | ||
1506 | (0 != rh->service) && | ||
1507 | (GNUNET_GNSRECORD_TYPE_BOX != rd[i].record_type) ) | ||
1508 | continue; /* we _only_ care about boxed records */ | ||
1509 | |||
1484 | rd_new[rd_off] = rd[i]; | 1510 | rd_new[rd_off] = rd[i]; |
1485 | /* Check if the embedded name(s) end in "+", and if so, | 1511 | /* Check if the embedded name(s) end in "+", and if so, |
1486 | replace the "+" with the zone at "ac_tail", changing the name | 1512 | replace the "+" with the zone at "ac_tail", changing the name |
@@ -1639,6 +1665,7 @@ handle_gns_resolution_result (void *cls, | |||
1639 | case GNUNET_GNSRECORD_TYPE_NICK: | 1665 | case GNUNET_GNSRECORD_TYPE_NICK: |
1640 | { | 1666 | { |
1641 | const char *nick; | 1667 | const char *nick; |
1668 | |||
1642 | nick = rd[i].data; | 1669 | nick = rd[i].data; |
1643 | if ((rd[i].data_size > 0) && | 1670 | if ((rd[i].data_size > 0) && |
1644 | (nick[rd[i].data_size -1] != '\0')) | 1671 | (nick[rd[i].data_size -1] != '\0')) |
@@ -1689,6 +1716,33 @@ handle_gns_resolution_result (void *cls, | |||
1689 | "Found GNS2DNS record, delegating to DNS!\n"); | 1716 | "Found GNS2DNS record, delegating to DNS!\n"); |
1690 | goto do_recurse; | 1717 | goto do_recurse; |
1691 | } | 1718 | } |
1719 | case GNUNET_GNSRECORD_TYPE_BOX: | ||
1720 | { | ||
1721 | /* unbox SRV/TLSA records if a specific one was requested */ | ||
1722 | if ( (0 != rh->protocol) && | ||
1723 | (0 != rh->service) && | ||
1724 | (rd[i].data_size >= sizeof (struct GNUNET_GNSRECORD_BoxRecord)) ) | ||
1725 | { | ||
1726 | const struct GNUNET_GNSRECORD_BoxRecord *box; | ||
1727 | |||
1728 | box = rd[i].data; | ||
1729 | if ( (ntohs (box->protocol) == rh->protocol) && | ||
1730 | (ntohs (box->service) == rh->service) ) | ||
1731 | { | ||
1732 | /* Box matches, unbox! */ | ||
1733 | rd_new[rd_off].record_type = ntohl (box->record_type); | ||
1734 | rd_new[rd_off].data_size -= sizeof (struct GNUNET_GNSRECORD_BoxRecord); | ||
1735 | rd_new[rd_off].data = &box[1]; | ||
1736 | rd_off++; | ||
1737 | } | ||
1738 | } | ||
1739 | else | ||
1740 | { | ||
1741 | /* no specific protocol/service specified, preserve all BOX | ||
1742 | records (for modern, GNS-enabled applications) */ | ||
1743 | rd_off++; | ||
1744 | } | ||
1745 | } | ||
1692 | default: | 1746 | default: |
1693 | rd_off++; | 1747 | rd_off++; |
1694 | break; | 1748 | break; |
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index d1de73e49..8247ff66d 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c | |||
@@ -108,6 +108,10 @@ gns_value_to_string (void *cls, | |||
108 | (const char*) &vpn[1]); | 108 | (const char*) &vpn[1]); |
109 | return vpn_str; | 109 | return vpn_str; |
110 | } | 110 | } |
111 | case GNUNET_GNSRECORD_TYPE_BOX: | ||
112 | /* FIXME: to be implemented! */ | ||
113 | GNUNET_break (0); | ||
114 | return NULL; | ||
111 | default: | 115 | default: |
112 | return NULL; | 116 | return NULL; |
113 | } | 117 | } |
@@ -231,6 +235,10 @@ gns_string_to_value (void *cls, | |||
231 | vpn->proto = htons ((uint16_t) proto); | 235 | vpn->proto = htons ((uint16_t) proto); |
232 | strcpy ((char*)&vpn[1], s_serv); | 236 | strcpy ((char*)&vpn[1], s_serv); |
233 | return GNUNET_OK; | 237 | return GNUNET_OK; |
238 | case GNUNET_GNSRECORD_TYPE_BOX: | ||
239 | /* FIXME: to be implemented! */ | ||
240 | GNUNET_break (0); | ||
241 | return GNUNET_SYSERR; | ||
234 | default: | 242 | default: |
235 | return GNUNET_SYSERR; | 243 | return GNUNET_SYSERR; |
236 | } | 244 | } |
@@ -250,6 +258,7 @@ static struct { | |||
250 | { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO }, | 258 | { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO }, |
251 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, | 259 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, |
252 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, | 260 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, |
261 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, | ||
253 | { NULL, UINT32_MAX } | 262 | { NULL, UINT32_MAX } |
254 | }; | 263 | }; |
255 | 264 | ||