1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
3 /* GIO - GLib Input, Output and Streaming Library
5 * Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2018 Igalia S.L.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General
19 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #include "gresolver.h"
27 #include "gnetworkingprivate.h"
28 #include "gasyncresult.h"
29 #include "ginetaddress.h"
31 #include "gsrvtarget.h"
32 #include "gthreadedresolver.h"
34 #include "gcancellable.h"
45 * @short_description: Asynchronous and cancellable DNS resolver
48 * #GResolver provides cancellable synchronous and asynchronous DNS
49 * resolution, for hostnames (g_resolver_lookup_by_address(),
50 * g_resolver_lookup_by_name() and their async variants) and SRV
51 * (service) records (g_resolver_lookup_service()).
53 * #GNetworkAddress and #GNetworkService provide wrappers around
54 * #GResolver functionality that also implement #GSocketConnectable,
55 * making it easy to connect to a remote host/service.
63 static guint signals[LAST_SIGNAL] = { 0 };
65 struct _GResolverPrivate {
68 time_t resolv_conf_timestamp; /* protected by @mutex */
77 * The object that handles DNS resolution. Use g_resolver_get_default()
78 * to get the default resolver.
80 * This is an abstract type; subclasses of it implement different resolvers for
81 * different platforms and situations.
83 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GResolver, g_resolver, G_TYPE_OBJECT,
84 G_ADD_PRIVATE (GResolver)
85 g_networking_init ();)
88 srv_records_to_targets (GList *records)
90 const gchar *hostname;
91 guint16 port, priority, weight;
95 for (l = records; l != NULL; l = g_list_next (l))
97 g_variant_get (l->data, "(qqq&s)", &priority, &weight, &port, &hostname);
98 target = g_srv_target_new (hostname, port, priority, weight);
99 g_variant_unref (l->data);
103 return g_srv_target_list_sort (records);
107 g_resolver_real_lookup_service (GResolver *resolver,
109 GCancellable *cancellable,
114 records = G_RESOLVER_GET_CLASS (resolver)->lookup_records (resolver,
116 G_RESOLVER_RECORD_SRV,
120 return srv_records_to_targets (records);
124 g_resolver_real_lookup_service_async (GResolver *resolver,
126 GCancellable *cancellable,
127 GAsyncReadyCallback callback,
130 G_RESOLVER_GET_CLASS (resolver)->lookup_records_async (resolver,
132 G_RESOLVER_RECORD_SRV,
139 g_resolver_real_lookup_service_finish (GResolver *resolver,
140 GAsyncResult *result,
145 records = G_RESOLVER_GET_CLASS (resolver)->lookup_records_finish (resolver,
149 return srv_records_to_targets (records);
153 g_resolver_finalize (GObject *object)
156 GResolver *resolver = G_RESOLVER (object);
158 g_mutex_clear (&resolver->priv->mutex);
161 G_OBJECT_CLASS (g_resolver_parent_class)->finalize (object);
165 g_resolver_class_init (GResolverClass *resolver_class)
167 GObjectClass *object_class = G_OBJECT_CLASS (resolver_class);
169 object_class->finalize = g_resolver_finalize;
171 /* Automatically pass these over to the lookup_records methods */
172 resolver_class->lookup_service = g_resolver_real_lookup_service;
173 resolver_class->lookup_service_async = g_resolver_real_lookup_service_async;
174 resolver_class->lookup_service_finish = g_resolver_real_lookup_service_finish;
178 * @resolver: a #GResolver
180 * Emitted when the resolver notices that the system resolver
181 * configuration has changed.
184 g_signal_new (I_("reload"),
187 G_STRUCT_OFFSET (GResolverClass, reload),
194 g_resolver_init (GResolver *resolver)
200 resolver->priv = g_resolver_get_instance_private (resolver);
203 if (stat (_PATH_RESCONF, &st) == 0)
204 resolver->priv->resolv_conf_timestamp = st.st_mtime;
206 g_mutex_init (&resolver->priv->mutex);
210 G_LOCK_DEFINE_STATIC (default_resolver);
211 static GResolver *default_resolver;
214 * g_resolver_get_default:
216 * Gets the default #GResolver. You should unref it when you are done
217 * with it. #GResolver may use its reference count as a hint about how
218 * many threads it should allocate for concurrent DNS resolutions.
220 * Returns: (transfer full): the default #GResolver.
225 g_resolver_get_default (void)
229 G_LOCK (default_resolver);
230 if (!default_resolver)
231 default_resolver = g_object_new (G_TYPE_THREADED_RESOLVER, NULL);
232 ret = g_object_ref (default_resolver);
233 G_UNLOCK (default_resolver);
239 * g_resolver_set_default:
240 * @resolver: the new default #GResolver
242 * Sets @resolver to be the application's default resolver (reffing
243 * @resolver, and unreffing the previous default resolver, if any).
244 * Future calls to g_resolver_get_default() will return this resolver.
246 * This can be used if an application wants to perform any sort of DNS
247 * caching or "pinning"; it can implement its own #GResolver that
248 * calls the original default resolver for DNS operations, and
249 * implements its own cache policies on top of that, and then set
250 * itself as the default resolver for all later code to use.
255 g_resolver_set_default (GResolver *resolver)
257 G_LOCK (default_resolver);
258 if (default_resolver)
259 g_object_unref (default_resolver);
260 default_resolver = g_object_ref (resolver);
261 G_UNLOCK (default_resolver);
265 maybe_emit_reload (GResolver *resolver)
270 if (stat (_PATH_RESCONF, &st) == 0)
272 g_mutex_lock (&resolver->priv->mutex);
273 if (st.st_mtime != resolver->priv->resolv_conf_timestamp)
275 resolver->priv->resolv_conf_timestamp = st.st_mtime;
276 g_mutex_unlock (&resolver->priv->mutex);
277 g_signal_emit (resolver, signals[RELOAD], 0);
280 g_mutex_unlock (&resolver->priv->mutex);
285 /* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */
287 remove_duplicates (GList *addrs)
293 /* TODO: if this is too slow (it's O(n^2) but n is typically really
294 * small), we can do something more clever but note that we must not
295 * change the order of elements...
297 for (l = addrs; l != NULL; l = l->next)
299 GInetAddress *address = G_INET_ADDRESS (l->data);
300 for (ll = l->next; ll != NULL; ll = lll)
302 GInetAddress *other_address = G_INET_ADDRESS (ll->data);
304 if (g_inet_address_equal (address, other_address))
306 g_object_unref (other_address);
307 /* we never return the first element */
308 g_warn_if_fail (g_list_delete_link (addrs, ll) == addrs);
315 hostname_is_localhost (const char *hostname)
317 size_t len = strlen (hostname);
320 /* Match "localhost", "localhost.", "*.localhost" and "*.localhost." */
321 if (len < strlen ("localhost"))
324 if (hostname[len - 1] == '.')
327 /* Scan backwards in @hostname to find the right-most dot (excluding the final dot, if it exists, as it was chopped off above).
328 * We can’t use strrchr() because because we need to operate with string lengths.
329 * End with @p pointing to the character after the right-most dot. */
330 p = hostname + len - 1;
331 while (p >= hostname)
338 else if (p == hostname)
345 return g_ascii_strncasecmp (p, "localhost", MAX (len, strlen ("localhost"))) == 0;
348 /* Note that this does not follow the "FALSE means @error is set"
349 * convention. The return value tells the caller whether it should
350 * return @addrs and @error to the caller right away, or if it should
351 * continue and trying to resolve the name as a hostname.
354 handle_ip_address_or_localhost (const char *hostname,
356 GResolverNameLookupFlags flags,
362 struct in_addr ip4addr;
365 addr = g_inet_address_new_from_string (hostname);
368 *addrs = g_list_append (NULL, addr);
376 /* Reject IPv6 addresses that have brackets ('[' or ']') and/or port numbers,
377 * as no valid addresses should contain these at this point.
378 * Non-standard IPv4 addresses would be rejected during the call to
379 * getaddrinfo() later.
381 if (strrchr (hostname, '[') != NULL ||
382 strrchr (hostname, ']') != NULL)
385 /* Reject non-standard IPv4 numbers-and-dots addresses.
386 * g_inet_address_new_from_string() will have accepted any "real" IP
387 * address, so if inet_aton() succeeds, then it's an address we want
390 if (inet_aton (hostname, &ip4addr))
394 gchar *error_message = g_win32_error_message (WSAHOST_NOT_FOUND);
396 gchar *error_message = g_locale_to_utf8 (gai_strerror (EAI_NONAME), -1, NULL, NULL, NULL);
397 if (error_message == NULL)
398 error_message = g_strdup ("[Invalid UTF-8]");
400 g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
401 _("Error resolving “%s”: %s"),
402 hostname, error_message);
403 g_free (error_message);
408 /* Always resolve localhost to a loopback address so it can be reliably considered secure.
409 This behavior is being adopted by browsers:
410 - https://w3c.github.io/webappsec-secure-contexts/
411 - https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/RC9dSw-O3fE/E3_0XaT0BAAJ
412 - https://chromium.googlesource.com/chromium/src.git/+/8da2a80724a9b896890602ff77ef2216cb951399
413 - https://bugs.webkit.org/show_bug.cgi?id=171934
414 - https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-06
416 if (hostname_is_localhost (hostname))
418 if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY)
419 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6));
420 if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY)
421 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4));
424 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6));
425 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4));
434 lookup_by_name_real (GResolver *resolver,
435 const gchar *hostname,
436 GResolverNameLookupFlags flags,
437 GCancellable *cancellable,
441 gchar *ascii_hostname = NULL;
443 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
444 g_return_val_if_fail (hostname != NULL, NULL);
445 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
446 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
448 /* Check if @hostname is just an IP address */
449 if (handle_ip_address_or_localhost (hostname, &addrs, flags, error))
452 if (g_hostname_is_non_ascii (hostname))
453 hostname = ascii_hostname = g_hostname_to_ascii (hostname);
457 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
458 _("Invalid hostname"));
462 maybe_emit_reload (resolver);
464 if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
466 if (!G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags)
468 g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
469 /* Translators: The placeholder is for a function name. */
470 _("%s not implemented"), "lookup_by_name_with_flags");
471 g_free (ascii_hostname);
474 addrs = G_RESOLVER_GET_CLASS (resolver)->
475 lookup_by_name_with_flags (resolver, hostname, flags, cancellable, error);
478 addrs = G_RESOLVER_GET_CLASS (resolver)->
479 lookup_by_name (resolver, hostname, cancellable, error);
481 remove_duplicates (addrs);
483 g_free (ascii_hostname);
488 * g_resolver_lookup_by_name:
489 * @resolver: a #GResolver
490 * @hostname: the hostname to look up
491 * @cancellable: (nullable): a #GCancellable, or %NULL
492 * @error: return location for a #GError, or %NULL
494 * Synchronously resolves @hostname to determine its associated IP
495 * address(es). @hostname may be an ASCII-only or UTF-8 hostname, or
496 * the textual form of an IP address (in which case this just becomes
497 * a wrapper around g_inet_address_new_from_string()).
499 * On success, g_resolver_lookup_by_name() will return a non-empty #GList of
500 * #GInetAddress, sorted in order of preference and guaranteed to not
501 * contain duplicates. That is, if using the result to connect to
502 * @hostname, you should attempt to connect to the first address
503 * first, then the second if the first fails, etc. If you are using
504 * the result to listen on a socket, it is appropriate to add each
505 * result using e.g. g_socket_listener_add_address().
507 * If the DNS resolution fails, @error (if non-%NULL) will be set to a
508 * value from #GResolverError and %NULL will be returned.
510 * If @cancellable is non-%NULL, it can be used to cancel the
511 * operation, in which case @error (if non-%NULL) will be set to
512 * %G_IO_ERROR_CANCELLED.
514 * If you are planning to connect to a socket on the resolved IP
515 * address, it may be easier to create a #GNetworkAddress and use its
516 * #GSocketConnectable interface.
518 * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
519 * of #GInetAddress, or %NULL on error. You
520 * must unref each of the addresses and free the list when you are
521 * done with it. (You can use g_resolver_free_addresses() to do this.)
526 g_resolver_lookup_by_name (GResolver *resolver,
527 const gchar *hostname,
528 GCancellable *cancellable,
531 return lookup_by_name_real (resolver,
533 G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT,
539 * g_resolver_lookup_by_name_with_flags:
540 * @resolver: a #GResolver
541 * @hostname: the hostname to look up
542 * @flags: extra #GResolverNameLookupFlags for the lookup
543 * @cancellable: (nullable): a #GCancellable, or %NULL
544 * @error: (nullable): return location for a #GError, or %NULL
546 * This differs from g_resolver_lookup_by_name() in that you can modify
547 * the lookup behavior with @flags. For example this can be used to limit
548 * results with %G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY.
550 * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
551 * of #GInetAddress, or %NULL on error. You
552 * must unref each of the addresses and free the list when you are
553 * done with it. (You can use g_resolver_free_addresses() to do this.)
558 g_resolver_lookup_by_name_with_flags (GResolver *resolver,
559 const gchar *hostname,
560 GResolverNameLookupFlags flags,
561 GCancellable *cancellable,
564 return lookup_by_name_real (resolver,
572 lookup_by_name_async_real (GResolver *resolver,
573 const gchar *hostname,
574 GResolverNameLookupFlags flags,
575 GCancellable *cancellable,
576 GAsyncReadyCallback callback,
579 gchar *ascii_hostname = NULL;
581 GError *error = NULL;
583 g_return_if_fail (G_IS_RESOLVER (resolver));
584 g_return_if_fail (hostname != NULL);
585 g_return_if_fail (!(flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY && flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY));
587 /* Check if @hostname is just an IP address */
588 if (handle_ip_address_or_localhost (hostname, &addrs, flags, &error))
592 task = g_task_new (resolver, cancellable, callback, user_data);
593 g_task_set_source_tag (task, lookup_by_name_async_real);
594 g_task_set_name (task, "[gio] resolver lookup");
596 g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
598 g_task_return_error (task, error);
599 g_object_unref (task);
603 if (g_hostname_is_non_ascii (hostname))
604 hostname = ascii_hostname = g_hostname_to_ascii (hostname);
610 g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
611 _("Invalid hostname"));
612 task = g_task_new (resolver, cancellable, callback, user_data);
613 g_task_set_source_tag (task, lookup_by_name_async_real);
614 g_task_set_name (task, "[gio] resolver lookup");
615 g_task_return_error (task, error);
616 g_object_unref (task);
620 maybe_emit_reload (resolver);
622 if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
624 if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_async == NULL)
628 g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
629 /* Translators: The placeholder is for a function name. */
630 _("%s not implemented"), "lookup_by_name_with_flags_async");
631 task = g_task_new (resolver, cancellable, callback, user_data);
632 g_task_set_source_tag (task, lookup_by_name_async_real);
633 g_task_set_name (task, "[gio] resolver lookup");
634 g_task_return_error (task, error);
635 g_object_unref (task);
638 G_RESOLVER_GET_CLASS (resolver)->
639 lookup_by_name_with_flags_async (resolver, hostname, flags, cancellable, callback, user_data);
642 G_RESOLVER_GET_CLASS (resolver)->
643 lookup_by_name_async (resolver, hostname, cancellable, callback, user_data);
645 g_free (ascii_hostname);
649 lookup_by_name_finish_real (GResolver *resolver,
650 GAsyncResult *result,
656 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
657 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
658 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
660 if (g_async_result_legacy_propagate_error (result, error))
662 else if (g_async_result_is_tagged (result, lookup_by_name_async_real))
664 /* Handle the stringified-IP-addr case */
665 return g_task_propagate_pointer (G_TASK (result), error);
670 g_assert (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_finish != NULL);
671 addrs = G_RESOLVER_GET_CLASS (resolver)->
672 lookup_by_name_with_flags_finish (resolver, result, error);
675 addrs = G_RESOLVER_GET_CLASS (resolver)->
676 lookup_by_name_finish (resolver, result, error);
678 remove_duplicates (addrs);
684 * g_resolver_lookup_by_name_with_flags_async:
685 * @resolver: a #GResolver
686 * @hostname: the hostname to look up the address of
687 * @flags: extra #GResolverNameLookupFlags for the lookup
688 * @cancellable: (nullable): a #GCancellable, or %NULL
689 * @callback: (scope async): callback to call after resolution completes
690 * @user_data: (closure): data for @callback
692 * Begins asynchronously resolving @hostname to determine its
693 * associated IP address(es), and eventually calls @callback, which
694 * must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
695 * See g_resolver_lookup_by_name() for more details.
700 g_resolver_lookup_by_name_with_flags_async (GResolver *resolver,
701 const gchar *hostname,
702 GResolverNameLookupFlags flags,
703 GCancellable *cancellable,
704 GAsyncReadyCallback callback,
707 lookup_by_name_async_real (resolver,
716 * g_resolver_lookup_by_name_async:
717 * @resolver: a #GResolver
718 * @hostname: the hostname to look up the address of
719 * @cancellable: (nullable): a #GCancellable, or %NULL
720 * @callback: (scope async): callback to call after resolution completes
721 * @user_data: (closure): data for @callback
723 * Begins asynchronously resolving @hostname to determine its
724 * associated IP address(es), and eventually calls @callback, which
725 * must call g_resolver_lookup_by_name_finish() to get the result.
726 * See g_resolver_lookup_by_name() for more details.
731 g_resolver_lookup_by_name_async (GResolver *resolver,
732 const gchar *hostname,
733 GCancellable *cancellable,
734 GAsyncReadyCallback callback,
737 lookup_by_name_async_real (resolver,
746 * g_resolver_lookup_by_name_finish:
747 * @resolver: a #GResolver
748 * @result: the result passed to your #GAsyncReadyCallback
749 * @error: return location for a #GError, or %NULL
751 * Retrieves the result of a call to
752 * g_resolver_lookup_by_name_async().
754 * If the DNS resolution failed, @error (if non-%NULL) will be set to
755 * a value from #GResolverError. If the operation was cancelled,
756 * @error will be set to %G_IO_ERROR_CANCELLED.
758 * Returns: (element-type GInetAddress) (transfer full): a #GList
759 * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
765 g_resolver_lookup_by_name_finish (GResolver *resolver,
766 GAsyncResult *result,
769 return lookup_by_name_finish_real (resolver,
776 * g_resolver_lookup_by_name_with_flags_finish:
777 * @resolver: a #GResolver
778 * @result: the result passed to your #GAsyncReadyCallback
779 * @error: return location for a #GError, or %NULL
781 * Retrieves the result of a call to
782 * g_resolver_lookup_by_name_with_flags_async().
784 * If the DNS resolution failed, @error (if non-%NULL) will be set to
785 * a value from #GResolverError. If the operation was cancelled,
786 * @error will be set to %G_IO_ERROR_CANCELLED.
788 * Returns: (element-type GInetAddress) (transfer full): a #GList
789 * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
795 g_resolver_lookup_by_name_with_flags_finish (GResolver *resolver,
796 GAsyncResult *result,
799 return lookup_by_name_finish_real (resolver,
806 * g_resolver_free_addresses: (skip)
807 * @addresses: a #GList of #GInetAddress
809 * Frees @addresses (which should be the return value from
810 * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_finish()).
811 * (This is a convenience method; you can also simply free the results
817 g_resolver_free_addresses (GList *addresses)
821 for (a = addresses; a; a = a->next)
822 g_object_unref (a->data);
823 g_list_free (addresses);
827 * g_resolver_lookup_by_address:
828 * @resolver: a #GResolver
829 * @address: the address to reverse-resolve
830 * @cancellable: (nullable): a #GCancellable, or %NULL
831 * @error: return location for a #GError, or %NULL
833 * Synchronously reverse-resolves @address to determine its
834 * associated hostname.
836 * If the DNS resolution fails, @error (if non-%NULL) will be set to
837 * a value from #GResolverError.
839 * If @cancellable is non-%NULL, it can be used to cancel the
840 * operation, in which case @error (if non-%NULL) will be set to
841 * %G_IO_ERROR_CANCELLED.
843 * Returns: a hostname (either ASCII-only, or in ASCII-encoded
844 * form), or %NULL on error.
849 g_resolver_lookup_by_address (GResolver *resolver,
850 GInetAddress *address,
851 GCancellable *cancellable,
854 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
855 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
857 maybe_emit_reload (resolver);
858 return G_RESOLVER_GET_CLASS (resolver)->
859 lookup_by_address (resolver, address, cancellable, error);
863 * g_resolver_lookup_by_address_async:
864 * @resolver: a #GResolver
865 * @address: the address to reverse-resolve
866 * @cancellable: (nullable): a #GCancellable, or %NULL
867 * @callback: (scope async): callback to call after resolution completes
868 * @user_data: (closure): data for @callback
870 * Begins asynchronously reverse-resolving @address to determine its
871 * associated hostname, and eventually calls @callback, which must
872 * call g_resolver_lookup_by_address_finish() to get the final result.
877 g_resolver_lookup_by_address_async (GResolver *resolver,
878 GInetAddress *address,
879 GCancellable *cancellable,
880 GAsyncReadyCallback callback,
883 g_return_if_fail (G_IS_RESOLVER (resolver));
884 g_return_if_fail (G_IS_INET_ADDRESS (address));
886 maybe_emit_reload (resolver);
887 G_RESOLVER_GET_CLASS (resolver)->
888 lookup_by_address_async (resolver, address, cancellable, callback, user_data);
892 * g_resolver_lookup_by_address_finish:
893 * @resolver: a #GResolver
894 * @result: the result passed to your #GAsyncReadyCallback
895 * @error: return location for a #GError, or %NULL
897 * Retrieves the result of a previous call to
898 * g_resolver_lookup_by_address_async().
900 * If the DNS resolution failed, @error (if non-%NULL) will be set to
901 * a value from #GResolverError. If the operation was cancelled,
902 * @error will be set to %G_IO_ERROR_CANCELLED.
904 * Returns: a hostname (either ASCII-only, or in ASCII-encoded
905 * form), or %NULL on error.
910 g_resolver_lookup_by_address_finish (GResolver *resolver,
911 GAsyncResult *result,
914 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
916 if (g_async_result_legacy_propagate_error (result, error))
919 return G_RESOLVER_GET_CLASS (resolver)->
920 lookup_by_address_finish (resolver, result, error);
924 g_resolver_get_service_rrname (const char *service,
925 const char *protocol,
928 gchar *rrname, *ascii_domain = NULL;
930 if (g_hostname_is_non_ascii (domain))
931 domain = ascii_domain = g_hostname_to_ascii (domain);
935 rrname = g_strdup_printf ("_%s._%s.%s", service, protocol, domain);
937 g_free (ascii_domain);
942 * g_resolver_lookup_service:
943 * @resolver: a #GResolver
944 * @service: the service type to look up (eg, "ldap")
945 * @protocol: the networking protocol to use for @service (eg, "tcp")
946 * @domain: the DNS domain to look up the service in
947 * @cancellable: (nullable): a #GCancellable, or %NULL
948 * @error: return location for a #GError, or %NULL
950 * Synchronously performs a DNS SRV lookup for the given @service and
951 * @protocol in the given @domain and returns an array of #GSrvTarget.
952 * @domain may be an ASCII-only or UTF-8 hostname. Note also that the
953 * @service and @protocol arguments do not include the leading underscore
954 * that appears in the actual DNS entry.
956 * On success, g_resolver_lookup_service() will return a non-empty #GList of
957 * #GSrvTarget, sorted in order of preference. (That is, you should
958 * attempt to connect to the first target first, then the second if
959 * the first fails, etc.)
961 * If the DNS resolution fails, @error (if non-%NULL) will be set to
962 * a value from #GResolverError and %NULL will be returned.
964 * If @cancellable is non-%NULL, it can be used to cancel the
965 * operation, in which case @error (if non-%NULL) will be set to
966 * %G_IO_ERROR_CANCELLED.
968 * If you are planning to connect to the service, it is usually easier
969 * to create a #GNetworkService and use its #GSocketConnectable
972 * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
973 * #GSrvTarget, or %NULL on error. You must free each of the targets and the
974 * list when you are done with it. (You can use g_resolver_free_targets() to do
980 g_resolver_lookup_service (GResolver *resolver,
981 const gchar *service,
982 const gchar *protocol,
984 GCancellable *cancellable,
990 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
991 g_return_val_if_fail (service != NULL, NULL);
992 g_return_val_if_fail (protocol != NULL, NULL);
993 g_return_val_if_fail (domain != NULL, NULL);
995 rrname = g_resolver_get_service_rrname (service, protocol, domain);
998 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
999 _("Invalid domain"));
1003 maybe_emit_reload (resolver);
1004 targets = G_RESOLVER_GET_CLASS (resolver)->
1005 lookup_service (resolver, rrname, cancellable, error);
1012 * g_resolver_lookup_service_async:
1013 * @resolver: a #GResolver
1014 * @service: the service type to look up (eg, "ldap")
1015 * @protocol: the networking protocol to use for @service (eg, "tcp")
1016 * @domain: the DNS domain to look up the service in
1017 * @cancellable: (nullable): a #GCancellable, or %NULL
1018 * @callback: (scope async): callback to call after resolution completes
1019 * @user_data: (closure): data for @callback
1021 * Begins asynchronously performing a DNS SRV lookup for the given
1022 * @service and @protocol in the given @domain, and eventually calls
1023 * @callback, which must call g_resolver_lookup_service_finish() to
1024 * get the final result. See g_resolver_lookup_service() for more
1030 g_resolver_lookup_service_async (GResolver *resolver,
1031 const gchar *service,
1032 const gchar *protocol,
1033 const gchar *domain,
1034 GCancellable *cancellable,
1035 GAsyncReadyCallback callback,
1040 g_return_if_fail (G_IS_RESOLVER (resolver));
1041 g_return_if_fail (service != NULL);
1042 g_return_if_fail (protocol != NULL);
1043 g_return_if_fail (domain != NULL);
1045 rrname = g_resolver_get_service_rrname (service, protocol, domain);
1048 g_task_report_new_error (resolver, callback, user_data,
1049 g_resolver_lookup_service_async,
1050 G_IO_ERROR, G_IO_ERROR_FAILED,
1051 _("Invalid domain"));
1055 maybe_emit_reload (resolver);
1056 G_RESOLVER_GET_CLASS (resolver)->
1057 lookup_service_async (resolver, rrname, cancellable, callback, user_data);
1063 * g_resolver_lookup_service_finish:
1064 * @resolver: a #GResolver
1065 * @result: the result passed to your #GAsyncReadyCallback
1066 * @error: return location for a #GError, or %NULL
1068 * Retrieves the result of a previous call to
1069 * g_resolver_lookup_service_async().
1071 * If the DNS resolution failed, @error (if non-%NULL) will be set to
1072 * a value from #GResolverError. If the operation was cancelled,
1073 * @error will be set to %G_IO_ERROR_CANCELLED.
1075 * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
1076 * #GSrvTarget, or %NULL on error. See g_resolver_lookup_service() for more
1082 g_resolver_lookup_service_finish (GResolver *resolver,
1083 GAsyncResult *result,
1086 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1088 if (g_async_result_legacy_propagate_error (result, error))
1091 return G_RESOLVER_GET_CLASS (resolver)->
1092 lookup_service_finish (resolver, result, error);
1096 * g_resolver_free_targets: (skip)
1097 * @targets: a #GList of #GSrvTarget
1099 * Frees @targets (which should be the return value from
1100 * g_resolver_lookup_service() or g_resolver_lookup_service_finish()).
1101 * (This is a convenience method; you can also simply free the
1107 g_resolver_free_targets (GList *targets)
1111 for (t = targets; t; t = t->next)
1112 g_srv_target_free (t->data);
1113 g_list_free (targets);
1117 * g_resolver_lookup_records:
1118 * @resolver: a #GResolver
1119 * @rrname: the DNS name to look up the record for
1120 * @record_type: the type of DNS record to look up
1121 * @cancellable: (nullable): a #GCancellable, or %NULL
1122 * @error: return location for a #GError, or %NULL
1124 * Synchronously performs a DNS record lookup for the given @rrname and returns
1125 * a list of records as #GVariant tuples. See #GResolverRecordType for
1126 * information on what the records contain for each @record_type.
1128 * If the DNS resolution fails, @error (if non-%NULL) will be set to
1129 * a value from #GResolverError and %NULL will be returned.
1131 * If @cancellable is non-%NULL, it can be used to cancel the
1132 * operation, in which case @error (if non-%NULL) will be set to
1133 * %G_IO_ERROR_CANCELLED.
1135 * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
1136 * #GVariant, or %NULL on error. You must free each of the records and the list
1137 * when you are done with it. (You can use g_list_free_full() with
1138 * g_variant_unref() to do this.)
1143 g_resolver_lookup_records (GResolver *resolver,
1144 const gchar *rrname,
1145 GResolverRecordType record_type,
1146 GCancellable *cancellable,
1151 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1152 g_return_val_if_fail (rrname != NULL, NULL);
1154 maybe_emit_reload (resolver);
1155 records = G_RESOLVER_GET_CLASS (resolver)->
1156 lookup_records (resolver, rrname, record_type, cancellable, error);
1162 * g_resolver_lookup_records_async:
1163 * @resolver: a #GResolver
1164 * @rrname: the DNS name to look up the record for
1165 * @record_type: the type of DNS record to look up
1166 * @cancellable: (nullable): a #GCancellable, or %NULL
1167 * @callback: (scope async): callback to call after resolution completes
1168 * @user_data: (closure): data for @callback
1170 * Begins asynchronously performing a DNS lookup for the given
1171 * @rrname, and eventually calls @callback, which must call
1172 * g_resolver_lookup_records_finish() to get the final result. See
1173 * g_resolver_lookup_records() for more details.
1178 g_resolver_lookup_records_async (GResolver *resolver,
1179 const gchar *rrname,
1180 GResolverRecordType record_type,
1181 GCancellable *cancellable,
1182 GAsyncReadyCallback callback,
1185 g_return_if_fail (G_IS_RESOLVER (resolver));
1186 g_return_if_fail (rrname != NULL);
1188 maybe_emit_reload (resolver);
1189 G_RESOLVER_GET_CLASS (resolver)->
1190 lookup_records_async (resolver, rrname, record_type, cancellable, callback, user_data);
1194 * g_resolver_lookup_records_finish:
1195 * @resolver: a #GResolver
1196 * @result: the result passed to your #GAsyncReadyCallback
1197 * @error: return location for a #GError, or %NULL
1199 * Retrieves the result of a previous call to
1200 * g_resolver_lookup_records_async(). Returns a non-empty list of records as
1201 * #GVariant tuples. See #GResolverRecordType for information on what the
1204 * If the DNS resolution failed, @error (if non-%NULL) will be set to
1205 * a value from #GResolverError. If the operation was cancelled,
1206 * @error will be set to %G_IO_ERROR_CANCELLED.
1208 * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
1209 * #GVariant, or %NULL on error. You must free each of the records and the list
1210 * when you are done with it. (You can use g_list_free_full() with
1211 * g_variant_unref() to do this.)
1216 g_resolver_lookup_records_finish (GResolver *resolver,
1217 GAsyncResult *result,
1220 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1221 return G_RESOLVER_GET_CLASS (resolver)->
1222 lookup_records_finish (resolver, result, error);
1226 g_resolver_get_serial (GResolver *resolver)
1230 g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
1232 maybe_emit_reload (resolver);
1235 g_mutex_lock (&resolver->priv->mutex);
1236 result = resolver->priv->resolv_conf_timestamp;
1237 g_mutex_unlock (&resolver->priv->mutex);
1246 * g_resolver_error_quark:
1248 * Gets the #GResolver Error Quark.
1250 * Returns: a #GQuark.
1254 G_DEFINE_QUARK (g-resolver-error-quark, g_resolver_error)