/*
 * QEMU DNS resolver
 *
 * Copyright (c) 2016-2017 Red Hat, Inc.
 *
 * 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/>.
 *
 */

#ifndef QIO_DNS_RESOLVER_H
#define QIO_DNS_RESOLVER_H

#include "qapi/qapi-types-sockets.h"
#include "qom/object.h"
#include "io/task.h"

#define TYPE_QIO_DNS_RESOLVER "qio-dns-resolver"
OBJECT_DECLARE_SIMPLE_TYPE(QIODNSResolver,
                           QIO_DNS_RESOLVER)


/**
 * QIODNSResolver:
 *
 * The QIODNSResolver class provides a framework for doing
 * DNS resolution on SocketAddress objects, independently
 * of socket creation.
 *
 * <example>
 *   <title>Resolving addresses synchronously</title>
 *   <programlisting>
 *    int mylisten(SocketAddress *addr, Error **errp) {
 *      QIODNSResolver *resolver = qio_dns_resolver_get_instance();
 *      SocketAddress **rawaddrs = NULL;
 *      size_t nrawaddrs = 0;
 *      Error *err = NULL;
 *      QIOChannel **socks = NULL;
 *      size_t nsocks = 0;
 *
 *      if (qio_dns_resolver_lookup_sync(dns, addr, &nrawaddrs,
 *                                       &rawaddrs, errp) < 0) {
 *          return -1;
 *      }
 *
 *      for (i = 0; i < nrawaddrs; i++) {
 *         QIOChannel *sock = qio_channel_new();
 *         Error *local_err = NULL;
 *         qio_channel_listen_sync(sock, rawaddrs[i], &local_err);
 *         if (local_err) {
 *            error_propagate(&err, local_err);
 *         } else {
 *            socks = g_renew(QIOChannelSocket *, socks, nsocks + 1);
 *            socks[nsocks++] = sock;
 *         }
 *         qapi_free_SocketAddress(rawaddrs[i]);
 *      }
 *      g_free(rawaddrs);
 *
 *      if (nsocks == 0) {
 *         error_propagate(errp, err);
 *      } else {
 *         error_free(err);
 *      }
 *   }
 *   </programlisting>
 * </example>
 *
 * <example>
 *   <title>Resolving addresses asynchronously</title>
 *   <programlisting>
 *    typedef struct MyListenData {
 *       Error *err;
 *       QIOChannelSocket **socks;
 *       size_t nsocks;
 *    } MyListenData;
 *
 *    void mylistenresult(QIOTask *task, void *opaque) {
 *      MyListenData *data = opaque;
 *      QIODNSResolver *resolver =
 *         QIO_DNS_RESOLVER(qio_task_get_source(task);
 *      SocketAddress **rawaddrs = NULL;
 *      size_t nrawaddrs = 0;
 *      Error *err = NULL;
 *
 *      if (qio_task_propagate_error(task, &data->err)) {
 *         return;
 *      }
 *
 *      qio_dns_resolver_lookup_result(resolver, task,
 *                                     &nrawaddrs, &rawaddrs);
 *
 *      for (i = 0; i < nrawaddrs; i++) {
 *         QIOChannel *sock = qio_channel_new();
 *         Error *local_err = NULL;
 *         qio_channel_listen_sync(sock, rawaddrs[i], &local_err);
 *         if (local_err) {
 *            error_propagate(&err, local_err);
 *         } else {
 *            socks = g_renew(QIOChannelSocket *, socks, nsocks + 1);
 *            socks[nsocks++] = sock;
 *         }
 *         qapi_free_SocketAddress(rawaddrs[i]);
 *      }
 *      g_free(rawaddrs);
 *
 *      if (nsocks == 0) {
 *         error_propagate(&data->err, err);
 *      } else {
 *         error_free(err);
 *      }
 *    }
 *
 *    void mylisten(SocketAddress *addr, MyListenData *data) {
 *      QIODNSResolver *resolver = qio_dns_resolver_get_instance();
 *      qio_dns_resolver_lookup_async(dns, addr,
 *                                    mylistenresult, data, NULL);
 *    }
 *   </programlisting>
 * </example>
 */
struct QIODNSResolver {
    Object parent;
};



/**
 * qio_dns_resolver_get_instance:
 *
 * Get the singleton dns resolver instance. The caller
 * does not own a reference on the returned object.
 *
 * Returns: the single dns resolver instance
 */
QIODNSResolver *qio_dns_resolver_get_instance(void);

/**
 * qio_dns_resolver_lookup_sync:
 * @resolver: the DNS resolver instance
 * @addr: the address to resolve
 * @naddr: pointer to hold number of resolved addresses
 * @addrs: pointer to hold resolved addresses
 * @errp: pointer to NULL initialized error object
 *
 * This will attempt to resolve the address provided
 * in @addr. If resolution succeeds, @addrs will be filled
 * with all the resolved addresses. @naddrs will specify
 * the number of entries allocated in @addrs. The caller
 * is responsible for freeing each entry in @addrs, as
 * well as @addrs itself. @naddrs is guaranteed to be
 * greater than zero on success.
 *
 * DNS resolution will be done synchronously so execution
 * of the caller may be blocked for an arbitrary length
 * of time.
 *
 * Returns: 0 if resolution was successful, -1 on error
 */
int qio_dns_resolver_lookup_sync(QIODNSResolver *resolver,
                                 SocketAddress *addr,
                                 size_t *naddrs,
                                 SocketAddress ***addrs,
                                 Error **errp);

/**
 * qio_dns_resolver_lookup_async:
 * @resolver: the DNS resolver instance
 * @addr: the address to resolve
 * @func: the callback to invoke on lookup completion
 * @opaque: data blob to pass to @func
 * @notify: the callback to free @opaque, or NULL
 *
 * This will attempt to resolve the address provided
 * in @addr. The callback @func will be invoked when
 * resolution has either completed or failed. On
 * success, the @func should call the method
 * qio_dns_resolver_lookup_result() to obtain the
 * results.
 *
 * DNS resolution will be done asynchronously so execution
 * of the caller will not be blocked.
 */
void qio_dns_resolver_lookup_async(QIODNSResolver *resolver,
                                   SocketAddress *addr,
                                   QIOTaskFunc func,
                                   gpointer opaque,
                                   GDestroyNotify notify);

/**
 * qio_dns_resolver_lookup_result:
 * @resolver: the DNS resolver instance
 * @task: the task object to get results for
 * @naddr: pointer to hold number of resolved addresses
 * @addrs: pointer to hold resolved addresses
 *
 * This method should be called from the callback passed
 * to qio_dns_resolver_lookup_async() in order to obtain
 * results.  @addrs will be filled with all the resolved
 * addresses. @naddrs will specify the number of entries
 * allocated in @addrs. The caller is responsible for
 * freeing each entry in @addrs, as well as @addrs itself.
 */
void qio_dns_resolver_lookup_result(QIODNSResolver *resolver,
                                    QIOTask *task,
                                    size_t *naddrs,
                                    SocketAddress ***addrs);

#endif /* QIO_DNS_RESOLVER_H */
