// SPDX-License-Identifier: GPL-2.0
/*
 * This times how long it takes to bind to a port when the port already
 * has multiple sockets in its bhash table.
 *
 * In the setup(), we populate the port's bhash table with
 * MAX_THREADS * MAX_CONNECTIONS number of entries.
 */

#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <pthread.h>
#include <string.h>
#include <stdbool.h>

#define MAX_THREADS 600
#define MAX_CONNECTIONS 40

static const char *setup_addr_v6 = "::1";
static const char *setup_addr_v4 = "127.0.0.1";
static const char *setup_addr;
static const char *bind_addr;
static const char *port;
bool use_v6;
int ret;

static int fd_array[MAX_THREADS][MAX_CONNECTIONS];

static int bind_socket(int opt, const char *addr)
{
	struct addrinfo *res, hint = {};
	int sock_fd, reuse = 1, err;
	int domain = use_v6 ? AF_INET6 : AF_INET;

	sock_fd = socket(domain, SOCK_STREAM, 0);
	if (sock_fd < 0) {
		perror("socket fd err");
		return sock_fd;
	}

	hint.ai_family = domain;
	hint.ai_socktype = SOCK_STREAM;

	err = getaddrinfo(addr, port, &hint, &res);
	if (err) {
		perror("getaddrinfo failed");
		goto cleanup;
	}

	if (opt) {
		err = setsockopt(sock_fd, SOL_SOCKET, opt, &reuse, sizeof(reuse));
		if (err) {
			perror("setsockopt failed");
			goto err_free_info;
		}
	}

	err = bind(sock_fd, res->ai_addr, res->ai_addrlen);
	if (err) {
		perror("failed to bind to port");
		goto err_free_info;
	}
	freeaddrinfo(res);
	return sock_fd;
err_free_info:
	freeaddrinfo(res);
cleanup:
	close(sock_fd);
	return err;
}

static void *setup(void *arg)
{
	int sock_fd, i;
	int *array = (int *)arg;

	for (i = 0; i < MAX_CONNECTIONS; i++) {
		sock_fd = bind_socket(SO_REUSEPORT, setup_addr);
		if (sock_fd < 0) {
			ret = sock_fd;
			pthread_exit(&ret);
		}
		array[i] = sock_fd;
	}

	return NULL;
}

int main(int argc, const char *argv[])
{
	int listener_fd, sock_fd, i, j;
	pthread_t tid[MAX_THREADS];
	clock_t begin, end;

	if (argc != 4) {
		printf("Usage: listener <port> <ipv6 | ipv4> <bind-addr>\n");
		return -1;
	}

	port = argv[1];
	use_v6 = strcmp(argv[2], "ipv6") == 0;
	bind_addr = argv[3];

	setup_addr = use_v6 ? setup_addr_v6 : setup_addr_v4;

	listener_fd = bind_socket(SO_REUSEPORT, setup_addr);
	if (listen(listener_fd, 100) < 0) {
		perror("listen failed");
		return -1;
	}

	/* Set up threads to populate the bhash table entry for the port */
	for (i = 0; i < MAX_THREADS; i++)
		pthread_create(&tid[i], NULL, setup, fd_array[i]);

	for (i = 0; i < MAX_THREADS; i++)
		pthread_join(tid[i], NULL);

	if (ret)
		goto done;

	begin = clock();

	/* Bind to the same port on a different address */
	sock_fd  = bind_socket(0, bind_addr);
	if (sock_fd < 0)
		goto done;

	end = clock();

	printf("time spent = %f\n", (double)(end - begin) / CLOCKS_PER_SEC);

	/* clean up */
	close(sock_fd);

done:
	close(listener_fd);
	for (i = 0; i < MAX_THREADS; i++) {
		for (j = 0; i < MAX_THREADS; i++)
			close(fd_array[i][j]);
	}

	return 0;
}
