/*
 * Copyright (c) 2013-2016 Intel Corporation.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * 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 "iwarp_pm.h"

static LIST_HEAD(mapped_ports);		/* list of mapped ports */

/**
 * create_iwpm_map_request - Create a new map request tracking object
 * @req_nlh: netlink header of the received client message
 * @src_addr: the local address of the client initiating the request
 * @remote_addr: the destination (the port mapper peer) address
 * @assochandle: unique number per host
 * @msg_type: message types are request, accept and ack
 * @send_msg: message to retransmit to the remote port mapper peer,
 * 	      if the request isn't serviced on time.
 */
iwpm_mapping_request *create_iwpm_map_request(struct nlmsghdr *req_nlh,
				struct sockaddr_storage *src_addr, struct sockaddr_storage *remote_addr,
				 __u64 assochandle, int msg_type, iwpm_send_msg *send_msg)
{
	iwpm_mapping_request *iwpm_map_req;
	__u32 type = 0, seq = 0, pid = 0;

	/* create iwpm conversation tracking object */
	iwpm_map_req = malloc(sizeof(iwpm_mapping_request));
	if (!iwpm_map_req)
		return NULL;
	if (req_nlh) {
		type = req_nlh->nlmsg_type;
		seq = req_nlh->nlmsg_seq;
		pid = req_nlh->nlmsg_pid;
	}
	memset(iwpm_map_req, 0, sizeof(iwpm_mapping_request));
	iwpm_map_req->timeout = IWPM_MAP_REQ_TIMEOUT;
	iwpm_map_req->complete = 0;
	iwpm_map_req->msg_type = msg_type;
	iwpm_map_req->send_msg = send_msg;

	iwpm_map_req->nlmsg_type = type;
	iwpm_map_req->nlmsg_seq = seq;
	iwpm_map_req->nlmsg_pid = pid;
	/* assochandle helps match iwpm request sent to remote peer with future iwpm accept/reject */
	iwpm_map_req->assochandle = assochandle;
	if (!assochandle)
		iwpm_map_req->assochandle = (uintptr_t)iwpm_map_req;

	memcpy(&iwpm_map_req->src_addr, src_addr, sizeof(struct sockaddr_storage));
	/* keep record of remote IP address and port */
	memcpy(&iwpm_map_req->remote_addr, remote_addr, sizeof(struct sockaddr_storage));
	return iwpm_map_req;
}

/**
 * add_iwpm_map_request - Add a map request tracking object to a global list
 * @iwpm_map_req: mapping request to be saved
 */
void add_iwpm_map_request(iwpm_mapping_request *iwpm_map_req)
{
	pthread_mutex_lock(&map_req_mutex);
	list_add(&mapping_reqs, &iwpm_map_req->entry);
	/* if not wake, signal the thread that a new request has been posted */
	if (!wake)
		pthread_cond_signal(&cond_req_complete);
	pthread_mutex_unlock(&map_req_mutex);
}

/**
 * remove_iwpm_map_request - Free a map request tracking object
 * @iwpm_map_req: mapping request to be removed
 *
 * Routine must be called within lock context
 */
void remove_iwpm_map_request(iwpm_mapping_request *iwpm_map_req)
{
	if (!iwpm_map_req->complete && iwpm_map_req->msg_type != IWARP_PM_REQ_ACK) {
		iwpm_debug(IWARP_PM_RETRY_DBG, "remove_iwpm_map_request: "
			"Timeout for request (type = %u pid = %d)\n",
			iwpm_map_req->msg_type, iwpm_map_req->nlmsg_pid);
	}
	list_del(&iwpm_map_req->entry);
	if (iwpm_map_req->send_msg)
		free(iwpm_map_req->send_msg);
	free(iwpm_map_req);
}

/**
 * update_iwpm_map_request - Find and update a map request tracking object
 * @assochandle: the request assochandle to search for
 * @src_addr: the request src address to search for
 * @msg_type: the request type to search for
 * @iwpm_copy_req: to store a copy of the found map request object
 * @update: if set update the found request, otherwise don't update
 */
