/*
 * Copyright (C) 2010-2022 Willy Tarreau <w@1wt.eu>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <time.h>
#include <limits.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#define MAXCONN 1

const int zero = 0;
const int one = 1;

struct conn {
	struct sockaddr_storage cli_addr;
	int fd_bck;
};

struct errmsg {
	char *msg;
	int size;
	int len;
};

struct sockaddr_storage frt_addr; // listen address
struct sockaddr_storage srv_addr; // server address

#define MAXPKTSIZE 16384
#define MAXREORDER 20
char trash[MAXPKTSIZE];

/* history buffer, to resend random packets */
struct {
	char buf[MAXPKTSIZE];
	size_t len;
} history[MAXREORDER];
int history_idx = 0;
unsigned int rand_rate = 0;
unsigned int corr_rate = 0;
unsigned int corr_span = 1;
unsigned int corr_base = 0;

struct conn conns[MAXCONN];        // sole connection for now
int fd_frt;

int nbfd = 0;
int nbconn = MAXCONN;


/* display the message and exit with the code */
__attribute__((noreturn)) void die(int code, const char *format, ...)
{
	va_list args;

	va_start(args, format);
	vfprintf(stderr, format, args);
	va_end(args);
	exit(code);
}

/* Xorshift RNG */
unsigned int prng_state = ~0U/3; // half bits set, but any seed will fit
static inline unsigned int prng(unsigned int range)
{
	unsigned int x = prng_state;

	x ^= x << 13;
	x ^= x >> 17;
	x ^= x << 5;
	prng_state = x;
        return ((unsigned long long)x * (range - 1) + x) >> 32;
}

/* converts str in the form [<ipv4>|<ipv6>|<hostname>]:port to struct sockaddr_storage.
 * Returns < 0 with err set in case of error.
 */
int addr_to_ss(char *str, struct sockaddr_storage *ss, struct errmsg *err)
{
	char *port_str;
	int port;

	/* look for the addr/port delimiter, it's the last colon. */
	if ((port_str = strrchr(str, ':')) == NULL)
		port_str = str;
	else
		*port_str++ = 0;

	port = atoi(port_str);
	if (port <= 0 || port > 65535) {
		err->len = snprintf(err->msg, err->size, "Missing/invalid port number: '%s'\n", port_str);
		return -1;
	}
	*port_str = 0; // present an empty address if none was set

	memset(ss, 0, sizeof(*ss));

	if (strrchr(str, ':') != NULL) {
		/* IPv6 address contains ':' */
		ss->ss_family = AF_INET6;
		((struct sockaddr_in6 *)ss)->sin6_port = htons(port);

		if (!inet_pton(ss->ss_family, str, &((struct sockaddr_in6 *)ss)->sin6_addr)) {
			err->len = snprintf(err->msg, err->size, "Invalid IPv6 server address: '%s'", str);
			return -1;
		}
	}
	else {
		ss->ss_family = AF_INET;
		((struct sockaddr_in *)ss)->sin_port = htons(port);

		if (*str == '*' || *str == '\0') { /* INADDR_ANY */
			((struct sockaddr_in *)ss)->sin_addr.s_addr = INADDR_ANY;
			return 0;
		}

		if (!inet_pton(ss->ss_family, str, &((struct sockaddr_in *)ss)->sin_addr)) {
			struct hostent *he = gethostbyname(str);

			if (he == NULL) {
				err->len = snprintf(err->msg, err->size, "Invalid IPv4 server name: '%s'", str);
				return -1;
			}
			((struct sockaddr_in *)ss)->sin_addr = *(struct in_addr *) *(he->h_addr_list);
		}
	}
	return 0;
}

/* returns <0 with err in case of error or the front FD */
int create_udp_listener(struct sockaddr_storage *addr, struct errmsg *err)
{
	int fd;

	if ((fd = socket(addr->ss_family, SOCK_DGRAM, 0)) == -1) {
		err->len = snprintf(err->msg, err->size, "socket(): '%s'", strerror(errno));
		goto fail;
	}

	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
		err->len = snprintf(err->msg, err->size, "fcntl(O_NONBLOCK): '%s'", strerror(errno));
		goto fail;
	}

	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1) {
		err->len = snprintf(err->msg, err->size, "setsockopt(SO_REUSEADDR): '%s'", strerror(errno));
		goto fail;
	}

#ifdef SO_REUSEPORT
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *) &one, sizeof(one)) == -1) {
		err->len = snprintf(err->msg, err->size, "setsockopt(SO_REUSEPORT): '%s'", strerror(errno));
		goto fail;
	}
