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 * SPDX-License-Identifier: LGPL-2.1-or-later
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General
21 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "gresolver.h"
29 #include "gnetworkingprivate.h"
30 #include "gasyncresult.h"
31 #include "ginetaddress.h"
33 #include "gsrvtarget.h"
34 #include "gthreadedresolver.h"
36 #include "gcancellable.h"
47 * @short_description: Asynchronous and cancellable DNS resolver
50 * #GResolver provides cancellable synchronous and asynchronous DNS
51 * resolution, for hostnames (g_resolver_lookup_by_address(),
52 * g_resolver_lookup_by_name() and their async variants) and SRV
53 * (service) records (g_resolver_lookup_service()).
55 * #GNetworkAddress and #GNetworkService provide wrappers around
56 * #GResolver functionality that also implement #GSocketConnectable,
57 * making it easy to connect to a remote host/service.
65 static guint signals[LAST_SIGNAL] = { 0 };
67 struct _GResolverPrivate {
70 time_t resolv_conf_timestamp; /* protected by @mutex */
79 * The object that handles DNS resolution. Use g_resolver_get_default()
80 * to get the default resolver.
82 * This is an abstract type; subclasses of it implement different resolvers for
83 * different platforms and situations.
85 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GResolver, g_resolver, G_TYPE_OBJECT,
86 G_ADD_PRIVATE (GResolver)
87 g_networking_init ();)
90 srv_records_to_targets (GList *records)
92 const gchar *hostname;
93 guint16 port, priority, weight;
97 for (l = records; l != NULL; l = g_list_next (l))
99 g_variant_get (l->data, "(qqq&s)", &priority, &weight, &port, &hostname);
100 target = g_srv_target_new (hostname, port, priority, weight);
101 g_variant_unref (l->data);
105 return g_srv_target_list_sort (records);
109 g_resolver_real_lookup_service (GResolver *resolver,
111 GCancellable *cancellable,
116 records = G_RESOLVER_GET_CLASS (resolver)->lookup_records (resolver,
118 G_RESOLVER_RECORD_SRV,
122 return srv_records_to_targets (records);
126 g_resolver_real_lookup_service_async (GResolver *resolver,
128 GCancellable *cancellable,
129 GAsyncReadyCallback callback,
132 G_RESOLVER_GET_CLASS (resolver)->lookup_records_async (resolver,
134 G_RESOLVER_RECORD_SRV,
141 g_resolver_real_lookup_service_finish (GResolver *resolver,
142 GAsyncResult *result,
147 records = G_RESOLVER_GET_CLASS (resolver)->lookup_records_finish (resolver,
151 return srv_records_to_targets (records);
155 g_resolver_finalize (GObject *object)
158 GResolver *resolver = G_RESOLVER (object);
160 g_mutex_clear (&resolver->priv->mutex);
163 G_OBJECT_CLASS (g_resolver_parent_class)->finalize (object);
167 g_resolver_class_init (GResolverClass *resolver_class)
169 GObjectClass *object_class = G_OBJECT_CLASS (resolver_class);
171 object_class->finalize = g_resolver_finalize;
173 /* Automatically pass these over to the lookup_records methods */
174 resolver_class->lookup_service = g_resolver_real_lookup_service;
175 resolver_class->lookup_service_async = g_resolver_real_lookup_service_async;
176 resolver_class->lookup_service_finish = g_resolver_real_lookup_service_finish;
180 * @resolver: a #GResolver
182 * Emitted when the resolver notices that the system resolver
183 * configuration has changed.
186 g_signal_new (I_("reload"),
189 G_STRUCT_OFFSET (GResolverClass, reload),
196 g_resolver_init (GResolver *resolver)
202 resolver->priv = g_resolver_get_instance_private (resolver);
205 if (stat (_PATH_RESCONF, &st) == 0)
206 resolver->priv->resolv_conf_timestamp = st.st_mtime;
208 g_mutex_init (&resolver->priv->mutex);
212 G_LOCK_DEFINE_STATIC (default_resolver);
213 static GResolver *default_resolver;
216 * g_resolver_get_default:
218 * Gets the default #GResolver. You should unref it when you are done
219 * with it. #GResolver may use its reference count as a hint about how
220 * many threads it should allocate for concurrent DNS resolutions.
222 * Returns: (transfer full): the default #GResolver.
227 g_resolver_get_default (void)
231 G_LOCK (default_resolver);
232 if (!default_resolver)
233 default_resolver = g_object_new (G_TYPE_THREADED_RESOLVER, NULL);
234 ret = g_object_ref (default_resolver);
235 G_UNLOCK (default_resolver);
241 * g_resolver_set_default:
242 * @resolver: the new default #GResolver
244 * Sets @resolver to be the application's default resolver (reffing
245 * @resolver, and unreffing the previous default resolver, if any).
246 * Future calls to g_resolver_get_default() will return this resolver.
248 * This can be used if an application wants to perform any sort of DNS
249 * caching or "pinning"; it can implement its own #GResolver that
250 * calls the original default resolver for DNS operations, and
251 * implements its own cache policies on top of that, and then set
252 * itself as the default resolver for all later code to use.
257 g_resolver_set_default (GResolver *resolver)
259 G_LOCK (default_resolver);
260 if (default_resolver)
261 g_object_unref (default_resolver);
262 default_resolver = g_object_ref (resolver);
263 G_UNLOCK (default_resolver);
267 maybe_emit_reload (GResolver *resolver)
272 if (stat (_PATH_RESCONF, &st) == 0)
274 g_mutex_lock (&resolver->priv->mutex);
275 if (st.st_mtime != resolver->priv->resolv_conf_timestamp)
277 resolver->priv->resolv_conf_timestamp = st.st_mtime;
278 g_mutex_unlock (&resolver->priv->mutex);
279 g_signal_emit (resolver, signals[RELOAD], 0);
282 g_mutex_unlock (&resolver->priv->mutex);
287 /* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */
289 remove_duplicates (GList *addrs)
295 /* TODO: if this is too slow (it's O(n^2) but n is typically really
296 * small), we can do something more clever but note that we must not
297 * change the order of elements...
299 for (l = addrs; l != NULL; l = l->next)
301 GInetAddress *address = G_INET_ADDRESS (l->data);
302 for (ll = l->next; ll != NULL; ll = lll)
304 GInetAddress *other_address = G_INET_ADDRESS (ll->data);
306 if (g_inet_address_equal (address, other_address))
308 g_object_unref (other_address);
309 /* we never return the first element */
310 g_warn_if_fail (g_list_delete_link (addrs, ll) == addrs);
317 hostname_is_localhost (const char *hostname)
319 size_t len = strlen (hostname);
322 /* Match "localhost", "localhost.", "*.localhost" and "*.localhost." */
323 if (len < strlen ("localhost"))
326 if (hostname[len - 1] == '.')
329 /* Scan backwards in @hostname to find the right-most dot (excluding the final dot, if it exists, as it was chopped off above).
330 * We can’t use strrchr() because because we need to operate with string lengths.
331 * End with @p pointing to the character after the right-most dot. */
332 p = hostname + len - 1;
333 while (p >= hostname)
340 else if (p == hostname)
347 return g_ascii_strncasecmp (p, "localhost", MAX (len, strlen ("localhost"))) == 0;
350 /* Note that this does not follow the "FALSE means @error is set"
351 * convention. The return value tells the caller whether it should
352 * return @addrs and @error to the caller right away, or if it should
353 * continue and trying to resolve the name as a hostname.
356 handle_ip_address_or_localhost (const char *hostname,
358 GResolverNameLookupFlags flags,
364 struct in_addr ip4addr;
367 addr = g_inet_address_new_from_string (hostname);
370 *addrs = g_list_append (NULL, addr);
378 /* Reject IPv6 addresses that have brackets ('[' or ']') and/or port numbers,
379 * as no valid addresses should contain these at this point.
380 * Non-standard IPv4 addresses would be rejected during the call to
381 * getaddrinfo() later.
383 if (strrchr (hostname, '[') != NULL ||
384 strrchr (hostname, ']') != NULL)
387 /* Reject non-standard IPv4 numbers-and-dots addresses.
388 * g_inet_address_new_from_string() will have accepted any "real" IP
389 * address, so if inet_aton() succeeds, then it's an address we want
392 if (inet_aton (hostname, &ip4addr))
396 gchar *error_message = g_win32_error_message (WSAHOST_NOT_FOUND);
398 gchar *error_message = g_locale_to_utf8 (gai_strerror (EAI_NONAME), -1, NULL, NULL, NULL);
399 if (error_message == NULL)
400 error_message = g_strdup ("[Invalid UTF-8]");
402 g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
403 _("Error resolving “%s”: %s"),
404 hostname, error_message);
405 g_free (error_message);
410 /* Always resolve localhost to a loopback address so it can be reliably considered secure.
411 This behavior is being adopted by browsers:
412 - https://w3c.github.io/webappsec-secure-contexts/
413 - https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/RC9dSw-O3fE/E3_0XaT0BAAJ
414 - https://chromium.googlesource.com/chromium/src.git/+/8da2a80724a9b896890602ff77ef2216cb951399
415 - https://bugs.webkit.org/show_bug.cgi?id=171934
416 - https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-06
418 if (hostname_is_localhost (hostname))
420 if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY)
421 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6));
422 if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY)
423 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4));
426 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6));
427 *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4));
436 lookup_by_name_real (GResolver *resolver,
437 const gchar *hostname,
438 GResolverNameLookupFlags flags,
439 GCancellable *cancellable,
443 gchar *ascii_hostname = NULL;
445 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
446 g_return_val_if_fail (hostname != NULL, NULL);
447 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
448 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
450 /* Check if @hostname is just an IP address */
451 if (handle_ip_address_or_localhost (hostname, &addrs, flags, error))
454 if (g_hostname_is_non_ascii (hostname))
455 hostname = ascii_hostname = g_hostname_to_ascii (hostname);
459 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
460 _("Invalid hostname"));
464 maybe_emit_reload (resolver);
466 if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
468 if (!G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags)
470 g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
471 /* Translators: The placeholder is for a function name. */
472 _("%s not implemented"), "lookup_by_name_with_flags");
473 g_free (ascii_hostname);
476 addrs = G_RESOLVER_GET_CLASS (resolver)->
477 lookup_by_name_with_flags (resolver, hostname, flags, cancellable, error);
480 addrs = G_RESOLVER_GET_CLASS (resolver)->
481 lookup_by_name (resolver, hostname, cancellable, error);
483 remove_duplicates (addrs);
485 g_free (ascii_hostname);
490 * g_resolver_lookup_by_name:
491 * @resolver: a #GResolver
492 * @hostname: the hostname to look up
493 * @cancellable: (nullable): a #GCancellable, or %NULL
494 * @error: return location for a #GError, or %NULL
496 * Synchronously resolves @hostname to determine its associated IP
497 * address(es). @hostname may be an ASCII-only or UTF-8 hostname, or
498 * the textual form of an IP address (in which case this just becomes
499 * a wrapper around g_inet_address_new_from_string()).
501 * On success, g_resolver_lookup_by_name() will return a non-empty #GList of
502 * #GInetAddress, sorted in order of preference and guaranteed to not
503 * contain duplicates. That is, if using the result to connect to
504 * @hostname, you should attempt to connect to the first address
505 * first, then the second if the first fails, etc. If you are using
506 * the result to listen on a socket, it is appropriate to add each
507 * result using e.g. g_socket_listener_add_address().
509 * If the DNS resolution fails, @error (if non-%NULL) will be set to a
510 * value from #GResolverError and %NULL will be returned.
512 * If @cancellable is non-%NULL, it can be used to cancel the
513 * operation, in which case @error (if non-%NULL) will be set to
514 * %G_IO_ERROR_CANCELLED.
516 * If you are planning to connect to a socket on the resolved IP
517 * address, it may be easier to create a #GNetworkAddress and use its
518 * #GSocketConnectable interface.
520 * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
521 * of #GInetAddress, or %NULL on error. You
522 * must unref each of the addresses and free the list when you are
523 * done with it. (You can use g_resolver_free_addresses() to do this.)
528 g_resolver_lookup_by_name (GResolver *resolver,
529 const gchar *hostname,
530 GCancellable *cancellable,
533 return lookup_by_name_real (resolver,
535 G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT,
541 * g_resolver_lookup_by_name_with_flags:
542 * @resolver: a #GResolver
543 * @hostname: the hostname to look up
544 * @flags: extra #GResolverNameLookupFlags for the lookup
545 * @cancellable: (nullable): a #GCancellable, or %NULL
546 * @error: (nullable): return location for a #GError, or %NULL
548 * This differs from g_resolver_lookup_by_name() in that you can modify
549 * the lookup behavior with @flags. For example this can be used to limit
550 * results with %G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY.
552 * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
553 * of #GInetAddress, or %NULL on error. You
554 * must unref each of the addresses and free the list when you are
555 * done with it. (You can use g_resolver_free_addresses() to do this.)
560 g_resolver_lookup_by_name_with_flags (GResolver *resolver,
561 const gchar *hostname,
562 GResolverNameLookupFlags flags,
563 GCancellable *cancellable,
566 return lookup_by_name_real (resolver,
574 lookup_by_name_async_real (GResolver *resolver,
575 const gchar *hostname,
576 GResolverNameLookupFlags flags,
577 GCancellable *cancellable,
578 GAsyncReadyCallback callback,
581 gchar *ascii_hostname = NULL;
583 GError *error = NULL;
585 g_return_if_fail (G_IS_RESOLVER (resolver));
586 g_return_if_fail (hostname != NULL);
587 g_return_if_fail (!(flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY && flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY));
589 /* Check if @hostname is just an IP address */
590 if (handle_ip_address_or_localhost (hostname, &addrs, flags, &error))
594 task = g_task_new (resolver, cancellable, callback, user_data);
595 g_task_set_source_tag (task, lookup_by_name_async_real);
596 g_task_set_name (task, "[gio] resolver lookup");
598 g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
600 g_task_return_error (task, error);
601 g_object_unref (task);
605 if (g_hostname_is_non_ascii (hostname))
606 hostname = ascii_hostname = g_hostname_to_ascii (hostname);
612 g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
613 _("Invalid hostname"));
614 task = g_task_new (resolver, cancellable, callback, user_data);
615 g_task_set_source_tag (task, lookup_by_name_async_real);
616 g_task_set_name (task, "[gio] resolver lookup");
617 g_task_return_error (task, error);
618 g_object_unref (task);
622 maybe_emit_reload (resolver);
624 if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
626 if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_async == NULL)
630 g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
631 /* Translators: The placeholder is for a function name. */
632 _("%s not implemented"), "lookup_by_name_with_flags_async");
633 task = g_task_new (resolver, cancellable, callback, user_data);
634 g_task_set_source_tag (task, lookup_by_name_async_real);
635 g_task_set_name (task, "[gio] resolver lookup");
636 g_task_return_error (task, error);
637 g_object_unref (task);
640 G_RESOLVER_GET_CLASS (resolver)->
641 lookup_by_name_with_flags_async (resolver, hostname, flags, cancellable, callback, user_data);
644 G_RESOLVER_GET_CLASS (resolver)->
645 lookup_by_name_async (resolver, hostname, cancellable, callback, user_data);
647 g_free (ascii_hostname);
651 lookup_by_name_finish_real (GResolver *resolver,
652 GAsyncResult *result,
658 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
659 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
660 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
662 if (g_async_result_legacy_propagate_error (result, error))
664 else if (g_async_result_is_tagged (result, lookup_by_name_async_real))
666 /* Handle the stringified-IP-addr case */
667 return g_task_propagate_pointer (G_TASK (result), error);
672 g_assert (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_finish != NULL);
673 addrs = G_RESOLVER_GET_CLASS (resolver)->
674 lookup_by_name_with_flags_finish (resolver, result, error);
677 addrs = G_RESOLVER_GET_CLASS (resolver)->
678 lookup_by_name_finish (resolver, result, error);
680 remove_duplicates (addrs);
686 * g_resolver_lookup_by_name_with_flags_async:
687 * @resolver: a #GResolver
688 * @hostname: the hostname to look up the address of
689 * @flags: extra #GResolverNameLookupFlags for the lookup
690 * @cancellable: (nullable): a #GCancellable, or %NULL
691 * @callback: (scope async): callback to call after resolution completes
692 * @user_data: (closure): data for @callback
694 * Begins asynchronously resolving @hostname to determine its
695 * associated IP address(es), and eventually calls @callback, which
696 * must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
697 * See g_resolver_lookup_by_name() for more details.
702 g_resolver_lookup_by_name_with_flags_async (GResolver *resolver,
703 const gchar *hostname,
704 GResolverNameLookupFlags flags,
705 GCancellable *cancellable,
706 GAsyncReadyCallback callback,
709 lookup_by_name_async_real (resolver,
718 * g_resolver_lookup_by_name_async:
719 * @resolver: a #GResolver
720 * @hostname: the hostname to look up the address of
721 * @cancellable: (nullable): a #GCancellable, or %NULL
722 * @callback: (scope async): callback to call after resolution completes
723 * @user_data: (closure): data for @callback
725 * Begins asynchronously resolving @hostname to determine its
726 * associated IP address(es), and eventually calls @callback, which
727 * must call g_resolver_lookup_by_name_finish() to get the result.
728 * See g_resolver_lookup_by_name() for more details.
733 g_resolver_lookup_by_name_async (GResolver *resolver,
734 const gchar *hostname,
735 GCancellable *cancellable,
736 GAsyncReadyCallback callback,
739 lookup_by_name_async_real (resolver,
748 * g_resolver_lookup_by_name_finish:
749 * @resolver: a #GResolver
750 * @result: the result passed to your #GAsyncReadyCallback
751 * @error: return location for a #GError, or %NULL
753 * Retrieves the result of a call to
754 * g_resolver_lookup_by_name_async().
756 * If the DNS resolution failed, @error (if non-%NULL) will be set to
757 * a value from #GResolverError. If the operation was cancelled,
758 * @error will be set to %G_IO_ERROR_CANCELLED.
760 * Returns: (element-type GInetAddress) (transfer full): a #GList
761 * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
767 g_resolver_lookup_by_name_finish (GResolver *resolver,
768 GAsyncResult *result,
771 return lookup_by_name_finish_real (resolver,
778 * g_resolver_lookup_by_name_with_flags_finish:
779 * @resolver: a #GResolver
780 * @result: the result passed to your #GAsyncReadyCallback
781 * @error: return location for a #GError, or %NULL
783 * Retrieves the result of a call to
784 * g_resolver_lookup_by_name_with_flags_async().
786 * If the DNS resolution failed, @error (if non-%NULL) will be set to
787 * a value from #GResolverError. If the operation was cancelled,
788 * @error will be set to %G_IO_ERROR_CANCELLED.
790 * Returns: (element-type GInetAddress) (transfer full): a #GList
791 * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
797 g_resolver_lookup_by_name_with_flags_finish (GResolver *resolver,
798 GAsyncResult *result,
801 return lookup_by_name_finish_real (resolver,
808 * g_resolver_free_addresses: (skip)
809 * @addresses: a #GList of #GInetAddress
811 * Frees @addresses (which should be the return value from
812 * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_finish()).
813 * (This is a convenience method; you can also simply free the results
819 g_resolver_free_addresses (GList *addresses)
823 for (a = addresses; a; a = a->next)
824 g_object_unref (a->data);
825 g_list_free (addresses);
829 * g_resolver_lookup_by_address:
830 * @resolver: a #GResolver
831 * @address: the address to reverse-resolve
832 * @cancellable: (nullable): a #GCancellable, or %NULL
833 * @error: return location for a #GError, or %NULL
835 * Synchronously reverse-resolves @address to determine its
836 * associated hostname.
838 * If the DNS resolution fails, @error (if non-%NULL) will be set to
839 * a value from #GResolverError.
841 * If @cancellable is non-%NULL, it can be used to cancel the
842 * operation, in which case @error (if non-%NULL) will be set to
843 * %G_IO_ERROR_CANCELLED.
845 * Returns: a hostname (either ASCII-only, or in ASCII-encoded
846 * form), or %NULL on error.
851 g_resolver_lookup_by_address (GResolver *resolver,
852 GInetAddress *address,
853 GCancellable *cancellable,
856 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
857 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
859 maybe_emit_reload (resolver);
860 return G_RESOLVER_GET_CLASS (resolver)->
861 lookup_by_address (resolver, address, cancellable, error);
865 * g_resolver_lookup_by_address_async:
866 * @resolver: a #GResolver
867 * @address: the address to reverse-resolve
868 * @cancellable: (nullable): a #GCancellable, or %NULL
869 * @callback: (scope async): callback to call after resolution completes
870 * @user_data: (closure): data for @callback
872 * Begins asynchronously reverse-resolving @address to determine its
873 * associated hostname, and eventually calls @callback, which must
874 * call g_resolver_lookup_by_address_finish() to get the final result.
879 g_resolver_lookup_by_address_async (GResolver *resolver,
880 GInetAddress *address,
881 GCancellable *cancellable,
882 GAsyncReadyCallback callback,
885 g_return_if_fail (G_IS_RESOLVER (resolver));
886 g_return_if_fail (G_IS_INET_ADDRESS (address));
888 maybe_emit_reload (resolver);
889 G_RESOLVER_GET_CLASS (resolver)->
890 lookup_by_address_async (resolver, address, cancellable, callback, user_data);
894 * g_resolver_lookup_by_address_finish:
895 * @resolver: a #GResolver
896 * @result: the result passed to your #GAsyncReadyCallback
897 * @error: return location for a #GError, or %NULL
899 * Retrieves the result of a previous call to
900 * g_resolver_lookup_by_address_async().
902 * If the DNS resolution failed, @error (if non-%NULL) will be set to
903 * a value from #GResolverError. If the operation was cancelled,
904 * @error will be set to %G_IO_ERROR_CANCELLED.
906 * Returns: a hostname (either ASCII-only, or in ASCII-encoded
907 * form), or %NULL on error.
912 g_resolver_lookup_by_address_finish (GResolver *resolver,
913 GAsyncResult *result,
916 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
918 if (g_async_result_legacy_propagate_error (result, error))
921 return G_RESOLVER_GET_CLASS (resolver)->
922 lookup_by_address_finish (resolver, result, error);
926 g_resolver_get_service_rrname (const char *service,
927 const char *protocol,
930 gchar *rrname, *ascii_domain = NULL;
932 if (g_hostname_is_non_ascii (domain))
933 domain = ascii_domain = g_hostname_to_ascii (domain);
937 rrname = g_strdup_printf ("_%s._%s.%s", service, protocol, domain);
939 g_free (ascii_domain);
944 * g_resolver_lookup_service:
945 * @resolver: a #GResolver
946 * @service: the service type to look up (eg, "ldap")
947 * @protocol: the networking protocol to use for @service (eg, "tcp")
948 * @domain: the DNS domain to look up the service in
949 * @cancellable: (nullable): a #GCancellable, or %NULL
950 * @error: return location for a #GError, or %NULL
952 * Synchronously performs a DNS SRV lookup for the given @service and
953 * @protocol in the given @domain and returns an array of #GSrvTarget.
954 * @domain may be an ASCII-only or UTF-8 hostname. Note also that the
955 * @service and @protocol arguments do not include the leading underscore
956 * that appears in the actual DNS entry.
958 * On success, g_resolver_lookup_service() will return a non-empty #GList of
959 * #GSrvTarget, sorted in order of preference. (That is, you should
960 * attempt to connect to the first target first, then the second if
961 * the first fails, etc.)
963 * If the DNS resolution fails, @error (if non-%NULL) will be set to
964 * a value from #GResolverError and %NULL will be returned.
966 * If @cancellable is non-%NULL, it can be used to cancel the
967 * operation, in which case @error (if non-%NULL) will be set to
968 * %G_IO_ERROR_CANCELLED.
970 * If you are planning to connect to the service, it is usually easier
971 * to create a #GNetworkService and use its #GSocketConnectable
974 * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
975 * #GSrvTarget, or %NULL on error. You must free each of the targets and the
976 * list when you are done with it. (You can use g_resolver_free_targets() to do
982 g_resolver_lookup_service (GResolver *resolver,
983 const gchar *service,
984 const gchar *protocol,
986 GCancellable *cancellable,
992 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
993 g_return_val_if_fail (service != NULL, NULL);
994 g_return_val_if_fail (protocol != NULL, NULL);
995 g_return_val_if_fail (domain != NULL, NULL);
997 rrname = g_resolver_get_service_rrname (service, protocol, domain);
1000 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
1001 _("Invalid domain"));
1005 maybe_emit_reload (resolver);
1006 targets = G_RESOLVER_GET_CLASS (resolver)->
1007 lookup_service (resolver, rrname, cancellable, error);
1014 * g_resolver_lookup_service_async:
1015 * @resolver: a #GResolver
1016 * @service: the service type to look up (eg, "ldap")
1017 * @protocol: the networking protocol to use for @service (eg, "tcp")
1018 * @domain: the DNS domain to look up the service in
1019 * @cancellable: (nullable): a #GCancellable, or %NULL
1020 * @callback: (scope async): callback to call after resolution completes
1021 * @user_data: (closure): data for @callback
1023 * Begins asynchronously performing a DNS SRV lookup for the given
1024 * @service and @protocol in the given @domain, and eventually calls
1025 * @callback, which must call g_resolver_lookup_service_finish() to
1026 * get the final result. See g_resolver_lookup_service() for more
1032 g_resolver_lookup_service_async (GResolver *resolver,
1033 const gchar *service,
1034 const gchar *protocol,
1035 const gchar *domain,
1036 GCancellable *cancellable,
1037 GAsyncReadyCallback callback,
1042 g_return_if_fail (G_IS_RESOLVER (resolver));
1043 g_return_if_fail (service != NULL);
1044 g_return_if_fail (protocol != NULL);
1045 g_return_if_fail (domain != NULL);
1047 rrname = g_resolver_get_service_rrname (service, protocol, domain);
1050 g_task_report_new_error (resolver, callback, user_data,
1051 g_resolver_lookup_service_async,
1052 G_IO_ERROR, G_IO_ERROR_FAILED,
1053 _("Invalid domain"));
1057 maybe_emit_reload (resolver);
1058 G_RESOLVER_GET_CLASS (resolver)->
1059 lookup_service_async (resolver, rrname, cancellable, callback, user_data);
1065 * g_resolver_lookup_service_finish:
1066 * @resolver: a #GResolver
1067 * @result: the result passed to your #GAsyncReadyCallback
1068 * @error: return location for a #GError, or %NULL
1070 * Retrieves the result of a previous call to
1071 * g_resolver_lookup_service_async().
1073 * If the DNS resolution failed, @error (if non-%NULL) will be set to
1074 * a value from #GResolverError. If the operation was cancelled,
1075 * @error will be set to %G_IO_ERROR_CANCELLED.
1077 * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
1078 * #GSrvTarget, or %NULL on error. See g_resolver_lookup_service() for more
1084 g_resolver_lookup_service_finish (GResolver *resolver,
1085 GAsyncResult *result,
1088 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1090 if (g_async_result_legacy_propagate_error (result, error))
1093 return G_RESOLVER_GET_CLASS (resolver)->
1094 lookup_service_finish (resolver, result, error);
1098 * g_resolver_free_targets: (skip)
1099 * @targets: a #GList of #GSrvTarget
1101 * Frees @targets (which should be the return value from
1102 * g_resolver_lookup_service() or g_resolver_lookup_service_finish()).
1103 * (This is a convenience method; you can also simply free the
1109 g_resolver_free_targets (GList *targets)
1113 for (t = targets; t; t = t->next)
1114 g_srv_target_free (t->data);
1115 g_list_free (targets);
1119 * g_resolver_lookup_records:
1120 * @resolver: a #GResolver
1121 * @rrname: the DNS name to look up the record for
1122 * @record_type: the type of DNS record to look up
1123 * @cancellable: (nullable): a #GCancellable, or %NULL
1124 * @error: return location for a #GError, or %NULL
1126 * Synchronously performs a DNS record lookup for the given @rrname and returns
1127 * a list of records as #GVariant tuples. See #GResolverRecordType for
1128 * information on what the records contain for each @record_type.
1130 * If the DNS resolution fails, @error (if non-%NULL) will be set to
1131 * a value from #GResolverError and %NULL will be returned.
1133 * If @cancellable is non-%NULL, it can be used to cancel the
1134 * operation, in which case @error (if non-%NULL) will be set to
1135 * %G_IO_ERROR_CANCELLED.
1137 * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
1138 * #GVariant, or %NULL on error. You must free each of the records and the list
1139 * when you are done with it. (You can use g_list_free_full() with
1140 * g_variant_unref() to do this.)
1145 g_resolver_lookup_records (GResolver *resolver,
1146 const gchar *rrname,
1147 GResolverRecordType record_type,
1148 GCancellable *cancellable,
1153 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1154 g_return_val_if_fail (rrname != NULL, NULL);
1156 maybe_emit_reload (resolver);
1157 records = G_RESOLVER_GET_CLASS (resolver)->
1158 lookup_records (resolver, rrname, record_type, cancellable, error);
1164 * g_resolver_lookup_records_async:
1165 * @resolver: a #GResolver
1166 * @rrname: the DNS name to look up the record for
1167 * @record_type: the type of DNS record to look up
1168 * @cancellable: (nullable): a #GCancellable, or %NULL
1169 * @callback: (scope async): callback to call after resolution completes
1170 * @user_data: (closure): data for @callback
1172 * Begins asynchronously performing a DNS lookup for the given
1173 * @rrname, and eventually calls @callback, which must call
1174 * g_resolver_lookup_records_finish() to get the final result. See
1175 * g_resolver_lookup_records() for more details.
1180 g_resolver_lookup_records_async (GResolver *resolver,
1181 const gchar *rrname,
1182 GResolverRecordType record_type,
1183 GCancellable *cancellable,
1184 GAsyncReadyCallback callback,
1187 g_return_if_fail (G_IS_RESOLVER (resolver));
1188 g_return_if_fail (rrname != NULL);
1190 maybe_emit_reload (resolver);
1191 G_RESOLVER_GET_CLASS (resolver)->
1192 lookup_records_async (resolver, rrname, record_type, cancellable, callback, user_data);
1196 * g_resolver_lookup_records_finish:
1197 * @resolver: a #GResolver
1198 * @result: the result passed to your #GAsyncReadyCallback
1199 * @error: return location for a #GError, or %NULL
1201 * Retrieves the result of a previous call to
1202 * g_resolver_lookup_records_async(). Returns a non-empty list of records as
1203 * #GVariant tuples. See #GResolverRecordType for information on what the
1206 * If the DNS resolution failed, @error (if non-%NULL) will be set to
1207 * a value from #GResolverError. If the operation was cancelled,
1208 * @error will be set to %G_IO_ERROR_CANCELLED.
1210 * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
1211 * #GVariant, or %NULL on error. You must free each of the records and the list
1212 * when you are done with it. (You can use g_list_free_full() with
1213 * g_variant_unref() to do this.)
1218 g_resolver_lookup_records_finish (GResolver *resolver,
1219 GAsyncResult *result,
1222 g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1223 return G_RESOLVER_GET_CLASS (resolver)->
1224 lookup_records_finish (resolver, result, error);
1228 g_resolver_get_serial (GResolver *resolver)
1232 g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
1234 maybe_emit_reload (resolver);
1237 g_mutex_lock (&resolver->priv->mutex);
1238 result = resolver->priv->resolv_conf_timestamp;
1239 g_mutex_unlock (&resolver->priv->mutex);
1248 * g_resolver_error_quark:
1250 * Gets the #GResolver Error Quark.
1252 * Returns: a #GQuark.
1256 G_DEFINE_QUARK (g-resolver-error-quark, g_resolver_error)