int update_iwpm_map_request(__u64 assochandle, struct sockaddr_storage *src_addr,
				int msg_type, iwpm_mapping_request *iwpm_copy_req, int update)
{
	iwpm_mapping_request *iwpm_map_req;
	int ret = -EINVAL;

	pthread_mutex_lock(&map_req_mutex);
	/* look for a matching entry in the list */
	list_for_each(&mapping_reqs, iwpm_map_req, entry) {
		if (assochandle == iwpm_map_req->assochandle &&
				(msg_type & iwpm_map_req->msg_type) &&
				check_same_sockaddr(src_addr, &iwpm_map_req->src_addr)) {
			ret = 0;
			/* get a copy of the request (a different thread is in charge of freeing it) */
			memcpy(iwpm_copy_req, iwpm_map_req, sizeof(iwpm_mapping_request));
			if (!update)
				goto update_map_request_exit;
			if (iwpm_map_req->complete)
				goto update_map_request_exit;

			/* update the request object */
			if (iwpm_map_req->msg_type == IWARP_PM_REQ_ACK) {
				iwpm_map_req->timeout = IWPM_MAP_REQ_TIMEOUT;
				iwpm_map_req->complete = 0;
			} else {
				/* already serviced request could be freed */
				iwpm_map_req->timeout = 0;
				iwpm_map_req->complete = 1;
			}
			goto update_map_request_exit;
		}
	}
update_map_request_exit:
	pthread_mutex_unlock(&map_req_mutex);
	return ret;
}

/**
 * send_iwpm_msg - Form and send iwpm message to the remote peer
 */
int send_iwpm_msg(void (*form_msg_type)(iwpm_wire_msg *, iwpm_msg_parms *),
			iwpm_msg_parms *msg_parms, struct sockaddr_storage *recv_addr, int send_sock)
{
	iwpm_send_msg send_msg;

	form_msg_type(&send_msg.data, msg_parms);
	form_iwpm_send_msg(send_sock, recv_addr, msg_parms->msize, &send_msg);
	return add_iwpm_pending_msg(&send_msg);
}

/**
 * get_iwpm_tcp_port - Get a new TCP port from the host stack
 * @addr_family: should be valid AF_INET or AF_INET6
 * @requested_port: set only if reopening of mapped port
 * @mapped_addr: to store the mapped TCP port
 * @new_sock: to store socket handle (bound to the mapped TCP port)
*/
static int get_iwpm_tcp_port(__u16 addr_family, __be16 requested_port,
					struct sockaddr_storage *mapped_addr, int *new_sock)
{
	sockaddr_union bind_addr;
	struct sockaddr_in *bind_in4;
	struct sockaddr_in6 *bind_in6;
	socklen_t sockname_len;
	__be16 *new_port = NULL, *mapped_port = NULL;
	const char *str_err = "";

	/* create a socket */
	*new_sock = socket(addr_family, SOCK_STREAM, 0);
	if (*new_sock < 0) {
		str_err = "Unable to create socket";
		goto get_tcp_port_error;
	}

	memset(&bind_addr, 0, sizeof(bind_addr));
	switch (addr_family) {
	case AF_INET:
		mapped_port = &((struct sockaddr_in *)mapped_addr)->sin_port;
		bind_in4 = &bind_addr.v4_sockaddr;
		bind_in4->sin_family = addr_family;
		bind_in4->sin_addr.s_addr = htobe32(INADDR_ANY);
		if (requested_port)
			requested_port = *mapped_port;
		bind_in4->sin_port = requested_port;
		new_port = &bind_in4->sin_port;
		break;
	case AF_INET6:
		mapped_port = &((struct sockaddr_in6 *)mapped_addr)->sin6_port;
		bind_in6 = &bind_addr.v6_sockaddr;
		bind_in6->sin6_family = addr_family;
		bind_in6->sin6_addr = in6addr_any;
		if (requested_port)
			requested_port = *mapped_port;
		bind_in6->sin6_port = requested_port;
		new_port = &bind_in6->sin6_port;
		break;
	default:
		str_err = "Invalid Internet address family";
		goto get_tcp_port_error;
	}

