[glib/wip/tingping/happy-eyeballs: 1/3] gresolver: Add g_resolver_lookup_by_name_with_flags{_async, _finish, }



commit 763c783ff5f1f8384e9916e7b9a47f8df5c82329
Author: Patrick Griffis <pgriffis igalia com>
Date:   Wed Oct 17 11:14:10 2018 -0400

    gresolver: Add g_resolver_lookup_by_name_with_flags{_async,_finish,}
    
    This allows higher levels to have more control over resolving
    (ipv4 or ipv6 for now) which allows for optimizations such
    as requesting both in parallel as RFC 8305 recommends.

 gio/gresolver.c         | 311 ++++++++++++++++++++++++++++++++++++++----------
 gio/gresolver.h         |  51 +++++++-
 gio/gthreadedresolver.c | 166 +++++++++++++++++++++-----
 3 files changed, 428 insertions(+), 100 deletions(-)
---
diff --git a/gio/gresolver.c b/gio/gresolver.c
index b60544a20..4ab9ac62b 100644
--- a/gio/gresolver.c
+++ b/gio/gresolver.c
@@ -347,6 +347,59 @@ handle_ip_address (const char  *hostname,
   return FALSE;
 }
 
+static GList *
+lookup_by_name_real (GResolver               *resolver,
+                     const gchar             *hostname,
+                     GResolverNameLookupFlags flags,
+                     gboolean                 with_flags,
+                     GCancellable            *cancellable,
+                     GError                 **error)
+{
+  GList *addrs;
+  gchar *ascii_hostname = NULL;
+
+  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
+  g_return_val_if_fail (hostname != NULL, NULL);
+
+  /* Check if @hostname is just an IP address */
+  if (handle_ip_address (hostname, &addrs, error))
+    return addrs;
+
+  if (g_hostname_is_non_ascii (hostname))
+    hostname = ascii_hostname = g_hostname_to_ascii (hostname);
+
+  if (!hostname)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           _("Invalid hostname"));
+      return NULL;
+    }
+
+  g_resolver_maybe_reload (resolver);
+
+  if (with_flags)
+    {
+      if (!G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags)
+        {
+          g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               _("lookup_by_name_with_flags not implemented"));
+          g_free (ascii_hostname);
+          return NULL;
+        }
+      addrs = G_RESOLVER_GET_CLASS (resolver)->
+        lookup_by_name_with_flags (resolver, hostname, flags, cancellable, error);
+    }
+  else
+    addrs = G_RESOLVER_GET_CLASS (resolver)->
+      lookup_by_name (resolver, hostname, cancellable, error);
+
+
+  remove_duplicates (addrs);
+
+  g_free (ascii_hostname);
+  return addrs;
+}
+
 /**
  * g_resolver_lookup_by_name:
  * @resolver: a #GResolver
@@ -391,57 +444,52 @@ g_resolver_lookup_by_name (GResolver     *resolver,
                            GCancellable  *cancellable,
                            GError       **error)
 {
-  GList *addrs;
-  gchar *ascii_hostname = NULL;
-
-  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
-  g_return_val_if_fail (hostname != NULL, NULL);
-
-  /* Check if @hostname is just an IP address */
-  if (handle_ip_address (hostname, &addrs, error))
-    return addrs;
-
-  if (g_hostname_is_non_ascii (hostname))
-    hostname = ascii_hostname = g_hostname_to_ascii (hostname);
-
-  if (!hostname)
-    {
-      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                           _("Invalid hostname"));
-      return NULL;
-    }
-
-  g_resolver_maybe_reload (resolver);
-  addrs = G_RESOLVER_GET_CLASS (resolver)->
-    lookup_by_name (resolver, hostname, cancellable, error);
-
-  remove_duplicates (addrs);
-
-  g_free (ascii_hostname);
-  return addrs;
+  return lookup_by_name_real (resolver,
+                              hostname,
+                              0, FALSE,
+                              cancellable,
+                              error);
 }
 
 /**
- * g_resolver_lookup_by_name_async:
+ * g_resolver_lookup_by_name_with_flags:
  * @resolver: a #GResolver
- * @hostname: the hostname to look up the address of
+ * @hostname: the hostname to look up
+ * @flags: extra #GResolverNameLookupFlags for the lookup
  * @cancellable: (nullable): a #GCancellable, or %NULL
- * @callback: (scope async): callback to call after resolution completes
- * @user_data: (closure): data for @callback
+ * @error: return location for a #GError, or %NULL
  *
- * Begins asynchronously resolving @hostname to determine its
- * associated IP address(es), and eventually calls @callback, which
- * must call g_resolver_lookup_by_name_finish() to get the result.
- * See g_resolver_lookup_by_name() for more details.
+ * See g_resolver_lookup_by_name() for more information.
  *
- * Since: 2.22
+ * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
+ * of #GInetAddress, or %NULL on error. You
+ * must unref each of the addresses and free the list when you are
+ * done with it. (You can use g_resolver_free_addresses() to do this.)
+ *
+ * Since: 2.60
  */
