/*
 * Copyright (c) 2019 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);

#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <zephyr/ztest_assert.h>

#include <zephyr/net/socket.h>
#include <zephyr/net/net_ip.h>

#include "../../socket_helpers.h"

#define TEST_IPV4_ANY_ADDR "0.0.0.0"
#define TEST_MY_IPV4_ADDR "192.0.2.1"
#define TEST_MY_IPV4_ADDR2 "192.0.2.2"

#define TEST_IPV6_ANY_ADDR "::"
#define TEST_MY_IPV6_ADDR "2001:db8::1"
#define TEST_MY_IPV6_ADDR2 "2001:db8::2"

#define LOCAL_PORT 4242

#define TCP_TEARDOWN_TIMEOUT K_SECONDS(3)

#define SHOULD_SUCCEED true
#define SHOULD_FAIL false

static void test_add_local_ip_address(sa_family_t family, const char *ip)
{
	if (family == AF_INET) {
		struct sockaddr_in addr;

		zsock_inet_pton(AF_INET, ip, &addr.sin_addr);

		zassert_not_null(net_if_ipv4_addr_add(net_if_get_default(),
						      &addr.sin_addr,
						      NET_ADDR_MANUAL,
						      0),
				 "Cannot add IPv4 address %s", ip);
	} else if (family == AF_INET6) {
		struct sockaddr_in6 addr;

		zsock_inet_pton(AF_INET6, ip, &addr.sin6_addr);

		zassert_not_null(net_if_ipv6_addr_add(net_if_get_default(),
						      &addr.sin6_addr,
						      NET_ADDR_MANUAL,
						      0),
				 "Cannot add IPv6 address %s", ip);
	}
}

static void *setup(void)
{
	/* Make sure that both the specified IPv4 and IPv6 addresses are
	 * added to the network interface.
	 */
	test_add_local_ip_address(AF_INET, TEST_MY_IPV4_ADDR);
	test_add_local_ip_address(AF_INET6, TEST_MY_IPV6_ADDR);

	return NULL;
}

static inline void prepare_sock_tcp(sa_family_t family, const char *ip, uint16_t port,
				       int *sock, struct sockaddr *addr)
{
	if (family == AF_INET) {
		prepare_sock_tcp_v4(ip,
				    port,
				    sock,
				    (struct sockaddr_in *) addr);
	} else if (family == AF_INET6) {
		prepare_sock_tcp_v6(ip,
				    port,
				    sock,
				    (struct sockaddr_in6 *) addr);
	}
}

static inline void prepare_sock_udp(sa_family_t family, const char *ip, uint16_t port,
				       int *sock, struct sockaddr *addr)
{
	if (family == AF_INET) {
		prepare_sock_udp_v4(ip,
				    port,
				    sock,
				    (struct sockaddr_in *) addr);
	} else if (family == AF_INET6) {
		prepare_sock_udp_v6(ip,
				    port,
				    sock,
				    (struct sockaddr_in6 *) addr);
	}
}

static void test_getsocketopt_reuseaddr(int sock, void *optval, socklen_t *optlen)
{
	zassert_equal(getsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen),
		      0,
		      "getsocketopt() failed with error %d", errno);
}

static void test_setsocketopt_reuseaddr(int sock, void *optval, socklen_t optlen)
{
	zassert_equal(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen),
		      0,
		      "setsocketopt() failed with error %d", errno);
}

static void test_enable_reuseaddr(int sock)
{
	int value = 1;

	test_setsocketopt_reuseaddr(sock, &value, sizeof(value));
}

static void test_getsocketopt_reuseport(int sock, void *optval, socklen_t *optlen)
{
	zassert_equal(getsockopt(sock, SOL_SOCKET, SO_REUSEPORT, optval, optlen),
		      0,
		      "getsocketopt() failed with error %d", errno);
}

static void test_setsocketopt_reuseport(int sock, void *optval, socklen_t optlen)
{
	zassert_equal(setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, optval, optlen),
		      0,
		      "setsocketopt() failed with error %d", errno);
}

