/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */

/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2008 Red Hat, Inc.
 * Copyright (C) 2018 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"
#include <glib.h>
#include "glibintl.h"

#include "gresolver.h"
#include "gnetworkingprivate.h"
#include "gasyncresult.h"
#include "ginetaddress.h"
#include "gtask.h"
#include "gsrvtarget.h"
#include "gthreadedresolver.h"
#include "gioerror.h"
#include "gcancellable.h"

#ifdef G_OS_UNIX
#include <sys/stat.h>
#endif

#include <stdlib.h>


/**
 * SECTION:gresolver
 * @short_description: Asynchronous and cancellable DNS resolver
 * @include: gio/gio.h
 *
 * #GResolver provides cancellable synchronous and asynchronous DNS
 * resolution, for hostnames (g_resolver_lookup_by_address(),
 * g_resolver_lookup_by_name() and their async variants) and SRV
 * (service) records (g_resolver_lookup_service()).
 *
 * #GNetworkAddress and #GNetworkService provide wrappers around
 * #GResolver functionality that also implement #GSocketConnectable,
 * making it easy to connect to a remote host/service.
 */

enum {
  RELOAD,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

struct _GResolverPrivate {
#ifdef G_OS_UNIX
  time_t resolv_conf_timestamp;
#else
  int dummy;
#endif
};

/**
 * GResolver:
 *
 * The object that handles DNS resolution. Use g_resolver_get_default()
 * to get the default resolver.
 *
 * This is an abstract type; subclasses of it implement different resolvers for
 * different platforms and situations.
 */
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GResolver, g_resolver, G_TYPE_OBJECT,
                                  G_ADD_PRIVATE (GResolver)
                                  g_networking_init ();)

static GList *
srv_records_to_targets (GList *records)
{
  const gchar *hostname;
  guint16 port, priority, weight;
  GSrvTarget *target;
  GList *l;

  for (l = records; l != NULL; l = g_list_next (l))
    {
      g_variant_get (l->data, "(qqq&s)", &priority, &weight, &port, &hostname);
      target = g_srv_target_new (hostname, port, priority, weight);
      g_variant_unref (l->data);
      l->data = target;
    }

  return g_srv_target_list_sort (records);
}

static GList *
g_resolver_real_lookup_service (GResolver            *resolver,
                                const gchar          *rrname,
                                GCancellable         *cancellable,
                                GError              **error)
{
  GList *records;

  records = G_RESOLVER_GET_CLASS (resolver)->lookup_records (resolver,
                                                             rrname,
                                                             G_RESOLVER_RECORD_SRV,
                                                             cancellable,
                                                             error);

  return srv_records_to_targets (records);
}

static void
g_resolver_real_lookup_service_async (GResolver            *resolver,
                                      const gchar          *rrname,
                                      GCancellable         *cancellable,
                                      GAsyncReadyCallback   callback,
                                      gpointer              user_data)
{
  G_RESOLVER_GET_CLASS (resolver)->lookup_records_async (resolver,
                                                         rrname,
                                                         G_RESOLVER_RECORD_SRV,
                                                         cancellable,
                                                         callback,
                                                         user_data);
}

static GList *
g_resolver_real_lookup_service_finish (GResolver            *resolver,
                                       GAsyncResult         *result,
                                       GError              **error)
{
  GList *records;

  records = G_RESOLVER_GET_CLASS (resolver)->lookup_records_finish (resolver,
                                                                    result,
                                                                    error);

  return srv_records_to_targets (records);
}

static void
g_resolver_class_init (GResolverClass *resolver_class)
{
  /* Automatically pass these over to the lookup_records methods */
  resolver_class->lookup_service = g_resolver_real_lookup_service;
  resolver_class->lookup_service_async = g_resolver_real_lookup_service_async;
  resolver_class->lookup_service_finish = g_resolver_real_lookup_service_finish;

  /**
   * GResolver::reload:
   * @resolver: a #GResolver
   *
   * Emitted when the resolver notices that the system resolver
   * configuration has changed.
   **/
  signals[RELOAD] =
    g_signal_new (I_("reload"),
		  G_TYPE_RESOLVER,
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GResolverClass, reload),
		  NULL, NULL,
		  NULL,
		  G_TYPE_NONE, 0);
}