-void
-g_resolver_lookup_by_name_async (GResolver           *resolver,
-                                 const gchar         *hostname,
-                                 GCancellable        *cancellable,
-                                 GAsyncReadyCallback  callback,
-                                 gpointer             user_data)
+GList *
+g_resolver_lookup_by_name_with_flags (GResolver               *resolver,
+                                      const gchar             *hostname,
+                                      GResolverNameLookupFlags flags,
+                                      GCancellable            *cancellable,
+                                      GError                 **error)
+{
+  return lookup_by_name_real (resolver,
+                              hostname,
+                              flags, TRUE,
+                              cancellable,
+                              error);
+}
+
+static void
+lookup_by_name_async_real (GResolver               *resolver,
+                           const gchar             *hostname,
+                           GResolverNameLookupFlags flags,
+                           gboolean                 with_flags,
+                           GCancellable            *cancellable,
+                           GAsyncReadyCallback      callback,
+                           gpointer                 user_data)
 {
   gchar *ascii_hostname = NULL;
   GList *addrs;
@@ -456,7 +504,7 @@ g_resolver_lookup_by_name_async (GResolver           *resolver,
       GTask *task;
 
       task = g_task_new (resolver, cancellable, callback, user_data);
-      g_task_set_source_tag (task, g_resolver_lookup_by_name_async);
+      g_task_set_source_tag (task, lookup_by_name_async_real);
       if (addrs)
         g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
       else
@@ -475,19 +523,138 @@ g_resolver_lookup_by_name_async (GResolver           *resolver,
       g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
                            _("Invalid hostname"));
       task = g_task_new (resolver, cancellable, callback, user_data);
-      g_task_set_source_tag (task, g_resolver_lookup_by_name_async);
+      g_task_set_source_tag (task, lookup_by_name_async_real);
       g_task_return_error (task, error);
       g_object_unref (task);
       return;
     }
 
   g_resolver_maybe_reload (resolver);
-  G_RESOLVER_GET_CLASS (resolver)->
-    lookup_by_name_async (resolver, hostname, cancellable, callback, user_data);
+
+  if (with_flags)
+    {
+      if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_async == NULL)
+        {
+          GTask *task;
+
+          g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               _("lookup_by_name_with_flags_async not implemented"));
+          task = g_task_new (resolver, cancellable, callback, user_data);
+          g_task_set_source_tag (task, lookup_by_name_async_real);
+          g_task_return_error (task, error);
+          g_object_unref (task);
+        }
+      else
+        G_RESOLVER_GET_CLASS (resolver)->
+          lookup_by_name_with_flags_async (resolver, hostname, flags, cancellable, callback, user_data);
+    }
+  else
+    G_RESOLVER_GET_CLASS (resolver)->
+      lookup_by_name_async (resolver, hostname, cancellable, callback, user_data);
 
   g_free (ascii_hostname);
 }
 
