/*
 * Helper functions for tests using sockets
 *
 * Copyright 2015-2018 Red Hat, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) version 3 of the License.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "qemu/sockets.h"
#include "socket-helpers.h"

#ifndef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0
#endif
#ifndef EAI_ADDRFAMILY
# define EAI_ADDRFAMILY 0
#endif

/*
 * @hostname: a DNS name or numeric IP address
 *
 * Check whether it is possible to bind & connect to ports
 * on the DNS name or IP address @hostname. If an IP address
 * is used, it must not be a wildcard address.
 *
 * Returns 0 on success, -1 on error with errno set
 */
static int socket_can_bind_connect(const char *hostname, int family)
{
    int lfd = -1, cfd = -1, afd = -1;
    struct addrinfo ai, *res = NULL;
    struct sockaddr_storage ss;
    socklen_t sslen = sizeof(ss);
    int soerr;
    socklen_t soerrlen = sizeof(soerr);
    bool check_soerr = false;
    int rc;
    int ret = -1;

    memset(&ai, 0, sizeof(ai));
    ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
    ai.ai_family = family;
    ai.ai_socktype = SOCK_STREAM;

    /* lookup */
    rc = getaddrinfo(hostname, NULL, &ai, &res);
    if (rc != 0) {
        if (rc == EAI_ADDRFAMILY || rc == EAI_FAMILY || rc == EAI_NONAME) {
            errno = EADDRNOTAVAIL;
        } else {
            errno = EINVAL;
        }
        goto cleanup;
    }

    lfd = qemu_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (lfd < 0) {
        goto cleanup;
    }

    cfd = qemu_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (cfd < 0) {
        goto cleanup;
    }

    if (bind(lfd, res->ai_addr, res->ai_addrlen) < 0) {
        goto cleanup;
    }

    if (listen(lfd, 1) < 0) {
        goto cleanup;
    }

    if (getsockname(lfd, (struct sockaddr *)&ss, &sslen) < 0) {
        goto cleanup;
    }

    qemu_set_nonblock(cfd);
    if (connect(cfd, (struct sockaddr *)&ss, sslen) < 0) {
        if (errno == EINPROGRESS) {
            check_soerr = true;
        } else {
            goto cleanup;
        }
    }

    sslen = sizeof(ss);
    afd = accept(lfd,  (struct sockaddr *)&ss, &sslen);
    if (afd < 0) {
        goto cleanup;
    }

    if (check_soerr) {
        if (getsockopt(cfd, SOL_SOCKET, SO_ERROR, &soerr, &soerrlen) < 0) {
            goto cleanup;
        }
        if (soerr) {
            errno = soerr;
            goto cleanup;
        }
    }

    ret = 0;

 cleanup:
    if (afd != -1) {
        close(afd);
    }
    if (cfd != -1) {
        close(cfd);
    }
    if (lfd != -1) {
        close(lfd);
    }
    if (res) {
        freeaddrinfo(res);
    }
    return ret;
}


int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6)
{
    *has_ipv4 = *has_ipv6 = false;

    if (socket_can_bind_connect("127.0.0.1", PF_INET) < 0) {
        if (errno != EADDRNOTAVAIL) {
            return -1;
        }
    } else {
        *has_ipv4 = true;
    }

    if (socket_can_bind_connect("::1", PF_INET6) < 0) {
        if (errno != EADDRNOTAVAIL) {
            return -1;
        }
    } else {
        *has_ipv6 = true;
    }

    return 0;
}