static void test_enable_reuseport(int sock)
{
	int value = 1;

	test_setsocketopt_reuseport(sock, &value, sizeof(value));
}

static void test_bind_success(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
	zassert_equal(bind(sock, addr, addrlen),
		      0,
		      "bind() failed with error %d", errno);
}

static void test_bind_fail(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
	zassert_equal(bind(sock, addr, addrlen),
		      -1,
		      "bind() succeeded incorrectly");

	zassert_equal(errno, EADDRINUSE, "bind() returned unexpected errno (%d)", errno);
}

static void test_listen(int sock)
{
	zassert_equal(listen(sock, 0),
		      0,
		      "listen() failed with error %d", errno);
}

static void test_connect_success(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
	zassert_equal(connect(sock, addr, addrlen),
		      0,
		      "connect() failed with error %d", errno);

	if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) {
		/* Let the connection proceed */
		k_msleep(50);
	}
}

static void test_connect_fail(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
	zassert_equal(connect(sock, addr, addrlen),
		      -1,
		      "connect() succeeded incorrectly");

	zassert_equal(errno, EADDRINUSE, "connect() returned unexpected errno (%d)", errno);
}

static int test_accept(int sock, struct sockaddr *addr, socklen_t *addrlen)
{
	int new_sock = accept(sock, addr, addrlen);

	zassert_not_equal(new_sock, -1, "accept() failed with error %d", errno);

	return new_sock;
}

static void test_sendto(int sock, const void *buf, size_t len, int flags,
		       const struct sockaddr *dest_addr, socklen_t addrlen)
{
	zassert_equal(sendto(sock, buf, len, flags, dest_addr, addrlen),
		      len,
		      "sendto failed with error %d", errno);
}

static void test_recvfrom_success(int sock, void *buf, size_t max_len, int flags,
			 struct sockaddr *src_addr, socklen_t *addrlen)
{
	zassert_equal(recvfrom(sock, buf, max_len, flags, src_addr, addrlen),
		      max_len,
		      "recvfrom failed with error %d", errno);
}

static void test_recvfrom_fail(int sock, void *buf, size_t max_len, int flags,
			 struct sockaddr *src_addr, socklen_t *addrlen)
{
	zassert_equal(recvfrom(sock, buf, max_len, flags, src_addr, addrlen),
		      -1,
		      "recvfrom succeeded incorrectly");

	zassert_equal(errno, EAGAIN, "recvfrom() returned unexpected errno (%d)", errno);
}

static void test_recv_success(int sock, void *buf, size_t max_len, int flags)
{
	zassert_equal(recv(sock, buf, max_len, flags),
		      max_len,
		      "recv failed with error %d", errno);
}

static void test_recv_fail(int sock, void *buf, size_t max_len, int flags)
{
	zassert_equal(recv(sock, buf, max_len, flags),
		      -1,
		      "recvfrom succeeded incorrectly");

	zassert_equal(errno, EAGAIN, "recvfrom() returned unexpected errno (%d)", errno);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_enable_disable)
{
	int server_sock = -1;
	int value = -1;
	socklen_t value_size = sizeof(int);

	server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	zassert_true(server_sock >= 0, "socket open failed");

	/* Read initial value */
	test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
	zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()");
	zassert_equal(value, (int) false, "SO_REUSEADDR incorrectly set (expected false)");

	/* Enable option */
	value = 1;
	test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);

	/* Enable option (with other value as linux takes any int here) */
	value = 2;
	test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);

	/* Enable option (with other value as linux takes any int here) */
	value = 0x100;
	test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);

	/* Enable option (with other value as linux takes any int here) */
	value = -1;
	test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);

	close(server_sock);
}