+static GList *
+lookup_by_name_finish_real (GResolver     *resolver,
+                            GAsyncResult  *result,
+                            GError       **error,
+                            gboolean       with_flags)
+{
+  GList *addrs;
+
+  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
+
+  if (g_async_result_legacy_propagate_error (result, error))
+    return NULL;
+  else if (g_async_result_is_tagged (result, lookup_by_name_async_real))
+    {
+      /* Handle the stringified-IP-addr case */
+      return g_task_propagate_pointer (G_TASK (result), error);
+    }
+
+  if (with_flags)
+    {
+      if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_finish == NULL)
+        {
+          g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               _("lookup_by_name_with_flags_finish not implemented"));
+          return NULL;
+        }
+      addrs = G_RESOLVER_GET_CLASS (resolver)->
+        lookup_by_name_with_flags_finish (resolver, result, error);
+    }
+  else
+    addrs = G_RESOLVER_GET_CLASS (resolver)->
+      lookup_by_name_finish (resolver, result, error);
+
+  remove_duplicates (addrs);
+
+  return addrs;
+}
+
+/**
+ * g_resolver_lookup_by_name_with_flags_async:
+ * @resolver: a #GResolver
+ * @hostname: the hostname to look up the address of
+ * @flags: extra #GResolverNameLookupFlags for the lookup
+ * @cancellable: (nullable): a #GCancellable, or %NULL
+ * @callback: (scope async): callback to call after resolution completes
+ * @user_data: (closure): data for @callback
+ *
+ * Begins asynchronously resolving @hostname to determine its
+ * associated IP address(es), and eventually calls @callback, which
+ * must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
+ * See g_resolver_lookup_by_name() for more details.
+ *
+ * Since: 2.60
+ */
+void
+g_resolver_lookup_by_name_with_flags_async (GResolver               *resolver,
+                                            const gchar             *hostname,
+                                            GResolverNameLookupFlags flags,
+                                            GCancellable            *cancellable,
+                                            GAsyncReadyCallback      callback,
+                                            gpointer                 user_data)
+{
+  lookup_by_name_async_real (resolver,
+                             hostname,
+                             flags, TRUE,
+                             cancellable,
+                             callback,
+                             user_data);
+}
+
+/**
+ * g_resolver_lookup_by_name_async:
+ * @resolver: a #GResolver
+ * @hostname: the hostname to look up the address of
+ * @cancellable: (nullable): a #GCancellable, or %NULL
+ * @callback: (scope async): callback to call after resolution completes
+ * @user_data: (closure): data for @callback
+ *
+ * Begins asynchronously resolving @hostname to determine its
+ * associated IP address(es), and eventually calls @callback, which
+ * must call g_resolver_lookup_by_name_finish() to get the result.
+ * See g_resolver_lookup_by_name() for more details.
+ *
+ * Since: 2.22
+ */
+void
+g_resolver_lookup_by_name_async (GResolver           *resolver,
+                                 const gchar         *hostname,
+                                 GCancellable        *cancellable,
+                                 GAsyncReadyCallback  callback,
+                                 gpointer             user_data)
+{
+  lookup_by_name_async_real (resolver,
+                             hostname,
+                             0, FALSE,
+                             cancellable,
+                             callback,
+                             user_data);
+}
+
 /**
  * g_resolver_lookup_by_name_finish:
  * @resolver: a #GResolver
@@ -512,24 +679,40 @@ g_resolver_lookup_by_name_finish (GResolver     *resolver,
                                   GAsyncResult  *result,
                                   GError       **error)
 {
-  GList *addrs;
-
-  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
-
-  if (g_async_result_legacy_propagate_error (result, error))
-    return NULL;
-  else if (g_async_result_is_tagged (result, g_resolver_lookup_by_name_async))
-    {
-      /* Handle the stringified-IP-addr case */
-      return g_task_propagate_pointer (G_TASK (result), error);
-    }
-
-  addrs = G_RESOLVER_GET_CLASS (resolver)->
-    lookup_by_name_finish (resolver, result, error);
-
-  remove_duplicates (addrs);
+  return lookup_by_name_finish_real (resolver,
+                                     result,
+                                     error,
+                                     FALSE);
+}
 