static void
g_resolver_init (GResolver *resolver)
{
#ifdef G_OS_UNIX
  struct stat st;
#endif

  resolver->priv = g_resolver_get_instance_private (resolver);

#ifdef G_OS_UNIX
  if (stat (_PATH_RESCONF, &st) == 0)
    resolver->priv->resolv_conf_timestamp = st.st_mtime;
#endif
}

G_LOCK_DEFINE_STATIC (default_resolver);
static GResolver *default_resolver;

/**
 * g_resolver_get_default:
 *
 * Gets the default #GResolver. You should unref it when you are done
 * with it. #GResolver may use its reference count as a hint about how
 * many threads it should allocate for concurrent DNS resolutions.
 *
 * Returns: (transfer full): the default #GResolver.
 *
 * Since: 2.22
 */
GResolver *
g_resolver_get_default (void)
{
  GResolver *ret;

  G_LOCK (default_resolver);
  if (!default_resolver)
    default_resolver = g_object_new (G_TYPE_THREADED_RESOLVER, NULL);
  ret = g_object_ref (default_resolver);
  G_UNLOCK (default_resolver);

  return ret;
}

/**
 * g_resolver_set_default:
 * @resolver: the new default #GResolver
 *
 * Sets @resolver to be the application's default resolver (reffing
 * @resolver, and unreffing the previous default resolver, if any).
 * Future calls to g_resolver_get_default() will return this resolver.
 *
 * This can be used if an application wants to perform any sort of DNS
 * caching or "pinning"; it can implement its own #GResolver that
 * calls the original default resolver for DNS operations, and
 * implements its own cache policies on top of that, and then set
 * itself as the default resolver for all later code to use.
 *
 * Since: 2.22
 */
void
g_resolver_set_default (GResolver *resolver)
{
  G_LOCK (default_resolver);
  if (default_resolver)
    g_object_unref (default_resolver);
  default_resolver = g_object_ref (resolver);
  G_UNLOCK (default_resolver);
}

/* Bionic has res_init() but it's not in any header */
#ifdef __BIONIC__
int res_init (void);
#endif

static void
g_resolver_maybe_reload (GResolver *resolver)
{
#ifdef G_OS_UNIX
  struct stat st;

  if (stat (_PATH_RESCONF, &st) == 0)
    {
      if (st.st_mtime != resolver->priv->resolv_conf_timestamp)
        {
          resolver->priv->resolv_conf_timestamp = st.st_mtime;
#ifdef HAVE_RES_INIT
          res_init ();
#endif
          g_signal_emit (resolver, signals[RELOAD], 0);
        }
    }
#endif
}

/* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */
static void
remove_duplicates (GList *addrs)
{
  GList *l;
  GList *ll;
  GList *lll;

  /* TODO: if this is too slow (it's O(n^2) but n is typically really
   * small), we can do something more clever but note that we must not
   * change the order of elements...
   */
  for (l = addrs; l != NULL; l = l->next)
    {
      GInetAddress *address = G_INET_ADDRESS (l->data);
      for (ll = l->next; ll != NULL; ll = lll)
        {
          GInetAddress *other_address = G_INET_ADDRESS (ll->data);
          lll = ll->next;
          if (g_inet_address_equal (address, other_address))
            {
              g_object_unref (other_address);
              /* we never return the first element */
              g_warn_if_fail (g_list_delete_link (addrs, ll) == addrs);
            }
        }
    }
}

/* Note that this does not follow the "FALSE means @error is set"
 * convention. The return value tells the caller whether it should
 * return @addrs and @error to the caller right away, or if it should
 * continue and trying to resolve the name as a hostname.
 */
