[glib/wip/tingping/gsocket-unknown-error] gnetworkaddress: Properly handle DNS returning no ipv6 addresses



commit f24f4a1e0ebdcbc7204a79390339f71e8034173c
Author: Patrick Griffis <tingping tingping se>
Date:   Sat Nov 23 11:42:16 2019 -0800

    gnetworkaddress: Properly handle DNS returning no ipv6 addresses
    
    If the ipv6 addresses returned is empty it should wait on ipv4.

 gio/gnetworkaddress.c     |  6 +++--
 gio/tests/gsocketclient.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 gio/tests/meson.build     |  1 +
 3 files changed, 61 insertions(+), 2 deletions(-)
---
diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c
index f12f93585..bc5cda33d 100644
--- a/gio/gnetworkaddress.c
+++ b/gio/gnetworkaddress.c
@@ -1238,11 +1238,13 @@ got_ipv6_addresses (GObject      *source_object,
   GNetworkAddressAddressEnumerator *addr_enum = user_data;
   GResolver *resolver = G_RESOLVER (source_object);
   GList *addresses;
+  gboolean got_addresses;
   GError *error = NULL;
 
   addr_enum->state ^= RESOLVE_STATE_WAITING_ON_IPV6;
 
   addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error);
+  got_addresses = addresses != NULL;
   if (!error)
     g_network_address_address_enumerator_add_addresses (addr_enum, g_steal_pointer (&addresses), resolver);
   else
@@ -1255,11 +1257,11 @@ got_ipv6_addresses (GObject      *source_object,
       g_clear_pointer (&addr_enum->wait_source, g_source_unref);
     }
 
-  /* If we got an error before ipv4 then let its response handle it.
+  /* If we got an error or no addresses before ipv4 then let its response handle it.
    * If we get ipv6 response first or error second then
    * immediately complete the task.
    */
-  if (error != NULL && !addr_enum->last_error && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4))
+  if ((error != NULL || !got_addresses) && !addr_enum->last_error && (addr_enum->state & 
RESOLVE_STATE_WAITING_ON_IPV4))
     {
       /* ipv6 lookup failed, but ipv4 is still outstanding.  wait. */
       addr_enum->last_error = g_steal_pointer (&error);
diff --git a/gio/tests/gsocketclient.c b/gio/tests/gsocketclient.c
new file mode 100644
index 000000000..94f0681e8
--- /dev/null
+++ b/gio/tests/gsocketclient.c
@@ -0,0 +1,56 @@
+#include "config.h"
+#include "mock-resolver.h"
+
+#include <gio/gio.h>
+
+static void
+on_connected (GObject *client, GAsyncResult *res, gpointer user_data)
+{
+  GError *error = NULL;
+  GSocketConnection *connection = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), res, &error);
+  g_main_loop_quit (user_data);
+
+  /* We want to make sure we made it to the point of conencting to a socket */
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED);
+  g_assert_null (connection);
+}
+
+static void
+test_no_ipv6_addresses (void)
+{
+  GMainLoop *loop = g_main_loop_new (NULL, FALSE);
+  GSocketClient *client = g_socket_client_new ();
+  GSocketConnectable *connectable = g_network_address_new ("gnome.fake", 1234);
+  GResolver *original_resolver = g_resolver_get_default ();
+  MockResolver *mock_resolver = mock_resolver_new ();
+  GList *ipv4_results = NULL;
+
+  /* This tests that the client sucessfully attempts an ipv4 address when no ipv6 address is returned */
+
+  g_resolver_set_default (G_RESOLVER (mock_resolver));
+  ipv4_results = g_list_append (ipv4_results, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4));
+  mock_resolver_set_ipv4_results (mock_resolver, ipv4_results);
+  mock_resolver_set_ipv4_delay_ms (mock_resolver, 100);
+
+  g_socket_client_set_timeout (client, 5);
+  g_socket_client_connect_async (client, connectable, NULL, on_connected, loop);
+  g_main_loop_run (loop);
+
+  g_resolver_set_default (original_resolver);
+  g_list_free_full (ipv4_results, (GDestroyNotify) g_object_unref);
+  g_object_unref (original_resolver);
+  g_object_unref (mock_resolver);
+  g_object_unref (client);
+  g_object_unref (connectable);
+  g_main_loop_unref (loop);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+  g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/";);
+
+  g_test_add_func ("/socket-client/basic", test_no_ipv6_addresses);
+  return g_test_run ();
+}
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index 8b5d105f5..32f10e294 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -79,6 +79,7 @@ gio_tests = {
   'tls-interaction' : {'extra_sources' : ['gtesttlsbackend.c']},
   'tls-database' : {'extra_sources' : ['gtesttlsbackend.c']},
   'gdbus-address-get-session' : {},
+  'gsocketclient' : {'extra_sources' : ['mock-resolver.c']},
 }
 
 test_extra_programs = {


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