[glib/wip/tingping/happy-eyeballs: 1/3] gresolver: Add g_resolver_lookup_by_name_with_flags{_async, _finish, }
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/tingping/happy-eyeballs: 1/3] gresolver: Add g_resolver_lookup_by_name_with_flags{_async, _finish, }
- Date: Fri, 26 Oct 2018 14:25:56 +0000 (UTC)
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]