static gboolean
handle_ip_address (const char  *hostname,
                   GList      **addrs,
                   GError     **error)
{
  GInetAddress *addr;

#ifndef G_OS_WIN32
  struct in_addr ip4addr;
#endif

  addr = g_inet_address_new_from_string (hostname);
  if (addr)
    {
      *addrs = g_list_append (NULL, addr);
      return TRUE;
    }

  *addrs = NULL;

#ifdef G_OS_WIN32

  /* Reject IPv6 addresses that have brackets ('[' or ']') and/or port numbers,
   * as no valid addresses should contain these at this point.
   * Non-standard IPv4 addresses would be rejected during the call to
   * getaddrinfo() later.
   */
  if (strrchr (hostname, '[') != NULL ||
      strrchr (hostname, ']') != NULL)
#else

  /* Reject non-standard IPv4 numbers-and-dots addresses.
   * g_inet_address_new_from_string() will have accepted any "real" IP
   * address, so if inet_aton() succeeds, then it's an address we want
   * to reject.
   */
  if (inet_aton (hostname, &ip4addr))
#endif
    {
#ifdef G_OS_WIN32
      gchar *error_message = g_win32_error_message (WSAHOST_NOT_FOUND);
#else
      gchar *error_message = g_locale_to_utf8 (gai_strerror (EAI_NONAME), -1, NULL, NULL, NULL);
      if (error_message == NULL)
        error_message = g_strdup ("[Invalid UTF-8]");
#endif
      g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
                   _("Error resolving “%s”: %s"),
                   hostname, error_message);
      g_free (error_message);

      return TRUE;
    }

  return FALSE;
}

static GList *
lookup_by_name_real (GResolver                 *resolver,
                     const gchar               *hostname,
                     GResolverNameLookupFlags   flags,
                     GCancellable              *cancellable,
                     GError                    **error)
{
  GList *addrs;
  gchar *ascii_hostname = NULL;

  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
  g_return_val_if_fail (hostname != NULL, NULL);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  /* Check if @hostname is just an IP address */
  if (handle_ip_address (hostname, &addrs, error))
    return addrs;

  if (g_hostname_is_non_ascii (hostname))
    hostname = ascii_hostname = g_hostname_to_ascii (hostname);

  if (!hostname)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Invalid hostname"));
      return NULL;
    }

  g_resolver_maybe_reload (resolver);

  if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
    {
      if (!G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                       /* Translators: The placeholder is for a function name. */
                       _("%s not implemented"), "lookup_by_name_with_flags");
          g_free (ascii_hostname);
          return NULL;
        }
      addrs = G_RESOLVER_GET_CLASS (resolver)->
        lookup_by_name_with_flags (resolver, hostname, flags, cancellable, error);
    }
  else
    addrs = G_RESOLVER_GET_CLASS (resolver)->
      lookup_by_name (resolver, hostname, cancellable, error);

  remove_duplicates (addrs);

  g_free (ascii_hostname);
  return addrs;
}

/**
 * g_resolver_lookup_by_name:
 * @resolver: a #GResolver
 * @hostname: the hostname to look up
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Synchronously resolves @hostname to determine its associated IP
 * address(es). @hostname may be an ASCII-only or UTF-8 hostname, or
 * the textual form of an IP address (in which case this just becomes
 * a wrapper around g_inet_address_new_from_string()).
 *
 * On success, g_resolver_lookup_by_name() will return a non-empty #GList of
 * #GInetAddress, sorted in order of preference and guaranteed to not
 * contain duplicates. That is, if using the result to connect to
 * @hostname, you should attempt to connect to the first address
 * first, then the second if the first fails, etc. If you are using
 * the result to listen on a socket, it is appropriate to add each
 * result using e.g. g_socket_listener_add_address().
 *
 * If the DNS resolution fails, @error (if non-%NULL) will be set to a
 * value from #GResolverError and %NULL will be returned.
 *
 * If @cancellable is non-%NULL, it can be used to cancel the
 * operation, in which case @error (if non-%NULL) will be set to
 * %G_IO_ERROR_CANCELLED.
 *
 * If you are planning to connect to a socket on the resolved IP
 * address, it may be easier to create a #GNetworkAddress and use its
 * #GSocketConnectable interface.
 *
 * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
 * of #GInetAddress, or %NULL on error. You
 * must unref each of the addresses and free the list when you are
 * done with it. (You can use g_resolver_free_addresses() to do this.)
 *
 * Since: 2.22
 */
GList *
g_resolver_lookup_by_name (GResolver     *resolver,
                           const gchar   *hostname,
                           GCancellable  *cancellable,
                           GError       **error)
{
  return lookup_by_name_real (resolver,
                              hostname,
                              G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT,
                              cancellable,
                              error);
}