-  return addrs;
+/**
+ * g_resolver_lookup_by_name_with_flags_finish:
+ * @resolver: a #GResolver
+ * @result: the result passed to your #GAsyncReadyCallback
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the result of a call to
+ * g_resolver_lookup_by_name_with_flags_async().
+ *
+ * If the DNS resolution failed, @error (if non-%NULL) will be set to
+ * a value from #GResolverError. If the operation was cancelled,
+ * @error will be set to %G_IO_ERROR_CANCELLED.
+ *
+ * Returns: (element-type GInetAddress) (transfer full): a #GList
+ * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
+ * for more details.
+ *
+ * Since: 2.60
+ */
+GList *
+g_resolver_lookup_by_name_with_flags_finish (GResolver     *resolver,
+                                             GAsyncResult  *result,
+                                             GError       **error)
+{
+  return lookup_by_name_finish_real (resolver,
+                                     result,
+                                     error,
+                                     TRUE);
 }
 
 /**
diff --git a/gio/gresolver.h b/gio/gresolver.h
index a39e8f7fd..335446bfd 100644
--- a/gio/gresolver.h
+++ b/gio/gresolver.h
@@ -43,6 +43,20 @@ struct _GResolver {
   GResolverPrivate *priv;
 };
 
+/**
+ * GResolverNameLookupFlags:
+ * @G_RESOLVER_LOOKUP_NAME_FLAGS_DEFAULT: lookup behavior is unchanged
+ * @G_RESOLVER_LOOKUP_NAME_FLAGS_IPV4: only resolve ipv4 addresses, cannot combine with 
#G_RESOLVER_LOOKUP_NAME_FLAGS_IPV6
+ * @G_RESOLVER_LOOKUP_NAME_FLAGS_IPV6: only resolve ipv6 addresses, cannot combine with 
#G_RESOLVER_LOOKUP_NAME_FLAGS_IPV4
+ *
+ * Flags to modify lookup behavior.
+ */
+typedef enum {
+  G_RESOLVER_LOOKUP_NAME_FLAGS_DEFAULT = 0,
+  G_RESOLVER_LOOKUP_NAME_FLAGS_IPV4 = 1 << 0,
+  G_RESOLVER_LOOKUP_NAME_FLAGS_IPV6 = 1 << 1,
+} GResolverNameLookupFlags;
+
 struct _GResolverClass {
   GObjectClass parent_class;
 
@@ -105,11 +119,20 @@ struct _GResolverClass {
   GList * ( *lookup_records_finish)    (GResolver            *resolver,
                                         GAsyncResult         *result,
                                         GError              **error);
-
-  /* Padding for future expansion */
-  void (*_g_reserved4) (void);
-  void (*_g_reserved5) (void);
-  void (*_g_reserved6) (void);
+  void    ( *lookup_by_name_with_flags_async)  (GResolver               *resolver,
+                                                const gchar             *hostname,
+                                                GResolverNameLookupFlags flags,
+                                                GCancellable            *cancellable,
+                                                GAsyncReadyCallback      callback,
+                                                gpointer                 user_data);
+  GList * ( *lookup_by_name_with_flags_finish) (GResolver               *resolver,
+                                                GAsyncResult            *result,
+                                                GError                 **error);
+  GList * ( *lookup_by_name_with_flags)        (GResolver               *resolver,
+                                                const gchar             *hostname,
+                                                GResolverNameLookupFlags flags,
+                                                GCancellable            *cancellable,
+                                                GError                 **error);
 
 };
 
@@ -135,7 +158,23 @@ GLIB_AVAILABLE_IN_ALL
 GList     *g_resolver_lookup_by_name_finish     (GResolver            *resolver,
                                                 GAsyncResult         *result,
                                                 GError              **error);
-
+GLIB_AVAILABLE_IN_2_60
+void       g_resolver_lookup_by_name_with_flags_async  (GResolver               *resolver,
+                                                        const gchar             *hostname,
+                                                        GResolverNameLookupFlags flags,
+                                                        GCancellable            *cancellable,
+                                                        GAsyncReadyCallback      callback,
+                                                        gpointer                 user_data);
+GLIB_AVAILABLE_IN_2_60
+GList     *g_resolver_lookup_by_name_with_flags_finish (GResolver               *resolver,
+                                                        GAsyncResult            *result,
+                                                        GError                 **error);
+GLIB_AVAILABLE_IN_2_60
+GList     *g_resolver_lookup_by_name_with_flags        (GResolver            *resolver,
+                                                        const gchar          *hostname,
+                                                        GResolverNameLookupFlags flags,
+                                                        GCancellable         *cancellable,
+                                                        GError              **error);
 GLIB_AVAILABLE_IN_ALL
 void       g_resolver_free_addresses            (GList                *addresses);
 
diff --git a/gio/gthreadedresolver.c b/gio/gthreadedresolver.c
index 9e110cd0b..5ec093fbf 100644
--- a/gio/gthreadedresolver.c
+++ b/gio/gthreadedresolver.c
@@ -63,7 +63,43 @@ g_resolver_error_from_addrinfo_error (gint err)
     }
 }
 
