Imported Upstream version 2.72.3
[platform/upstream/glib.git] / gio / gresolver.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /* GIO - GLib Input, Output and Streaming Library
4  *
5  * Copyright (C) 2008 Red Hat, Inc.
6  * Copyright (C) 2018 Igalia S.L.
7  *
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.
12  *
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.
17  *
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/>.
20  */
21
22 #include "config.h"
23 #include <glib.h>
24 #include "glibintl.h"
25
26 #include "gresolver.h"
27 #include "gnetworkingprivate.h"
28 #include "gasyncresult.h"
29 #include "ginetaddress.h"
30 #include "gtask.h"
31 #include "gsrvtarget.h"
32 #include "gthreadedresolver.h"
33 #include "gioerror.h"
34 #include "gcancellable.h"
35
36 #ifdef G_OS_UNIX
37 #include <sys/stat.h>
38 #endif
39
40 #include <stdlib.h>
41
42
43 /**
44  * SECTION:gresolver
45  * @short_description: Asynchronous and cancellable DNS resolver
46  * @include: gio/gio.h
47  *
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()).
52  *
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.
56  */
57
58 enum {
59   RELOAD,
60   LAST_SIGNAL
61 };
62
63 static guint signals[LAST_SIGNAL] = { 0 };
64
65 struct _GResolverPrivate {
66 #ifdef G_OS_UNIX
67   GMutex mutex;
68   time_t resolv_conf_timestamp;  /* protected by @mutex */
69 #else
70   int dummy;
71 #endif
72 };
73
74 /**
75  * GResolver:
76  *
77  * The object that handles DNS resolution. Use g_resolver_get_default()
78  * to get the default resolver.
79  *
80  * This is an abstract type; subclasses of it implement different resolvers for
81  * different platforms and situations.
82  */
83 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GResolver, g_resolver, G_TYPE_OBJECT,
84                                   G_ADD_PRIVATE (GResolver)
85                                   g_networking_init ();)
86
87 static GList *
88 srv_records_to_targets (GList *records)
89 {
90   const gchar *hostname;
91   guint16 port, priority, weight;
92   GSrvTarget *target;
93   GList *l;
94
95   for (l = records; l != NULL; l = g_list_next (l))
96     {
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);
100       l->data = target;
101     }
102
103   return g_srv_target_list_sort (records);
104 }
105
106 static GList *
107 g_resolver_real_lookup_service (GResolver            *resolver,
108                                 const gchar          *rrname,
109                                 GCancellable         *cancellable,
110                                 GError              **error)
111 {
112   GList *records;
113
114   records = G_RESOLVER_GET_CLASS (resolver)->lookup_records (resolver,
115                                                              rrname,
116                                                              G_RESOLVER_RECORD_SRV,
117                                                              cancellable,
118                                                              error);
119
120   return srv_records_to_targets (records);
121 }
122
123 static void
124 g_resolver_real_lookup_service_async (GResolver            *resolver,
125                                       const gchar          *rrname,
126                                       GCancellable         *cancellable,
127                                       GAsyncReadyCallback   callback,
128                                       gpointer              user_data)
129 {
130   G_RESOLVER_GET_CLASS (resolver)->lookup_records_async (resolver,
131                                                          rrname,
132                                                          G_RESOLVER_RECORD_SRV,
133                                                          cancellable,
134                                                          callback,
135                                                          user_data);
136 }
137
138 static GList *
139 g_resolver_real_lookup_service_finish (GResolver            *resolver,
140                                        GAsyncResult         *result,
141                                        GError              **error)
142 {
143   GList *records;
144
145   records = G_RESOLVER_GET_CLASS (resolver)->lookup_records_finish (resolver,
146                                                                     result,
147                                                                     error);
148
149   return srv_records_to_targets (records);
150 }
151
152 static void
153 g_resolver_finalize (GObject *object)
154 {
155 #ifdef G_OS_UNIX
156   GResolver *resolver = G_RESOLVER (object);
157
158   g_mutex_clear (&resolver->priv->mutex);
159 #endif
160
161   G_OBJECT_CLASS (g_resolver_parent_class)->finalize (object);
162 }
163
164 static void
165 g_resolver_class_init (GResolverClass *resolver_class)
166 {
167   GObjectClass *object_class = G_OBJECT_CLASS (resolver_class);
168
169   object_class->finalize = g_resolver_finalize;
170
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;
175
176   /**
177    * GResolver::reload:
178    * @resolver: a #GResolver
179    *
180    * Emitted when the resolver notices that the system resolver
181    * configuration has changed.
182    **/
183   signals[RELOAD] =
184     g_signal_new (I_("reload"),
185                   G_TYPE_RESOLVER,
186                   G_SIGNAL_RUN_LAST,
187                   G_STRUCT_OFFSET (GResolverClass, reload),
188                   NULL, NULL,
189                   NULL,
190                   G_TYPE_NONE, 0);
191 }
192
193 static void
194 g_resolver_init (GResolver *resolver)
195 {
196 #ifdef G_OS_UNIX
197   struct stat st;
198 #endif
199
200   resolver->priv = g_resolver_get_instance_private (resolver);
201
202 #ifdef G_OS_UNIX
203   if (stat (_PATH_RESCONF, &st) == 0)
204     resolver->priv->resolv_conf_timestamp = st.st_mtime;
205
206   g_mutex_init (&resolver->priv->mutex);
207 #endif
208 }
209
210 G_LOCK_DEFINE_STATIC (default_resolver);
211 static GResolver *default_resolver;
212
213 /**
214  * g_resolver_get_default:
215  *
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.
219  *
220  * Returns: (transfer full): the default #GResolver.
221  *
222  * Since: 2.22
223  */
224 GResolver *
225 g_resolver_get_default (void)
226 {
227   GResolver *ret;
228
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);
234
235   return ret;
236 }
237
238 /**
239  * g_resolver_set_default:
240  * @resolver: the new default #GResolver
241  *
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.
245  *
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.
251  *
252  * Since: 2.22
253  */
254 void
255 g_resolver_set_default (GResolver *resolver)
256 {
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);
262 }
263
264 static void
265 maybe_emit_reload (GResolver *resolver)
266 {
267 #ifdef G_OS_UNIX
268   struct stat st;
269
270   if (stat (_PATH_RESCONF, &st) == 0)
271     {
272       g_mutex_lock (&resolver->priv->mutex);
273       if (st.st_mtime != resolver->priv->resolv_conf_timestamp)
274         {
275           resolver->priv->resolv_conf_timestamp = st.st_mtime;
276           g_mutex_unlock (&resolver->priv->mutex);
277           g_signal_emit (resolver, signals[RELOAD], 0);
278         }
279       else
280         g_mutex_unlock (&resolver->priv->mutex);
281     }
282 #endif
283 }
284
285 /* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */
286 static void
287 remove_duplicates (GList *addrs)
288 {
289   GList *l;
290   GList *ll;
291   GList *lll;
292
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...
296    */
297   for (l = addrs; l != NULL; l = l->next)
298     {
299       GInetAddress *address = G_INET_ADDRESS (l->data);
300       for (ll = l->next; ll != NULL; ll = lll)
301         {
302           GInetAddress *other_address = G_INET_ADDRESS (ll->data);
303           lll = ll->next;
304           if (g_inet_address_equal (address, other_address))
305             {
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);
309             }
310         }
311     }
312 }
313
314 static gboolean
315 hostname_is_localhost (const char *hostname)
316 {
317   size_t len = strlen (hostname);
318   const char *p;
319
320   /* Match "localhost", "localhost.", "*.localhost" and "*.localhost." */
321   if (len < strlen ("localhost"))
322     return FALSE;
323
324   if (hostname[len - 1] == '.')
325       len--;
326
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)
332     {
333       if (*p == '.')
334        {
335          p++;
336          break;
337        }
338       else if (p == hostname)
339         break;
340       p--;
341     }
342
343   len -= p - hostname;
344
345   return g_ascii_strncasecmp (p, "localhost", MAX (len, strlen ("localhost"))) == 0;
346 }
347
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.
352  */
353 static gboolean
354 handle_ip_address_or_localhost (const char                *hostname,
355                                 GList                    **addrs,
356                                 GResolverNameLookupFlags   flags,
357                                 GError                   **error)
358 {
359   GInetAddress *addr;
360
361 #ifndef G_OS_WIN32
362   struct in_addr ip4addr;
363 #endif
364
365   addr = g_inet_address_new_from_string (hostname);
366   if (addr)
367     {
368       *addrs = g_list_append (NULL, addr);
369       return TRUE;
370     }
371
372   *addrs = NULL;
373
374 #ifdef G_OS_WIN32
375
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.
380    */
381   if (strrchr (hostname, '[') != NULL ||
382       strrchr (hostname, ']') != NULL)
383 #else
384
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
388    * to reject.
389    */
390   if (inet_aton (hostname, &ip4addr))
391 #endif
392     {
393 #ifdef G_OS_WIN32
394       gchar *error_message = g_win32_error_message (WSAHOST_NOT_FOUND);
395 #else
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]");
399 #endif
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);
404
405       return TRUE;
406     }
407
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
415   */
416   if (hostname_is_localhost (hostname))
417     {
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));
422       if (*addrs == NULL)
423         {
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));
426         }
427       return TRUE;
428     }
429
430   return FALSE;
431 }
432
433 static GList *
434 lookup_by_name_real (GResolver                 *resolver,
435                      const gchar               *hostname,
436                      GResolverNameLookupFlags   flags,
437                      GCancellable              *cancellable,
438                      GError                    **error)
439 {
440   GList *addrs;
441   gchar *ascii_hostname = NULL;
442
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);
447
448   /* Check if @hostname is just an IP address */
449   if (handle_ip_address_or_localhost (hostname, &addrs, flags, error))
450     return addrs;
451
452   if (g_hostname_is_non_ascii (hostname))
453     hostname = ascii_hostname = g_hostname_to_ascii (hostname);
454
455   if (!hostname)
456     {
457       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
458                            _("Invalid hostname"));
459       return NULL;
460     }
461
462   maybe_emit_reload (resolver);
463
464   if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
465     {
466       if (!G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags)
467         {
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);
472           return NULL;
473         }
474       addrs = G_RESOLVER_GET_CLASS (resolver)->
475         lookup_by_name_with_flags (resolver, hostname, flags, cancellable, error);
476     }
477   else
478     addrs = G_RESOLVER_GET_CLASS (resolver)->
479       lookup_by_name (resolver, hostname, cancellable, error);
480
481   remove_duplicates (addrs);
482
483   g_free (ascii_hostname);
484   return addrs;
485 }
486
487 /**
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
493  *
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()).
498  *
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().
506  *
507  * If the DNS resolution fails, @error (if non-%NULL) will be set to a
508  * value from #GResolverError and %NULL will be returned.
509  *
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.
513  *
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.
517  *
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.)
522  *
523  * Since: 2.22
524  */
525 GList *
526 g_resolver_lookup_by_name (GResolver     *resolver,
527                            const gchar   *hostname,
528                            GCancellable  *cancellable,
529                            GError       **error)
530 {
531   return lookup_by_name_real (resolver,
532                               hostname,
533                               G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT,
534                               cancellable,
535                               error);
536 }
537
538 /**
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
545  *
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.
549  *
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.)
554  *
555  * Since: 2.60
556  */
557 GList *
558 g_resolver_lookup_by_name_with_flags (GResolver                 *resolver,
559                                       const gchar               *hostname,
560                                       GResolverNameLookupFlags   flags,
561                                       GCancellable              *cancellable,
562                                       GError                   **error)
563 {
564   return lookup_by_name_real (resolver,
565                               hostname,
566                               flags,
567                               cancellable,
568                               error);
569 }
570
571 static void
572 lookup_by_name_async_real (GResolver                *resolver,
573                            const gchar              *hostname,
574                            GResolverNameLookupFlags  flags,
575                            GCancellable             *cancellable,
576                            GAsyncReadyCallback       callback,
577                            gpointer                  user_data)
578 {
579   gchar *ascii_hostname = NULL;
580   GList *addrs;
581   GError *error = NULL;
582
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));
586
587   /* Check if @hostname is just an IP address */
588   if (handle_ip_address_or_localhost (hostname, &addrs, flags, &error))
589     {
590       GTask *task;
591
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");
595       if (addrs)
596         g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
597       else
598         g_task_return_error (task, error);
599       g_object_unref (task);
600       return;
601     }
602
603   if (g_hostname_is_non_ascii (hostname))
604     hostname = ascii_hostname = g_hostname_to_ascii (hostname);
605
606   if (!hostname)
607     {
608       GTask *task;
609
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);
617       return;
618     }
619
620   maybe_emit_reload (resolver);
621
622   if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
623     {
624       if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_async == NULL)
625         {
626           GTask *task;
627
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);
636         }
637       else
638         G_RESOLVER_GET_CLASS (resolver)->
639           lookup_by_name_with_flags_async (resolver, hostname, flags, cancellable, callback, user_data);
640     }
641   else
642     G_RESOLVER_GET_CLASS (resolver)->
643       lookup_by_name_async (resolver, hostname, cancellable, callback, user_data);
644
645   g_free (ascii_hostname);
646 }
647
648 static GList *
649 lookup_by_name_finish_real (GResolver     *resolver,
650                             GAsyncResult  *result,
651                             GError       **error,
652                             gboolean       with_flags)
653 {
654   GList *addrs;
655
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);
659
660   if (g_async_result_legacy_propagate_error (result, error))
661     return NULL;
662   else if (g_async_result_is_tagged (result, lookup_by_name_async_real))
663     {
664       /* Handle the stringified-IP-addr case */
665       return g_task_propagate_pointer (G_TASK (result), error);
666     }
667
668   if (with_flags)
669     {
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);
673     }
674   else
675     addrs = G_RESOLVER_GET_CLASS (resolver)->
676       lookup_by_name_finish (resolver, result, error);
677
678   remove_duplicates (addrs);
679
680   return addrs;
681 }
682
683 /**
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
691  *
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.
696  *
697  * Since: 2.60
698  */
699 void
700 g_resolver_lookup_by_name_with_flags_async (GResolver                *resolver,
701                                             const gchar              *hostname,
702                                             GResolverNameLookupFlags  flags,
703                                             GCancellable             *cancellable,
704                                             GAsyncReadyCallback       callback,
705                                             gpointer                  user_data)
706 {
707   lookup_by_name_async_real (resolver,
708                              hostname,
709                              flags,
710                              cancellable,
711                              callback,
712                              user_data);
713 }
714
715 /**
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
722  *
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.
727  *
728  * Since: 2.22
729  */
730 void
731 g_resolver_lookup_by_name_async (GResolver           *resolver,
732                                  const gchar         *hostname,
733                                  GCancellable        *cancellable,
734                                  GAsyncReadyCallback  callback,
735                                  gpointer             user_data)
736 {
737   lookup_by_name_async_real (resolver,
738                              hostname,
739                              0,
740                              cancellable,
741                              callback,
742                              user_data);
743 }
744
745 /**
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
750  *
751  * Retrieves the result of a call to
752  * g_resolver_lookup_by_name_async().
753  *
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.
757  *
758  * Returns: (element-type GInetAddress) (transfer full): a #GList
759  * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
760  * for more details.
761  *
762  * Since: 2.22
763  */
764 GList *
765 g_resolver_lookup_by_name_finish (GResolver     *resolver,
766                                   GAsyncResult  *result,
767                                   GError       **error)
768 {
769   return lookup_by_name_finish_real (resolver,
770                                      result,
771                                      error,
772                                      FALSE);
773 }
774
775 /**
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
780  *
781  * Retrieves the result of a call to
782  * g_resolver_lookup_by_name_with_flags_async().
783  *
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.
787  *
788  * Returns: (element-type GInetAddress) (transfer full): a #GList
789  * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
790  * for more details.
791  *
792  * Since: 2.60
793  */
794 GList *
795 g_resolver_lookup_by_name_with_flags_finish (GResolver     *resolver,
796                                              GAsyncResult  *result,
797                                              GError       **error)
798 {
799   return lookup_by_name_finish_real (resolver,
800                                      result,
801                                      error,
802                                      TRUE);
803 }
804
805 /**
806  * g_resolver_free_addresses: (skip)
807  * @addresses: a #GList of #GInetAddress
808  *
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
812  * by hand.)
813  *
814  * Since: 2.22
815  */
816 void
817 g_resolver_free_addresses (GList *addresses)
818 {
819   GList *a;
820
821   for (a = addresses; a; a = a->next)
822     g_object_unref (a->data);
823   g_list_free (addresses);
824 }
825
826 /**
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
832  *
833  * Synchronously reverse-resolves @address to determine its
834  * associated hostname.
835  *
836  * If the DNS resolution fails, @error (if non-%NULL) will be set to
837  * a value from #GResolverError.
838  *
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.
842  *
843  * Returns: a hostname (either ASCII-only, or in ASCII-encoded
844  *     form), or %NULL on error.
845  *
846  * Since: 2.22
847  */
848 gchar *
849 g_resolver_lookup_by_address (GResolver     *resolver,
850                               GInetAddress  *address,
851                               GCancellable  *cancellable,
852                               GError       **error)
853 {
854   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
855   g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
856
857   maybe_emit_reload (resolver);
858   return G_RESOLVER_GET_CLASS (resolver)->
859     lookup_by_address (resolver, address, cancellable, error);
860 }
861
862 /**
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
869  *
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.
873  *
874  * Since: 2.22
875  */
876 void
877 g_resolver_lookup_by_address_async (GResolver           *resolver,
878                                     GInetAddress        *address,
879                                     GCancellable        *cancellable,
880                                     GAsyncReadyCallback  callback,
881                                     gpointer             user_data)
882 {
883   g_return_if_fail (G_IS_RESOLVER (resolver));
884   g_return_if_fail (G_IS_INET_ADDRESS (address));
885
886   maybe_emit_reload (resolver);
887   G_RESOLVER_GET_CLASS (resolver)->
888     lookup_by_address_async (resolver, address, cancellable, callback, user_data);
889 }
890
891 /**
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
896  *
897  * Retrieves the result of a previous call to
898  * g_resolver_lookup_by_address_async().
899  *
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.
903  *
904  * Returns: a hostname (either ASCII-only, or in ASCII-encoded
905  * form), or %NULL on error.
906  *
907  * Since: 2.22
908  */
909 gchar *
910 g_resolver_lookup_by_address_finish (GResolver     *resolver,
911                                      GAsyncResult  *result,
912                                      GError       **error)
913 {
914   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
915
916   if (g_async_result_legacy_propagate_error (result, error))
917     return NULL;
918
919   return G_RESOLVER_GET_CLASS (resolver)->
920     lookup_by_address_finish (resolver, result, error);
921 }
922
923 static gchar *
924 g_resolver_get_service_rrname (const char *service,
925                                const char *protocol,
926                                const char *domain)
927 {
928   gchar *rrname, *ascii_domain = NULL;
929
930   if (g_hostname_is_non_ascii (domain))
931     domain = ascii_domain = g_hostname_to_ascii (domain);
932   if (!domain)
933     return NULL;
934
935   rrname = g_strdup_printf ("_%s._%s.%s", service, protocol, domain);
936
937   g_free (ascii_domain);
938   return rrname;
939 }
940
941 /**
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
949  *
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.
955  *
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.)
960  *
961  * If the DNS resolution fails, @error (if non-%NULL) will be set to
962  * a value from #GResolverError and %NULL will be returned.
963  *
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.
967  *
968  * If you are planning to connect to the service, it is usually easier
969  * to create a #GNetworkService and use its #GSocketConnectable
970  * interface.
971  *
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
975  * this.)
976  *
977  * Since: 2.22
978  */
979 GList *
980 g_resolver_lookup_service (GResolver     *resolver,
981                            const gchar   *service,
982                            const gchar   *protocol,
983                            const gchar   *domain,
984                            GCancellable  *cancellable,
985                            GError       **error)
986 {
987   GList *targets;
988   gchar *rrname;
989
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);
994
995   rrname = g_resolver_get_service_rrname (service, protocol, domain);
996   if (!rrname)
997     {
998       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
999                            _("Invalid domain"));
1000       return NULL;
1001     }
1002
1003   maybe_emit_reload (resolver);
1004   targets = G_RESOLVER_GET_CLASS (resolver)->
1005     lookup_service (resolver, rrname, cancellable, error);
1006
1007   g_free (rrname);
1008   return targets;
1009 }
1010
1011 /**
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
1020  *
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
1025  * details.
1026  *
1027  * Since: 2.22
1028  */
1029 void
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,
1036                                  gpointer             user_data)
1037 {
1038   gchar *rrname;
1039
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);
1044
1045   rrname = g_resolver_get_service_rrname (service, protocol, domain);
1046   if (!rrname)
1047     {
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"));
1052       return;
1053     }
1054
1055   maybe_emit_reload (resolver);
1056   G_RESOLVER_GET_CLASS (resolver)->
1057     lookup_service_async (resolver, rrname, cancellable, callback, user_data);
1058
1059   g_free (rrname);
1060 }
1061
1062 /**
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
1067  *
1068  * Retrieves the result of a previous call to
1069  * g_resolver_lookup_service_async().
1070  *
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.
1074  *
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
1077  * details.
1078  *
1079  * Since: 2.22
1080  */
1081 GList *
1082 g_resolver_lookup_service_finish (GResolver     *resolver,
1083                                   GAsyncResult  *result,
1084                                   GError       **error)
1085 {
1086   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1087
1088   if (g_async_result_legacy_propagate_error (result, error))
1089     return NULL;
1090
1091   return G_RESOLVER_GET_CLASS (resolver)->
1092     lookup_service_finish (resolver, result, error);
1093 }
1094
1095 /**
1096  * g_resolver_free_targets: (skip)
1097  * @targets: a #GList of #GSrvTarget
1098  *
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
1102  * results by hand.)
1103  *
1104  * Since: 2.22
1105  */
1106 void
1107 g_resolver_free_targets (GList *targets)
1108 {
1109   GList *t;
1110
1111   for (t = targets; t; t = t->next)
1112     g_srv_target_free (t->data);
1113   g_list_free (targets);
1114 }
1115
1116 /**
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
1123  *
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.
1127  *
1128  * If the DNS resolution fails, @error (if non-%NULL) will be set to
1129  * a value from #GResolverError and %NULL will be returned.
1130  *
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.
1134  *
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.)
1139  *
1140  * Since: 2.34
1141  */
1142 GList *
1143 g_resolver_lookup_records (GResolver            *resolver,
1144                            const gchar          *rrname,
1145                            GResolverRecordType   record_type,
1146                            GCancellable         *cancellable,
1147                            GError              **error)
1148 {
1149   GList *records;
1150
1151   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
1152   g_return_val_if_fail (rrname != NULL, NULL);
1153
1154   maybe_emit_reload (resolver);
1155   records = G_RESOLVER_GET_CLASS (resolver)->
1156     lookup_records (resolver, rrname, record_type, cancellable, error);
1157
1158   return records;
1159 }
1160
1161 /**
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
1169  *
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.
1174  *
1175  * Since: 2.34
1176  */
1177 void
1178 g_resolver_lookup_records_async (GResolver           *resolver,
1179                                  const gchar         *rrname,
1180                                  GResolverRecordType  record_type,
1181                                  GCancellable        *cancellable,
1182                                  GAsyncReadyCallback  callback,
1183                                  gpointer             user_data)
1184 {
1185   g_return_if_fail (G_IS_RESOLVER (resolver));
1186   g_return_if_fail (rrname != NULL);
1187
1188   maybe_emit_reload (resolver);
1189   G_RESOLVER_GET_CLASS (resolver)->
1190     lookup_records_async (resolver, rrname, record_type, cancellable, callback, user_data);
1191 }
1192
1193 /**
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
1198  *
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
1202  * records contain.
1203  *
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.
1207  *
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.)
1212  *
1213  * Since: 2.34
1214  */
1215 GList *
1216 g_resolver_lookup_records_finish (GResolver     *resolver,
1217                                   GAsyncResult  *result,
1218                                   GError       **error)
1219 {
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);
1223 }
1224
1225 guint64
1226 g_resolver_get_serial (GResolver *resolver)
1227 {
1228   guint64 result;
1229
1230   g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
1231
1232   maybe_emit_reload (resolver);
1233
1234 #ifdef G_OS_UNIX
1235   g_mutex_lock (&resolver->priv->mutex);
1236   result = resolver->priv->resolv_conf_timestamp;
1237   g_mutex_unlock (&resolver->priv->mutex);
1238 #else
1239   result = 1;
1240 #endif
1241
1242   return result;
1243 }
1244
1245 /**
1246  * g_resolver_error_quark:
1247  *
1248  * Gets the #GResolver Error Quark.
1249  *
1250  * Returns: a #GQuark.
1251  *
1252  * Since: 2.22
1253  */
1254 G_DEFINE_QUARK (g-resolver-error-quark, g_resolver_error)