LCOV - code coverage report
Current view: top level - glib/gio - gresolver.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 190 319 59.6 %
Date: 2024-04-16 05:15:53 Functions: 28 44 63.6 %
Branches: 66 110 60.0 %

           Branch data     Line data    Source code
       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                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       9                 :            :  *
      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.
      14                 :            :  *
      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.
      19                 :            :  *
      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/>.
      22                 :            :  */
      23                 :            : 
      24                 :            : #include "config.h"
      25                 :            : #include <glib.h>
      26                 :            : #include "glibintl.h"
      27                 :            : 
      28                 :            : #include "gresolver.h"
      29                 :            : #include "gnetworkingprivate.h"
      30                 :            : #include "gasyncresult.h"
      31                 :            : #include "ginetaddress.h"
      32                 :            : #include "gtask.h"
      33                 :            : #include "gsrvtarget.h"
      34                 :            : #include "gthreadedresolver.h"
      35                 :            : #include "gioerror.h"
      36                 :            : #include "gcancellable.h"
      37                 :            : 
      38                 :            : #ifdef G_OS_UNIX
      39                 :            : #include <sys/stat.h>
      40                 :            : #endif
      41                 :            : 
      42                 :            : #include <stdlib.h>
      43                 :            : 
      44                 :            : 
      45                 :            : /**
      46                 :            :  * GResolver:
      47                 :            :  *
      48                 :            :  * The object that handles DNS resolution. Use [func@Gio.Resolver.get_default]
      49                 :            :  * to get the default resolver.
      50                 :            :  *
      51                 :            :  * `GResolver` provides cancellable synchronous and asynchronous DNS
      52                 :            :  * resolution, for hostnames ([method@Gio.Resolver.lookup_by_address],
      53                 :            :  * [method@Gio.Resolver.lookup_by_name] and their async variants) and SRV
      54                 :            :  * (service) records ([method@Gio.Resolver.lookup_service]).
      55                 :            :  *
      56                 :            :  * [class@Gio.NetworkAddress] and [class@Gio.NetworkService] provide wrappers
      57                 :            :  * around `GResolver` functionality that also implement
      58                 :            :  * [iface@Gio.SocketConnectable], making it easy to connect to a remote
      59                 :            :  * host/service.
      60                 :            :  *
      61                 :            :  * The default resolver (see [func@Gio.Resolver.get_default]) has a timeout of
      62                 :            :  * 30s set on it since GLib 2.78. Earlier versions of GLib did not support
      63                 :            :  * resolver timeouts.
      64                 :            :  *
      65                 :            :  * This is an abstract type; subclasses of it implement different resolvers for
      66                 :            :  * different platforms and situations.
      67                 :            :  */
      68                 :            : 
      69                 :            : typedef enum {
      70                 :            :   PROP_TIMEOUT = 1,
      71                 :            : } GResolverProperty;
      72                 :            : 
      73                 :            : static GParamSpec *props[PROP_TIMEOUT + 1] = { NULL, };
      74                 :            : 
      75                 :            : enum {
      76                 :            :   RELOAD,
      77                 :            :   LAST_SIGNAL
      78                 :            : };
      79                 :            : 
      80                 :            : static guint signals[LAST_SIGNAL] = { 0 };
      81                 :            : 
      82                 :            : struct _GResolverPrivate {
      83                 :            :   unsigned timeout_ms;
      84                 :            : 
      85                 :            : #ifdef G_OS_UNIX
      86                 :            :   GMutex mutex;
      87                 :            :   time_t resolv_conf_timestamp;  /* protected by @mutex */
      88                 :            : #endif
      89                 :            : };
      90                 :            : 
      91   [ +  +  +  -  :        389 : G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GResolver, g_resolver, G_TYPE_OBJECT,
                   +  + ]
      92                 :            :                                   G_ADD_PRIVATE (GResolver)
      93                 :            :                                   g_networking_init ();)
      94                 :            : 
      95                 :            : static GList *
      96                 :          0 : srv_records_to_targets (GList *records)
      97                 :            : {
      98                 :            :   const gchar *hostname;
      99                 :            :   guint16 port, priority, weight;
     100                 :            :   GSrvTarget *target;
     101                 :            :   GList *l;
     102                 :            : 
     103         [ #  # ]:          0 :   for (l = records; l != NULL; l = g_list_next (l))
     104                 :            :     {
     105                 :          0 :       g_variant_get (l->data, "(qqq&s)", &priority, &weight, &port, &hostname);
     106                 :          0 :       target = g_srv_target_new (hostname, port, priority, weight);
     107                 :          0 :       g_variant_unref (l->data);
     108         [ #  # ]:          0 :       l->data = target;
     109                 :            :     }
     110                 :            : 
     111                 :          0 :   return g_srv_target_list_sort (records);
     112                 :            : }
     113                 :            : 
     114                 :            : static GList *
     115                 :          0 : g_resolver_real_lookup_service (GResolver            *resolver,
     116                 :            :                                 const gchar          *rrname,
     117                 :            :                                 GCancellable         *cancellable,
     118                 :            :                                 GError              **error)
     119                 :            : {
     120                 :            :   GList *records;
     121                 :            : 
     122                 :          0 :   records = G_RESOLVER_GET_CLASS (resolver)->lookup_records (resolver,
     123                 :            :                                                              rrname,
     124                 :            :                                                              G_RESOLVER_RECORD_SRV,
     125                 :            :                                                              cancellable,
     126                 :            :                                                              error);
     127                 :            : 
     128                 :          0 :   return srv_records_to_targets (records);
     129                 :            : }
     130                 :            : 
     131                 :            : static void
     132                 :          0 : g_resolver_real_lookup_service_async (GResolver            *resolver,
     133                 :            :                                       const gchar          *rrname,
     134                 :            :                                       GCancellable         *cancellable,
     135                 :            :                                       GAsyncReadyCallback   callback,
     136                 :            :                                       gpointer              user_data)
     137                 :            : {
     138                 :          0 :   G_RESOLVER_GET_CLASS (resolver)->lookup_records_async (resolver,
     139                 :            :                                                          rrname,
     140                 :            :                                                          G_RESOLVER_RECORD_SRV,
     141                 :            :                                                          cancellable,
     142                 :            :                                                          callback,
     143                 :            :                                                          user_data);
     144                 :          0 : }
     145                 :            : 
     146                 :            : static GList *
     147                 :          0 : g_resolver_real_lookup_service_finish (GResolver            *resolver,
     148                 :            :                                        GAsyncResult         *result,
     149                 :            :                                        GError              **error)
     150                 :            : {
     151                 :            :   GList *records;
     152                 :            : 
     153                 :          0 :   records = G_RESOLVER_GET_CLASS (resolver)->lookup_records_finish (resolver,
     154                 :            :                                                                     result,
     155                 :            :                                                                     error);
     156                 :            : 
     157                 :          0 :   return srv_records_to_targets (records);
     158                 :            : }
     159                 :            : 
     160                 :            : static void
     161                 :          0 : g_resolver_get_property (GObject    *object,
     162                 :            :                          guint       prop_id,
     163                 :            :                          GValue     *value,
     164                 :            :                          GParamSpec *pspec)
     165                 :            : {
     166                 :          0 :   GResolver *self = G_RESOLVER (object);
     167                 :            : 
     168         [ #  # ]:          0 :   switch ((GResolverProperty) prop_id)
     169                 :            :     {
     170                 :          0 :     case PROP_TIMEOUT:
     171                 :          0 :       g_value_set_uint (value, g_resolver_get_timeout (self));
     172                 :          0 :       break;
     173                 :          0 :     default:
     174                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     175                 :            :     }
     176                 :          0 : }
     177                 :            : 
     178                 :            : static void
     179                 :          4 : g_resolver_set_property (GObject      *object,
     180                 :            :                          guint         prop_id,
     181                 :            :                          const GValue *value,
     182                 :            :                          GParamSpec   *pspec)
     183                 :            : {
     184                 :          4 :   GResolver *self = G_RESOLVER (object);
     185                 :            : 
     186         [ +  - ]:          4 :   switch ((GResolverProperty) prop_id)
     187                 :            :     {
     188                 :          4 :     case PROP_TIMEOUT:
     189                 :          4 :       g_resolver_set_timeout (self, g_value_get_uint (value));
     190                 :          4 :       break;
     191                 :          0 :     default:
     192                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     193                 :            :     }
     194                 :          4 : }
     195                 :            : 
     196                 :            : static void
     197                 :         16 : g_resolver_finalize (GObject *object)
     198                 :            : {
     199                 :            : #ifdef G_OS_UNIX
     200                 :         16 :   GResolver *resolver = G_RESOLVER (object);
     201                 :            : 
     202                 :         16 :   g_mutex_clear (&resolver->priv->mutex);
     203                 :            : #endif
     204                 :            : 
     205                 :         16 :   G_OBJECT_CLASS (g_resolver_parent_class)->finalize (object);
     206                 :         16 : }
     207                 :            : 
     208                 :            : static void
     209                 :          6 : g_resolver_class_init (GResolverClass *resolver_class)
     210                 :            : {
     211                 :          6 :   GObjectClass *object_class = G_OBJECT_CLASS (resolver_class);
     212                 :            : 
     213                 :          6 :   object_class->get_property = g_resolver_get_property;
     214                 :          6 :   object_class->set_property = g_resolver_set_property;
     215                 :          6 :   object_class->finalize = g_resolver_finalize;
     216                 :            : 
     217                 :            :   /* Automatically pass these over to the lookup_records methods */
     218                 :          6 :   resolver_class->lookup_service = g_resolver_real_lookup_service;
     219                 :          6 :   resolver_class->lookup_service_async = g_resolver_real_lookup_service_async;
     220                 :          6 :   resolver_class->lookup_service_finish = g_resolver_real_lookup_service_finish;
     221                 :            : 
     222                 :            :   /**
     223                 :            :    * GResolver:timeout:
     224                 :            :    *
     225                 :            :    * The timeout applied to all resolver lookups, in milliseconds.
     226                 :            :    *
     227                 :            :    * This may be changed through the lifetime of the #GResolver. The new value
     228                 :            :    * will apply to any lookups started after the change, but not to any
     229                 :            :    * already-ongoing lookups.
     230                 :            :    *
     231                 :            :    * If this is `0`, no timeout is applied to lookups.
     232                 :            :    *
     233                 :            :    * No timeout was applied to lookups before this property was added in
     234                 :            :    * GLib 2.78.
     235                 :            :    *
     236                 :            :    * Since: 2.78
     237                 :            :    */
     238                 :          6 :   props[PROP_TIMEOUT] =
     239                 :          6 :     g_param_spec_uint ("timeout", NULL, NULL,
     240                 :            :                        0, G_MAXUINT, 0,
     241                 :            :                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
     242                 :            : 
     243                 :          6 :   g_object_class_install_properties (object_class, G_N_ELEMENTS (props), props);
     244                 :            : 
     245                 :            :   /**
     246                 :            :    * GResolver::reload:
     247                 :            :    * @resolver: a #GResolver
     248                 :            :    *
     249                 :            :    * Emitted when the resolver notices that the system resolver
     250                 :            :    * configuration has changed.
     251                 :            :    **/
     252                 :          6 :   signals[RELOAD] =
     253                 :          6 :     g_signal_new (I_("reload"),
     254                 :            :                   G_TYPE_RESOLVER,
     255                 :            :                   G_SIGNAL_RUN_LAST,
     256                 :            :                   G_STRUCT_OFFSET (GResolverClass, reload),
     257                 :            :                   NULL, NULL,
     258                 :            :                   NULL,
     259                 :            :                   G_TYPE_NONE, 0);
     260                 :          6 : }
     261                 :            : 
     262                 :            : static void
     263                 :         22 : g_resolver_init (GResolver *resolver)
     264                 :            : {
     265                 :            : #ifdef G_OS_UNIX
     266                 :            :   struct stat st;
     267                 :            : #endif
     268                 :            : 
     269                 :         22 :   resolver->priv = g_resolver_get_instance_private (resolver);
     270                 :            : 
     271                 :            : #ifdef G_OS_UNIX
     272         [ +  - ]:         22 :   if (stat (_PATH_RESCONF, &st) == 0)
     273                 :         22 :     resolver->priv->resolv_conf_timestamp = st.st_mtime;
     274                 :            : 
     275                 :         22 :   g_mutex_init (&resolver->priv->mutex);
     276                 :            : #endif
     277                 :         22 : }
     278                 :            : 
     279                 :            : G_LOCK_DEFINE_STATIC (default_resolver);
     280                 :            : static GResolver *default_resolver;
     281                 :            : 
     282                 :            : /**
     283                 :            :  * g_resolver_get_default:
     284                 :            :  *
     285                 :            :  * Gets the default #GResolver. You should unref it when you are done
     286                 :            :  * with it. #GResolver may use its reference count as a hint about how
     287                 :            :  * many threads it should allocate for concurrent DNS resolutions.
     288                 :            :  *
     289                 :            :  * Returns: (transfer full): the default #GResolver.
     290                 :            :  *
     291                 :            :  * Since: 2.22
     292                 :            :  */
     293                 :            : GResolver *
     294                 :        137 : g_resolver_get_default (void)
     295                 :            : {
     296                 :            :   GResolver *ret;
     297                 :            : 
     298                 :        137 :   G_LOCK (default_resolver);
     299         [ +  + ]:        137 :   if (!default_resolver)
     300                 :          4 :     default_resolver = g_object_new (G_TYPE_THREADED_RESOLVER,
     301                 :            :                                      "timeout", 30000,
     302                 :            :                                      NULL);
     303                 :        137 :   ret = g_object_ref (default_resolver);
     304                 :        137 :   G_UNLOCK (default_resolver);
     305                 :            : 
     306                 :        137 :   return ret;
     307                 :            : }
     308                 :            : 
     309                 :            : /**
     310                 :            :  * g_resolver_set_default:
     311                 :            :  * @resolver: the new default #GResolver
     312                 :            :  *
     313                 :            :  * Sets @resolver to be the application's default resolver (reffing
     314                 :            :  * @resolver, and unreffing the previous default resolver, if any).
     315                 :            :  * Future calls to g_resolver_get_default() will return this resolver.
     316                 :            :  *
     317                 :            :  * This can be used if an application wants to perform any sort of DNS
     318                 :            :  * caching or "pinning"; it can implement its own #GResolver that
     319                 :            :  * calls the original default resolver for DNS operations, and
     320                 :            :  * implements its own cache policies on top of that, and then set
     321                 :            :  * itself as the default resolver for all later code to use.
     322                 :            :  *
     323                 :            :  * Since: 2.22
     324                 :            :  */
     325                 :            : void
     326                 :         35 : g_resolver_set_default (GResolver *resolver)
     327                 :            : {
     328                 :         35 :   G_LOCK (default_resolver);
     329         [ +  + ]:         35 :   if (default_resolver)
     330                 :         34 :     g_object_unref (default_resolver);
     331                 :         35 :   default_resolver = g_object_ref (resolver);
     332                 :         35 :   G_UNLOCK (default_resolver);
     333                 :         35 : }
     334                 :            : 
     335                 :            : static void
     336                 :        145 : maybe_emit_reload (GResolver *resolver)
     337                 :            : {
     338                 :            : #ifdef G_OS_UNIX
     339                 :            :   struct stat st;
     340                 :            : 
     341         [ +  - ]:        145 :   if (stat (_PATH_RESCONF, &st) == 0)
     342                 :            :     {
     343                 :        145 :       g_mutex_lock (&resolver->priv->mutex);
     344         [ -  + ]:        145 :       if (st.st_mtime != resolver->priv->resolv_conf_timestamp)
     345                 :            :         {
     346                 :          0 :           resolver->priv->resolv_conf_timestamp = st.st_mtime;
     347                 :          0 :           g_mutex_unlock (&resolver->priv->mutex);
     348                 :          0 :           g_signal_emit (resolver, signals[RELOAD], 0);
     349                 :            :         }
     350                 :            :       else
     351                 :        145 :         g_mutex_unlock (&resolver->priv->mutex);
     352                 :            :     }
     353                 :            : #endif
     354                 :        145 : }
     355                 :            : 
     356                 :            : /* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */
     357                 :            : static void
     358                 :         46 : remove_duplicates (GList *addrs)
     359                 :            : {
     360                 :            :   GList *l;
     361                 :            :   GList *ll;
     362                 :            :   GList *lll;
     363                 :            : 
     364                 :            :   /* TODO: if this is too slow (it's O(n^2) but n is typically really
     365                 :            :    * small), we can do something more clever but note that we must not
     366                 :            :    * change the order of elements...
     367                 :            :    */
     368         [ +  + ]:         89 :   for (l = addrs; l != NULL; l = l->next)
     369                 :            :     {
     370                 :         43 :       GInetAddress *address = G_INET_ADDRESS (l->data);
     371         [ +  + ]:         62 :       for (ll = l->next; ll != NULL; ll = lll)
     372                 :            :         {
     373                 :         19 :           GInetAddress *other_address = G_INET_ADDRESS (ll->data);
     374                 :         19 :           lll = ll->next;
     375         [ -  + ]:         19 :           if (g_inet_address_equal (address, other_address))
     376                 :            :             {
     377                 :          0 :               g_object_unref (other_address);
     378                 :            :               /* we never return the first element */
     379         [ #  # ]:          0 :               g_warn_if_fail (g_list_delete_link (addrs, ll) == addrs);
     380                 :            :             }
     381                 :            :         }
     382                 :            :     }
     383                 :         46 : }
     384                 :            : 
     385                 :            : static gboolean
     386                 :         57 : hostname_is_localhost (const char *hostname)
     387                 :            : {
     388                 :         57 :   size_t len = strlen (hostname);
     389                 :            :   const char *p;
     390                 :            : 
     391                 :            :   /* Match "localhost", "localhost.", "*.localhost" and "*.localhost." */
     392         [ +  + ]:         57 :   if (len < strlen ("localhost"))
     393                 :          1 :     return FALSE;
     394                 :            : 
     395         [ +  + ]:         56 :   if (hostname[len - 1] == '.')
     396                 :          2 :       len--;
     397                 :            : 
     398                 :            :   /* Scan backwards in @hostname to find the right-most dot (excluding the final dot, if it exists, as it was chopped off above).
     399                 :            :    * We can’t use strrchr() because because we need to operate with string lengths.
     400                 :            :    * End with @p pointing to the character after the right-most dot. */
     401                 :         56 :   p = hostname + len - 1;
     402         [ +  - ]:        318 :   while (p >= hostname)
     403                 :            :     {
     404         [ +  + ]:        318 :       if (*p == '.')
     405                 :            :        {
     406                 :         47 :          p++;
     407                 :         47 :          break;
     408                 :            :        }
     409         [ +  + ]:        271 :       else if (p == hostname)
     410                 :          9 :         break;
     411                 :        262 :       p--;
     412                 :            :     }
     413                 :            : 
     414                 :         56 :   len -= p - hostname;
     415                 :            : 
     416                 :         56 :   return g_ascii_strncasecmp (p, "localhost", MAX (len, strlen ("localhost"))) == 0;
     417                 :            : }
     418                 :            : 
     419                 :            : /* Note that this does not follow the "FALSE means @error is set"
     420                 :            :  * convention. The return value tells the caller whether it should
     421                 :            :  * return @addrs and @error to the caller right away, or if it should
     422                 :            :  * continue and trying to resolve the name as a hostname.
     423                 :            :  */
     424                 :            : static gboolean
     425                 :         88 : handle_ip_address_or_localhost (const char                *hostname,
     426                 :            :                                 GList                    **addrs,
     427                 :            :                                 GResolverNameLookupFlags   flags,
     428                 :            :                                 GError                   **error)
     429                 :            : {
     430                 :            :   GInetAddress *addr;
     431                 :            : 
     432                 :            : #ifndef G_OS_WIN32
     433                 :            :   struct in_addr ip4addr;
     434                 :            : #endif
     435                 :            : 
     436                 :         88 :   addr = g_inet_address_new_from_string (hostname);
     437         [ +  + ]:         88 :   if (addr)
     438                 :            :     {
     439                 :         17 :       *addrs = g_list_append (NULL, addr);
     440                 :         17 :       return TRUE;
     441                 :            :     }
     442                 :            : 
     443                 :         71 :   *addrs = NULL;
     444                 :            : 
     445                 :            : #ifdef G_OS_WIN32
     446                 :            : 
     447                 :            :   /* Reject IPv6 addresses that have brackets ('[' or ']') and/or port numbers,
     448                 :            :    * as no valid addresses should contain these at this point.
     449                 :            :    * Non-standard IPv4 addresses would be rejected during the call to
     450                 :            :    * getaddrinfo() later.
     451                 :            :    */
     452                 :            :   if (strrchr (hostname, '[') != NULL ||
     453                 :            :       strrchr (hostname, ']') != NULL)
     454                 :            : #else
     455                 :            : 
     456                 :            :   /* Reject non-standard IPv4 numbers-and-dots addresses.
     457                 :            :    * g_inet_address_new_from_string() will have accepted any "real" IP
     458                 :            :    * address, so if inet_aton() succeeds, then it's an address we want
     459                 :            :    * to reject.
     460                 :            :    */
     461         [ +  + ]:         71 :   if (inet_aton (hostname, &ip4addr))
     462                 :            : #endif
     463                 :            :     {
     464                 :            : #ifdef G_OS_WIN32
     465                 :            :       gchar *error_message = g_win32_error_message (WSAHOST_NOT_FOUND);
     466                 :            : #else
     467                 :         14 :       gchar *error_message = g_locale_to_utf8 (gai_strerror (EAI_NONAME), -1, NULL, NULL, NULL);
     468         [ -  + ]:         14 :       if (error_message == NULL)
     469                 :          0 :         error_message = g_strdup ("[Invalid UTF-8]");
     470                 :            : #endif
     471                 :         14 :       g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
     472                 :            :                    _("Error resolving “%s”: %s"),
     473                 :            :                    hostname, error_message);
     474                 :         14 :       g_free (error_message);
     475                 :            : 
     476                 :         14 :       return TRUE;
     477                 :            :     }
     478                 :            : 
     479                 :            :   /* Always resolve localhost to a loopback address so it can be reliably considered secure.
     480                 :            :      This behavior is being adopted by browsers:
     481                 :            :      - https://w3c.github.io/webappsec-secure-contexts/
     482                 :            :      - https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/RC9dSw-O3fE/E3_0XaT0BAAJ
     483                 :            :      - https://chromium.googlesource.com/chromium/src.git/+/8da2a80724a9b896890602ff77ef2216cb951399
     484                 :            :      - https://bugs.webkit.org/show_bug.cgi?id=171934
     485                 :            :      - https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-06
     486                 :            :   */
     487         [ +  + ]:         57 :   if (hostname_is_localhost (hostname))
     488                 :            :     {
     489         [ +  + ]:         10 :       if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY)
     490                 :          3 :         *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6)); 
     491         [ +  + ]:         10 :       if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY)
     492                 :          3 :         *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4));
     493         [ +  + ]:         10 :       if (*addrs == NULL)
     494                 :            :         {
     495                 :          4 :           *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6));
     496                 :          4 :           *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4));
     497                 :            :         }
     498                 :         10 :       return TRUE;
     499                 :            :     }
     500                 :            : 
     501                 :         47 :   return FALSE;
     502                 :            : }
     503                 :            : 
     504                 :            : static GList *
     505                 :         41 : lookup_by_name_real (GResolver                 *resolver,
     506                 :            :                      const gchar               *hostname,
     507                 :            :                      GResolverNameLookupFlags   flags,
     508                 :            :                      GCancellable              *cancellable,
     509                 :            :                      GError                    **error)
     510                 :            : {
     511                 :            :   GList *addrs;
     512                 :         41 :   gchar *ascii_hostname = NULL;
     513                 :            : 
     514                 :         41 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
     515                 :         41 :   g_return_val_if_fail (hostname != NULL, NULL);
     516                 :         41 :   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
     517                 :         41 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     518                 :            : 
     519                 :            :   /* Check if @hostname is just an IP address */
     520         [ +  + ]:         41 :   if (handle_ip_address_or_localhost (hostname, &addrs, flags, error))
     521                 :         30 :     return addrs;
     522                 :            : 
     523         [ -  + ]:         11 :   if (g_hostname_is_non_ascii (hostname))
     524                 :          0 :     hostname = ascii_hostname = g_hostname_to_ascii (hostname);
     525                 :            : 
     526         [ -  + ]:         11 :   if (!hostname)
     527                 :            :     {
     528                 :          0 :       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
     529                 :            :                            _("Invalid hostname"));
     530                 :          0 :       return NULL;
     531                 :            :     }
     532                 :            : 
     533                 :         11 :   maybe_emit_reload (resolver);
     534                 :            : 
     535         [ -  + ]:         11 :   if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
     536                 :            :     {
     537         [ #  # ]:          0 :       if (!G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags)
     538                 :            :         {
     539                 :          0 :           g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
     540                 :            :                        /* Translators: The placeholder is for a function name. */
     541                 :            :                        _("%s not implemented"), "lookup_by_name_with_flags");
     542                 :          0 :           g_free (ascii_hostname);
     543                 :          0 :           return NULL;
     544                 :            :         }
     545                 :          0 :       addrs = G_RESOLVER_GET_CLASS (resolver)->
     546                 :            :         lookup_by_name_with_flags (resolver, hostname, flags, cancellable, error);
     547                 :            :     }
     548                 :            :   else
     549                 :         11 :     addrs = G_RESOLVER_GET_CLASS (resolver)->
     550                 :            :       lookup_by_name (resolver, hostname, cancellable, error);
     551                 :            : 
     552                 :         11 :   remove_duplicates (addrs);
     553                 :            : 
     554                 :         11 :   g_free (ascii_hostname);
     555                 :         11 :   return addrs;
     556                 :            : }
     557                 :            : 
     558                 :            : /**
     559                 :            :  * g_resolver_lookup_by_name:
     560                 :            :  * @resolver: a #GResolver
     561                 :            :  * @hostname: the hostname to look up
     562                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
     563                 :            :  * @error: return location for a #GError, or %NULL
     564                 :            :  *
     565                 :            :  * Synchronously resolves @hostname to determine its associated IP
     566                 :            :  * address(es). @hostname may be an ASCII-only or UTF-8 hostname, or
     567                 :            :  * the textual form of an IP address (in which case this just becomes
     568                 :            :  * a wrapper around g_inet_address_new_from_string()).
     569                 :            :  *
     570                 :            :  * On success, g_resolver_lookup_by_name() will return a non-empty #GList of
     571                 :            :  * #GInetAddress, sorted in order of preference and guaranteed to not
     572                 :            :  * contain duplicates. That is, if using the result to connect to
     573                 :            :  * @hostname, you should attempt to connect to the first address
     574                 :            :  * first, then the second if the first fails, etc. If you are using
     575                 :            :  * the result to listen on a socket, it is appropriate to add each
     576                 :            :  * result using e.g. g_socket_listener_add_address().
     577                 :            :  *
     578                 :            :  * If the DNS resolution fails, @error (if non-%NULL) will be set to a
     579                 :            :  * value from #GResolverError and %NULL will be returned.
     580                 :            :  *
     581                 :            :  * If @cancellable is non-%NULL, it can be used to cancel the
     582                 :            :  * operation, in which case @error (if non-%NULL) will be set to
     583                 :            :  * %G_IO_ERROR_CANCELLED.
     584                 :            :  *
     585                 :            :  * If you are planning to connect to a socket on the resolved IP
     586                 :            :  * address, it may be easier to create a #GNetworkAddress and use its
     587                 :            :  * #GSocketConnectable interface.
     588                 :            :  *
     589                 :            :  * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
     590                 :            :  * of #GInetAddress, or %NULL on error. You
     591                 :            :  * must unref each of the addresses and free the list when you are
     592                 :            :  * done with it. (You can use g_resolver_free_addresses() to do this.)
     593                 :            :  *
     594                 :            :  * Since: 2.22
     595                 :            :  */
     596                 :            : GList *
     597                 :         41 : g_resolver_lookup_by_name (GResolver     *resolver,
     598                 :            :                            const gchar   *hostname,
     599                 :            :                            GCancellable  *cancellable,
     600                 :            :                            GError       **error)
     601                 :            : {
     602                 :         41 :   return lookup_by_name_real (resolver,
     603                 :            :                               hostname,
     604                 :            :                               G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT,
     605                 :            :                               cancellable,
     606                 :            :                               error);
     607                 :            : }
     608                 :            : 
     609                 :            : /**
     610                 :            :  * g_resolver_lookup_by_name_with_flags:
     611                 :            :  * @resolver: a #GResolver
     612                 :            :  * @hostname: the hostname to look up
     613                 :            :  * @flags: extra #GResolverNameLookupFlags for the lookup
     614                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
     615                 :            :  * @error: (nullable): return location for a #GError, or %NULL
     616                 :            :  *
     617                 :            :  * This differs from g_resolver_lookup_by_name() in that you can modify
     618                 :            :  * the lookup behavior with @flags. For example this can be used to limit
     619                 :            :  * results with %G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY.
     620                 :            :  *
     621                 :            :  * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
     622                 :            :  * of #GInetAddress, or %NULL on error. You
     623                 :            :  * must unref each of the addresses and free the list when you are
     624                 :            :  * done with it. (You can use g_resolver_free_addresses() to do this.)
     625                 :            :  *
     626                 :            :  * Since: 2.60
     627                 :            :  */
     628                 :            : GList *
     629                 :          0 : g_resolver_lookup_by_name_with_flags (GResolver                 *resolver,
     630                 :            :                                       const gchar               *hostname,
     631                 :            :                                       GResolverNameLookupFlags   flags,
     632                 :            :                                       GCancellable              *cancellable,
     633                 :            :                                       GError                   **error)
     634                 :            : {
     635                 :          0 :   return lookup_by_name_real (resolver,
     636                 :            :                               hostname,
     637                 :            :                               flags,
     638                 :            :                               cancellable,
     639                 :            :                               error);
     640                 :            : }
     641                 :            : 
     642                 :            : static void
     643                 :         47 : lookup_by_name_async_real (GResolver                *resolver,
     644                 :            :                            const gchar              *hostname,
     645                 :            :                            GResolverNameLookupFlags  flags,
     646                 :            :                            GCancellable             *cancellable,
     647                 :            :                            GAsyncReadyCallback       callback,
     648                 :            :                            gpointer                  user_data)
     649                 :            : {
     650                 :         47 :   gchar *ascii_hostname = NULL;
     651                 :            :   GList *addrs;
     652                 :         47 :   GError *error = NULL;
     653                 :            : 
     654                 :         58 :   g_return_if_fail (G_IS_RESOLVER (resolver));
     655                 :         47 :   g_return_if_fail (hostname != NULL);
     656                 :         47 :   g_return_if_fail (!(flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY && flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY));
     657                 :            : 
     658                 :            :   /* Check if @hostname is just an IP address */
     659         [ +  + ]:         47 :   if (handle_ip_address_or_localhost (hostname, &addrs, flags, &error))
     660                 :            :     {
     661                 :            :       GTask *task;
     662                 :            : 
     663                 :         11 :       task = g_task_new (resolver, cancellable, callback, user_data);
     664         [ +  - ]:         11 :       g_task_set_source_tag (task, lookup_by_name_async_real);
     665                 :         11 :       g_task_set_name (task, "[gio] resolver lookup");
     666         [ +  - ]:         11 :       if (addrs)
     667                 :         11 :         g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
     668                 :            :       else
     669                 :          0 :         g_task_return_error (task, error);
     670                 :         11 :       g_object_unref (task);
     671                 :         11 :       return;
     672                 :            :     }
     673                 :            : 
     674         [ -  + ]:         36 :   if (g_hostname_is_non_ascii (hostname))
     675                 :          0 :     hostname = ascii_hostname = g_hostname_to_ascii (hostname);
     676                 :            : 
     677         [ -  + ]:         36 :   if (!hostname)
     678                 :            :     {
     679                 :            :       GTask *task;
     680                 :            : 
     681                 :          0 :       g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
     682                 :            :                            _("Invalid hostname"));
     683                 :          0 :       task = g_task_new (resolver, cancellable, callback, user_data);
     684         [ #  # ]:          0 :       g_task_set_source_tag (task, lookup_by_name_async_real);
     685                 :          0 :       g_task_set_name (task, "[gio] resolver lookup");
     686                 :          0 :       g_task_return_error (task, error);
     687                 :          0 :       g_object_unref (task);
     688                 :          0 :       return;
     689                 :            :     }
     690                 :            : 
     691                 :         36 :   maybe_emit_reload (resolver);
     692                 :            : 
     693         [ +  + ]:         36 :   if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
     694                 :            :     {
     695         [ -  + ]:         34 :       if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_async == NULL)
     696                 :            :         {
     697                 :            :           GTask *task;
     698                 :            : 
     699                 :          0 :           g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
     700                 :            :                        /* Translators: The placeholder is for a function name. */
     701                 :            :                        _("%s not implemented"), "lookup_by_name_with_flags_async");
     702                 :          0 :           task = g_task_new (resolver, cancellable, callback, user_data);
     703         [ #  # ]:          0 :           g_task_set_source_tag (task, lookup_by_name_async_real);
     704                 :          0 :           g_task_set_name (task, "[gio] resolver lookup");
     705                 :          0 :           g_task_return_error (task, error);
     706                 :          0 :           g_object_unref (task);
     707                 :            :         }
     708                 :            :       else
     709                 :         34 :         G_RESOLVER_GET_CLASS (resolver)->
     710                 :            :           lookup_by_name_with_flags_async (resolver, hostname, flags, cancellable, callback, user_data);
     711                 :            :     }
     712                 :            :   else
     713                 :          2 :     G_RESOLVER_GET_CLASS (resolver)->
     714                 :            :       lookup_by_name_async (resolver, hostname, cancellable, callback, user_data);
     715                 :            : 
     716                 :         36 :   g_free (ascii_hostname);
     717                 :            : }
     718                 :            : 
     719                 :            : static GList *
     720                 :         46 : lookup_by_name_finish_real (GResolver     *resolver,
     721                 :            :                             GAsyncResult  *result,
     722                 :            :                             GError       **error,
     723                 :            :                             gboolean       with_flags)
     724                 :            : {
     725                 :            :   GList *addrs;
     726                 :            : 
     727                 :         46 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
     728                 :         46 :   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
     729                 :         46 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     730                 :            : 
     731         [ -  + ]:         46 :   if (g_async_result_legacy_propagate_error (result, error))
     732                 :          0 :     return NULL;
     733         [ +  + ]:         46 :   else if (g_async_result_is_tagged (result, lookup_by_name_async_real))
     734                 :            :     {
     735                 :            :       /* Handle the stringified-IP-addr case */
     736                 :         11 :       return g_task_propagate_pointer (G_TASK (result), error);
     737                 :            :     }
     738                 :            : 
     739         [ +  + ]:         35 :   if (with_flags)
     740                 :            :     {
     741                 :         33 :       g_assert (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_finish != NULL);
     742                 :         33 :       addrs = G_RESOLVER_GET_CLASS (resolver)->
     743                 :            :         lookup_by_name_with_flags_finish (resolver, result, error);
     744                 :            :     }
     745                 :            :   else
     746                 :          2 :     addrs = G_RESOLVER_GET_CLASS (resolver)->
     747                 :            :       lookup_by_name_finish (resolver, result, error);
     748                 :            : 
     749                 :         35 :   remove_duplicates (addrs);
     750                 :            : 
     751                 :         35 :   return addrs;
     752                 :            : }
     753                 :            : 
     754                 :            : /**
     755                 :            :  * g_resolver_lookup_by_name_with_flags_async:
     756                 :            :  * @resolver: a #GResolver
     757                 :            :  * @hostname: the hostname to look up the address of
     758                 :            :  * @flags: extra #GResolverNameLookupFlags for the lookup
     759                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
     760                 :            :  * @callback: (scope async) (closure user_data): callback to call after resolution completes
     761                 :            :  * @user_data: data for @callback
     762                 :            :  *
     763                 :            :  * Begins asynchronously resolving @hostname to determine its
     764                 :            :  * associated IP address(es), and eventually calls @callback, which
     765                 :            :  * must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
     766                 :            :  * See g_resolver_lookup_by_name() for more details.
     767                 :            :  *
     768                 :            :  * Since: 2.60
     769                 :            :  */
     770                 :            : void
     771                 :         40 : g_resolver_lookup_by_name_with_flags_async (GResolver                *resolver,
     772                 :            :                                             const gchar              *hostname,
     773                 :            :                                             GResolverNameLookupFlags  flags,
     774                 :            :                                             GCancellable             *cancellable,
     775                 :            :                                             GAsyncReadyCallback       callback,
     776                 :            :                                             gpointer                  user_data)
     777                 :            : {
     778                 :         40 :   lookup_by_name_async_real (resolver,
     779                 :            :                              hostname,
     780                 :            :                              flags,
     781                 :            :                              cancellable,
     782                 :            :                              callback,
     783                 :            :                              user_data);
     784                 :         40 : }
     785                 :            : 
     786                 :            : /**
     787                 :            :  * g_resolver_lookup_by_name_async:
     788                 :            :  * @resolver: a #GResolver
     789                 :            :  * @hostname: the hostname to look up the address of
     790                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
     791                 :            :  * @callback: (scope async) (closure user_data): callback to call after resolution completes
     792                 :            :  * @user_data: data for @callback
     793                 :            :  *
     794                 :            :  * Begins asynchronously resolving @hostname to determine its
     795                 :            :  * associated IP address(es), and eventually calls @callback, which
     796                 :            :  * must call g_resolver_lookup_by_name_finish() to get the result.
     797                 :            :  * See g_resolver_lookup_by_name() for more details.
     798                 :            :  *
     799                 :            :  * Since: 2.22
     800                 :            :  */
     801                 :            : void
     802                 :          7 : g_resolver_lookup_by_name_async (GResolver           *resolver,
     803                 :            :                                  const gchar         *hostname,
     804                 :            :                                  GCancellable        *cancellable,
     805                 :            :                                  GAsyncReadyCallback  callback,
     806                 :            :                                  gpointer             user_data)
     807                 :            : {
     808                 :          7 :   lookup_by_name_async_real (resolver,
     809                 :            :                              hostname,
     810                 :            :                              0,
     811                 :            :                              cancellable,
     812                 :            :                              callback,
     813                 :            :                              user_data);
     814                 :          7 : }
     815                 :            : 
     816                 :            : /**
     817                 :            :  * g_resolver_lookup_by_name_finish:
     818                 :            :  * @resolver: a #GResolver
     819                 :            :  * @result: the result passed to your #GAsyncReadyCallback
     820                 :            :  * @error: return location for a #GError, or %NULL
     821                 :            :  *
     822                 :            :  * Retrieves the result of a call to
     823                 :            :  * g_resolver_lookup_by_name_async().
     824                 :            :  *
     825                 :            :  * If the DNS resolution failed, @error (if non-%NULL) will be set to
     826                 :            :  * a value from #GResolverError. If the operation was cancelled,
     827                 :            :  * @error will be set to %G_IO_ERROR_CANCELLED.
     828                 :            :  *
     829                 :            :  * Returns: (element-type GInetAddress) (transfer full): a #GList
     830                 :            :  * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
     831                 :            :  * for more details.
     832                 :            :  *
     833                 :            :  * Since: 2.22
     834                 :            :  */
     835                 :            : GList *
     836                 :          7 : g_resolver_lookup_by_name_finish (GResolver     *resolver,
     837                 :            :                                   GAsyncResult  *result,
     838                 :            :                                   GError       **error)
     839                 :            : {
     840                 :          7 :   return lookup_by_name_finish_real (resolver,
     841                 :            :                                      result,
     842                 :            :                                      error,
     843                 :            :                                      FALSE);
     844                 :            : }
     845                 :            : 
     846                 :            : /**
     847                 :            :  * g_resolver_lookup_by_name_with_flags_finish:
     848                 :            :  * @resolver: a #GResolver
     849                 :            :  * @result: the result passed to your #GAsyncReadyCallback
     850                 :            :  * @error: return location for a #GError, or %NULL
     851                 :            :  *
     852                 :            :  * Retrieves the result of a call to
     853                 :            :  * g_resolver_lookup_by_name_with_flags_async().
     854                 :            :  *
     855                 :            :  * If the DNS resolution failed, @error (if non-%NULL) will be set to
     856                 :            :  * a value from #GResolverError. If the operation was cancelled,
     857                 :            :  * @error will be set to %G_IO_ERROR_CANCELLED.
     858                 :            :  *
     859                 :            :  * Returns: (element-type GInetAddress) (transfer full): a #GList
     860                 :            :  * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
     861                 :            :  * for more details.
     862                 :            :  *
     863                 :            :  * Since: 2.60
     864                 :            :  */
     865                 :            : GList *
     866                 :         39 : g_resolver_lookup_by_name_with_flags_finish (GResolver     *resolver,
     867                 :            :                                              GAsyncResult  *result,
     868                 :            :                                              GError       **error)
     869                 :            : {
     870                 :         39 :   return lookup_by_name_finish_real (resolver,
     871                 :            :                                      result,
     872                 :            :                                      error,
     873                 :            :                                      TRUE);
     874                 :            : }
     875                 :            : 
     876                 :            : /**
     877                 :            :  * g_resolver_free_addresses: (skip)
     878                 :            :  * @addresses: a #GList of #GInetAddress
     879                 :            :  *
     880                 :            :  * Frees @addresses (which should be the return value from
     881                 :            :  * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_finish()).
     882                 :            :  * (This is a convenience method; you can also simply free the results
     883                 :            :  * by hand.)
     884                 :            :  *
     885                 :            :  * Since: 2.22
     886                 :            :  */
     887                 :            : void
     888                 :         29 : g_resolver_free_addresses (GList *addresses)
     889                 :            : {
     890                 :            :   GList *a;
     891                 :            : 
     892         [ +  + ]:        103 :   for (a = addresses; a; a = a->next)
     893                 :         74 :     g_object_unref (a->data);
     894                 :         29 :   g_list_free (addresses);
     895                 :         29 : }
     896                 :            : 
     897                 :            : /**
     898                 :            :  * g_resolver_lookup_by_address:
     899                 :            :  * @resolver: a #GResolver
     900                 :            :  * @address: the address to reverse-resolve
     901                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
     902                 :            :  * @error: return location for a #GError, or %NULL
     903                 :            :  *
     904                 :            :  * Synchronously reverse-resolves @address to determine its
     905                 :            :  * associated hostname.
     906                 :            :  *
     907                 :            :  * If the DNS resolution fails, @error (if non-%NULL) will be set to
     908                 :            :  * a value from #GResolverError.
     909                 :            :  *
     910                 :            :  * If @cancellable is non-%NULL, it can be used to cancel the
     911                 :            :  * operation, in which case @error (if non-%NULL) will be set to
     912                 :            :  * %G_IO_ERROR_CANCELLED.
     913                 :            :  *
     914                 :            :  * Returns: a hostname (either ASCII-only, or in ASCII-encoded
     915                 :            :  *     form), or %NULL on error.
     916                 :            :  *
     917                 :            :  * Since: 2.22
     918                 :            :  */
     919                 :            : gchar *
     920                 :          0 : g_resolver_lookup_by_address (GResolver     *resolver,
     921                 :            :                               GInetAddress  *address,
     922                 :            :                               GCancellable  *cancellable,
     923                 :            :                               GError       **error)
     924                 :            : {
     925                 :          0 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
     926                 :          0 :   g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
     927                 :            : 
     928                 :          0 :   maybe_emit_reload (resolver);
     929                 :          0 :   return G_RESOLVER_GET_CLASS (resolver)->
     930                 :            :     lookup_by_address (resolver, address, cancellable, error);
     931                 :            : }
     932                 :            : 
     933                 :            : /**
     934                 :            :  * g_resolver_lookup_by_address_async:
     935                 :            :  * @resolver: a #GResolver
     936                 :            :  * @address: the address to reverse-resolve
     937                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
     938                 :            :  * @callback: (scope async) (closure user_data): callback to call after resolution completes
     939                 :            :  * @user_data: data for @callback
     940                 :            :  *
     941                 :            :  * Begins asynchronously reverse-resolving @address to determine its
     942                 :            :  * associated hostname, and eventually calls @callback, which must
     943                 :            :  * call g_resolver_lookup_by_address_finish() to get the final result.
     944                 :            :  *
     945                 :            :  * Since: 2.22
     946                 :            :  */
     947                 :            : void
     948                 :          0 : g_resolver_lookup_by_address_async (GResolver           *resolver,
     949                 :            :                                     GInetAddress        *address,
     950                 :            :                                     GCancellable        *cancellable,
     951                 :            :                                     GAsyncReadyCallback  callback,
     952                 :            :                                     gpointer             user_data)
     953                 :            : {
     954                 :          0 :   g_return_if_fail (G_IS_RESOLVER (resolver));
     955                 :          0 :   g_return_if_fail (G_IS_INET_ADDRESS (address));
     956                 :            : 
     957                 :          0 :   maybe_emit_reload (resolver);
     958                 :          0 :   G_RESOLVER_GET_CLASS (resolver)->
     959                 :            :     lookup_by_address_async (resolver, address, cancellable, callback, user_data);
     960                 :            : }
     961                 :            : 
     962                 :            : /**
     963                 :            :  * g_resolver_lookup_by_address_finish:
     964                 :            :  * @resolver: a #GResolver
     965                 :            :  * @result: the result passed to your #GAsyncReadyCallback
     966                 :            :  * @error: return location for a #GError, or %NULL
     967                 :            :  *
     968                 :            :  * Retrieves the result of a previous call to
     969                 :            :  * g_resolver_lookup_by_address_async().
     970                 :            :  *
     971                 :            :  * If the DNS resolution failed, @error (if non-%NULL) will be set to
     972                 :            :  * a value from #GResolverError. If the operation was cancelled,
     973                 :            :  * @error will be set to %G_IO_ERROR_CANCELLED.
     974                 :            :  *
     975                 :            :  * Returns: a hostname (either ASCII-only, or in ASCII-encoded
     976                 :            :  * form), or %NULL on error.
     977                 :            :  *
     978                 :            :  * Since: 2.22
     979                 :            :  */
     980                 :            : gchar *
     981                 :          0 : g_resolver_lookup_by_address_finish (GResolver     *resolver,
     982                 :            :                                      GAsyncResult  *result,
     983                 :            :                                      GError       **error)
     984                 :            : {
     985                 :          0 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
     986                 :            : 
     987         [ #  # ]:          0 :   if (g_async_result_legacy_propagate_error (result, error))
     988                 :          0 :     return NULL;
     989                 :            : 
     990                 :          0 :   return G_RESOLVER_GET_CLASS (resolver)->
     991                 :            :     lookup_by_address_finish (resolver, result, error);
     992                 :            : }
     993                 :            : 
     994                 :            : static gchar *
     995                 :          0 : g_resolver_get_service_rrname (const char *service,
     996                 :            :                                const char *protocol,
     997                 :            :                                const char *domain)
     998                 :            : {
     999                 :          0 :   gchar *rrname, *ascii_domain = NULL;
    1000                 :            : 
    1001         [ #  # ]:          0 :   if (g_hostname_is_non_ascii (domain))
    1002                 :          0 :     domain = ascii_domain = g_hostname_to_ascii (domain);
    1003         [ #  # ]:          0 :   if (!domain)
    1004                 :          0 :     return NULL;
    1005                 :            : 
    1006                 :          0 :   rrname = g_strdup_printf ("_%s._%s.%s", service, protocol, domain);
    1007                 :            : 
    1008                 :          0 :   g_free (ascii_domain);
    1009                 :          0 :   return rrname;
    1010                 :            : }
    1011                 :            : 
    1012                 :            : /**
    1013                 :            :  * g_resolver_lookup_service:
    1014                 :            :  * @resolver: a #GResolver
    1015                 :            :  * @service: the service type to look up (eg, "ldap")
    1016                 :            :  * @protocol: the networking protocol to use for @service (eg, "tcp")
    1017                 :            :  * @domain: the DNS domain to look up the service in
    1018                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
    1019                 :            :  * @error: return location for a #GError, or %NULL
    1020                 :            :  *
    1021                 :            :  * Synchronously performs a DNS SRV lookup for the given @service and
    1022                 :            :  * @protocol in the given @domain and returns an array of #GSrvTarget.
    1023                 :            :  * @domain may be an ASCII-only or UTF-8 hostname. Note also that the
    1024                 :            :  * @service and @protocol arguments do not include the leading underscore
    1025                 :            :  * that appears in the actual DNS entry.
    1026                 :            :  *
    1027                 :            :  * On success, g_resolver_lookup_service() will return a non-empty #GList of
    1028                 :            :  * #GSrvTarget, sorted in order of preference. (That is, you should
    1029                 :            :  * attempt to connect to the first target first, then the second if
    1030                 :            :  * the first fails, etc.)
    1031                 :            :  *
    1032                 :            :  * If the DNS resolution fails, @error (if non-%NULL) will be set to
    1033                 :            :  * a value from #GResolverError and %NULL will be returned.
    1034                 :            :  *
    1035                 :            :  * If @cancellable is non-%NULL, it can be used to cancel the
    1036                 :            :  * operation, in which case @error (if non-%NULL) will be set to
    1037                 :            :  * %G_IO_ERROR_CANCELLED.
    1038                 :            :  *
    1039                 :            :  * If you are planning to connect to the service, it is usually easier
    1040                 :            :  * to create a #GNetworkService and use its #GSocketConnectable
    1041                 :            :  * interface.
    1042                 :            :  *
    1043                 :            :  * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
    1044                 :            :  * #GSrvTarget, or %NULL on error. You must free each of the targets and the
    1045                 :            :  * list when you are done with it. (You can use g_resolver_free_targets() to do
    1046                 :            :  * this.)
    1047                 :            :  *
    1048                 :            :  * Since: 2.22
    1049                 :            :  */
    1050                 :            : GList *
    1051                 :          0 : g_resolver_lookup_service (GResolver     *resolver,
    1052                 :            :                            const gchar   *service,
    1053                 :            :                            const gchar   *protocol,
    1054                 :            :                            const gchar   *domain,
    1055                 :            :                            GCancellable  *cancellable,
    1056                 :            :                            GError       **error)
    1057                 :            : {
    1058                 :            :   GList *targets;
    1059                 :            :   gchar *rrname;
    1060                 :            : 
    1061                 :          0 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
    1062                 :          0 :   g_return_val_if_fail (service != NULL, NULL);
    1063                 :          0 :   g_return_val_if_fail (protocol != NULL, NULL);
    1064                 :          0 :   g_return_val_if_fail (domain != NULL, NULL);
    1065                 :            : 
    1066                 :          0 :   rrname = g_resolver_get_service_rrname (service, protocol, domain);
    1067         [ #  # ]:          0 :   if (!rrname)
    1068                 :            :     {
    1069                 :          0 :       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
    1070                 :            :                            _("Invalid domain"));
    1071                 :          0 :       return NULL;
    1072                 :            :     }
    1073                 :            : 
    1074                 :          0 :   maybe_emit_reload (resolver);
    1075                 :          0 :   targets = G_RESOLVER_GET_CLASS (resolver)->
    1076                 :            :     lookup_service (resolver, rrname, cancellable, error);
    1077                 :            : 
    1078                 :          0 :   g_free (rrname);
    1079                 :          0 :   return targets;
    1080                 :            : }
    1081                 :            : 
    1082                 :            : /**
    1083                 :            :  * g_resolver_lookup_service_async:
    1084                 :            :  * @resolver: a #GResolver
    1085                 :            :  * @service: the service type to look up (eg, "ldap")
    1086                 :            :  * @protocol: the networking protocol to use for @service (eg, "tcp")
    1087                 :            :  * @domain: the DNS domain to look up the service in
    1088                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
    1089                 :            :  * @callback: (scope async) (closure user_data): callback to call after resolution completes
    1090                 :            :  * @user_data: data for @callback
    1091                 :            :  *
    1092                 :            :  * Begins asynchronously performing a DNS SRV lookup for the given
    1093                 :            :  * @service and @protocol in the given @domain, and eventually calls
    1094                 :            :  * @callback, which must call g_resolver_lookup_service_finish() to
    1095                 :            :  * get the final result. See g_resolver_lookup_service() for more
    1096                 :            :  * details.
    1097                 :            :  *
    1098                 :            :  * Since: 2.22
    1099                 :            :  */
    1100                 :            : void
    1101                 :          0 : g_resolver_lookup_service_async (GResolver           *resolver,
    1102                 :            :                                  const gchar         *service,
    1103                 :            :                                  const gchar         *protocol,
    1104                 :            :                                  const gchar         *domain,
    1105                 :            :                                  GCancellable        *cancellable,
    1106                 :            :                                  GAsyncReadyCallback  callback,
    1107                 :            :                                  gpointer             user_data)
    1108                 :            : {
    1109                 :            :   gchar *rrname;
    1110                 :            : 
    1111                 :          0 :   g_return_if_fail (G_IS_RESOLVER (resolver));
    1112                 :          0 :   g_return_if_fail (service != NULL);
    1113                 :          0 :   g_return_if_fail (protocol != NULL);
    1114                 :          0 :   g_return_if_fail (domain != NULL);
    1115                 :            : 
    1116                 :          0 :   rrname = g_resolver_get_service_rrname (service, protocol, domain);
    1117         [ #  # ]:          0 :   if (!rrname)
    1118                 :            :     {
    1119                 :          0 :       g_task_report_new_error (resolver, callback, user_data,
    1120                 :            :                                g_resolver_lookup_service_async,
    1121                 :            :                                G_IO_ERROR, G_IO_ERROR_FAILED,
    1122                 :          0 :                                _("Invalid domain"));
    1123                 :          0 :       return;
    1124                 :            :     }
    1125                 :            : 
    1126                 :          0 :   maybe_emit_reload (resolver);
    1127                 :          0 :   G_RESOLVER_GET_CLASS (resolver)->
    1128                 :            :     lookup_service_async (resolver, rrname, cancellable, callback, user_data);
    1129                 :            : 
    1130                 :          0 :   g_free (rrname);
    1131                 :            : }
    1132                 :            : 
    1133                 :            : /**
    1134                 :            :  * g_resolver_lookup_service_finish:
    1135                 :            :  * @resolver: a #GResolver
    1136                 :            :  * @result: the result passed to your #GAsyncReadyCallback
    1137                 :            :  * @error: return location for a #GError, or %NULL
    1138                 :            :  *
    1139                 :            :  * Retrieves the result of a previous call to
    1140                 :            :  * g_resolver_lookup_service_async().
    1141                 :            :  *
    1142                 :            :  * If the DNS resolution failed, @error (if non-%NULL) will be set to
    1143                 :            :  * a value from #GResolverError. If the operation was cancelled,
    1144                 :            :  * @error will be set to %G_IO_ERROR_CANCELLED.
    1145                 :            :  *
    1146                 :            :  * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
    1147                 :            :  * #GSrvTarget, or %NULL on error. See g_resolver_lookup_service() for more
    1148                 :            :  * details.
    1149                 :            :  *
    1150                 :            :  * Since: 2.22
    1151                 :            :  */
    1152                 :            : GList *
    1153                 :          0 : g_resolver_lookup_service_finish (GResolver     *resolver,
    1154                 :            :                                   GAsyncResult  *result,
    1155                 :            :                                   GError       **error)
    1156                 :            : {
    1157                 :          0 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
    1158                 :            : 
    1159         [ #  # ]:          0 :   if (g_async_result_legacy_propagate_error (result, error))
    1160                 :          0 :     return NULL;
    1161                 :            : 
    1162                 :          0 :   return G_RESOLVER_GET_CLASS (resolver)->
    1163                 :            :     lookup_service_finish (resolver, result, error);
    1164                 :            : }
    1165                 :            : 
    1166                 :            : /**
    1167                 :            :  * g_resolver_free_targets: (skip)
    1168                 :            :  * @targets: a #GList of #GSrvTarget
    1169                 :            :  *
    1170                 :            :  * Frees @targets (which should be the return value from
    1171                 :            :  * g_resolver_lookup_service() or g_resolver_lookup_service_finish()).
    1172                 :            :  * (This is a convenience method; you can also simply free the
    1173                 :            :  * results by hand.)
    1174                 :            :  *
    1175                 :            :  * Since: 2.22
    1176                 :            :  */
    1177                 :            : void
    1178                 :          1 : g_resolver_free_targets (GList *targets)
    1179                 :            : {
    1180                 :            :   GList *t;
    1181                 :            : 
    1182         [ +  + ]:          7 :   for (t = targets; t; t = t->next)
    1183                 :          6 :     g_srv_target_free (t->data);
    1184                 :          1 :   g_list_free (targets);
    1185                 :          1 : }
    1186                 :            : 
    1187                 :            : /**
    1188                 :            :  * g_resolver_lookup_records:
    1189                 :            :  * @resolver: a #GResolver
    1190                 :            :  * @rrname: the DNS name to look up the record for
    1191                 :            :  * @record_type: the type of DNS record to look up
    1192                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
    1193                 :            :  * @error: return location for a #GError, or %NULL
    1194                 :            :  *
    1195                 :            :  * Synchronously performs a DNS record lookup for the given @rrname and returns
    1196                 :            :  * a list of records as #GVariant tuples. See #GResolverRecordType for
    1197                 :            :  * information on what the records contain for each @record_type.
    1198                 :            :  *
    1199                 :            :  * If the DNS resolution fails, @error (if non-%NULL) will be set to
    1200                 :            :  * a value from #GResolverError and %NULL will be returned.
    1201                 :            :  *
    1202                 :            :  * If @cancellable is non-%NULL, it can be used to cancel the
    1203                 :            :  * operation, in which case @error (if non-%NULL) will be set to
    1204                 :            :  * %G_IO_ERROR_CANCELLED.
    1205                 :            :  *
    1206                 :            :  * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
    1207                 :            :  * #GVariant, or %NULL on error. You must free each of the records and the list
    1208                 :            :  * when you are done with it. (You can use g_list_free_full() with
    1209                 :            :  * g_variant_unref() to do this.)
    1210                 :            :  *
    1211                 :            :  * Since: 2.34
    1212                 :            :  */
    1213                 :            : GList *
    1214                 :          0 : g_resolver_lookup_records (GResolver            *resolver,
    1215                 :            :                            const gchar          *rrname,
    1216                 :            :                            GResolverRecordType   record_type,
    1217                 :            :                            GCancellable         *cancellable,
    1218                 :            :                            GError              **error)
    1219                 :            : {
    1220                 :            :   GList *records;
    1221                 :            : 
    1222                 :          0 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
    1223                 :          0 :   g_return_val_if_fail (rrname != NULL, NULL);
    1224                 :            : 
    1225                 :          0 :   maybe_emit_reload (resolver);
    1226                 :          0 :   records = G_RESOLVER_GET_CLASS (resolver)->
    1227                 :            :     lookup_records (resolver, rrname, record_type, cancellable, error);
    1228                 :            : 
    1229                 :          0 :   return records;
    1230                 :            : }
    1231                 :            : 
    1232                 :            : /**
    1233                 :            :  * g_resolver_lookup_records_async:
    1234                 :            :  * @resolver: a #GResolver
    1235                 :            :  * @rrname: the DNS name to look up the record for
    1236                 :            :  * @record_type: the type of DNS record to look up
    1237                 :            :  * @cancellable: (nullable): a #GCancellable, or %NULL
    1238                 :            :  * @callback: (scope async) (closure user_data): callback to call after resolution completes
    1239                 :            :  * @user_data: data for @callback
    1240                 :            :  *
    1241                 :            :  * Begins asynchronously performing a DNS lookup for the given
    1242                 :            :  * @rrname, and eventually calls @callback, which must call
    1243                 :            :  * g_resolver_lookup_records_finish() to get the final result. See
    1244                 :            :  * g_resolver_lookup_records() for more details.
    1245                 :            :  *
    1246                 :            :  * Since: 2.34
    1247                 :            :  */
    1248                 :            : void
    1249                 :          0 : g_resolver_lookup_records_async (GResolver           *resolver,
    1250                 :            :                                  const gchar         *rrname,
    1251                 :            :                                  GResolverRecordType  record_type,
    1252                 :            :                                  GCancellable        *cancellable,
    1253                 :            :                                  GAsyncReadyCallback  callback,
    1254                 :            :                                  gpointer             user_data)
    1255                 :            : {
    1256                 :          0 :   g_return_if_fail (G_IS_RESOLVER (resolver));
    1257                 :          0 :   g_return_if_fail (rrname != NULL);
    1258                 :            : 
    1259                 :          0 :   maybe_emit_reload (resolver);
    1260                 :          0 :   G_RESOLVER_GET_CLASS (resolver)->
    1261                 :            :     lookup_records_async (resolver, rrname, record_type, cancellable, callback, user_data);
    1262                 :            : }
    1263                 :            : 
    1264                 :            : /**
    1265                 :            :  * g_resolver_lookup_records_finish:
    1266                 :            :  * @resolver: a #GResolver
    1267                 :            :  * @result: the result passed to your #GAsyncReadyCallback
    1268                 :            :  * @error: return location for a #GError, or %NULL
    1269                 :            :  *
    1270                 :            :  * Retrieves the result of a previous call to
    1271                 :            :  * g_resolver_lookup_records_async(). Returns a non-empty list of records as
    1272                 :            :  * #GVariant tuples. See #GResolverRecordType for information on what the
    1273                 :            :  * records contain.
    1274                 :            :  *
    1275                 :            :  * If the DNS resolution failed, @error (if non-%NULL) will be set to
    1276                 :            :  * a value from #GResolverError. If the operation was cancelled,
    1277                 :            :  * @error will be set to %G_IO_ERROR_CANCELLED.
    1278                 :            :  *
    1279                 :            :  * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
    1280                 :            :  * #GVariant, or %NULL on error. You must free each of the records and the list
    1281                 :            :  * when you are done with it. (You can use g_list_free_full() with
    1282                 :            :  * g_variant_unref() to do this.)
    1283                 :            :  *
    1284                 :            :  * Since: 2.34
    1285                 :            :  */
    1286                 :            : GList *
    1287                 :          0 : g_resolver_lookup_records_finish (GResolver     *resolver,
    1288                 :            :                                   GAsyncResult  *result,
    1289                 :            :                                   GError       **error)
    1290                 :            : {
    1291                 :          0 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
    1292                 :          0 :   return G_RESOLVER_GET_CLASS (resolver)->
    1293                 :            :     lookup_records_finish (resolver, result, error);
    1294                 :            : }
    1295                 :            : 
    1296                 :            : guint64
    1297                 :         98 : g_resolver_get_serial (GResolver *resolver)
    1298                 :            : {
    1299                 :            :   guint64 result;
    1300                 :            : 
    1301                 :         98 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
    1302                 :            : 
    1303                 :         98 :   maybe_emit_reload (resolver);
    1304                 :            : 
    1305                 :            : #ifdef G_OS_UNIX
    1306                 :         98 :   g_mutex_lock (&resolver->priv->mutex);
    1307                 :         98 :   result = resolver->priv->resolv_conf_timestamp;
    1308                 :         98 :   g_mutex_unlock (&resolver->priv->mutex);
    1309                 :            : #else
    1310                 :            :   result = 1;
    1311                 :            : #endif
    1312                 :            : 
    1313                 :         98 :   return result;
    1314                 :            : }
    1315                 :            : 
    1316                 :            : /**
    1317                 :            :  * g_resolver_get_timeout:
    1318                 :            :  * @resolver: a #GResolver
    1319                 :            :  *
    1320                 :            :  * Get the timeout applied to all resolver lookups. See #GResolver:timeout.
    1321                 :            :  *
    1322                 :            :  * Returns: the resolver timeout, in milliseconds, or `0` for no timeout
    1323                 :            :  *
    1324                 :            :  * Since: 2.78
    1325                 :            :  */
    1326                 :            : unsigned
    1327                 :          3 : g_resolver_get_timeout (GResolver *resolver)
    1328                 :            : {
    1329                 :          3 :   GResolverPrivate *priv = g_resolver_get_instance_private (resolver);
    1330                 :            : 
    1331                 :          3 :   g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
    1332                 :            : 
    1333                 :          3 :   return priv->timeout_ms;
    1334                 :            : }
    1335                 :            : 
    1336                 :            : /**
    1337                 :            :  * g_resolver_set_timeout:
    1338                 :            :  * @resolver: a #GResolver
    1339                 :            :  * @timeout_ms: timeout in milliseconds, or `0` for no timeouts
    1340                 :            :  *
    1341                 :            :  * Set the timeout applied to all resolver lookups. See #GResolver:timeout.
    1342                 :            :  *
    1343                 :            :  * Since: 2.78
    1344                 :            :  */
    1345                 :            : void
    1346                 :          4 : g_resolver_set_timeout (GResolver *resolver,
    1347                 :            :                         unsigned   timeout_ms)
    1348                 :            : {
    1349                 :          4 :   GResolverPrivate *priv = g_resolver_get_instance_private (resolver);
    1350                 :            : 
    1351                 :          4 :   g_return_if_fail (G_IS_RESOLVER (resolver));
    1352                 :            : 
    1353         [ -  + ]:          4 :   if (priv->timeout_ms == timeout_ms)
    1354                 :          0 :     return;
    1355                 :            : 
    1356                 :          4 :   priv->timeout_ms = timeout_ms;
    1357                 :          4 :   g_object_notify_by_pspec (G_OBJECT (resolver), props[PROP_TIMEOUT]);
    1358                 :            : }
    1359                 :            : 
    1360                 :            : /**
    1361                 :            :  * g_resolver_error_quark:
    1362                 :            :  *
    1363                 :            :  * Gets the #GResolver Error Quark.
    1364                 :            :  *
    1365                 :            :  * Returns: a #GQuark.
    1366                 :            :  *
    1367                 :            :  * Since: 2.22
    1368                 :            :  */
    1369         [ +  + ]:         82 : G_DEFINE_QUARK (g-resolver-error-quark, g_resolver_error)

Generated by: LCOV version 1.14