/*
 * QTest testcase for netdev stream and dgram
 *
 * Copyright (c) 2022 Red Hat, Inc.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/sockets.h"
#include <glib/gstdio.h>
#include "../unit/socket-helpers.h"
#include "libqtest.h"
#include "qobject/qstring.h"
#include "qemu/sockets.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-sockets.h"

#define CONNECTION_TIMEOUT    60

#define EXPECT_STATE(q, e, t)                             \
do {                                                      \
    char *resp = NULL;                                    \
    g_test_timer_start();                                 \
    do {                                                  \
        g_free(resp);                                     \
        resp = qtest_hmp(q, "info network");              \
        if (t) {                                          \
            strrchr(resp, t)[0] = 0;                      \
        }                                                 \
        if (g_str_equal(resp, e)) {                       \
            break;                                        \
        }                                                 \
    } while (g_test_timer_elapsed() < CONNECTION_TIMEOUT); \
    g_assert_cmpstr(resp, ==, e);                         \
    g_free(resp);                                         \
} while (0)

static gchar *tmpdir;

static int inet_get_free_port_socket_ipv4(int sock)
{
    struct sockaddr_in addr;
    socklen_t len;

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = 0;
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        return -1;
    }

    len = sizeof(addr);
    if (getsockname(sock,  (struct sockaddr *)&addr, &len) < 0) {
        return -1;
    }

    return ntohs(addr.sin_port);
}

static int inet_get_free_port_socket_ipv6(int sock)
{
    struct sockaddr_in6 addr;
    socklen_t len;

    memset(&addr, 0, sizeof(addr));
    addr.sin6_family = AF_INET6;
    addr.sin6_addr = in6addr_any;
    addr.sin6_port = 0;
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        return -1;
    }

    len = sizeof(addr);
    if (getsockname(sock,  (struct sockaddr *)&addr, &len) < 0) {
        return -1;
    }

    return ntohs(addr.sin6_port);
}

static int inet_get_free_port_multiple(int nb, int *port, bool ipv6)
{
    g_autofree int *sock = g_new(int, nb);
    int i;

    for (i = 0; i < nb; i++) {
        sock[i] = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
        if (sock[i] < 0) {
            break;
        }
        port[i] = ipv6 ? inet_get_free_port_socket_ipv6(sock[i]) :
                         inet_get_free_port_socket_ipv4(sock[i]);
        if (port[i] == -1) {
            break;
        }
    }

    nb = i;
    for (i = 0; i < nb; i++) {
        close(sock[i]);
    }

    return nb;
}

static int inet_get_free_port(bool ipv6)
{
    int nb, port;

    nb = inet_get_free_port_multiple(1, &port, ipv6);
    g_assert_cmpint(nb, ==, 1);

    return port;
}

static void test_stream_inet_ipv4(void)
{
    QTestState *qts0, *qts1;
    char *expect;
    int port;

    port = inet_get_free_port(false);
    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=true,addr.type=inet,"
                       "addr.ipv4=on,addr.ipv6=off,"
                       "addr.host=127.0.0.1,addr.port=%d", port);

    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,server=false,id=st0,addr.type=inet,"
                       "addr.ipv4=on,addr.ipv6=off,"
                       "addr.host=127.0.0.1,addr.port=%d", port);

    expect = g_strdup_printf("st0: index=0,type=stream,tcp:127.0.0.1:%d\r\n",
                             port);
    EXPECT_STATE(qts1, expect, 0);
    g_free(expect);

    /* the port is unknown, check only the address */
    EXPECT_STATE(qts0, "st0: index=0,type=stream,tcp:127.0.0.1", ':');

    qtest_quit(qts1);
    qtest_quit(qts0);
}