#endif
	if (bind(fd, (struct sockaddr *)&frt_addr, addr->ss_family == AF_INET6 ?
		 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) == -1) {
		err->len = snprintf(err->msg, err->size, "bind(): '%s'", strerror(errno));
		goto fail;
	}

	/* the socket is ready */
	return fd;

 fail:
	if (fd > -1)
		close(fd);
	fd = -1;
	return fd;
}

/* recompute pollfds using frt_fd and scanning nbconn connections.
 * Returns the number of FDs in the set.
 */
int update_pfd(struct pollfd *pfd, int frt_fd, struct conn *conns, int nbconn)
{
	int nbfd = 0;
	int i;

	pfd[nbfd].fd   = frt_fd;
	pfd[nbfd].events = POLLIN;
	nbfd++;

	for (i = 0; i < nbconn; i++) {
		if (conns[i].fd_bck < 0)
			continue;
		pfd[nbfd].fd = conns[i].fd_bck;
		pfd[nbfd].events = POLLIN;
		nbfd++;
	}
	return nbfd;
}

/* searches a connection using fd <fd> as back connection, returns it if found
 * otherwise NULL.
 */
struct conn *conn_bck_lookup(struct conn *conns, int nbconn, int fd)
{
	int i;

	for (i = 0; i < nbconn; i++) {
		if (conns[i].fd_bck < 0)
			continue;
		if (conns[i].fd_bck == fd)
			return &conns[i];
	}
	return NULL;
}

/* Try to establish a connection to <sa>. Return the fd or -1 in case of error */
int add_connection(struct sockaddr_storage *ss)
{
	int fd;

	fd = socket(ss->ss_family, SOCK_DGRAM, 0);
	if (fd < 0)
		goto fail;

	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
		goto fail;

	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1)
		goto fail;

	if (connect(fd, (struct sockaddr *)ss, ss->ss_family == AF_INET6 ?
		    sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) == -1) {
		if (errno != EINPROGRESS)
			goto fail;
	}

	return fd;
 fail:
	if (fd > -1)
		close(fd);
	return -1;
}

/* Handle a read operation on an front FD. Will either reuse the existing
 * connection if the source is found, or will allocate a new one, possibly
 * replacing the oldest one. Returns <0 on error or the number of bytes
 * transmitted.
 */
int handle_frt(int fd, struct pollfd *pfd, struct conn *conns, int nbconn)
{
	struct sockaddr_storage addr;
	socklen_t addrlen;
	struct conn *conn;
	char *pktbuf = trash;
	int ret;
	int i;

	if (rand_rate > 0) {
		/* keep a copy of this packet */
		history_idx++;
		if (history_idx >= MAXREORDER)
			history_idx = 0;
		pktbuf = history[history_idx].buf;
	}

	ret = recvfrom(fd, pktbuf, MAXPKTSIZE, MSG_DONTWAIT | MSG_NOSIGNAL,
		       (struct sockaddr *)&addr, &addrlen);

	if (rand_rate > 0) {
		history[history_idx].len = ret; // note: we may store -1/EAGAIN
		if (prng(100) < rand_rate) {
			/* return a random buffer or nothing */
			int idx = prng(MAXREORDER + 1) - 1;
			if (idx < 0) {
				/* pretend we didn't receive anything */
				return 0;
			}
			pktbuf = history[idx].buf;
			ret    = history[idx].len;
			if (ret < 0)
				errno = EAGAIN;
		}
	}

	if (ret == 0)
		return 0;

	if (ret < 0)
		return errno == EAGAIN ? 0 : -1;

	if (corr_rate > 0 && prng(100) < corr_rate) {
		unsigned int rnd = prng(corr_span * 256); // pos and value
		unsigned int pos = corr_base + (rnd >> 8);

		if (pos < ret)
			pktbuf[pos] ^= rnd;
	}

	conn = NULL;
	for (i = 0; i < nbconn; i++) {
		if (addr.ss_family != conns[i].cli_addr.ss_family)
			continue;
		if (memcmp(&conns[i].cli_addr, &addr,
			   (addr.ss_family == AF_INET6) ?
			   sizeof(struct sockaddr_in6) :
			   sizeof(struct sockaddr_in)) != 0)
			continue;
		conn = &conns[i];
		break;
	}

	if (!conn) {
		/* address not found, create a new conn or replace the oldest
		 * one. For now we support a single one.
		 */
		conn = &conns[0];

		memcpy(&conn->cli_addr, &addr,
		       (addr.ss_family == AF_INET6) ?
		       sizeof(struct sockaddr_in6) :
		       sizeof(struct sockaddr_in));

		if (conn->fd_bck < 0) {
			/* try to create a new connection */
			conn->fd_bck = add_connection(&srv_addr);
			nbfd = update_pfd(pfd, fd, conns, nbconn); // FIXME: MAXCONN instead ?
		}
	}

	if (conn->fd_bck < 0)
		return 0;

	ret = send(conn->fd_bck, pktbuf, ret, MSG_DONTWAIT | MSG_NOSIGNAL);
	return ret;
}

