[glib: 1/13] tests: Add basic test framework for GResolver DNS parsing




commit 5cdacced3fe58965d1ff592bd8fc3c100accede4
Author: Patrick Griffis <pgriffis igalia com>
Date:   Fri Mar 18 14:22:38 2022 +0000

    tests: Add basic test framework for GResolver DNS parsing
    
    Split out from https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2134
    by Philip Withnall so it can be used in advance of HTTPS DNS record
    support landing.
    
    Reworked to no longer use test fixtures, as it’s simple enough to build
    the response header in each test.
    
    The tests are built on Unix only, as they test the parsing code in
    `g_resolver_records_from_res_query()`, which is Unix-specific. The
    Windows DNS APIs provide much more structured results which don’t need
    parsing.

 gio/meson.build              |   8 +++
 gio/tests/meson.build        |   1 +
 gio/tests/resolver-parsing.c | 116 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 125 insertions(+)
---
diff --git a/gio/meson.build b/gio/meson.build
index 874de4b153..543763eeac 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -74,6 +74,14 @@ if host_system != 'windows'
     endif
   endif
 
+  # dn_comp()
+  if cc.links('''#include <resolv.h>
+                 int main (int argc, char ** argv) {
+                   return dn_comp(NULL, NULL, 0, NULL, NULL) == -1;
+                 } ''', args : network_args, name : 'dn_comp()')
+    glib_conf.set('HAVE_DN_COMP', 1)
+  endif
+
   # res_nclose()
   if cc.links('''#include <sys/types.h>
                  #include <netinet/in.h>
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index a27bc53d13..3ed23a5f21 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -191,6 +191,7 @@ if host_machine.system() != 'windows'
     },
     'gdbus-peer-object-manager' : {},
     'live-g-file' : {},
+    'resolver-parsing' : {'dependencies' : [network_libs]},
     'socket-address' : {},
     'stream-rw_all' : {},
     'unix-fd' : {},
diff --git a/gio/tests/resolver-parsing.c b/gio/tests/resolver-parsing.c
new file mode 100644
index 0000000000..e6fc749366
--- /dev/null
+++ b/gio/tests/resolver-parsing.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Patrick Griffis <pgriffis igalia com>
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <gio/gnetworking.h>
+
+#define GIO_COMPILATION
+#include "gthreadedresolver.h"
+#undef GIO_COMPILATION
+
+#ifdef HAVE_DN_COMP
+static void
+dns_builder_add_uint8 (GByteArray *builder,
+                       guint8      value)
+{
+  g_byte_array_append (builder, &value, 1);
+}
+
+static void
+dns_builder_add_uint16 (GByteArray *builder,
+                        guint16     value)
+{
+    dns_builder_add_uint8 (builder, (value >> 8)  & 0xFF);
+    dns_builder_add_uint8 (builder, (value)       & 0xFF);
+}
+
+static void
+dns_builder_add_uint32 (GByteArray *builder,
+                        guint32     value)
+{
+    dns_builder_add_uint8 (builder, (value >> 24) & 0xFF);
+    dns_builder_add_uint8 (builder, (value >> 16) & 0xFF);
+    dns_builder_add_uint8 (builder, (value >> 8)  & 0xFF);
+    dns_builder_add_uint8 (builder, (value)       & 0xFF);
+}
+
+static void
+dns_builder_add_length_prefixed_string (GByteArray *builder,
+                                        const char *string)
+{
+    guint8 length;
+
+    g_assert (strlen (string) <= G_MAXUINT8);
+
+    length = (guint8) strlen (string);
+    dns_builder_add_uint8 (builder, length);
+
+    /* Don't include trailing NUL */
+    g_byte_array_append (builder, (const guchar *)string, length);
+}
+
+static void
+dns_builder_add_domain (GByteArray *builder,
+                        const char *string)
+{
+  int ret;
+  guchar buffer[256];
+
+  ret = dn_comp (string, buffer, sizeof (buffer), NULL, NULL);
+  g_assert (ret != -1);
+
+  g_byte_array_append (builder, buffer, ret);
+}
+
+static void
+dns_builder_add_answer_data (GByteArray *builder,
+                             GByteArray *answer)
+{
+  dns_builder_add_uint16 (builder, answer->len); /* rdlength */
+  g_byte_array_append (builder, answer->data, answer->len);
+}
+
+static GByteArray *
+dns_header (void)
+{
+  GByteArray *answer = g_byte_array_sized_new (2046);
+
+  /* Start with a header, we ignore everything except ancount.
+     https://datatracker.ietf.org/doc/html/rfc1035#section-4.1.1 */
+  dns_builder_add_uint16 (answer, 0); /* ID */
+  dns_builder_add_uint16 (answer, 0); /* |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   | */
+  dns_builder_add_uint16 (answer, 0); /* QDCOUNT */
+  dns_builder_add_uint16 (answer, 1); /* ANCOUNT (1 answer) */
+  dns_builder_add_uint16 (answer, 0); /* NSCOUNT */
+  dns_builder_add_uint16 (answer, 0); /* ARCOUNT */
+
+  return g_steal_pointer (&answer);
+}
+#endif /* HAVE_DN_COMP */
+
+int
+main (int   argc,
+      char *argv[])
+{
+  g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
+
+  return g_test_run ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]