static void wait_stream_connected(QTestState *qts, const char *id,
                                  SocketAddress **addr)
{
    QDict *resp, *data;
    QString *qstr;
    QObject *obj;
    Visitor *v = NULL;

    resp = qtest_qmp_eventwait_ref(qts, "NETDEV_STREAM_CONNECTED");
    g_assert_nonnull(resp);
    data = qdict_get_qdict(resp, "data");
    g_assert_nonnull(data);

    qstr = qobject_to(QString, qdict_get(data, "netdev-id"));
    g_assert_nonnull(data);

    g_assert(!strcmp(qstring_get_str(qstr), id));

    obj = qdict_get(data, "addr");

    v = qobject_input_visitor_new(obj);
    visit_type_SocketAddress(v, NULL, addr, NULL);
    visit_free(v);
    qobject_unref(resp);
}

static void wait_stream_disconnected(QTestState *qts, const char *id)
{
    QDict *resp, *data;
    QString *qstr;

    resp = qtest_qmp_eventwait_ref(qts, "NETDEV_STREAM_DISCONNECTED");
    g_assert_nonnull(resp);
    data = qdict_get_qdict(resp, "data");
    g_assert_nonnull(data);

    qstr = qobject_to(QString, qdict_get(data, "netdev-id"));
    g_assert_nonnull(data);

    g_assert(!strcmp(qstring_get_str(qstr), id));
    qobject_unref(resp);
}

static void test_stream_unix_reconnect(void)
{
    QTestState *qts0, *qts1;
    SocketAddress *addr;
    gchar *path;

    path = g_strconcat(tmpdir, "/stream_unix_reconnect", NULL);
    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=true,addr.type=unix,"
                       "addr.path=%s", path);

    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,server=false,id=st0,addr.type=unix,"
                       "addr.path=%s,reconnect-ms=1000", path);

    wait_stream_connected(qts0, "st0", &addr);
    g_assert_cmpint(addr->type, ==, SOCKET_ADDRESS_TYPE_UNIX);
    g_assert_cmpstr(addr->u.q_unix.path, ==, path);
    qapi_free_SocketAddress(addr);

    /* kill server */
    qtest_quit(qts0);

    /* check client has been disconnected */
    wait_stream_disconnected(qts1, "st0");

    /* restart server */
    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=true,addr.type=unix,"
                       "addr.path=%s", path);

    /* wait connection events*/
    wait_stream_connected(qts0, "st0", &addr);
    g_assert_cmpint(addr->type, ==, SOCKET_ADDRESS_TYPE_UNIX);
    g_assert_cmpstr(addr->u.q_unix.path, ==, path);
    qapi_free_SocketAddress(addr);

    wait_stream_connected(qts1, "st0", &addr);
    g_assert_cmpint(addr->type, ==, SOCKET_ADDRESS_TYPE_UNIX);
    g_assert_cmpstr(addr->u.q_unix.path, ==, path);
    qapi_free_SocketAddress(addr);

    qtest_quit(qts1);
    qtest_quit(qts0);
    g_free(path);
}

static void test_stream_inet_ipv6(void)
{
    QTestState *qts0, *qts1;
    char *expect;
    int port;

    port = inet_get_free_port(true);
    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=true,addr.type=inet,"
                       "addr.ipv4=off,addr.ipv6=on,"
                       "addr.host=::1,addr.port=%d", port);

    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,server=false,id=st0,addr.type=inet,"
                       "addr.ipv4=off,addr.ipv6=on,"
                       "addr.host=::1,addr.port=%d", port);

    expect = g_strdup_printf("st0: index=0,type=stream,tcp:::1:%d\r\n",
                             port);
    EXPECT_STATE(qts1, expect, 0);
    g_free(expect);

    /* the port is unknown, check only the address */
    EXPECT_STATE(qts0, "st0: index=0,type=stream,tcp:::1", ':');

    qtest_quit(qts1);
    qtest_quit(qts0);
}

