avoid failing hard if 'gnunetcheck' db does not exist
[oweals/gnunet.git] / src / util / dnsparser.c
index 55475b1313082db2f0df912dd945bd0183be0031..7546ca1e970999deaf9fcba5505f70f63a86376a 100644 (file)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      Copyright (C) 2010-2014 GNUnet e.V.
+      Copyright (C) 2010-2014, 2018 GNUnet e.V.
 
       GNUnet is free software: you can redistribute it and/or modify it
       under the terms of the GNU Affero General Public License as published
       WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       Affero General Public License for more details.
-     
+
       You should have received a copy of the GNU Affero General Public License
       along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
  */
 
 /**
- * @file dns/dnsparser.c
+ * @file util/dnsparser.c
  * @brief helper library to parse DNS packets.
  * @author Philipp Toelke
  * @author Christian Grothoff
  */
 #include "platform.h"
+#if HAVE_LIBIDN2
+#if HAVE_IDN2_H
+#include <idn2.h>
+#elif HAVE_IDN2_IDN2_H
+#include <idn2/idn2.h>
+#endif
+#elif HAVE_LIBIDN
+#if HAVE_IDNA_H
 #include <idna.h>
+#elif HAVE_IDN_IDNA_H
+#include <idn/idna.h>
+#endif
+#endif
 #if WINDOWS
 #include <idn-free.h>
 #endif
 #include "gnunet_util_lib.h"