	if (bind(*new_sock, &bind_addr.sock_addr, sizeof(bind_addr))) {
		str_err = "Unable to bind the socket";
		goto get_tcp_port_error;
	}
	/* get the TCP port */
	sockname_len = sizeof(bind_addr);
	if (getsockname(*new_sock, &bind_addr.sock_addr, &sockname_len)) {
		str_err = "Unable to get socket name";
		goto get_tcp_port_error;
	}
	*mapped_port = *new_port;
	iwpm_debug(IWARP_PM_ALL_DBG, "get_iwpm_tcp_port: Open tcp port "
		"(addr family = %04X, requested port = %04X, mapped port = %04X).\n",
		addr_family, be16toh(requested_port), be16toh(*mapped_port));
	return 0;
get_tcp_port_error:
	syslog(LOG_WARNING, "get_iwpm_tcp_port: %s (addr family = %04X, requested port = %04X).\n",
				str_err, addr_family, be16toh(requested_port));
	return -errno;
}

/**
 * get_iwpm_port - Allocate and initialize a new mapped port object
 */
static iwpm_mapped_port *get_iwpm_port(int client_idx, struct sockaddr_storage *local_addr,
				struct sockaddr_storage *mapped_addr, int sd)
{
	iwpm_mapped_port *iwpm_port;

	iwpm_port = malloc(sizeof(iwpm_mapped_port));
	if (!iwpm_port) {
		syslog(LOG_WARNING, "get_iwpm_port: Unable to allocate a mapped port.\n");
		return NULL;
	}
	memset(iwpm_port, 0, sizeof(*iwpm_port));

	/* record local and mapped address in the mapped port object */
	memcpy(&iwpm_port->local_addr, local_addr, sizeof(struct sockaddr_storage));
	memcpy(&iwpm_port->mapped_addr, mapped_addr, sizeof(struct sockaddr_storage));
	iwpm_port->owner_client = client_idx;
	iwpm_port->sd = sd;
	atomic_init(&iwpm_port->ref_cnt, 1);
	if (is_wcard_ipaddr(local_addr))
		iwpm_port->wcard = 1;
	return iwpm_port;
}

/**
 * create_iwpm_mapped_port - Create a new mapped port object
 * @local_addr: local address to be mapped (IP address and TCP port)
 * @client_idx: the index of the client owner of the mapped port
 */
iwpm_mapped_port *create_iwpm_mapped_port(struct sockaddr_storage *local_addr, int client_idx, __u32 flags)
{
	iwpm_mapped_port *iwpm_port;
	struct sockaddr_storage mapped_addr;
	int new_sd;

	memcpy(&mapped_addr, local_addr, sizeof(mapped_addr));
	/* get a tcp port from the host net stack */
	if (flags & IWPM_FLAGS_NO_PORT_MAP) {
		new_sd = -1;
	} else {
		if (get_iwpm_tcp_port(local_addr->ss_family, 0, &mapped_addr, &new_sd))
			goto create_mapped_port_error;
	}
	iwpm_port = get_iwpm_port(client_idx, local_addr, &mapped_addr, new_sd);
	return iwpm_port;

create_mapped_port_error:
	iwpm_debug(IWARP_PM_ALL_DBG, "create_iwpm_mapped_port: Could not make port mapping.\n");
	return NULL;
}

/**
 * reopen_iwpm_mapped_port - Create a new mapped port object
 * @local_addr: local address to be mapped (IP address and TCP port)
 * @mapped_addr: mapped address to be remapped (IP address and TCP port)
 * @client_idx: the index of the client owner of the mapped port
 */