static void test_reuseaddr_unspecified_specified_common(sa_family_t family,
							char const *first_ip,
							char const *second_ip,
							bool should_succeed)
{
	int server_sock1 = -1;
	int server_sock2 = -1;

	struct sockaddr bind_addr1;
	struct sockaddr bind_addr2;

	/* Create the sockets */
	prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1);
	prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2);

	/* Bind the first socket */
	test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1));

	/* Try to bind the second socket, should fail */
	test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));

	/* Enable SO_REUSEADDR option for the second socket */
	test_enable_reuseaddr(server_sock2);

	/* Try to bind the second socket again */
	if (should_succeed) {
		test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2));
	} else {
		test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));
	}

	close(server_sock1);
	close(server_sock2);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_first_unspecified)
{
	test_reuseaddr_unspecified_specified_common(AF_INET,
						    TEST_IPV4_ANY_ADDR,
						    TEST_MY_IPV4_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_first_unspecified)
{
	test_reuseaddr_unspecified_specified_common(AF_INET6,
						    TEST_IPV6_ANY_ADDR,
						    TEST_MY_IPV6_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_second_unspecified)
{
	test_reuseaddr_unspecified_specified_common(AF_INET,
						    TEST_MY_IPV4_ADDR,
						    TEST_IPV4_ANY_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_second_unspecified)
{
	test_reuseaddr_unspecified_specified_common(AF_INET6,
						    TEST_MY_IPV6_ADDR,
						    TEST_IPV6_ANY_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_both_unspecified)
{
	test_reuseaddr_unspecified_specified_common(AF_INET,
						    TEST_IPV4_ANY_ADDR,
						    TEST_IPV4_ANY_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_both_unspecified)
{
	test_reuseaddr_unspecified_specified_common(AF_INET6,
						    TEST_IPV6_ANY_ADDR,
						    TEST_IPV6_ANY_ADDR,
						    SHOULD_FAIL);
}


static void test_reuseaddr_tcp_listening_common(sa_family_t family,
						char const *first_ip,
						char const *second_ip)
{
	int server_sock1 = -1;
	int server_sock2 = -1;

	struct sockaddr bind_addr1;
	struct sockaddr bind_addr2;

	/* Create the sockets */
	prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1);
	prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2);

	/* Bind the first socket */
	test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1));

	/* Set the first socket to LISTEN state */
	test_listen(server_sock1);

	/* Enable SO_REUSEADDR option for the second socket */
	test_enable_reuseaddr(server_sock2);

	/* Try to bind the second socket, should fail */
	test_bind_fail(server_sock2, (struct sockaddr *) &bind_addr2, sizeof(bind_addr2));

	close(server_sock1);
	close(server_sock2);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_unspecified_listening)
{
	test_reuseaddr_tcp_listening_common(AF_INET,
					    TEST_IPV4_ANY_ADDR,
					    TEST_MY_IPV4_ADDR);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_unspecified_listening)
{
	test_reuseaddr_tcp_listening_common(AF_INET6,
					    TEST_IPV6_ANY_ADDR,
					    TEST_MY_IPV6_ADDR);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_specified_listening)
{
	test_reuseaddr_tcp_listening_common(AF_INET,
					    TEST_MY_IPV4_ADDR,
					    TEST_IPV4_ANY_ADDR);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_specified_listening)
{
	test_reuseaddr_tcp_listening_common(AF_INET6,
					    TEST_MY_IPV6_ADDR,
					    TEST_IPV6_ANY_ADDR);
}


static void test_reuseaddr_tcp_tcp_time_wait_common(sa_family_t family,
						    char const *first_ip,
						    char const *second_ip)
{
	int server_sock = -1;
	int client_sock = -1;
	int accept_sock = -1;

	struct sockaddr bind_addr;
	struct sockaddr conn_addr;

	struct sockaddr accept_addr;
	socklen_t accept_addrlen = sizeof(accept_addr);

	prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr);
	prepare_sock_tcp(family, second_ip, LOCAL_PORT, &client_sock, &conn_addr);

	/* Bind the server socket */
	test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));

	/* Start listening on the server socket */
	test_listen(server_sock);

	/* Connect the client */
	test_connect_success(client_sock, &conn_addr, sizeof(conn_addr));

	/* Accept the client */
	accept_sock = test_accept(server_sock, &accept_addr, &accept_addrlen);

	/* Close the server socket */
	close(server_sock);

	/* Close the accepted socket */
	close(accept_sock);

	/* Wait a short time for the accept socket to enter TIME_WAIT state*/
	k_msleep(50);

	/* Recreate the server socket */
	prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr);

	/* Bind the server socket, should fail */
	test_bind_fail(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));

	/* Enable SO_REUSEADDR option for the new server socket */
	test_enable_reuseaddr(server_sock);

	/* Try to bind the new server socket again, should work now */
	test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));

	close(client_sock);
	close(server_sock);

	/* Connection is in TIME_WAIT state, context will be released
	 * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it.
	 */
	k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY));
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_time_wait_unspecified)
{
	test_reuseaddr_tcp_tcp_time_wait_common(AF_INET,
						TEST_IPV4_ANY_ADDR,
						TEST_MY_IPV4_ADDR);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_time_wait_unspecified)
{
	test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6,
						TEST_IPV6_ANY_ADDR,
						TEST_MY_IPV6_ADDR);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_time_wait_specified)
{
	test_reuseaddr_tcp_tcp_time_wait_common(AF_INET,
						TEST_MY_IPV4_ADDR,
						TEST_MY_IPV4_ADDR);
}

ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_time_wait_specified)
{
	test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6,
						TEST_MY_IPV6_ADDR,
						TEST_MY_IPV6_ADDR);
}


