aboutsummaryrefslogtreecommitdiff
path: root/src/gns
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-06-06 11:06:15 +0000
committerChristian Grothoff <christian@grothoff.org>2014-06-06 11:06:15 +0000
commit552c240a850306b1ef4fc9cd831eedaf59995ddd (patch)
tree8610f11055354c793456753d1220c7eb83211463 /src/gns
parent2429173f65538442ae3d4fb58cc7a24a1d39f35f (diff)
downloadgnunet-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.c138
-rw-r--r--src/gns/plugin_gnsrecord_gns.c9
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 */
461static const struct GNUNET_CONFIGURATION_Handle *cfg; 473static 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 */
470static int
471is_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 ... */
580void * 561static void *
581memrchr (const void *s, 562memrchr (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