iwpm_mapped_port *reopen_iwpm_mapped_port(struct sockaddr_storage *local_addr,
						struct sockaddr_storage *mapped_addr, int client_idx,
						__u32 flags)
{
	iwpm_mapped_port *iwpm_port;
	int new_sd = -1;
	const char *str_err = "";

	if (local_addr->ss_family != mapped_addr->ss_family) {
		str_err = "Different local and mapped sockaddr families";
		goto reopen_mapped_port_error;
	}
	if (!(flags & IWPM_FLAGS_NO_PORT_MAP)) {
		if (get_iwpm_tcp_port(local_addr->ss_family, htobe16(1), mapped_addr, &new_sd))
			goto reopen_mapped_port_error;
	}
	iwpm_port = get_iwpm_port(client_idx, local_addr, mapped_addr, new_sd);
	return iwpm_port;

reopen_mapped_port_error:
	iwpm_debug(IWARP_PM_ALL_DBG, "reopen_iwpm_mapped_port: Could not make port mapping (%s).\n",
			str_err);
	if (new_sd >= 0)
		close(new_sd);
	return NULL;
}

/**
 * add_iwpm_mapped_port - Add mapping to a global list
 * @iwpm_port: mapping to be saved
 */
void add_iwpm_mapped_port(iwpm_mapped_port *iwpm_port)
{
	static int dbg_idx = 1;
	if (atomic_load(&iwpm_port->ref_cnt) > 1)
		return;
	iwpm_debug(IWARP_PM_ALL_DBG, "add_iwpm_mapped_port: Adding a new mapping #%d\n", dbg_idx++);
	list_add(&mapped_ports, &iwpm_port->entry);
}

/**
 * check_same_sockaddr - Compare two sock addresses;
 *                       return true if they are same, false otherwise
 */
int check_same_sockaddr(struct sockaddr_storage *sockaddr_a, struct sockaddr_storage *sockaddr_b)
{
	int ret = 0;
	if (sockaddr_a->ss_family == sockaddr_b->ss_family) {
		switch (sockaddr_a->ss_family) {
		case AF_INET: {
			struct sockaddr_in *in4addr_a = (struct sockaddr_in *)sockaddr_a;
			struct sockaddr_in *in4addr_b = (struct sockaddr_in *)sockaddr_b;

			if ((in4addr_a->sin_addr.s_addr == in4addr_b->sin_addr.s_addr)
			 		&& (in4addr_a->sin_port == in4addr_b->sin_port))
				ret = 1;

			break;
		}
		case AF_INET6: {
			struct sockaddr_in6 *in6addr_a = (struct sockaddr_in6 *)sockaddr_a;
			struct sockaddr_in6 *in6addr_b = (struct sockaddr_in6 *)sockaddr_b;

			if ((!memcmp(in6addr_a->sin6_addr.s6_addr,
					in6addr_b->sin6_addr.s6_addr, IWPM_IPADDR_SIZE)) &&
					(in6addr_a->sin6_port == in6addr_b->sin6_port))
				ret = 1;

			break;
		}
		default:
			syslog(LOG_WARNING, "check_same_sockaddr: Invalid addr family 0x%02X\n",
					sockaddr_a->ss_family);
			break;
		}
	}
	return ret;
}

/**
 * find_iwpm_mapping - Find saved mapped port object
 * @search_addr: IP address and port to search for in the list
 * @not_mapped: if set, compare local addresses, otherwise compare mapped addresses
 *
 * Compares the search_sockaddr to the addresses in the list,
 * to find a saved port object with the sockaddr or
 * a wild card address with the same tcp port
 */
iwpm_mapped_port *find_iwpm_mapping(struct sockaddr_storage *search_addr,
		int not_mapped)
{
	iwpm_mapped_port *iwpm_port, *saved_iwpm_port = NULL;
	struct sockaddr_storage *current_addr;

	list_for_each(&mapped_ports, iwpm_port, entry) {
		current_addr = (not_mapped)? &iwpm_port->local_addr : &iwpm_port->mapped_addr;

		if (get_sockaddr_port(search_addr) == get_sockaddr_port(current_addr)) {
			if (check_same_sockaddr(search_addr, current_addr) ||
					iwpm_port->wcard || is_wcard_ipaddr(search_addr)) {
				saved_iwpm_port = iwpm_port;
				goto find_mapping_exit;
			}
		}
	}
find_mapping_exit:
	return saved_iwpm_port;
}