ZTEST_SUITE(socket_reuseaddr_test_suite, NULL, setup, NULL, NULL, NULL);


ZTEST_USER(socket_reuseport_test_suite, test_enable_disable)
{
	int server_sock = -1;

	int value = -1;
	socklen_t value_size = sizeof(int);

	server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	zassert_true(server_sock >= 0, "socket open failed");

	/* Read initial value */
	test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
	zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()");
	zassert_equal(value, (int) false, "SO_REUSEPORT incorrectly set (expected false)");

	/* Enable option */
	value = 1;
	test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);

	/* Enable option (with other value as linux takes any int here) */
	value = 2;
	test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);

	/* Enable option (with other value as linux takes any int here) */
	value = 0x100;
	test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);

	/* Enable option (with other value as linux takes any int here) */
	value = -1;
	test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
	test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
	zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);

	close(server_sock);
}


static void test_reuseport_unspecified_specified_common(sa_family_t family,
							char const *first_ip,
							char const *second_ip,
							bool should_succeed)
{
	int server_sock1 = -1;
	int server_sock2 = -1;

	struct sockaddr bind_addr1;
	struct sockaddr bind_addr2;

	/* Create the sockets */
	prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1);
	prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2);

	/* Depending on the expected result, we enable SO_REUSEPORT for the first socket */
	if (should_succeed) {
		test_enable_reuseport(server_sock1);
	}

	/* Bind the first socket */
	test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1));

	/* Try to bind the second socket, should fail */
	test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));

	/* Enable SO_REUSEPORT option for the second socket */
	test_enable_reuseport(server_sock2);

	/* Try to bind the second socket again */
	if (should_succeed) {
		test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2));
	} else {
		test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));
	}

	close(server_sock1);
	close(server_sock2);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_unspecified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_IPV4_ANY_ADDR,
						    TEST_IPV4_ANY_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_unspecified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_IPV6_ANY_ADDR,
						    TEST_IPV6_ANY_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_unspecified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_IPV4_ANY_ADDR,
						    TEST_IPV4_ANY_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_unspecified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_IPV6_ANY_ADDR,
						    TEST_IPV6_ANY_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_specified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_MY_IPV4_ADDR,
						    TEST_MY_IPV4_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_specified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_MY_IPV6_ADDR,
						    TEST_MY_IPV6_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_specified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_MY_IPV4_ADDR,
						    TEST_MY_IPV4_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_specified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_MY_IPV6_ADDR,
						    TEST_MY_IPV6_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_first_unspecified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_IPV4_ANY_ADDR,
						    TEST_MY_IPV4_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_first_unspecified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_IPV6_ANY_ADDR,
						    TEST_MY_IPV6_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_first_unspecified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_IPV4_ANY_ADDR,
						    TEST_MY_IPV4_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_first_unspecified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_IPV6_ANY_ADDR,
						    TEST_MY_IPV6_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_second_unspecified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_MY_IPV4_ADDR,
						    TEST_IPV4_ANY_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_second_unspecified_bad)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_MY_IPV6_ADDR,
						    TEST_IPV6_ANY_ADDR,
						    SHOULD_FAIL);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_second_unspecified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET,
						    TEST_MY_IPV4_ADDR,
						    TEST_IPV4_ANY_ADDR,
						    SHOULD_SUCCEED);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_second_unspecified_good)
{
	test_reuseport_unspecified_specified_common(AF_INET6,
						    TEST_MY_IPV6_ADDR,
						    TEST_IPV6_ANY_ADDR,
						    SHOULD_SUCCEED);
}