/**
 * g_resolver_lookup_by_name_with_flags:
 * @resolver: a #GResolver
 * @hostname: the hostname to look up
 * @flags: extra #GResolverNameLookupFlags for the lookup
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: (nullable): return location for a #GError, or %NULL
 *
 * This differs from g_resolver_lookup_by_name() in that you can modify
 * the lookup behavior with @flags. For example this can be used to limit
 * results with #G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY.
 *
 * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
 * of #GInetAddress, or %NULL on error. You
 * must unref each of the addresses and free the list when you are
 * done with it. (You can use g_resolver_free_addresses() to do this.)
 *
 * Since: 2.60
 */
GList *
g_resolver_lookup_by_name_with_flags (GResolver                 *resolver,
                                      const gchar               *hostname,
                                      GResolverNameLookupFlags   flags,
                                      GCancellable              *cancellable,
                                      GError                   **error)
{
  return lookup_by_name_real (resolver,
                              hostname,
                              flags,
                              cancellable,
                              error);
}

static void
lookup_by_name_async_real (GResolver                *resolver,
                           const gchar              *hostname,
                           GResolverNameLookupFlags  flags,
                           GCancellable             *cancellable,
                           GAsyncReadyCallback       callback,
                           gpointer                  user_data)
{
  gchar *ascii_hostname = NULL;
  GList *addrs;
  GError *error = NULL;

  g_return_if_fail (G_IS_RESOLVER (resolver));
  g_return_if_fail (hostname != NULL);
  g_return_if_fail (!(flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY && flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY));

  /* Check if @hostname is just an IP address */
  if (handle_ip_address (hostname, &addrs, &error))
    {
      GTask *task;

      task = g_task_new (resolver, cancellable, callback, user_data);
      g_task_set_source_tag (task, lookup_by_name_async_real);
      if (addrs)
        g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
      else
        g_task_return_error (task, error);
      g_object_unref (task);
      return;
    }

  if (g_hostname_is_non_ascii (hostname))
    hostname = ascii_hostname = g_hostname_to_ascii (hostname);

  if (!hostname)
    {
      GTask *task;

      g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Invalid hostname"));
      task = g_task_new (resolver, cancellable, callback, user_data);
      g_task_set_source_tag (task, lookup_by_name_async_real);
      g_task_return_error (task, error);
      g_object_unref (task);
      return;
    }

  g_resolver_maybe_reload (resolver);

  if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
    {
      if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_async == NULL)
        {
          GTask *task;

          g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                       /* Translators: The placeholder is for a function name. */
                       _("%s not implemented"), "lookup_by_name_with_flags_async");
          task = g_task_new (resolver, cancellable, callback, user_data);
          g_task_set_source_tag (task, lookup_by_name_async_real);
          g_task_return_error (task, error);
          g_object_unref (task);
        }
      else
        G_RESOLVER_GET_CLASS (resolver)->
          lookup_by_name_with_flags_async (resolver, hostname, flags, cancellable, callback, user_data);
    }
  else
    G_RESOLVER_GET_CLASS (resolver)->
      lookup_by_name_async (resolver, hostname, cancellable, callback, user_data);

  g_free (ascii_hostname);
}

static GList *
lookup_by_name_finish_real (GResolver     *resolver,
                            GAsyncResult  *result,
                            GError       **error,
                            gboolean       with_flags)
{
  GList *addrs;

  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  if (g_async_result_legacy_propagate_error (result, error))
    return NULL;
  else if (g_async_result_is_tagged (result, lookup_by_name_async_real))
    {
      /* Handle the stringified-IP-addr case */
      return g_task_propagate_pointer (G_TASK (result), error);
    }

  if (with_flags)
    {
      g_assert (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_finish != NULL);
      addrs = G_RESOLVER_GET_CLASS (resolver)->
        lookup_by_name_with_flags_finish (resolver, result, error);
    }
  else
    addrs = G_RESOLVER_GET_CLASS (resolver)->
      lookup_by_name_finish (resolver, result, error);

  remove_duplicates (addrs);

  return addrs;
}

/**
 * g_resolver_lookup_by_name_with_flags_async:
 * @resolver: a #GResolver
 * @hostname: the hostname to look up the address of
 * @flags: extra #GResolverNameLookupFlags for the lookup
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @callback: (scope async): callback to call after resolution completes
 * @user_data: (closure): data for @callback
 *
 * Begins asynchronously resolving @hostname to determine its
 * associated IP address(es), and eventually calls @callback, which
 * must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
 * See g_resolver_lookup_by_name() for more details.
 *
 * Since: 2.60
 */