-static struct addrinfo addrinfo_hints;
+#ifndef AI_ADDRCONFIG
+#define G_ADDRCONFIG 0
+#else
+#define G_ADDRCONFIG AI_ADDRCONFIG
+#endif
+
+/* socktype and protocol don't actually matter, they just get copied into the
+ * returned addrinfo structures (and then we ignore them). But if
+ * we leave them unset, we'll get back duplicate answers.
+ */
+#define ADDRINFO_INIT { \
+  .ai_flags = G_ADDRCONFIG, \
+  .ai_socktype = SOCK_STREAM, \
+  .ai_protocol = IPPROTO_TCP, \
+}
+
+typedef struct {
+  char *hostname;
+  int address_family;
+} LookupData;
+
+static LookupData *
+lookup_data_new (const char *hostname,
+                 int         address_family)
+{
+  LookupData *data = g_new (LookupData, 1);
+  data->hostname = g_strdup (hostname);
+  data->address_family = address_family;
+  return data;
+}
+
+static void
+lookup_data_free (LookupData *data)
+{
+  g_free (data->hostname);
+  g_free (data);
+}
 
 static void
 do_lookup_by_name (GTask         *task,
@@ -71,11 +107,14 @@ do_lookup_by_name (GTask         *task,
                    gpointer       task_data,
                    GCancellable  *cancellable)
 {
-  const char *hostname = task_data;
+  LookupData *lookup_data = task_data;
+  const char *hostname = lookup_data->hostname;
   struct addrinfo *res = NULL;
   GList *addresses;
   gint retval;
+  struct addrinfo addrinfo_hints = ADDRINFO_INIT;
 
+  addrinfo_hints.ai_family = lookup_data->address_family;
   retval = getaddrinfo (hostname, NULL, &addrinfo_hints, &res);
 
   if (retval == 0)
@@ -139,10 +178,58 @@ lookup_by_name (GResolver     *resolver,
 {
   GTask *task;
   GList *addresses;
+  LookupData data = {
+    .hostname = (char*)hostname,
+    .address_family = AF_UNSPEC,
+  };
 
   task = g_task_new (resolver, cancellable, NULL, NULL);
   g_task_set_source_tag (task, lookup_by_name);
-  g_task_set_task_data (task, g_strdup (hostname), g_free);
+  g_task_set_task_data (task, &data, NULL);
+  g_task_set_return_on_cancel (task, TRUE);
+  g_task_run_in_thread_sync (task, do_lookup_by_name);
+  addresses = g_task_propagate_pointer (task, error);
+  g_object_unref (task);
+
+  return addresses;
+}
+
+static int
+flags_to_family (GResolverNameLookupFlags flags)
+{
+  int address_family = AF_UNSPEC;
+
+  if (flags & G_RESOLVER_LOOKUP_NAME_FLAGS_IPV4)
+    address_family = AF_INET;
+
+  if (flags & G_RESOLVER_LOOKUP_NAME_FLAGS_IPV6)
+    {
+      address_family = AF_INET6;
+      /* You can only filter by one family at a time */
+      if (flags & G_RESOLVER_LOOKUP_NAME_FLAGS_IPV4)
+        g_warning ("G_RESOLVER_LOOKUP_NAME_FLAGS_IPV4 ignored because G_RESOLVER_LOOKUP_NAME_FLAGS_IPV6 
set");
+    }
+
+  return address_family;
+}
+
+static GList *
+lookup_by_name_with_flags (GResolver               *resolver,
+                           const gchar             *hostname,
+                           GResolverNameLookupFlags flags,
+                           GCancellable            *cancellable,
+                           GError                 **error)
+{
+  GTask *task;
+  GList *addresses;
+  LookupData data = {
+    .hostname = (char*)hostname,
+    .address_family = flags_to_family (flags),
+  };
+
+  task = g_task_new (resolver, cancellable, NULL, NULL);
+  g_task_set_source_tag (task, lookup_by_name_with_flags);
+  g_task_set_task_data (task, &data, NULL);
   g_task_set_return_on_cancel (task, TRUE);
   g_task_run_in_thread_sync (task, do_lookup_by_name);
   addresses = g_task_propagate_pointer (task, error);
@@ -152,22 +239,40 @@ lookup_by_name (GResolver     *resolver,
 }
 
 static void
-lookup_by_name_async (GResolver           *resolver,
-                      const gchar         *hostname,
-                      GCancellable        *cancellable,
-                      GAsyncReadyCallback  callback,
-                      gpointer             user_data)
+lookup_by_name_with_flags_async (GResolver                *resolver,
+                                 const gchar              *hostname,
+                                 GResolverNameLookupFlags  flags,
+                                 GCancellable             *cancellable,
+                                 GAsyncReadyCallback       callback,
+                                 gpointer                  user_data)
 {
   GTask *task;
+  LookupData *data;
 
+  data = lookup_data_new (hostname, flags_to_family (flags));
   task = g_task_new (resolver, cancellable, callback, user_data);
-  g_task_set_source_tag (task, lookup_by_name_async);
-  g_task_set_task_data (task, g_strdup (hostname), g_free);
+  g_task_set_source_tag (task, lookup_by_name_with_flags_async);
+  g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free);
   g_task_set_return_on_cancel (task, TRUE);
   g_task_run_in_thread (task, do_lookup_by_name);
   g_object_unref (task);
 }
 
+static void
+lookup_by_name_async (GResolver           *resolver,
+                      const gchar         *hostname,
+                      GCancellable        *cancellable,
+                      GAsyncReadyCallback  callback,
+                      gpointer             user_data)
+{
+  lookup_by_name_with_flags_async (resolver,
+                                   hostname,
+                                   G_RESOLVER_LOOKUP_NAME_FLAGS_DEFAULT,
+                                   cancellable,
+                                   callback,
+                                   user_data);
+}
+
 static GList *
 lookup_by_name_finish (GResolver     *resolver,
                        GAsyncResult  *result,
@@ -178,6 +283,15 @@ lookup_by_name_finish (GResolver     *resolver,
   return g_task_propagate_pointer (G_TASK (result), error);
 }
 
+static GList *
+lookup_by_name_with_flags_finish (GResolver     *resolver,
+                                  GAsyncResult  *result,
+                                  GError       **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, resolver), NULL);
+
+  return g_task_propagate_pointer (G_TASK (result), error);
+}
 
 static void
 do_lookup_by_address (GTask         *task,
@@ -970,24 +1084,16 @@ g_threaded_resolver_class_init (GThreadedResolverClass *threaded_class)
 {
   GResolverClass *resolver_class = G_RESOLVER_CLASS (threaded_class);
 
-  resolver_class->lookup_by_name           = lookup_by_name;
-  resolver_class->lookup_by_name_async     = lookup_by_name_async;
-  resolver_class->lookup_by_name_finish    = lookup_by_name_finish;
-  resolver_class->lookup_by_address        = lookup_by_address;
-  resolver_class->lookup_by_address_async  = lookup_by_address_async;
-  resolver_class->lookup_by_address_finish = lookup_by_address_finish;
-  resolver_class->lookup_records           = lookup_records;
-  resolver_class->lookup_records_async     = lookup_records_async;
-  resolver_class->lookup_records_finish    = lookup_records_finish;
-
-  /* Initialize addrinfo_hints */
-#ifdef AI_ADDRCONFIG
-  addrinfo_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-  /* These two don't actually matter, they just get copied into the
-   * returned addrinfo structures (and then we ignore them). But if
-   * we leave them unset, we'll get back duplicate answers.
-   */
-  addrinfo_hints.ai_socktype = SOCK_STREAM;
-  addrinfo_hints.ai_protocol = IPPROTO_TCP;
+  resolver_class->lookup_by_name                   = lookup_by_name;
+  resolver_class->lookup_by_name_async             = lookup_by_name_async;
+  resolver_class->lookup_by_name_finish            = lookup_by_name_finish;
+  resolver_class->lookup_by_name_with_flags        = lookup_by_name_with_flags;
+  resolver_class->lookup_by_name_with_flags_async  = lookup_by_name_with_flags_async;
+  resolver_class->lookup_by_name_with_flags_finish = lookup_by_name_with_flags_finish;
+  resolver_class->lookup_by_address                = lookup_by_address;
+  resolver_class->lookup_by_address_async          = lookup_by_address_async;
+  resolver_class->lookup_by_address_finish         = lookup_by_address_finish;
+  resolver_class->lookup_records                   = lookup_records;
+  resolver_class->lookup_records_async             = lookup_records_async;
+  resolver_class->lookup_records_finish            = lookup_records_finish;
 }


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