enum sockets_reuseport_enabled {
	NONE_SET = 0,
	FIRST_SET,
	SECOND_SET,
	BOTH_SET
};

static void test_reuseport_udp_server_client_common(sa_family_t family,
						    char const *ip,
						    enum sockets_reuseport_enabled setup)
{
	int server_sock = -1;
	int client_sock = -1;
	int accept_sock = 1;

	struct sockaddr server_addr;
	struct sockaddr client_addr;

	struct sockaddr accept_addr;
	socklen_t accept_addr_len = sizeof(accept_addr);

	char tx_buf = 0x55;
	char rx_buf;

	/* Create sockets */
	prepare_sock_udp(family, ip, LOCAL_PORT, &server_sock, &server_addr);
	prepare_sock_udp(family, ip, 0, &client_sock, &client_addr);

	/* Make sure we can bind to the address:port */
	if (setup == FIRST_SET || setup == BOTH_SET) {
		test_enable_reuseport(server_sock);
	}

	/* Bind server socket */
	test_bind_success(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr));

	/* Bind client socket (on a random port) */
	test_bind_success(client_sock, (struct sockaddr *) &client_addr, sizeof(client_addr));

	/* Send message from client to server */
	test_sendto(client_sock, &tx_buf, sizeof(tx_buf), 0, &server_addr, sizeof(server_addr));

	/* Give the packet a chance to go through the net stack */
	k_msleep(50);

	/* Receive data from the client */
	rx_buf = 0;
	test_recvfrom_success(server_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT,
		       &accept_addr, &accept_addr_len);
	zassert_equal(rx_buf, tx_buf, "wrong data");

	/* Create a more specific socket to have a direct connection to the new client */
	accept_sock = socket(family, SOCK_DGRAM, IPPROTO_UDP);
	zassert_true(accept_sock >= 0, "socket open failed");

	/* Make sure we can bind to the address:port */
	if (setup == SECOND_SET || setup == BOTH_SET) {
		test_enable_reuseport(accept_sock);
	}

	/* Try to bind new client socket */
	if (setup == BOTH_SET) {
		/* Should succeed */
		test_bind_success(accept_sock, (struct sockaddr *) &server_addr,
				  sizeof(server_addr));
	} else {
		/* Should fail */
		test_bind_fail(accept_sock, (struct sockaddr *) &server_addr,
			       sizeof(server_addr));
	}

	/* Connect the client to set remote address and remote port */
	test_connect_success(accept_sock, &accept_addr, sizeof(accept_addr));

	/* Send another message from client to server */
	test_sendto(client_sock, &tx_buf, sizeof(tx_buf), 0, &server_addr, sizeof(server_addr));

	/* Give the packet a chance to go through the net stack */
	k_msleep(50);

	/* Receive the data */
	if (setup == BOTH_SET) {
		/* We should receive data on the new specific socket, not on the general one */
		rx_buf = 0;
		test_recvfrom_fail(server_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT,
			&accept_addr, &accept_addr_len);

		rx_buf = 0;
		test_recv_success(accept_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT);
	} else {
		/* We should receive data on the general server socket */
		rx_buf = 0;
		test_recvfrom_success(server_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT,
			&accept_addr, &accept_addr_len);

		rx_buf = 0;
		test_recv_fail(accept_sock, &rx_buf, sizeof(rx_buf), MSG_DONTWAIT);
	}

	close(accept_sock);
	close(client_sock);
	close(server_sock);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_both_not_set)
{
	test_reuseport_udp_server_client_common(AF_INET,
						TEST_MY_IPV4_ADDR,
						NONE_SET);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_both_not_set)
{
	test_reuseport_udp_server_client_common(AF_INET6,
						TEST_MY_IPV6_ADDR,
						NONE_SET);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_first_not_set)
{
	test_reuseport_udp_server_client_common(AF_INET,
						TEST_MY_IPV4_ADDR,
						SECOND_SET);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_first_not_set)
{
	test_reuseport_udp_server_client_common(AF_INET6,
						TEST_MY_IPV6_ADDR,
						SECOND_SET);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_second_not_set)
{
	test_reuseport_udp_server_client_common(AF_INET,
						TEST_MY_IPV4_ADDR,
						FIRST_SET);
}


ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_second_not_set)
{
	test_reuseport_udp_server_client_common(AF_INET6,
						TEST_MY_IPV6_ADDR,
						FIRST_SET);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_good)
{
	test_reuseport_udp_server_client_common(AF_INET,
						TEST_MY_IPV4_ADDR,
						BOTH_SET);
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_good)
{
	test_reuseport_udp_server_client_common(AF_INET6,
						TEST_MY_IPV6_ADDR,
						BOTH_SET);
}