void
g_resolver_lookup_by_name_with_flags_async (GResolver                *resolver,
                                            const gchar              *hostname,
                                            GResolverNameLookupFlags  flags,
                                            GCancellable             *cancellable,
                                            GAsyncReadyCallback       callback,
                                            gpointer                  user_data)
{
  lookup_by_name_async_real (resolver,
                             hostname,
                             flags,
                             cancellable,
                             callback,
                             user_data);
}

/**
 * g_resolver_lookup_by_name_async:
 * @resolver: a #GResolver
 * @hostname: the hostname to look up the address of
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @callback: (scope async): callback to call after resolution completes
 * @user_data: (closure): data for @callback
 *
 * Begins asynchronously resolving @hostname to determine its
 * associated IP address(es), and eventually calls @callback, which
 * must call g_resolver_lookup_by_name_finish() to get the result.
 * See g_resolver_lookup_by_name() for more details.
 *
 * Since: 2.22
 */
void
g_resolver_lookup_by_name_async (GResolver           *resolver,
                                 const gchar         *hostname,
                                 GCancellable        *cancellable,
                                 GAsyncReadyCallback  callback,
                                 gpointer             user_data)
{
  lookup_by_name_async_real (resolver,
                             hostname,
                             0,
                             cancellable,
                             callback,
                             user_data);
}

/**
 * g_resolver_lookup_by_name_finish:
 * @resolver: a #GResolver
 * @result: the result passed to your #GAsyncReadyCallback
 * @error: return location for a #GError, or %NULL
 *
 * Retrieves the result of a call to
 * g_resolver_lookup_by_name_async().
 *
 * If the DNS resolution failed, @error (if non-%NULL) will be set to
 * a value from #GResolverError. If the operation was cancelled,
 * @error will be set to %G_IO_ERROR_CANCELLED.
 *
 * Returns: (element-type GInetAddress) (transfer full): a #GList
 * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
 * for more details.
 *
 * Since: 2.22
 */
GList *
g_resolver_lookup_by_name_finish (GResolver     *resolver,
                                  GAsyncResult  *result,
                                  GError       **error)
{
  return lookup_by_name_finish_real (resolver,
                                     result,
                                     error,
                                     FALSE);
}

/**
 * g_resolver_lookup_by_name_with_flags_finish:
 * @resolver: a #GResolver
 * @result: the result passed to your #GAsyncReadyCallback
 * @error: return location for a #GError, or %NULL
 *
 * Retrieves the result of a call to
 * g_resolver_lookup_by_name_with_flags_async().
 *
 * If the DNS resolution failed, @error (if non-%NULL) will be set to
 * a value from #GResolverError. If the operation was cancelled,
 * @error will be set to %G_IO_ERROR_CANCELLED.
 *
 * Returns: (element-type GInetAddress) (transfer full): a #GList
 * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
 * for more details.
 *
 * Since: 2.60
 */
GList *
g_resolver_lookup_by_name_with_flags_finish (GResolver     *resolver,
                                             GAsyncResult  *result,
                                             GError       **error)
{
  return lookup_by_name_finish_real (resolver,
                                     result,
                                     error,
                                     TRUE);
}

/**
 * g_resolver_free_addresses: (skip)
 * @addresses: a #GList of #GInetAddress
 *
 * Frees @addresses (which should be the return value from
 * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_finish()).
 * (This is a convenience method; you can also simply free the results
 * by hand.)
 *
 * Since: 2.22
 */
void
g_resolver_free_addresses (GList *addresses)
{
  GList *a;

  for (a = addresses; a; a = a->next)
    g_object_unref (a->data);
  g_list_free (addresses);
}

/**
 * g_resolver_lookup_by_address:
 * @resolver: a #GResolver
 * @address: the address to reverse-resolve
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Synchronously reverse-resolves @address to determine its
 * associated hostname.
 *
 * If the DNS resolution fails, @error (if non-%NULL) will be set to
 * a value from #GResolverError.
 *
 * If @cancellable is non-%NULL, it can be used to cancel the
 * operation, in which case @error (if non-%NULL) will be set to
 * %G_IO_ERROR_CANCELLED.
 *
 * Returns: a hostname (either ASCII-only, or in ASCII-encoded
 *     form), or %NULL on error.
 *
 * Since: 2.22
 */
