(root)/
glib-2.79.0/
gio/
gnetworkaddress.c
       1  /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
       2  
       3  /* GIO - GLib Input, Output and Streaming Library
       4   *
       5   * Copyright (C) 2008 Red Hat, Inc.
       6   * Copyright (C) 2018 Igalia S.L.
       7   *
       8   * 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 <stdlib.h>
      29  #include "gnetworkaddress.h"
      30  #include "gasyncresult.h"
      31  #include "ginetaddress.h"
      32  #include "ginetsocketaddress.h"
      33  #include "gnetworkingprivate.h"
      34  #include "gproxyaddressenumerator.h"
      35  #include "gresolver.h"
      36  #include "gtask.h"
      37  #include "gsocketaddressenumerator.h"
      38  #include "gioerror.h"
      39  #include "gsocketconnectable.h"
      40  
      41  #include <string.h>
      42  
      43  /* As recommended by RFC 8305 this is the time it waits for a following
      44     DNS response to come in (ipv4 waiting on ipv6 generally)
      45   */
      46  #define HAPPY_EYEBALLS_RESOLUTION_DELAY_MS 50
      47  
      48  /**
      49   * GNetworkAddress:
      50   *
      51   * `GNetworkAddress` provides an easy way to resolve a hostname and
      52   * then attempt to connect to that host, handling the possibility of
      53   * multiple IP addresses and multiple address families.
      54   *
      55   * The enumeration results of resolved addresses *may* be cached as long
      56   * as this object is kept alive which may have unexpected results if
      57   * alive for too long.
      58   *
      59   * See [iface@Gio.SocketConnectable] for an example of using the connectable
      60   * interface.
      61   */
      62  
      63  struct _GNetworkAddressPrivate {
      64    gchar *hostname;
      65    guint16 port;
      66    GList *cached_sockaddrs;
      67    gchar *scheme;
      68  
      69    gint64 resolver_serial;
      70  };
      71  
      72  enum {
      73    PROP_0,
      74    PROP_HOSTNAME,
      75    PROP_PORT,
      76    PROP_SCHEME,
      77  };
      78  
      79  static void g_network_address_set_property (GObject      *object,
      80                                              guint         prop_id,
      81                                              const GValue *value,
      82                                              GParamSpec   *pspec);
      83  static void g_network_address_get_property (GObject      *object,
      84                                              guint         prop_id,
      85                                              GValue       *value,
      86                                              GParamSpec   *pspec);
      87  
      88  static void                      g_network_address_connectable_iface_init       (GSocketConnectableIface *iface);
      89  static GSocketAddressEnumerator *g_network_address_connectable_enumerate        (GSocketConnectable      *connectable);
      90  static GSocketAddressEnumerator	*g_network_address_connectable_proxy_enumerate  (GSocketConnectable      *connectable);
      91  static gchar                    *g_network_address_connectable_to_string        (GSocketConnectable      *connectable);
      92  
      93  G_DEFINE_TYPE_WITH_CODE (GNetworkAddress, g_network_address, G_TYPE_OBJECT,
      94                           G_ADD_PRIVATE (GNetworkAddress)
      95                           G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE,
      96                                                  g_network_address_connectable_iface_init))
      97  
      98  static void
      99  g_network_address_finalize (GObject *object)
     100  {
     101    GNetworkAddress *addr = G_NETWORK_ADDRESS (object);
     102  
     103    g_free (addr->priv->hostname);
     104    g_free (addr->priv->scheme);
     105    g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref);
     106  
     107    G_OBJECT_CLASS (g_network_address_parent_class)->finalize (object);
     108  }
     109  
     110  static void
     111  g_network_address_class_init (GNetworkAddressClass *klass)
     112  {
     113    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     114  
     115    gobject_class->set_property = g_network_address_set_property;
     116    gobject_class->get_property = g_network_address_get_property;
     117    gobject_class->finalize = g_network_address_finalize;
     118  
     119    /**
     120     * GNetworkAddress:hostname:
     121     *
     122     * Hostname to resolve.
     123     *
     124     * Since: 2.22
     125     */
     126    g_object_class_install_property (gobject_class, PROP_HOSTNAME,
     127                                     g_param_spec_string ("hostname", NULL, NULL,
     128                                                          NULL,
     129                                                          G_PARAM_READWRITE |
     130                                                          G_PARAM_CONSTRUCT_ONLY |
     131                                                          G_PARAM_STATIC_STRINGS));
     132  
     133    /**
     134     * GNetworkAddress:port:
     135     *
     136     * Network port.
     137     *
     138     * Since: 2.22
     139     */
     140    g_object_class_install_property (gobject_class, PROP_PORT,
     141                                     g_param_spec_uint ("port", NULL, NULL,
     142                                                        0, 65535, 0,
     143                                                        G_PARAM_READWRITE |
     144                                                        G_PARAM_CONSTRUCT_ONLY |
     145                                                        G_PARAM_STATIC_STRINGS));
     146  
     147    /**
     148     * GNetworkAddress:scheme:
     149     *
     150     * URI scheme.
     151     *
     152     * Since: 2.22
     153     */
     154    g_object_class_install_property (gobject_class, PROP_SCHEME,
     155                                     g_param_spec_string ("scheme", NULL, NULL,
     156                                                          NULL,
     157                                                          G_PARAM_READWRITE |
     158                                                          G_PARAM_CONSTRUCT_ONLY |
     159                                                          G_PARAM_STATIC_STRINGS));
     160  }
     161  
     162  static void
     163  g_network_address_connectable_iface_init (GSocketConnectableIface *connectable_iface)
     164  {
     165    connectable_iface->enumerate  = g_network_address_connectable_enumerate;
     166    connectable_iface->proxy_enumerate = g_network_address_connectable_proxy_enumerate;
     167    connectable_iface->to_string = g_network_address_connectable_to_string;
     168  }
     169  
     170  static void
     171  g_network_address_init (GNetworkAddress *addr)
     172  {
     173    addr->priv = g_network_address_get_instance_private (addr);
     174  }
     175  
     176  static void
     177  g_network_address_set_property (GObject      *object,
     178                                  guint         prop_id,
     179                                  const GValue *value,
     180                                  GParamSpec   *pspec)
     181  {
     182    GNetworkAddress *addr = G_NETWORK_ADDRESS (object);
     183  
     184    switch (prop_id)
     185      {
     186      case PROP_HOSTNAME:
     187        g_free (addr->priv->hostname);
     188        addr->priv->hostname = g_value_dup_string (value);
     189        break;
     190  
     191      case PROP_PORT:
     192        addr->priv->port = g_value_get_uint (value);
     193        break;
     194  
     195      case PROP_SCHEME:
     196        g_free (addr->priv->scheme);
     197        addr->priv->scheme = g_value_dup_string (value);
     198        break;
     199  
     200      default:
     201        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     202        break;
     203      }
     204  
     205  }
     206  
     207  static void
     208  g_network_address_get_property (GObject    *object,
     209                                  guint       prop_id,
     210                                  GValue     *value,
     211                                  GParamSpec *pspec)
     212  {
     213    GNetworkAddress *addr = G_NETWORK_ADDRESS (object);
     214  
     215    switch (prop_id)
     216      {
     217      case PROP_HOSTNAME:
     218        g_value_set_string (value, addr->priv->hostname);
     219        break;
     220  
     221      case PROP_PORT:
     222        g_value_set_uint (value, addr->priv->port);
     223        break;
     224  
     225      case PROP_SCHEME:
     226        g_value_set_string (value, addr->priv->scheme);
     227        break;
     228  
     229      default:
     230        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     231        break;
     232      }
     233  
     234  }
     235  
     236  /*
     237   * inet_addresses_to_inet_socket_addresses:
     238   * @addresses: (transfer full): #GList of #GInetAddress
     239   *
     240   * Returns: (transfer full): #GList of #GInetSocketAddress
     241   */
     242  static GList *
     243  inet_addresses_to_inet_socket_addresses (GNetworkAddress *addr,
     244                                           GList           *addresses)
     245  {
     246    GList *a, *socket_addresses = NULL;
     247  
     248    for (a = addresses; a; a = a->next)
     249      {
     250        GSocketAddress *sockaddr = g_inet_socket_address_new (a->data, addr->priv->port);
     251        socket_addresses = g_list_append (socket_addresses, g_steal_pointer (&sockaddr));
     252        g_object_unref (a->data);
     253      }
     254  
     255    g_list_free (addresses);
     256    return socket_addresses;
     257  }
     258  
     259  /*
     260   * g_network_address_set_cached_addresses:
     261   * @addr: A #GNetworkAddress
     262   * @addresses: (transfer full): List of #GInetAddress or #GInetSocketAddress
     263   * @resolver_serial: Serial of #GResolver used
     264   *
     265   * Consumes @addresses and uses them to replace the current internal list.
     266   */
     267  static void
     268  g_network_address_set_cached_addresses (GNetworkAddress *addr,
     269                                          GList           *addresses,
     270                                          guint64          resolver_serial)
     271  {
     272    g_assert (addresses != NULL);
     273  
     274    if (addr->priv->cached_sockaddrs)
     275      g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref);
     276  
     277    if (G_IS_INET_SOCKET_ADDRESS (addresses->data))
     278      addr->priv->cached_sockaddrs = g_steal_pointer (&addresses);
     279    else
     280      addr->priv->cached_sockaddrs = inet_addresses_to_inet_socket_addresses (addr, g_steal_pointer (&addresses));
     281    addr->priv->resolver_serial = resolver_serial;
     282  }
     283  
     284  static gboolean
     285  g_network_address_parse_sockaddr (GNetworkAddress *addr)
     286  {
     287    GSocketAddress *sockaddr;
     288  
     289    g_assert (addr->priv->cached_sockaddrs == NULL);
     290  
     291    sockaddr = g_inet_socket_address_new_from_string (addr->priv->hostname,
     292                                                      addr->priv->port);
     293    if (sockaddr)
     294      {
     295        addr->priv->cached_sockaddrs = g_list_append (addr->priv->cached_sockaddrs, sockaddr);
     296        return TRUE;
     297      }
     298    else
     299      return FALSE;
     300  }
     301  
     302  /**
     303   * g_network_address_new:
     304   * @hostname: the hostname
     305   * @port: the port
     306   *
     307   * Creates a new #GSocketConnectable for connecting to the given
     308   * @hostname and @port.
     309   *
     310   * Note that depending on the configuration of the machine, a
     311   * @hostname of `localhost` may refer to the IPv4 loopback address
     312   * only, or to both IPv4 and IPv6; use
     313   * g_network_address_new_loopback() to create a #GNetworkAddress that
     314   * is guaranteed to resolve to both addresses.
     315   *
     316   * Returns: (transfer full) (type GNetworkAddress): the new #GNetworkAddress
     317   *
     318   * Since: 2.22
     319   */
     320  GSocketConnectable *
     321  g_network_address_new (const gchar *hostname,
     322                         guint16      port)
     323  {
     324    return g_object_new (G_TYPE_NETWORK_ADDRESS,
     325                         "hostname", hostname,
     326                         "port", port,
     327                         NULL);
     328  }
     329  
     330  /**
     331   * g_network_address_new_loopback:
     332   * @port: the port
     333   *
     334   * Creates a new #GSocketConnectable for connecting to the local host
     335   * over a loopback connection to the given @port. This is intended for
     336   * use in connecting to local services which may be running on IPv4 or
     337   * IPv6.
     338   *
     339   * The connectable will return IPv4 and IPv6 loopback addresses,
     340   * regardless of how the host resolves `localhost`. By contrast,
     341   * g_network_address_new() will often only return an IPv4 address when
     342   * resolving `localhost`, and an IPv6 address for `localhost6`.
     343   *
     344   * g_network_address_get_hostname() will always return `localhost` for
     345   * a #GNetworkAddress created with this constructor.
     346   *
     347   * Returns: (transfer full) (type GNetworkAddress): the new #GNetworkAddress
     348   *
     349   * Since: 2.44
     350   */
     351  GSocketConnectable *
     352  g_network_address_new_loopback (guint16 port)
     353  {
     354    GNetworkAddress *addr;
     355    GList *addrs = NULL;
     356  
     357    addr = g_object_new (G_TYPE_NETWORK_ADDRESS,
     358                         "hostname", "localhost",
     359                         "port", port,
     360                         NULL);
     361  
     362    addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET6));
     363    addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET));
     364    g_network_address_set_cached_addresses (addr, g_steal_pointer (&addrs), 0);
     365  
     366    return G_SOCKET_CONNECTABLE (addr);
     367  }
     368  
     369  /**
     370   * g_network_address_parse:
     371   * @host_and_port: the hostname and optionally a port
     372   * @default_port: the default port if not in @host_and_port
     373   * @error: a pointer to a #GError, or %NULL
     374   *
     375   * Creates a new #GSocketConnectable for connecting to the given
     376   * @hostname and @port. May fail and return %NULL in case
     377   * parsing @host_and_port fails.
     378   *
     379   * @host_and_port may be in any of a number of recognised formats; an IPv6
     380   * address, an IPv4 address, or a domain name (in which case a DNS
     381   * lookup is performed). Quoting with [] is supported for all address
     382   * types. A port override may be specified in the usual way with a
     383   * colon.
     384   *
     385   * If no port is specified in @host_and_port then @default_port will be
     386   * used as the port number to connect to.
     387   *
     388   * In general, @host_and_port is expected to be provided by the user
     389   * (allowing them to give the hostname, and a port override if necessary)
     390   * and @default_port is expected to be provided by the application.
     391   *
     392   * (The port component of @host_and_port can also be specified as a
     393   * service name rather than as a numeric port, but this functionality
     394   * is deprecated, because it depends on the contents of /etc/services,
     395   * which is generally quite sparse on platforms other than Linux.)
     396   *
     397   * Returns: (transfer full) (type GNetworkAddress): the new
     398   *   #GNetworkAddress, or %NULL on error
     399   *
     400   * Since: 2.22
     401   */
     402  GSocketConnectable *
     403  g_network_address_parse (const gchar  *host_and_port,
     404                           guint16       default_port,
     405                           GError      **error)
     406  {
     407    GSocketConnectable *connectable;
     408    const gchar *port;
     409    guint16 portnum;
     410    gchar *name;
     411  
     412    g_return_val_if_fail (host_and_port != NULL, NULL);
     413  
     414    port = NULL;
     415    if (host_and_port[0] == '[')
     416      /* escaped host part (to allow, eg. "[2001:db8::1]:888") */
     417      {
     418        const gchar *end;
     419  
     420        end = strchr (host_and_port, ']');
     421        if (end == NULL)
     422          {
     423            g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
     424                         _("Hostname “%s” contains “[” but not “]”"), host_and_port);
     425            return NULL;
     426          }
     427  
     428        if (end[1] == '\0')
     429          port = NULL;
     430        else if (end[1] == ':')
     431          port = &end[2];
     432        else
     433          {
     434            g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
     435                         "The ']' character (in hostname '%s') must come at the"
     436                         " end or be immediately followed by ':' and a port",
     437                         host_and_port);
     438            return NULL;
     439          }
     440  
     441        name = g_strndup (host_and_port + 1, end - host_and_port - 1);
     442      }
     443  
     444    else if ((port = strchr (host_and_port, ':')))
     445      /* string has a ':' in it */
     446      {
     447        /* skip ':' */
     448        port++;
     449  
     450        if (strchr (port, ':'))
     451          /* more than one ':' in string */
     452          {
     453            /* this is actually an unescaped IPv6 address */
     454            name = g_strdup (host_and_port);
     455            port = NULL;
     456          }
     457        else
     458          name = g_strndup (host_and_port, port - host_and_port - 1);
     459      }
     460  
     461    else
     462      /* plain hostname, no port */
     463      name = g_strdup (host_and_port);
     464  
     465    if (port != NULL)
     466      {
     467        if (port[0] == '\0')
     468          {
     469            g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
     470                         "If a ':' character is given, it must be followed by a "
     471                         "port (in hostname '%s').", host_and_port);
     472            g_free (name);
     473            return NULL;
     474          }
     475  
     476        else if ('0' <= port[0] && port[0] <= '9')
     477          {
     478            char *end;
     479            long value;
     480  
     481            value = strtol (port, &end, 10);
     482            if (*end != '\0' || value < 0 || value > G_MAXUINT16)
     483              {
     484                g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
     485                             "Invalid numeric port '%s' specified in hostname '%s'",
     486                             port, host_and_port);
     487                g_free (name);
     488                return NULL;
     489              }
     490  
     491            portnum = value;
     492          }
     493  
     494        else
     495          {
     496            if (!g_getservbyname_ntohs (port, "tcp", &portnum))
     497              {
     498                g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
     499                             "Unknown service '%s' specified in hostname '%s'",
     500                             port, host_and_port);
     501  #ifdef HAVE_ENDSERVENT
     502                endservent ();
     503  #endif
     504                g_free (name);
     505                return NULL;
     506              }
     507  
     508  #ifdef HAVE_ENDSERVENT
     509            endservent ();
     510  #endif
     511          }
     512      }
     513    else
     514      {
     515        /* No port in host_and_port */
     516        portnum = default_port;
     517      }
     518  
     519    connectable = g_network_address_new (name, portnum);
     520    g_free (name);
     521  
     522    return connectable;
     523  }
     524  
     525  /**
     526   * g_network_address_parse_uri:
     527   * @uri: the hostname and optionally a port
     528   * @default_port: The default port if none is found in the URI
     529   * @error: a pointer to a #GError, or %NULL
     530   *
     531   * Creates a new #GSocketConnectable for connecting to the given
     532   * @uri. May fail and return %NULL in case parsing @uri fails.
     533   *
     534   * Using this rather than g_network_address_new() or
     535   * g_network_address_parse() allows #GSocketClient to determine
     536   * when to use application-specific proxy protocols.
     537   *
     538   * Returns: (transfer full) (type GNetworkAddress): the new
     539   *   #GNetworkAddress, or %NULL on error
     540   *
     541   * Since: 2.26
     542   */
     543  GSocketConnectable *
     544  g_network_address_parse_uri (const gchar  *uri,
     545      			     guint16       default_port,
     546  			     GError      **error)
     547  {
     548    GSocketConnectable *conn = NULL;
     549    gchar *scheme = NULL;
     550    gchar *hostname = NULL;
     551    gint port;
     552  
     553    if (!g_uri_split_network (uri, G_URI_FLAGS_NONE,
     554                              &scheme, &hostname, &port, NULL))
     555      {
     556        g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
     557                     "Invalid URI ‘%s", uri);
     558        return NULL;
     559      }
     560  
     561    if (port <= 0)
     562      port = default_port;
     563  
     564    conn = g_object_new (G_TYPE_NETWORK_ADDRESS,
     565                         "hostname", hostname,
     566                         "port", (guint) port,
     567                         "scheme", scheme,
     568                         NULL);
     569    g_free (scheme);
     570    g_free (hostname);
     571  
     572    return conn;
     573  }
     574  
     575  /**
     576   * g_network_address_get_hostname:
     577   * @addr: a #GNetworkAddress
     578   *
     579   * Gets @addr's hostname. This might be either UTF-8 or ASCII-encoded,
     580   * depending on what @addr was created with.
     581   *
     582   * Returns: @addr's hostname
     583   *
     584   * Since: 2.22
     585   */
     586  const gchar *
     587  g_network_address_get_hostname (GNetworkAddress *addr)
     588  {
     589    g_return_val_if_fail (G_IS_NETWORK_ADDRESS (addr), NULL);
     590  
     591    return addr->priv->hostname;
     592  }
     593  
     594  /**
     595   * g_network_address_get_port:
     596   * @addr: a #GNetworkAddress
     597   *
     598   * Gets @addr's port number
     599   *
     600   * Returns: @addr's port (which may be 0)
     601   *
     602   * Since: 2.22
     603   */
     604  guint16
     605  g_network_address_get_port (GNetworkAddress *addr)
     606  {
     607    g_return_val_if_fail (G_IS_NETWORK_ADDRESS (addr), 0);
     608  
     609    return addr->priv->port;
     610  }
     611  
     612  /**
     613   * g_network_address_get_scheme:
     614   * @addr: a #GNetworkAddress
     615   *
     616   * Gets @addr's scheme
     617   *
     618   * Returns: (nullable): @addr's scheme (%NULL if not built from URI)
     619   *
     620   * Since: 2.26
     621   */
     622  const gchar *
     623  g_network_address_get_scheme (GNetworkAddress *addr)
     624  {
     625    g_return_val_if_fail (G_IS_NETWORK_ADDRESS (addr), NULL);
     626  
     627    return addr->priv->scheme;
     628  }
     629  
     630  #define G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (_g_network_address_address_enumerator_get_type ())
     631  #define G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR, GNetworkAddressAddressEnumerator))
     632  
     633  typedef enum {
     634    RESOLVE_STATE_NONE = 0,
     635    RESOLVE_STATE_WAITING_ON_IPV4 = 1 << 0,
     636    RESOLVE_STATE_WAITING_ON_IPV6 = 1 << 1,
     637  } ResolveState;
     638  
     639  typedef struct {
     640    GSocketAddressEnumerator parent_instance;
     641  
     642    GNetworkAddress *addr; /* (owned) */
     643    GList *addresses; /* (owned) (nullable) */
     644    GList *current_item; /* (unowned) (nullable) */
     645    GTask *queued_task; /* (owned) (nullable) */
     646    GTask *waiting_task; /* (owned) (nullable) */
     647    GError *last_error; /* (owned) (nullable) */
     648    GSource *wait_source; /* (owned) (nullable) */
     649    GMainContext *context; /* (owned) (nullable) */
     650    ResolveState state;
     651  } GNetworkAddressAddressEnumerator;
     652  
     653  typedef struct {
     654    GSocketAddressEnumeratorClass parent_class;
     655  
     656  } GNetworkAddressAddressEnumeratorClass;
     657  
     658  static GType _g_network_address_address_enumerator_get_type (void);
     659  G_DEFINE_TYPE (GNetworkAddressAddressEnumerator, _g_network_address_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR)
     660  
     661  static void
     662  g_network_address_address_enumerator_finalize (GObject *object)
     663  {
     664    GNetworkAddressAddressEnumerator *addr_enum =
     665      G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (object);
     666  
     667    if (addr_enum->wait_source)
     668      {
     669        g_source_destroy (addr_enum->wait_source);
     670        g_clear_pointer (&addr_enum->wait_source, g_source_unref);
     671      }
     672    g_clear_object (&addr_enum->queued_task);
     673    g_clear_object (&addr_enum->waiting_task);
     674    g_clear_error (&addr_enum->last_error);
     675    g_object_unref (addr_enum->addr);
     676    g_clear_pointer (&addr_enum->context, g_main_context_unref);
     677    g_list_free_full (addr_enum->addresses, g_object_unref);
     678  
     679    G_OBJECT_CLASS (_g_network_address_address_enumerator_parent_class)->finalize (object);
     680  }
     681  
     682  static inline GSocketFamily
     683  get_address_family (GInetSocketAddress *address)
     684  {
     685    return g_inet_address_get_family (g_inet_socket_address_get_address (address));
     686  }
     687  
     688  static void
     689  list_split_families (GList  *list,
     690                       GList **out_ipv4,
     691                       GList **out_ipv6)
     692  {
     693    g_assert (out_ipv4);
     694    g_assert (out_ipv6);
     695  
     696    while (list)
     697      {
     698        GSocketFamily family = get_address_family (list->data);
     699        switch (family)
     700          {
     701            case G_SOCKET_FAMILY_IPV4:
     702              *out_ipv4 = g_list_prepend (*out_ipv4, list->data);
     703              break;
     704            case G_SOCKET_FAMILY_IPV6:
     705              *out_ipv6 = g_list_prepend (*out_ipv6, list->data);
     706              break;
     707            case G_SOCKET_FAMILY_INVALID:
     708            case G_SOCKET_FAMILY_UNIX:
     709              g_assert_not_reached ();
     710          }
     711  
     712        list = g_list_next (list);
     713      }
     714  
     715    *out_ipv4 = g_list_reverse (*out_ipv4);
     716    *out_ipv6 = g_list_reverse (*out_ipv6);
     717  }
     718  
     719  static GList *
     720  list_interleave_families (GList *list1,
     721                            GList *list2)
     722  {
     723    GList *interleaved = NULL;
     724  
     725    while (list1 || list2)
     726      {
     727        if (list1)
     728          {
     729            interleaved = g_list_append (interleaved, list1->data);
     730            list1 = g_list_delete_link (list1, list1);
     731          }
     732        if (list2)
     733          {
     734            interleaved = g_list_append (interleaved, list2->data);
     735            list2 = g_list_delete_link (list2, list2);
     736          }
     737      }
     738  
     739    return interleaved;
     740  }
     741  
     742  /* list_copy_interleaved:
     743   * @list: (transfer container): List to copy
     744   *
     745   * Does a shallow copy of a list with address families interleaved.
     746   *
     747   * For example:
     748   *   Input: [ipv6, ipv6, ipv4, ipv4]
     749   *   Output: [ipv6, ipv4, ipv6, ipv4]
     750   *
     751   * Returns: (transfer container): A new list
     752   */
     753  static GList *
     754  list_copy_interleaved (GList *list)
     755  {
     756    GList *ipv4 = NULL, *ipv6 = NULL;
     757  
     758    list_split_families (list, &ipv4, &ipv6);
     759    return list_interleave_families (ipv6, ipv4);
     760  }
     761  
     762  /* list_concat_interleaved:
     763   * @parent_list: (transfer container): Already existing list
     764   * @current_item: (transfer container): Item after which to resort
     765   * @new_list: (transfer container): New list to be interleaved and concatenated
     766   *
     767   * This differs from g_list_concat() + list_copy_interleaved() in that it sorts
     768   * items in the previous list starting from @current_item and concats the results
     769   * to @parent_list.
     770   *
     771   * Returns: (transfer container): New start of list
     772   */
     773  static GList *
     774  list_concat_interleaved (GList *parent_list,
     775                           GList *current_item,
     776                           GList *new_list)
     777  {
     778    GList *ipv4 = NULL, *ipv6 = NULL, *interleaved, *trailing = NULL;
     779    GSocketFamily last_family = G_SOCKET_FAMILY_IPV4; /* Default to starting with ipv6 */
     780  
     781    if (current_item)
     782      {
     783        last_family = get_address_family (current_item->data);
     784  
     785        /* Unused addresses will get removed, resorted, then readded */
     786        trailing = g_list_next (current_item);
     787        current_item->next = NULL;
     788      }
     789  
     790    list_split_families (trailing, &ipv4, &ipv6);
     791    list_split_families (new_list, &ipv4, &ipv6);
     792    g_list_free (new_list);
     793  
     794    if (trailing)
     795      g_list_free (trailing);
     796  
     797    if (last_family == G_SOCKET_FAMILY_IPV4)
     798      interleaved = list_interleave_families (ipv6, ipv4);
     799    else
     800      interleaved = list_interleave_families (ipv4, ipv6);
     801  
     802    return g_list_concat (parent_list, interleaved);
     803  }
     804  
     805  static void
     806  maybe_update_address_cache (GNetworkAddressAddressEnumerator *addr_enum,
     807                              GResolver                        *resolver)
     808  {
     809    GList *addresses, *p;
     810  
     811    /* Only cache complete results */
     812    if (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4 || addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV6)
     813      return;
     814  
     815    /* The enumerators list will not necessarily be fully sorted */
     816    addresses = list_copy_interleaved (addr_enum->addresses);
     817    for (p = addresses; p; p = p->next)
     818      g_object_ref (p->data);
     819  
     820    g_network_address_set_cached_addresses (addr_enum->addr, g_steal_pointer (&addresses), g_resolver_get_serial (resolver));
     821  }
     822  
     823  static void
     824  g_network_address_address_enumerator_add_addresses (GNetworkAddressAddressEnumerator *addr_enum,
     825                                                      GList                            *addresses,
     826                                                      GResolver                        *resolver)
     827  {
     828    GList *new_addresses = inet_addresses_to_inet_socket_addresses (addr_enum->addr, addresses);
     829  
     830    if (addr_enum->addresses == NULL)
     831      addr_enum->addresses = g_steal_pointer (&new_addresses);
     832    else
     833      addr_enum->addresses = list_concat_interleaved (addr_enum->addresses, addr_enum->current_item, g_steal_pointer (&new_addresses));
     834  
     835    maybe_update_address_cache (addr_enum, resolver);
     836  }
     837  
     838  static gpointer
     839  copy_object (gconstpointer src,
     840               gpointer      user_data)
     841  {
     842    return g_object_ref (G_OBJECT (src));
     843  }
     844  
     845  static GSocketAddress *
     846  init_and_query_next_address (GNetworkAddressAddressEnumerator *addr_enum)
     847  {
     848    GList *next_item;
     849  
     850    if (addr_enum->addresses == NULL)
     851      addr_enum->addresses = g_list_copy_deep (addr_enum->addr->priv->cached_sockaddrs,
     852                                               copy_object, NULL);
     853  
     854    /* We always want to look at the next item at call time to get the latest results.
     855       That means that sometimes ->next is NULL this call but is valid next call.
     856     */
     857    if (addr_enum->current_item == NULL)
     858      next_item = addr_enum->current_item = addr_enum->addresses;
     859    else
     860      next_item = g_list_next (addr_enum->current_item);
     861  
     862    if (next_item)
     863      {
     864        addr_enum->current_item = next_item;
     865        return g_object_ref (addr_enum->current_item->data);
     866      }
     867    else
     868      return NULL;
     869  }
     870  
     871  static GSocketAddress *
     872  g_network_address_address_enumerator_next (GSocketAddressEnumerator  *enumerator,
     873                                             GCancellable              *cancellable,
     874                                             GError                   **error)
     875  {
     876    GNetworkAddressAddressEnumerator *addr_enum =
     877      G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
     878  
     879    if (addr_enum->addresses == NULL)
     880      {
     881        GNetworkAddress *addr = addr_enum->addr;
     882        GResolver *resolver = g_resolver_get_default ();
     883        gint64 serial = g_resolver_get_serial (resolver);
     884  
     885        if (addr->priv->resolver_serial != 0 &&
     886            addr->priv->resolver_serial != serial)
     887          {
     888            /* Resolver has reloaded, discard cached addresses */
     889            g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref);
     890            addr->priv->cached_sockaddrs = NULL;
     891          }
     892  
     893        if (!addr->priv->cached_sockaddrs)
     894          g_network_address_parse_sockaddr (addr);
     895        if (!addr->priv->cached_sockaddrs)
     896          {
     897            GList *addresses;
     898  
     899            addresses = g_resolver_lookup_by_name (resolver,
     900                                                   addr->priv->hostname,
     901                                                   cancellable, error);
     902            if (!addresses)
     903              {
     904                g_object_unref (resolver);
     905                return NULL;
     906              }
     907  
     908            g_network_address_set_cached_addresses (addr, g_steal_pointer (&addresses), serial);
     909          }
     910  
     911        g_object_unref (resolver);
     912      }
     913  
     914    return init_and_query_next_address (addr_enum);
     915  }
     916  
     917  static void
     918  complete_queued_task (GNetworkAddressAddressEnumerator *addr_enum,
     919                        GTask                            *task,
     920                        GError                           *error)
     921  {
     922    if (error)
     923      g_task_return_error (task, error);
     924    else
     925      {
     926        GSocketAddress *sockaddr = init_and_query_next_address (addr_enum);
     927        g_task_return_pointer (task, g_steal_pointer (&sockaddr), g_object_unref);
     928      }
     929    g_object_unref (task);
     930  }
     931  
     932  static int
     933  on_address_timeout (gpointer user_data)
     934  {
     935    GNetworkAddressAddressEnumerator *addr_enum = user_data;
     936  
     937    /* Upon completion it may get unref'd by the owner */
     938    g_object_ref (addr_enum);
     939  
     940    if (addr_enum->queued_task != NULL)
     941        complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task),
     942                              g_steal_pointer (&addr_enum->last_error));
     943    else if (addr_enum->waiting_task != NULL)
     944        complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task),
     945                              NULL);
     946  
     947    g_clear_pointer (&addr_enum->wait_source, g_source_unref);
     948    g_object_unref (addr_enum);
     949  
     950    return G_SOURCE_REMOVE;
     951  }
     952  
     953  static void
     954  got_ipv6_addresses (GObject      *source_object,
     955                      GAsyncResult *result,
     956                      gpointer      user_data)
     957  {
     958    GNetworkAddressAddressEnumerator *addr_enum = user_data;
     959    GResolver *resolver = G_RESOLVER (source_object);
     960    GList *addresses;
     961    GError *error = NULL;
     962  
     963    addr_enum->state ^= RESOLVE_STATE_WAITING_ON_IPV6;
     964  
     965    addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error);
     966    if (!error)
     967      g_network_address_address_enumerator_add_addresses (addr_enum, g_steal_pointer (&addresses), resolver);
     968    else
     969      g_debug ("IPv6 DNS error: %s", error->message);
     970  
     971    /* If ipv4 was first and waiting on us it can stop waiting */
     972    if (addr_enum->wait_source)
     973      {
     974        g_source_destroy (addr_enum->wait_source);
     975        g_clear_pointer (&addr_enum->wait_source, g_source_unref);
     976      }
     977  
     978    /* If we got an error before ipv4 then let its response handle it.
     979     * If we get ipv6 response first or error second then
     980     * immediately complete the task.
     981     */
     982    if (error != NULL && !addr_enum->last_error && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4))
     983      {
     984        /* ipv6 lookup failed, but ipv4 is still outstanding.  wait. */
     985        addr_enum->last_error = g_steal_pointer (&error);
     986      }
     987    else if (addr_enum->waiting_task != NULL)
     988      {
     989        complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), NULL);
     990      }
     991    else if (addr_enum->queued_task != NULL)
     992      {
     993        GError *task_error = NULL;
     994  
     995        /* If both errored just use the ipv6 one,
     996           but if ipv6 errored and ipv4 didn't we don't error */
     997        if (error != NULL && addr_enum->last_error)
     998            task_error = g_steal_pointer (&error);
     999  
    1000        g_clear_error (&addr_enum->last_error);
    1001        complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task),
    1002                              g_steal_pointer (&task_error));
    1003      }
    1004  
    1005    g_clear_error (&error);
    1006    g_object_unref (addr_enum);
    1007  }
    1008  
    1009  static void
    1010  got_ipv4_addresses (GObject      *source_object,
    1011                      GAsyncResult *result,
    1012                      gpointer      user_data)
    1013  {
    1014    GNetworkAddressAddressEnumerator *addr_enum = user_data;
    1015    GResolver *resolver = G_RESOLVER (source_object);
    1016    GList *addresses;
    1017    GError *error = NULL;
    1018  
    1019    addr_enum->state ^= RESOLVE_STATE_WAITING_ON_IPV4;
    1020  
    1021    addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error);
    1022    if (!error)
    1023      g_network_address_address_enumerator_add_addresses (addr_enum, g_steal_pointer (&addresses), resolver);
    1024    else
    1025      g_debug ("IPv4 DNS error: %s", error->message);
    1026  
    1027    if (addr_enum->wait_source)
    1028      {
    1029        g_source_destroy (addr_enum->wait_source);
    1030        g_clear_pointer (&addr_enum->wait_source, g_source_unref);
    1031      }
    1032  
    1033    /* If ipv6 already came in and errored then we return.
    1034     * If ipv6 returned successfully then we don't need to do anything unless
    1035     * another enumeration was waiting on us.
    1036     * If ipv6 hasn't come we should wait a short while for it as RFC 8305 suggests.
    1037     */
    1038    if (addr_enum->last_error)
    1039      {
    1040        g_assert (addr_enum->queued_task);
    1041        g_clear_error (&addr_enum->last_error);
    1042        complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task),
    1043                              g_steal_pointer (&error));
    1044      }
    1045    else if (addr_enum->waiting_task != NULL)
    1046      {
    1047        complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), NULL);
    1048      }
    1049    else if (addr_enum->queued_task != NULL)
    1050      {
    1051        addr_enum->last_error = g_steal_pointer (&error);
    1052        addr_enum->wait_source = g_timeout_source_new (HAPPY_EYEBALLS_RESOLUTION_DELAY_MS);
    1053        g_source_set_callback (addr_enum->wait_source,
    1054                               on_address_timeout,
    1055                               addr_enum, NULL);
    1056        g_source_attach (addr_enum->wait_source, addr_enum->context);
    1057      }
    1058  
    1059    g_clear_error (&error);
    1060    g_object_unref (addr_enum);
    1061  }
    1062  
    1063  static void
    1064  g_network_address_address_enumerator_next_async (GSocketAddressEnumerator  *enumerator,
    1065                                                   GCancellable              *cancellable,
    1066                                                   GAsyncReadyCallback        callback,
    1067                                                   gpointer                   user_data)
    1068  {
    1069    GNetworkAddressAddressEnumerator *addr_enum =
    1070      G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
    1071    GSocketAddress *sockaddr;
    1072    GTask *task;
    1073  
    1074    task = g_task_new (addr_enum, cancellable, callback, user_data);
    1075    g_task_set_source_tag (task, g_network_address_address_enumerator_next_async);
    1076  
    1077    if (addr_enum->addresses == NULL && addr_enum->state == RESOLVE_STATE_NONE)
    1078      {
    1079        GNetworkAddress *addr = addr_enum->addr;
    1080        GResolver *resolver = g_resolver_get_default ();
    1081        gint64 serial = g_resolver_get_serial (resolver);
    1082  
    1083        if (addr->priv->resolver_serial != 0 &&
    1084            addr->priv->resolver_serial != serial)
    1085          {
    1086            /* Resolver has reloaded, discard cached addresses */
    1087            g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref);
    1088            addr->priv->cached_sockaddrs = NULL;
    1089          }
    1090  
    1091        if (addr->priv->cached_sockaddrs == NULL)
    1092          {
    1093            if (g_network_address_parse_sockaddr (addr))
    1094              complete_queued_task (addr_enum, task, NULL);
    1095            else
    1096              {
    1097                /* It does not make sense for this to be called multiple
    1098                 * times before the initial callback has been called */
    1099                g_assert (addr_enum->queued_task == NULL);
    1100  
    1101                addr_enum->state = RESOLVE_STATE_WAITING_ON_IPV4 | RESOLVE_STATE_WAITING_ON_IPV6;
    1102                addr_enum->queued_task = g_steal_pointer (&task);
    1103                /* Look up in parallel as per RFC 8305 */
    1104                g_resolver_lookup_by_name_with_flags_async (resolver,
    1105                                                            addr->priv->hostname,
    1106                                                            G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY,
    1107                                                            cancellable,
    1108                                                            got_ipv6_addresses, g_object_ref (addr_enum));
    1109                g_resolver_lookup_by_name_with_flags_async (resolver,
    1110                                                            addr->priv->hostname,
    1111                                                            G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY,
    1112                                                            cancellable,
    1113                                                            got_ipv4_addresses, g_object_ref (addr_enum));
    1114              }
    1115            g_object_unref (resolver);
    1116            return;
    1117          }
    1118  
    1119        g_object_unref (resolver);
    1120      }
    1121  
    1122    sockaddr = init_and_query_next_address (addr_enum);
    1123    if (sockaddr == NULL && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4 ||
    1124                             addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV6))
    1125      {
    1126        addr_enum->waiting_task = task;
    1127      }
    1128    else
    1129      {
    1130        g_task_return_pointer (task, sockaddr, g_object_unref);
    1131        g_object_unref (task);
    1132      }
    1133  }
    1134  
    1135  static GSocketAddress *
    1136  g_network_address_address_enumerator_next_finish (GSocketAddressEnumerator  *enumerator,
    1137                                                    GAsyncResult              *result,
    1138                                                    GError                   **error)
    1139  {
    1140    g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
    1141  
    1142    return g_task_propagate_pointer (G_TASK (result), error);
    1143  }
    1144  
    1145  static void
    1146  _g_network_address_address_enumerator_init (GNetworkAddressAddressEnumerator *enumerator)
    1147  {
    1148    enumerator->context = g_main_context_ref_thread_default ();
    1149  }
    1150  
    1151  static void
    1152  _g_network_address_address_enumerator_class_init (GNetworkAddressAddressEnumeratorClass *addrenum_class)
    1153  {
    1154    GObjectClass *object_class = G_OBJECT_CLASS (addrenum_class);
    1155    GSocketAddressEnumeratorClass *enumerator_class =
    1156      G_SOCKET_ADDRESS_ENUMERATOR_CLASS (addrenum_class);
    1157  
    1158    enumerator_class->next = g_network_address_address_enumerator_next;
    1159    enumerator_class->next_async = g_network_address_address_enumerator_next_async;
    1160    enumerator_class->next_finish = g_network_address_address_enumerator_next_finish;
    1161    object_class->finalize = g_network_address_address_enumerator_finalize;
    1162  }
    1163  
    1164  static GSocketAddressEnumerator *
    1165  g_network_address_connectable_enumerate (GSocketConnectable *connectable)
    1166  {
    1167    GNetworkAddressAddressEnumerator *addr_enum;
    1168  
    1169    addr_enum = g_object_new (G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR, NULL);
    1170    addr_enum->addr = g_object_ref (G_NETWORK_ADDRESS (connectable));
    1171  
    1172    return (GSocketAddressEnumerator *)addr_enum;
    1173  }
    1174  
    1175  static GSocketAddressEnumerator *
    1176  g_network_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
    1177  {
    1178    GNetworkAddress *self = G_NETWORK_ADDRESS (connectable);
    1179    GSocketAddressEnumerator *proxy_enum;
    1180    gchar *uri;
    1181  
    1182    uri = g_uri_join (G_URI_FLAGS_NONE,
    1183                      self->priv->scheme ? self->priv->scheme : "none",
    1184                      NULL,
    1185                      self->priv->hostname,
    1186                      self->priv->port,
    1187                      "",
    1188                      NULL,
    1189                      NULL);
    1190  
    1191    proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
    1192                               "connectable", connectable,
    1193        	       	       	     "uri", uri,
    1194        	       	       	     NULL);
    1195  
    1196    g_free (uri);
    1197  
    1198    return proxy_enum;
    1199  }
    1200  
    1201  static gchar *
    1202  g_network_address_connectable_to_string (GSocketConnectable *connectable)
    1203  {
    1204    GNetworkAddress *addr;
    1205    const gchar *scheme;
    1206    guint16 port;
    1207    GString *out;  /* owned */
    1208  
    1209    addr = G_NETWORK_ADDRESS (connectable);
    1210    out = g_string_new ("");
    1211  
    1212    scheme = g_network_address_get_scheme (addr);
    1213    if (scheme != NULL)
    1214      g_string_append_printf (out, "%s:", scheme);
    1215  
    1216    g_string_append (out, g_network_address_get_hostname (addr));
    1217  
    1218    port = g_network_address_get_port (addr);
    1219    if (port != 0)
    1220      g_string_append_printf (out, ":%u", port);
    1221  
    1222    return g_string_free (out, FALSE);
    1223  }