-#include "gnunet_dnsparser_lib.h"
-#include "gnunet_tun_lib.h"
 
 
 /**
@@ -760,6 +772,122 @@ GNUNET_DNSPARSER_parse (const char *udp_payload,
 }
 
 
+/**
+ * Duplicate (deep-copy) the given DNS record
+ *
+ * @param r the record
+ * @return the newly allocated record
+ */
+struct GNUNET_DNSPARSER_Record *
+GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r)
+{
+  struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup (r, sizeof (*r));
+
+  dup->name = GNUNET_strdup (r->name);
+  switch (r->type)
+  {
+    case GNUNET_DNSPARSER_TYPE_NS:
+    case GNUNET_DNSPARSER_TYPE_CNAME:
+    case GNUNET_DNSPARSER_TYPE_PTR:
+    {
+      dup->data.hostname = GNUNET_strdup (r->data.hostname);
+      break;
+    }
+    case GNUNET_DNSPARSER_TYPE_SOA:
+    {
+      dup->data.soa = GNUNET_DNSPARSER_duplicate_soa_record (r->data.soa);
+      break;
+    }
+    case GNUNET_DNSPARSER_TYPE_CERT:
+    {
+      dup->data.cert = GNUNET_DNSPARSER_duplicate_cert_record (r->data.cert);
+      break;
+    }
+    case GNUNET_DNSPARSER_TYPE_MX:
+    {
+      dup->data.mx = GNUNET_DNSPARSER_duplicate_mx_record (r->data.mx);
+      break;
+    }
+    case GNUNET_DNSPARSER_TYPE_SRV:
+    {
+      dup->data.srv = GNUNET_DNSPARSER_duplicate_srv_record (r->data.srv);
+      break;
+    }
+    default:
+    {
+      dup->data.raw.data = GNUNET_memdup (r->data.raw.data,
+                                         r->data.raw.data_len);
+    }
+  }
+  return dup;
+}
+
+
+/**
+ * Duplicate (deep-copy) the given DNS record
+ *
+ * @param r the record
+ * @return the newly allocated record
+ */
+struct GNUNET_DNSPARSER_SoaRecord *
+GNUNET_DNSPARSER_duplicate_soa_record (const struct GNUNET_DNSPARSER_SoaRecord *r)
+{
+  struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof (*r));
+
+  dup->mname = GNUNET_strdup (r->mname);
+  dup->rname = GNUNET_strdup (r->rname);
+  return dup;
+}
+
+
+/**
+ * Duplicate (deep-copy) the given DNS record
+ *
+ * @param r the record
+ * @return the newly allocated record
+ */
+struct GNUNET_DNSPARSER_CertRecord *
+GNUNET_DNSPARSER_duplicate_cert_record (const struct GNUNET_DNSPARSER_CertRecord *r)
+{
+  struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof (*r));
+
+  dup->certificate_data = GNUNET_strdup (r->certificate_data);
+  return dup;
+}
+
+
+/**
+ * Duplicate (deep-copy) the given DNS record
+ *
+ * @param r the record
+ * @return the newly allocated record
+ */
+struct GNUNET_DNSPARSER_MxRecord *
+GNUNET_DNSPARSER_duplicate_mx_record (const struct GNUNET_DNSPARSER_MxRecord *r)
+{
+  struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup (r, sizeof (*r));
+
+  dup->mxhost = GNUNET_strdup (r->mxhost);
+  return dup;
+}
+
+
+/**
+ * Duplicate (deep-copy) the given DNS record
+ *
+ * @param r the record
+ * @return the newly allocated record
+ */
+struct GNUNET_DNSPARSER_SrvRecord *
+GNUNET_DNSPARSER_duplicate_srv_record (const struct GNUNET_DNSPARSER_SrvRecord *r)
+{
+  struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof (*r));
+
+  dup->target = GNUNET_strdup (r->target);
+  return dup;
+}
+
+
 /**
  * Free memory taken by a packet.
  *
@@ -842,8 +970,11 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
       len = dot - idna_name;
     if ( (len >= 64) || (0 == len) )
     {
-      GNUNET_break (0);
-      goto fail; /* segment too long or empty */
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Invalid DNS name `%s': label with %u characters encountered\n",
+                  name,
+                  (unsigned int) len);
+      goto fail; /* label too long or empty */
     }
     dst[pos++] = (char) (uint8_t) len;
     GNUNET_memcpy (&dst[pos],
@@ -957,12 +1088,19 @@ GNUNET_DNSPARSER_builder_add_cert (char *dst,
 {
   struct GNUNET_TUN_DnsCertRecord dcert;
 
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#endif
   if ( (cert->cert_type > UINT16_MAX) ||
        (cert->algorithm > UINT8_MAX) )
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
   if (*off + sizeof (struct GNUNET_TUN_DnsCertRecord) + cert->certificate_size > dst_len)
     return GNUNET_NO;
   dcert.cert_type = htons ((uint16_t) cert->cert_type);
@@ -1185,7 +1323,6 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
   struct GNUNET_TUN_DnsHeader dns;
   size_t off;
   char tmp[max];
-  unsigned int i;
   int ret;
   int trc;
 
@@ -1203,7 +1340,7 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
 
   off = sizeof (struct GNUNET_TUN_DnsHeader);
   trc = GNUNET_NO;
-  for (i=0;i<p->num_queries;i++)
+  for (unsigned int i=0;i<p->num_queries;i++)
   {
     ret = GNUNET_DNSPARSER_builder_add_query (tmp,
                                              sizeof (tmp),
@@ -1218,7 +1355,7 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
       break;
     }
   }
-  for (i=0;i<p->num_answers;i++)
+  for (unsigned int i=0;i<p->num_answers;i++)
   {
     ret = add_record (tmp,
                      sizeof (tmp),
@@ -1233,7 +1370,7 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
       break;
     }
   }
-  for (i=0;i<p->num_authority_records;i++)
+  for (unsigned int i=0;i<p->num_authority_records;i++)
   {
     ret = add_record (tmp,
                      sizeof (tmp),
@@ -1248,7 +1385,7 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
       break;
     }
   }
-  for (i=0;i<p->num_additional_records;i++)
+  for (unsigned int i=0;i<p->num_additional_records;i++)
   {
     ret = add_record (tmp,
                      sizeof (tmp),