gchar *
g_resolver_lookup_by_address (GResolver     *resolver,
                              GInetAddress  *address,
                              GCancellable  *cancellable,
                              GError       **error)
{
  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
  g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);

  g_resolver_maybe_reload (resolver);
  return G_RESOLVER_GET_CLASS (resolver)->
    lookup_by_address (resolver, address, cancellable, error);
}

/**
 * g_resolver_lookup_by_address_async:
 * @resolver: a #GResolver
 * @address: the address to reverse-resolve
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @callback: (scope async): callback to call after resolution completes
 * @user_data: (closure): data for @callback
 *
 * Begins asynchronously reverse-resolving @address to determine its
 * associated hostname, and eventually calls @callback, which must
 * call g_resolver_lookup_by_address_finish() to get the final result.
 *
 * Since: 2.22
 */
void
g_resolver_lookup_by_address_async (GResolver           *resolver,
                                    GInetAddress        *address,
                                    GCancellable        *cancellable,
                                    GAsyncReadyCallback  callback,
                                    gpointer             user_data)
{
  g_return_if_fail (G_IS_RESOLVER (resolver));
  g_return_if_fail (G_IS_INET_ADDRESS (address));

  g_resolver_maybe_reload (resolver);
  G_RESOLVER_GET_CLASS (resolver)->
    lookup_by_address_async (resolver, address, cancellable, callback, user_data);
}

/**
 * g_resolver_lookup_by_address_finish:
 * @resolver: a #GResolver
 * @result: the result passed to your #GAsyncReadyCallback
 * @error: return location for a #GError, or %NULL
 *
 * Retrieves the result of a previous call to
 * g_resolver_lookup_by_address_async().
 *
 * If the DNS resolution failed, @error (if non-%NULL) will be set to
 * a value from #GResolverError. If the operation was cancelled,
 * @error will be set to %G_IO_ERROR_CANCELLED.
 *
 * Returns: a hostname (either ASCII-only, or in ASCII-encoded
 * form), or %NULL on error.
 *
 * Since: 2.22
 */
gchar *
g_resolver_lookup_by_address_finish (GResolver     *resolver,
                                     GAsyncResult  *result,
                                     GError       **error)
{
  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);

  if (g_async_result_legacy_propagate_error (result, error))
    return NULL;

  return G_RESOLVER_GET_CLASS (resolver)->
    lookup_by_address_finish (resolver, result, error);
}

static gchar *
g_resolver_get_service_rrname (const char *service,
                               const char *protocol,
                               const char *domain)
{
  gchar *rrname, *ascii_domain = NULL;

  if (g_hostname_is_non_ascii (domain))
    domain = ascii_domain = g_hostname_to_ascii (domain);
  if (!domain)
    return NULL;

  rrname = g_strdup_printf ("_%s._%s.%s", service, protocol, domain);

  g_free (ascii_domain);
  return rrname;
}

/**
 * g_resolver_lookup_service:
 * @resolver: a #GResolver
 * @service: the service type to look up (eg, "ldap")
 * @protocol: the networking protocol to use for @service (eg, "tcp")
 * @domain: the DNS domain to look up the service in
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Synchronously performs a DNS SRV lookup for the given @service and
 * @protocol in the given @domain and returns an array of #GSrvTarget.
 * @domain may be an ASCII-only or UTF-8 hostname. Note also that the
 * @service and @protocol arguments do not include the leading underscore
 * that appears in the actual DNS entry.
 *
 * On success, g_resolver_lookup_service() will return a non-empty #GList of
 * #GSrvTarget, sorted in order of preference. (That is, you should
 * attempt to connect to the first target first, then the second if
 * the first fails, etc.)
 *
 * If the DNS resolution fails, @error (if non-%NULL) will be set to
 * a value from #GResolverError and %NULL will be returned.
 *
 * If @cancellable is non-%NULL, it can be used to cancel the
 * operation, in which case @error (if non-%NULL) will be set to
 * %G_IO_ERROR_CANCELLED.
 *
 * If you are planning to connect to the service, it is usually easier
 * to create a #GNetworkService and use its #GSocketConnectable
 * interface.
 *
 * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
 * #GSrvTarget, or %NULL on error. You must free each of the targets and the
 * list when you are done with it. (You can use g_resolver_free_targets() to do
 * this.)
 *
 * Since: 2.22
 */
