#define _GNU_SOURCE

#include <sched.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>

#include <string.h>

#include <haproxy/api.h>
#include <haproxy/chunk.h>
#include <haproxy/errors.h>
#include <haproxy/global.h>
#include <haproxy/hash.h>
#include <haproxy/namespace.h>
#include <haproxy/signal.h>

/* Opens the namespace <ns_name> and returns the FD or -1 in case of error
 * (check errno).
 */
static int open_named_namespace(const char *ns_name)
{
	if (chunk_printf(&trash, "/var/run/netns/%s", ns_name) < 0)
		return -1;
	return open(trash.area, O_RDONLY | O_CLOEXEC);
}

static int default_namespace = -1;

static int init_default_namespace()
{
	if (chunk_printf(&trash, "/proc/%d/ns/net", getpid()) < 0)
		return -1;
	default_namespace = open(trash.area, O_RDONLY | O_CLOEXEC);
	return default_namespace;
}

static struct eb_root namespace_tree_root = EB_ROOT;

static void netns_sig_stop(struct sig_handler *sh)
{
	struct ebpt_node *node, *next;
	struct netns_entry *entry;

	/* close namespace file descriptors and remove registered namespaces from the
	 * tree when stopping */
	node = ebpt_first(&namespace_tree_root);
	while (node) {
		next = ebpt_next(node);
		ebpt_delete(node);
		entry = container_of(node, struct netns_entry, node);
		free(entry->node.key);
		close(entry->fd);
		free(entry);
		node = next;
	}
}

int netns_init(void)
{
	int err_code = 0;

	/* if no namespaces have been defined in the config then
	 * there is no point in trying to initialize anything:
	 * my_socketat() will never be called with a valid namespace
	 * structure and thus switching back to the default namespace
	 * is not needed either */
	if (!eb_is_empty(&namespace_tree_root)) {
		if (init_default_namespace() < 0) {
			ha_alert("Failed to open the default namespace.\n");
			err_code |= ERR_ALERT | ERR_FATAL;
		}
	}

	signal_register_fct(0, netns_sig_stop, 0);

	return err_code;
}

struct netns_entry* netns_store_insert(const char *ns_name)
{
	struct netns_entry *entry = NULL;
	int fd = open_named_namespace(ns_name);
	if (fd == -1)
		goto out;

	entry = calloc(1, sizeof(*entry));
	if (!entry)
		goto out;
	entry->fd = fd;
	entry->node.key = strdup(ns_name);
	entry->name_len = strlen(ns_name);
	ebis_insert(&namespace_tree_root, &entry->node);
out:
	return entry;
}

const struct netns_entry* netns_store_lookup(const char *ns_name, size_t ns_name_len)
{
	struct ebpt_node *node;

	node = ebis_lookup_len(&namespace_tree_root, ns_name, ns_name_len);
	if (node)
		return ebpt_entry(node, struct netns_entry, node);
	else
		return NULL;
}

/* Opens a socket in the namespace described by <ns> with the parameters <domain>,
 * <type> and <protocol> and returns the FD or -1 in case of error (check errno).
 */
int my_socketat(const struct netns_entry *ns, int domain, int type, int protocol)
{
	int sock;

	if (default_namespace >= 0 && ns && setns(ns->fd, CLONE_NEWNET) == -1)
		return -1;

	sock = socket(domain, type, protocol);

	if (default_namespace >= 0 && ns && setns(default_namespace, CLONE_NEWNET) == -1) {
		if (sock >= 0)
			close(sock);
		return -1;
	}
	return sock;
}

REGISTER_BUILD_OPTS("Built with network namespace support.");
