[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r33558 - in gnunet/src: gns include
From: |
gnunet |
Subject: |
[GNUnet-SVN] r33558 - in gnunet/src: gns include |
Date: |
Fri, 6 Jun 2014 13:06:15 +0200 |
Author: grothoff
Date: 2014-06-06 13:06:15 +0200 (Fri, 06 Jun 2014)
New Revision: 33558
Modified:
gnunet/src/gns/gnunet-service-gns_resolver.c
gnunet/src/gns/plugin_gnsrecord_gns.c
gnunet/src/include/gnunet_gnsrecord_lib.h
Log:
-preliminary support for BOX records
Modified: gnunet/src/gns/gnunet-service-gns_resolver.c
===================================================================
--- gnunet/src/gns/gnunet-service-gns_resolver.c 2014-06-06 10:08:43 UTC
(rev 33557)
+++ gnunet/src/gns/gnunet-service-gns_resolver.c 2014-06-06 11:06:15 UTC
(rev 33558)
@@ -362,6 +362,18 @@
enum GNUNET_GNS_LocalOptions options;
/**
+ * For SRV and TLSA records, the number of the
+ * protocol specified in the name. 0 if no protocol was given.
+ */
+ int protocol;
+
+ /**
+ * For SRV and TLSA records, the number of the
+ * service specified in the name. 0 if no service was given.
+ */
+ int service;
+
+ /**
* Desired type for the resolution.
*/
int record_type;
@@ -460,38 +472,7 @@
*/
static const struct GNUNET_CONFIGURATION_Handle *cfg;
-#if 0
-/**
- * Check if name is in srv format (_x._y.xxx)
- *
- * @param name
- * @return #GNUNET_YES if true
- */
-static int
-is_srv (const char *name)
-{
- char *ndup;
- int ret;
- if (*name != '_')
- return GNUNET_NO;
- if (NULL == strstr (name, "._"))
- return GNUNET_NO;
- ret = GNUNET_YES;
- ndup = GNUNET_strdup (name);
- strtok (ndup, ".");
- if (NULL == strtok (NULL, "."))
- ret = GNUNET_NO;
- if (NULL == strtok (NULL, "."))
- ret = GNUNET_NO;
- if (NULL != strtok (NULL, "."))
- ret = GNUNET_NO;
- GNUNET_free (ndup);
- return ret;
-}
-#endif
-
-
/**
* Determine if this name is canonical (is a legal name in a zone, without
delegation);
* note that we do not test that the name does not contain illegal characters,
we only
@@ -577,7 +558,7 @@
#if (defined WINDOWS) || (defined DARWIN)
/* Don't have this on W32, here's a naive implementation
* Was somehow removed on OS X ... */
-void *
+static void *
memrchr (const void *s,
int c,
size_t n)
@@ -616,6 +597,11 @@
const char *rp;
const char *dot;
size_t len;
+ char *ret;
+ char *srv_name;
+ char *proto_name;
+ struct protoent *pe;
+ struct servent *se;
if (0 == rh->name_resolution_pos)
return NULL;
@@ -636,17 +622,53 @@
rp = dot + 1;
rh->name_resolution_pos = dot - rh->name;
}
- /* merge labels starting with underscore with label on the right (SRV/DANE
case) */
- while ( (NULL != (dot = memrchr (rh->name,
- (int) '.',
- rh->name_resolution_pos))) &&
- ('_' == dot[1]) )
+ rh->protocol = 0;
+ rh->service = 0;
+ ret = GNUNET_strndup (rp, len);
+ /* If we have labels starting with underscore with label on
+ * the right (SRV/DANE/BOX case), determine port/protocol;
+ * The format of `rh->name` must be "_PORT._PROTOCOL".
+ */
+ if ( ('_' == rh->name[0]) &&
+ (NULL != (dot = memrchr (rh->name,
+ (int) '.',
+ rh->name_resolution_pos))) &&
+ ('_' == dot[1]) &&
+ (NULL == memrchr (rh->name,
+ (int) '.',
+ dot - rh->name)) )
{
- len += rh->name_resolution_pos - (dot - rh->name) - 1;
- rp = dot + 1;
- rh->name_resolution_pos = dot - rh->name;
+ srv_name = GNUNET_strndup (&rh->name[1],
+ (dot - rh->name) - 1);
+ proto_name = GNUNET_strndup (&dot[2],
+ rh->name_resolution_pos - (dot - rh->name) -
1);
+ rh->name_resolution_pos = 0;
+ pe = getprotobyname (proto_name);
+ if (NULL == pe)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Protocol `%s' unknown, skipping labels.\n"),
+ proto_name);
+ GNUNET_free (proto_name);
+ GNUNET_free (srv_name);
+ return ret;
+ }
+ se = getservbyname (srv_name,
+ proto_name);
+ if (NULL == se)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Service `%s' unknown for protocol `%s', skipping
labels.\n"),
+ srv_name,
+ proto_name);
+ GNUNET_free (proto_name);
+ GNUNET_free (srv_name);
+ return ret;
+ }
+ rh->protocol = pe->p_proto;
+ rh->service = se->s_port;
}
- return GNUNET_strndup (rp, len);
+ return ret;
}
@@ -849,7 +871,6 @@
GNUNET_DNSPARSER_free_packet (p);
return;
}
- /* FIXME: add DNAME support */
/* convert from (parsed) DNS to (binary) GNS format! */
rd_count = p->num_answers + p->num_authority_records +
p->num_additional_records;
@@ -1481,6 +1502,11 @@
shorten_ac = rh->ac_tail;
for (i=0;i<rd_count;i++)
{
+ if ( (0 != rh->protocol) &&
+ (0 != rh->service) &&
+ (GNUNET_GNSRECORD_TYPE_BOX != rd[i].record_type) )
+ continue; /* we _only_ care about boxed records */
+
rd_new[rd_off] = rd[i];
/* Check if the embedded name(s) end in "+", and if so,
replace the "+" with the zone at "ac_tail", changing the name
@@ -1639,6 +1665,7 @@
case GNUNET_GNSRECORD_TYPE_NICK:
{
const char *nick;
+
nick = rd[i].data;
if ((rd[i].data_size > 0) &&
(nick[rd[i].data_size -1] != '\0'))
@@ -1689,6 +1716,33 @@
"Found GNS2DNS record, delegating to DNS!\n");
goto do_recurse;
}
+ case GNUNET_GNSRECORD_TYPE_BOX:
+ {
+ /* unbox SRV/TLSA records if a specific one was requested */
+ if ( (0 != rh->protocol) &&
+ (0 != rh->service) &&
+ (rd[i].data_size >= sizeof (struct GNUNET_GNSRECORD_BoxRecord))
)
+ {
+ const struct GNUNET_GNSRECORD_BoxRecord *box;
+
+ box = rd[i].data;
+ if ( (ntohs (box->protocol) == rh->protocol) &&
+ (ntohs (box->service) == rh->service) )
+ {
+ /* Box matches, unbox! */
+ rd_new[rd_off].record_type = ntohl (box->record_type);
+ rd_new[rd_off].data_size -= sizeof (struct
GNUNET_GNSRECORD_BoxRecord);
+ rd_new[rd_off].data = &box[1];
+ rd_off++;
+ }
+ }
+ else
+ {
+ /* no specific protocol/service specified, preserve all BOX
+ records (for modern, GNS-enabled applications) */
+ rd_off++;
+ }
+ }
default:
rd_off++;
break;
Modified: gnunet/src/gns/plugin_gnsrecord_gns.c
===================================================================
--- gnunet/src/gns/plugin_gnsrecord_gns.c 2014-06-06 10:08:43 UTC (rev
33557)
+++ gnunet/src/gns/plugin_gnsrecord_gns.c 2014-06-06 11:06:15 UTC (rev
33558)
@@ -108,6 +108,10 @@
(const char*) &vpn[1]);
return vpn_str;
}
+ case GNUNET_GNSRECORD_TYPE_BOX:
+ /* FIXME: to be implemented! */
+ GNUNET_break (0);
+ return NULL;
default:
return NULL;
}
@@ -231,6 +235,10 @@
vpn->proto = htons ((uint16_t) proto);
strcpy ((char*)&vpn[1], s_serv);
return GNUNET_OK;
+ case GNUNET_GNSRECORD_TYPE_BOX:
+ /* FIXME: to be implemented! */
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
default:
return GNUNET_SYSERR;
}
@@ -250,6 +258,7 @@
{ "LEHO", GNUNET_GNSRECORD_TYPE_LEHO },
{ "VPN", GNUNET_GNSRECORD_TYPE_VPN },
{ "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
+ { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
{ NULL, UINT32_MAX }
};
Modified: gnunet/src/include/gnunet_gnsrecord_lib.h
===================================================================
--- gnunet/src/include/gnunet_gnsrecord_lib.h 2014-06-06 10:08:43 UTC (rev
33557)
+++ gnunet/src/include/gnunet_gnsrecord_lib.h 2014-06-06 11:06:15 UTC (rev
33558)
@@ -71,14 +71,19 @@
#define GNUNET_GNSRECORD_TYPE_GNS2DNS 65540
/**
+ * Record type for a boxed record (see TLSA/SRV handling in GNS).
+ */
+#define GNUNET_GNSRECORD_TYPE_BOX 65541
+
+/**
* Record type for a social place.
*/
-#define GNUNET_GNSRECORD_TYPE_PLACE 65541
+#define GNUNET_GNSRECORD_TYPE_PLACE 65542
/**
* Record type for a phone (of CONVERSATION).
*/
-#define GNUNET_GNSRECORD_TYPE_PHONE 65542
+#define GNUNET_GNSRECORD_TYPE_PHONE 65543
/**
@@ -202,6 +207,41 @@
/* followed by encrypted data */
};
+
+/**
+ * Record type used to box up SRV and TLSA records. For example, a
+ * TLSA record for "_https._tcp.foo.gnu" will be stored under
+ * "foo.gnu" as a BOX record with service 443 (https) and protocol 6
+ * (tcp) and record_type "TLSA". When a BOX record is received, GNS
+ * unboxes it if the name contained "_SERVICE._PROTO", otherwise GNS
+ * leaves it untouched. This is done to ensure that TLSA (and SRV)
+ * records do not require a separate network request, thus making TLSA
+ * records inseparable from the "main" A/AAAA/VPN/etc. records.
+ */
+struct GNUNET_GNSRECORD_BoxRecord
+{
+
+ /**
+ * Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).
+ * Yes, in IP protocols are usually limited to 8 bits. In NBO.
+ */
+ uint16_t protocol GNUNET_PACKED;
+
+ /**
+ * Service of the boxed record (aka port number), in NBO.
+ */
+ uint16_t service GNUNET_PACKED;
+
+ /**
+ * GNS record type of the boxed record. In NBO.
+ */
+ uint32_t record_type GNUNET_PACKED;
+
+ /* followed by the 'original' record */
+
+};
+
+
GNUNET_NETWORK_STRUCT_END
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r33558 - in gnunet/src: gns include,
gnunet <=