GList *
g_resolver_lookup_service (GResolver     *resolver,
                           const gchar   *service,
                           const gchar   *protocol,
                           const gchar   *domain,
                           GCancellable  *cancellable,
                           GError       **error)
{
  GList *targets;
  gchar *rrname;

  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
  g_return_val_if_fail (service != NULL, NULL);
  g_return_val_if_fail (protocol != NULL, NULL);
  g_return_val_if_fail (domain != NULL, NULL);

  rrname = g_resolver_get_service_rrname (service, protocol, domain);
  if (!rrname)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Invalid domain"));
      return NULL;
    }

  g_resolver_maybe_reload (resolver);
  targets = G_RESOLVER_GET_CLASS (resolver)->
    lookup_service (resolver, rrname, cancellable, error);

  g_free (rrname);
  return targets;
}

/**
 * g_resolver_lookup_service_async:
 * @resolver: a #GResolver
 * @service: the service type to look up (eg, "ldap")
 * @protocol: the networking protocol to use for @service (eg, "tcp")
 * @domain: the DNS domain to look up the service in
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @callback: (scope async): callback to call after resolution completes
 * @user_data: (closure): data for @callback
 *
 * Begins asynchronously performing a DNS SRV lookup for the given
 * @service and @protocol in the given @domain, and eventually calls
 * @callback, which must call g_resolver_lookup_service_finish() to
 * get the final result. See g_resolver_lookup_service() for more
 * details.
 *
 * Since: 2.22
 */
void
g_resolver_lookup_service_async (GResolver           *resolver,
                                 const gchar         *service,
                                 const gchar         *protocol,
                                 const gchar         *domain,
                                 GCancellable        *cancellable,
                                 GAsyncReadyCallback  callback,
                                 gpointer             user_data)
{
  gchar *rrname;

  g_return_if_fail (G_IS_RESOLVER (resolver));
  g_return_if_fail (service != NULL);
  g_return_if_fail (protocol != NULL);
  g_return_if_fail (domain != NULL);

  rrname = g_resolver_get_service_rrname (service, protocol, domain);
  if (!rrname)
    {
      g_task_report_new_error (resolver, callback, user_data,
                               g_resolver_lookup_service_async,
                               G_IO_ERROR, G_IO_ERROR_FAILED,
                               _("Invalid domain"));
      return;
    }

  g_resolver_maybe_reload (resolver);
  G_RESOLVER_GET_CLASS (resolver)->
    lookup_service_async (resolver, rrname, cancellable, callback, user_data);

  g_free (rrname);
}

/**
 * g_resolver_lookup_service_finish:
 * @resolver: a #GResolver
 * @result: the result passed to your #GAsyncReadyCallback
 * @error: return location for a #GError, or %NULL
 *
 * Retrieves the result of a previous call to
 * g_resolver_lookup_service_async().
 *
 * If the DNS resolution failed, @error (if non-%NULL) will be set to
 * a value from #GResolverError. If the operation was cancelled,
 * @error will be set to %G_IO_ERROR_CANCELLED.
 *
 * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
 * #GSrvTarget, or %NULL on error. See g_resolver_lookup_service() for more
 * details.
 *
 * Since: 2.22
 */
GList *
g_resolver_lookup_service_finish (GResolver     *resolver,
                                  GAsyncResult  *result,
                                  GError       **error)
{
  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);

  if (g_async_result_legacy_propagate_error (result, error))
    return NULL;

  return G_RESOLVER_GET_CLASS (resolver)->
    lookup_service_finish (resolver, result, error);
}

/**
 * g_resolver_free_targets: (skip)
 * @targets: a #GList of #GSrvTarget
 *
 * Frees @targets (which should be the return value from
 * g_resolver_lookup_service() or g_resolver_lookup_service_finish()).
 * (This is a convenience method; you can also simply free the
 * results by hand.)
 *
 * Since: 2.22
 */