/* Handle a read operation on an FD. Close and return 0 when the read returns zero or an error */
int handle_bck(int fd, struct pollfd *pfd, struct conn *conns, int nbconn)
{
	struct sockaddr_storage addr;
	socklen_t addrlen;
	struct conn *conn;
	char *pktbuf = trash;
	int ret;

	if (rand_rate > 0) {
		/* keep a copy of this packet */
		history_idx++;
		if (history_idx >= MAXREORDER)
			history_idx = 0;
		pktbuf = history[history_idx].buf;
	}

	ret = recvfrom(fd, pktbuf, MAXPKTSIZE, MSG_DONTWAIT | MSG_NOSIGNAL,
		       (struct sockaddr *)&addr, &addrlen);

	if (rand_rate > 0) {
		history[history_idx].len = ret; // note: we may store -1/EAGAIN
		if (prng(100) < rand_rate) {
			/* return a random buffer or nothing */
			int idx = prng(MAXREORDER + 1) - 1;
			if (idx < 0) {
				/* pretend we didn't receive anything */
				return 0;
			}
			pktbuf = history[idx].buf;
			ret    = history[idx].len;
			if (ret < 0)
				errno = EAGAIN;
		}
	}

	if (ret == 0)
		return 0;

	if (ret < 0)
		return errno == EAGAIN ? 0 : -1;

	conn = conn_bck_lookup(conns, nbconn, fd);
	if (!conn)
		return 0;

	ret = sendto(fd_frt, pktbuf, ret, MSG_DONTWAIT | MSG_NOSIGNAL,
		     (struct sockaddr *)&conn->cli_addr,
		     conn->cli_addr.ss_family == AF_INET6 ?
		     sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
	return ret;
}

/* print the usage message for program named <name> and exit with status <status> */
void usage(int status, const char *name)
{
	if (strchr(name, '/'))
		name = strrchr(name, '/') + 1;
	die(status,
	    "Usage: %s [-h] [options] [<laddr>:]<lport> [<saddr>:]<sport>\n"
	    "Options:\n"
	    "  -h           display this help\n"
	    "  -r rate      reorder/duplicate/lose around <rate>%% of packets\n"
	    "  -s seed      force initial random seed (currently %#x)\n"
	    "  -c rate      corrupt around <rate>%% of packets\n"
	    "  -o ofs       start offset of corrupted area (def: 0)\n"
	    "  -w width     width of the corrupted area (def: 1)\n"
	    "", name, prng_state);
}

int main(int argc, char **argv)
{
	struct errmsg err;
	struct pollfd *pfd;
	int opt;
	int i;

	err.len = 0;
	err.size = 100;
	err.msg = malloc(err.size);

	while ((opt = getopt(argc, argv, "hr:s:c:o:w:")) != -1) {
		switch (opt) {
		case 'r': // rand_rate%
			rand_rate = atoi(optarg);
			break;
		case 's': // seed
			prng_state = atol(optarg);
			break;
		case 'c': // corruption rate
			corr_rate = atol(optarg);
			break;
		case 'o': // corruption offset
			corr_base = atol(optarg);
			break;
		case 'w': // corruption width
			corr_span = atol(optarg);
			break;
		default: // help, anything else
			usage(0, argv[0]);
		}
	}

	if (argc - optind < 2)
		usage(1, argv[0]);

	if (addr_to_ss(argv[optind], &frt_addr, &err) < 0)
		die(1, "parsing listen address: %s\n", err.msg);

	if (addr_to_ss(argv[optind+1], &srv_addr, &err) < 0)
		die(1, "parsing server address: %s\n", err.msg);

	pfd = calloc(sizeof(struct pollfd), MAXCONN + 1);
	if (!pfd)
		die(1, "out of memory\n");

	fd_frt = create_udp_listener(&frt_addr, &err);
	if (fd_frt < 0)
		die(1, "binding listener: %s\n", err.msg);


	for (i = 0; i < MAXCONN; i++)
		conns[i].fd_bck = -1;

	nbfd = update_pfd(pfd, fd_frt, conns, MAXCONN);

	while (1) {
		/* listen for incoming packets */
		int ret, i;

		ret = poll(pfd, nbfd, 1000);
		if (ret <= 0)
			continue;

		for (i = 0; ret; i++) {
			if (!pfd[i].revents)
				continue;
			ret--;

			if (pfd[i].fd == fd_frt) {
				handle_frt(pfd[i].fd, pfd, conns, nbconn);
				continue;
			}

			handle_bck(pfd[i].fd, pfd, conns, nbconn);
		}
	}
}