static void test_stream_unix(void)
{
    QTestState *qts0, *qts1;
    char *expect;
    gchar *path;

    path = g_strconcat(tmpdir, "/stream_unix", NULL);

    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=true,"
                       "addr.type=unix,addr.path=%s,",
                       path);

    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=false,"
                       "addr.type=unix,addr.path=%s",
                       path);

    expect = g_strdup_printf("st0: index=0,type=stream,unix:%s\r\n", path);
    EXPECT_STATE(qts1, expect, 0);
    EXPECT_STATE(qts0, expect, 0);
    g_free(expect);
    g_free(path);

    qtest_quit(qts1);
    qtest_quit(qts0);
}

#ifdef CONFIG_LINUX
static void test_stream_unix_abstract(void)
{
    QTestState *qts0, *qts1;
    char *expect;
    gchar *path;

    path = g_strconcat(tmpdir, "/stream_unix_abstract", NULL);

    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=true,"
                       "addr.type=unix,addr.path=%s,"
                       "addr.abstract=on",
                       path);

    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,server=false,"
                       "addr.type=unix,addr.path=%s,addr.abstract=on",
                       path);

    expect = g_strdup_printf("st0: index=0,type=stream,unix:%s\r\n", path);
    EXPECT_STATE(qts1, expect, 0);
    EXPECT_STATE(qts0, expect, 0);
    g_free(expect);
    g_free(path);

    qtest_quit(qts1);
    qtest_quit(qts0);
}
#endif

#ifndef _WIN32
static void test_stream_fd(void)
{
    QTestState *qts0, *qts1;
    int sock[2];
    int ret;

    ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, sock);
    g_assert_true(ret == 0);

    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,addr.type=fd,addr.str=%d",
                       sock[0]);

    EXPECT_STATE(qts0, "st0: index=0,type=stream,unix:\r\n", 0);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev stream,id=st0,addr.type=fd,addr.str=%d",
                       sock[1]);

    EXPECT_STATE(qts1, "st0: index=0,type=stream,unix:\r\n", 0);
    EXPECT_STATE(qts0, "st0: index=0,type=stream,unix:\r\n", 0);

    qtest_quit(qts1);
    qtest_quit(qts0);

    close(sock[0]);
    close(sock[1]);
}
#endif

static void test_dgram_inet(void)
{
    QTestState *qts0, *qts1;
    char *expect;
    int port[2];
    int nb;

    nb = inet_get_free_port_multiple(2, port, false);
    g_assert_cmpint(nb, ==, 2);

    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev dgram,id=st0,"
                       "local.type=inet,local.host=127.0.0.1,local.port=%d,"
                       "remote.type=inet,remote.host=127.0.0.1,remote.port=%d",
                        port[0], port[1]);

    expect = g_strdup_printf("st0: index=0,type=dgram,"
                             "udp=127.0.0.1:%d/127.0.0.1:%d\r\n",
                             port[0], port[1]);
    EXPECT_STATE(qts0, expect, 0);
    g_free(expect);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev dgram,id=st0,"
                       "local.type=inet,local.host=127.0.0.1,local.port=%d,"
                       "remote.type=inet,remote.host=127.0.0.1,remote.port=%d",
                        port[1], port[0]);

    expect = g_strdup_printf("st0: index=0,type=dgram,"
                             "udp=127.0.0.1:%d/127.0.0.1:%d\r\n",
                             port[1], port[0]);
    EXPECT_STATE(qts1, expect, 0);
    g_free(expect);

    qtest_quit(qts1);
    qtest_quit(qts0);
}

#if !defined(_WIN32) && !defined(CONFIG_DARWIN)
static void test_dgram_mcast(void)
{
    QTestState *qts;

    qts = qtest_initf("-nodefaults -M none "
                      "-netdev dgram,id=st0,"
                      "remote.type=inet,remote.host=230.0.0.1,remote.port=1234");

    EXPECT_STATE(qts, "st0: index=0,type=dgram,mcast=230.0.0.1:1234\r\n", 0);

    qtest_quit(qts);
}
#endif