void
g_resolver_free_targets (GList *targets)
{
  GList *t;

  for (t = targets; t; t = t->next)
    g_srv_target_free (t->data);
  g_list_free (targets);
}

/**
 * g_resolver_lookup_records:
 * @resolver: a #GResolver
 * @rrname: the DNS name to look up the record for
 * @record_type: the type of DNS record to look up
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Synchronously performs a DNS record lookup for the given @rrname and returns
 * a list of records as #GVariant tuples. See #GResolverRecordType for
 * information on what the records contain for each @record_type.
 *
 * If the DNS resolution fails, @error (if non-%NULL) will be set to
 * a value from #GResolverError and %NULL will be returned.
 *
 * If @cancellable is non-%NULL, it can be used to cancel the
 * operation, in which case @error (if non-%NULL) will be set to
 * %G_IO_ERROR_CANCELLED.
 *
 * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
 * #GVariant, or %NULL on error. You must free each of the records and the list
 * when you are done with it. (You can use g_list_free_full() with
 * g_variant_unref() to do this.)
 *
 * Since: 2.34
 */
GList *
g_resolver_lookup_records (GResolver            *resolver,
                           const gchar          *rrname,
                           GResolverRecordType   record_type,
                           GCancellable         *cancellable,
                           GError              **error)
{
  GList *records;

  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
  g_return_val_if_fail (rrname != NULL, NULL);

  g_resolver_maybe_reload (resolver);
  records = G_RESOLVER_GET_CLASS (resolver)->
    lookup_records (resolver, rrname, record_type, cancellable, error);

  return records;
}

/**
 * g_resolver_lookup_records_async:
 * @resolver: a #GResolver
 * @rrname: the DNS name to look up the record for
 * @record_type: the type of DNS record to look up
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @callback: (scope async): callback to call after resolution completes
 * @user_data: (closure): data for @callback
 *
 * Begins asynchronously performing a DNS lookup for the given
 * @rrname, and eventually calls @callback, which must call
 * g_resolver_lookup_records_finish() to get the final result. See
 * g_resolver_lookup_records() for more details.
 *
 * Since: 2.34
 */
void
g_resolver_lookup_records_async (GResolver           *resolver,
                                 const gchar         *rrname,
                                 GResolverRecordType  record_type,
                                 GCancellable        *cancellable,
                                 GAsyncReadyCallback  callback,
                                 gpointer             user_data)
{
  g_return_if_fail (G_IS_RESOLVER (resolver));
  g_return_if_fail (rrname != NULL);

  g_resolver_maybe_reload (resolver);
  G_RESOLVER_GET_CLASS (resolver)->
    lookup_records_async (resolver, rrname, record_type, cancellable, callback, user_data);
}

/**
 * g_resolver_lookup_records_finish:
 * @resolver: a #GResolver
 * @result: the result passed to your #GAsyncReadyCallback
 * @error: return location for a #GError, or %NULL
 *
 * Retrieves the result of a previous call to
 * g_resolver_lookup_records_async(). Returns a non-empty list of records as
 * #GVariant tuples. See #GResolverRecordType for information on what the
 * records contain.
 *
 * If the DNS resolution failed, @error (if non-%NULL) will be set to
 * a value from #GResolverError. If the operation was cancelled,
 * @error will be set to %G_IO_ERROR_CANCELLED.
 *
 * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
 * #GVariant, or %NULL on error. You must free each of the records and the list
 * when you are done with it. (You can use g_list_free_full() with
 * g_variant_unref() to do this.)
 *
 * Since: 2.34
 */
GList *
g_resolver_lookup_records_finish (GResolver     *resolver,
                                  GAsyncResult  *result,
                                  GError       **error)
{
  g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
  return G_RESOLVER_GET_CLASS (resolver)->
    lookup_records_finish (resolver, result, error);
}

guint64
g_resolver_get_serial (GResolver *resolver)
{
  g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);

  g_resolver_maybe_reload (resolver);

#ifdef G_OS_UNIX
  return (guint64) resolver->priv->resolv_conf_timestamp;
#else
  return 1;
#endif
}

/**
 * g_resolver_error_quark:
 *
 * Gets the #GResolver Error Quark.
 *
 * Returns: a #GQuark.
 *
 * Since: 2.22
 */
G_DEFINE_QUARK (g-resolver-error-quark, g_resolver_error)