static void test_reuseport_tcp_identical_clients_common(sa_family_t family,
							char const *server_ip,
							char const *client_ip)
{
	int server_sock = -1;
	int client_sock1 = -1;
	int client_sock2 = -1;
	int accept_sock = 1;

	struct sockaddr server_addr;
	struct sockaddr client_addr;
	struct sockaddr connect_addr;

	struct sockaddr accept_addr;
	socklen_t accept_addr_len = sizeof(accept_addr);

	/* Create sockets */
	prepare_sock_tcp(family, server_ip, LOCAL_PORT, &server_sock, &server_addr);
	prepare_sock_tcp(family, client_ip, LOCAL_PORT + 1, &client_sock1, &client_addr);
	prepare_sock_tcp(family, client_ip, LOCAL_PORT, &client_sock2, &connect_addr);

	/* Enable SO_REUSEPORT option for the two sockets */
	test_enable_reuseport(client_sock1);
	test_enable_reuseport(client_sock2);

	/* Bind server socket */
	test_bind_success(server_sock, &server_addr, sizeof(server_addr));

	/* Start listening on the server socket */
	test_listen(server_sock);

	/* Bind the client sockets */
	test_bind_success(client_sock1, &client_addr, sizeof(client_addr));
	test_bind_success(client_sock2, &client_addr, sizeof(client_addr));

	/* Connect the first client */
	test_connect_success(client_sock1, &connect_addr, sizeof(connect_addr));

	/* Accept the first client */
	accept_sock = test_accept(server_sock, &accept_addr, &accept_addr_len);

	/* Connect the second client, should fail */
	test_connect_fail(client_sock2, (struct sockaddr *)&connect_addr, sizeof(connect_addr));

	close(accept_sock);
	close(client_sock1);
	close(client_sock2);
	close(server_sock);

	/* Connection is in TIME_WAIT state, context will be released
	 * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it.
	 */
	k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY));
}

ZTEST_USER(socket_reuseport_test_suite, test_ipv4_tcp_identical_clients)
{
	test_reuseport_tcp_identical_clients_common(AF_INET,
						    TEST_IPV4_ANY_ADDR,
						    TEST_MY_IPV4_ADDR);
}


ZTEST_USER(socket_reuseport_test_suite, test_ipv6_tcp_identical_clients)
{
	test_reuseport_tcp_identical_clients_common(AF_INET6,
						    TEST_IPV6_ANY_ADDR,
						    TEST_MY_IPV6_ADDR);
}

ZTEST_SUITE(socket_reuseport_test_suite, NULL, setup, NULL, NULL, NULL);