#ifndef _WIN32
static void test_dgram_unix(void)
{
    QTestState *qts0, *qts1;
    char *expect;
    gchar *path0, *path1;

    path0 = g_strconcat(tmpdir, "/dgram_unix0", NULL);
    path1 = g_strconcat(tmpdir, "/dgram_unix1", NULL);

    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev dgram,id=st0,local.type=unix,local.path=%s,"
                       "remote.type=unix,remote.path=%s",
                       path0, path1);

    expect = g_strdup_printf("st0: index=0,type=dgram,udp=%s:%s\r\n",
                             path0, path1);
    EXPECT_STATE(qts0, expect, 0);
    g_free(expect);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev dgram,id=st0,local.type=unix,local.path=%s,"
                       "remote.type=unix,remote.path=%s",
                       path1, path0);


    expect = g_strdup_printf("st0: index=0,type=dgram,udp=%s:%s\r\n",
                             path1, path0);
    EXPECT_STATE(qts1, expect, 0);
    g_free(expect);

    unlink(path0);
    g_free(path0);
    unlink(path1);
    g_free(path1);

    qtest_quit(qts1);
    qtest_quit(qts0);
}

static void test_dgram_fd(void)
{
    QTestState *qts0, *qts1;
    char *expect;
    int ret;
    int sv[2];

    ret = socketpair(PF_UNIX, SOCK_DGRAM, 0, sv);
    g_assert_cmpint(ret, !=, -1);

    qts0 = qtest_initf("-nodefaults -M none "
                       "-netdev dgram,id=st0,local.type=fd,local.str=%d",
                       sv[0]);

    expect = g_strdup_printf("st0: index=0,type=dgram,fd=%d unix\r\n", sv[0]);
    EXPECT_STATE(qts0, expect, 0);
    g_free(expect);

    qts1 = qtest_initf("-nodefaults -M none "
                       "-netdev dgram,id=st0,local.type=fd,local.str=%d",
                       sv[1]);


    expect = g_strdup_printf("st0: index=0,type=dgram,fd=%d unix\r\n", sv[1]);
    EXPECT_STATE(qts1, expect, 0);
    g_free(expect);

    qtest_quit(qts1);
    qtest_quit(qts0);

    close(sv[0]);
    close(sv[1]);
}
#endif

int main(int argc, char **argv)
{
    int ret;
    bool has_ipv4, has_ipv6, has_afunix;
    g_autoptr(GError) err = NULL;

    socket_init();
    g_test_init(&argc, &argv, NULL);

    if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) {
        g_error("socket_check_protocol_support() failed\n");
    }

    tmpdir = g_dir_make_tmp("netdev-socket.XXXXXX", &err);
    if (tmpdir == NULL) {
        g_error("Can't create temporary directory in %s: %s",
                g_get_tmp_dir(), err->message);
    }

    if (has_ipv4) {
        qtest_add_func("/netdev/stream/inet/ipv4", test_stream_inet_ipv4);
        qtest_add_func("/netdev/dgram/inet", test_dgram_inet);
#if !defined(_WIN32) && !defined(CONFIG_DARWIN)
        qtest_add_func("/netdev/dgram/mcast", test_dgram_mcast);
#endif
    }
    if (has_ipv6) {
        qtest_add_func("/netdev/stream/inet/ipv6", test_stream_inet_ipv6);
    }

    socket_check_afunix_support(&has_afunix);
    if (has_afunix) {
#ifndef _WIN32
        qtest_add_func("/netdev/dgram/unix", test_dgram_unix);
#endif
        qtest_add_func("/netdev/stream/unix/oneshot", test_stream_unix);
        qtest_add_func("/netdev/stream/unix/reconnect",
                       test_stream_unix_reconnect);
#ifdef CONFIG_LINUX
        qtest_add_func("/netdev/stream/unix/abstract",
                       test_stream_unix_abstract);
#endif
#ifndef _WIN32
        qtest_add_func("/netdev/stream/fd", test_stream_fd);
        qtest_add_func("/netdev/dgram/fd", test_dgram_fd);
#endif
    }

    ret = g_test_run();

    g_rmdir(tmpdir);
    g_free(tmpdir);

    return ret;
}
