gnunet-svn
[Top][All Lists]
Advanced

[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
 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]