/**
 * find_iwpm_same_mapping - Find saved mapped port object
 * @search_addr: IP address and port to search for in the list
 * @not_mapped: if set, compare local addresses, otherwise compare mapped addresses
 *
 * Compares the search_sockaddr to the addresses in the list,
 * to find a saved port object with the same sockaddr
 */
iwpm_mapped_port *find_iwpm_same_mapping(struct sockaddr_storage *search_addr,
		int not_mapped)
{
	iwpm_mapped_port *iwpm_port, *saved_iwpm_port = NULL;
	struct sockaddr_storage *current_addr;

	list_for_each(&mapped_ports, iwpm_port, entry) {
		current_addr = (not_mapped)? &iwpm_port->local_addr : &iwpm_port->mapped_addr;
		if (check_same_sockaddr(search_addr, current_addr)) {
			saved_iwpm_port = iwpm_port;
			goto find_same_mapping_exit;
		}
	}
find_same_mapping_exit:
	return saved_iwpm_port;
}

/**
 * free_iwpm_port - Free mapping object
 * @iwpm_port: mapped port object to be freed
 */
void free_iwpm_port(iwpm_mapped_port *iwpm_port)
{
	if (iwpm_port->sd != -1)
		close(iwpm_port->sd);
	free(iwpm_port);
}

/**
 * remove_iwpm_mapped_port - Remove a mapping from a global list
 * @iwpm_port: mapping to be removed
 *
 * Called only by the main iwarp port mapper thread
 */
void remove_iwpm_mapped_port(iwpm_mapped_port *iwpm_port)
{
	static int dbg_idx = 1;
	iwpm_debug(IWARP_PM_ALL_DBG, "remove_iwpm_mapped_port: index = %d\n", dbg_idx++);

	list_del(&iwpm_port->entry);
}

void print_iwpm_mapped_ports(void)
{
	iwpm_mapped_port *iwpm_port;
	int i = 0;

	syslog(LOG_WARNING, "print_iwpm_mapped_ports:\n");

	list_for_each(&mapped_ports, iwpm_port, entry) {
		syslog(LOG_WARNING, "Mapping #%d\n", i++);
		print_iwpm_sockaddr(&iwpm_port->local_addr, "Local address", IWARP_PM_DEBUG);
		print_iwpm_sockaddr(&iwpm_port->mapped_addr, "Mapped address", IWARP_PM_DEBUG);
	}
}

/**
 * form_iwpm_send_msg - Form a message to send on the wire
 */
void form_iwpm_send_msg(int pm_sock, struct sockaddr_storage *dest,
			int length, iwpm_send_msg *send_msg)
{
        send_msg->pm_sock = pm_sock;
        send_msg->length = length;
        memcpy(&send_msg->dest_addr, dest, sizeof(send_msg->dest_addr));
}

/**
 * add_iwpm_pending_msg - Add wire message to a global list of pending messages
 * @send_msg: message to send to the remote port mapper peer
 */
int add_iwpm_pending_msg(iwpm_send_msg *send_msg)
{
	iwpm_pending_msg *pending_msg = malloc(sizeof(iwpm_pending_msg));
	if (!pending_msg) {
		syslog(LOG_WARNING, "add_iwpm_pending_msg: Unable to allocate message.\n");
		return -ENOMEM;
	}
	memcpy(&pending_msg->send_msg, send_msg, sizeof(iwpm_send_msg));

	pthread_mutex_lock(&pending_msg_mutex);
	list_add(&pending_messages, &pending_msg->entry);
	pthread_mutex_unlock(&pending_msg_mutex);
	/* signal the thread that a new message has been posted */
	pthread_cond_signal(&cond_pending_msg);
	return 0;
}

/**
 * free_iwpm_mapped_ports - Free all iwpm mapped port objects
 */
void free_iwpm_mapped_ports(void)
{
	iwpm_mapped_port *iwpm_port;

	while ((iwpm_port = list_pop(&mapped_ports, iwpm_mapped_port, entry)))
		free_iwpm_port(iwpm_port);
}
