/** @file
 * @brief Generic connection related functions
 */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#if defined(CONFIG_NET_DEBUG_CONN)
#define SYS_LOG_DOMAIN "net/conn"
#define NET_LOG_ENABLED 1
#endif

#include <errno.h>
#include <misc/util.h>

#include <net/net_core.h>
#include <net/nbuf.h>

#include "net_private.h"
#include "icmpv6.h"
#include "icmpv4.h"
#include "connection.h"
#include "net_stats.h"

/** Is this connection used or not */
#define NET_CONN_IN_USE BIT(0)

/** Remote address set */
#define NET_CONN_REMOTE_ADDR_SET BIT(1)

/** Local address set */
#define NET_CONN_LOCAL_ADDR_SET BIT(2)

/** Rank bits */
#define NET_RANK_LOCAL_PORT         BIT(0)
#define NET_RANK_REMOTE_PORT        BIT(1)
#define NET_RANK_LOCAL_UNSPEC_ADDR  BIT(2)
#define NET_RANK_REMOTE_UNSPEC_ADDR BIT(3)
#define NET_RANK_LOCAL_SPEC_ADDR    BIT(4)
#define NET_RANK_REMOTE_SPEC_ADDR   BIT(5)

static struct net_conn conns[CONFIG_NET_MAX_CONN];

/* This is only used for getting source and destination ports. Because
 * both TCP and UDP header have these in the same location, we can check
 * them both using the UDP struct.
 */
#define NET_CONN_BUF(buf) ((struct net_udp_hdr *)(net_nbuf_udp_data(buf)))

#if defined(CONFIG_NET_DEBUG_CONN)
static inline const char *proto2str(enum net_ip_protocol proto)
{
	switch (proto) {
	case IPPROTO_ICMP:
		return "ICMPv4";
	case IPPROTO_TCP:
		return "TCP";
	case IPPROTO_UDP:
		return "UDP";
	case IPPROTO_ICMPV6:
		return "ICMPv6";
	default:
		break;
	}

	return "<unknown>";
}
#endif /* CONFIG_NET_DEBUG_CONN */

#if defined(CONFIG_NET_CONN_CACHE)

/* Cache the connection so that we do not have to go
 * through the full list of connections when receiving
 * a network packet. The cache contains an index to
 * corresponding entry in conns array.
 *
 * Hash value is constructed like this:
 *
 *   bit      description
 *   0  - 3   bits from remote port
 *   4  - 7   bits from local port
 *   8  - 18  bits from remote address
 *   19 - 29  bits from local address
 *   30       family
 *   31       protocol
 */
struct conn_hash {
	uint32_t value;
	int32_t idx;
};

struct conn_hash_neg {
	uint32_t value;
};

/** Connection cache */
static struct conn_hash conn_cache[CONFIG_NET_MAX_CONN];

/** Negative cache, we definitely do not have a connection
 * to these hosts.
 */
static struct conn_hash_neg conn_cache_neg[CONFIG_NET_MAX_CONN];

#define TAKE_BIT(val, bit, max, used)				\
	(((val & BIT(bit)) >> bit) << (max - used))

static inline uint8_t ports_to_hash(uint16_t remote_port,
				    uint16_t local_port)
{
	/* Note that we do not convert port value to network byte order */
	return (remote_port & BIT(0)) |
		((remote_port & BIT(4)) >> 3) |
		((remote_port & BIT(8)) >> 6) |
		((remote_port & BIT(15)) >> 12) |
		(((local_port & BIT(0)) |
		  ((local_port & BIT(4)) >> 3) |
		  ((local_port & BIT(8)) >> 6) |
		  ((local_port & BIT(15)) >> 12)) << 4);
}

static inline uint16_t ipv6_to_hash(struct in6_addr *addr)
{
	/* There is 11 bits available for IPv6 address */
	/* Use more bits from the lower part of address space */
	return
		/* Take 3 bits from higher values */
		TAKE_BIT(addr->s6_addr32[0], 31, 11, 1) |
		TAKE_BIT(addr->s6_addr32[0], 15, 11, 2) |
		TAKE_BIT(addr->s6_addr32[0], 7, 11, 3) |

		/* Take 2 bits from higher middle values */
		TAKE_BIT(addr->s6_addr32[1], 31, 11, 4) |
		TAKE_BIT(addr->s6_addr32[1], 15, 11, 5) |

		/* Take 2 bits from lower middle values */
		TAKE_BIT(addr->s6_addr32[2], 31, 11, 6) |
		TAKE_BIT(addr->s6_addr32[2], 15, 11, 7) |

		/* Take 4 bits from lower values */
		TAKE_BIT(addr->s6_addr32[3], 31, 11, 8) |
		TAKE_BIT(addr->s6_addr32[3], 15, 11, 9) |
		TAKE_BIT(addr->s6_addr32[3], 7, 11, 10) |
		TAKE_BIT(addr->s6_addr32[3], 0, 11, 11);
}

static inline uint16_t ipv4_to_hash(struct in_addr *addr)
{
	/* There is 11 bits available for IPv4 address */
	/* Use more bits from the lower part of address space */
	return
		TAKE_BIT(addr->s_addr[0], 31, 11, 1) |
		TAKE_BIT(addr->s_addr[0], 27, 11, 2) |
		TAKE_BIT(addr->s_addr[0], 21, 11, 3) |
		TAKE_BIT(addr->s_addr[0], 17, 11, 4) |
		TAKE_BIT(addr->s_addr[0], 14, 11, 5) |
		TAKE_BIT(addr->s_addr[0], 11, 11, 6) |
		TAKE_BIT(addr->s_addr[0], 8, 11, 7) |
		TAKE_BIT(addr->s_addr[0], 5, 11, 8) |
		TAKE_BIT(addr->s_addr[0], 3, 11, 9) |
		TAKE_BIT(addr->s_addr[0], 2, 11, 10) |
		TAKE_BIT(addr->s_addr[0], 0, 11, 11);
}

/* Return either the first free position in the cache (idx < 0) or
 * the existing cached position (idx >= 0)
 */
static int32_t check_hash(enum net_ip_protocol proto,
			  sa_family_t family,
			  void *remote_addr,
			  void *local_addr,
			  uint16_t remote_port,
			  uint16_t local_port,
			  uint32_t *cache_value)
{
	int i, free_pos = -1;
	uint32_t value = 0;

	value = ports_to_hash(remote_port, local_port);

#if defined(CONFIG_NET_UDP)
	if (proto == IPPROTO_UDP) {
		value |= BIT(31);
	}
#endif

#if defined(CONFIG_NET_TCP)
	if (proto == IPPROTO_TCP) {
		value &= ~BIT(31);
	}
#endif

#if defined(CONFIG_NET_IPV6)
	if (family == AF_INET6) {
		value |= BIT(30);
		value |= ipv6_to_hash((struct in6_addr *)remote_addr) << 8;
		value |= ipv6_to_hash((struct in6_addr *)local_addr) << 19;
	}
#endif

#if defined(CONFIG_NET_IPV4)
	if (family == AF_INET) {
		value &= ~BIT(30);
		value |= ipv4_to_hash((struct in_addr *)remote_addr) << 8;
		value |= ipv4_to_hash((struct in_addr *)local_addr) << 19;
	}
#endif

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (conn_cache[i].value == value) {
			return i;
		}

		if (conn_cache[i].idx < 0 && free_pos < 0) {
			free_pos = i;
		}
	}

	if (free_pos >= 0) {
		conn_cache[free_pos].value = value;
		return free_pos;
	}

	*cache_value = value;

	return -ENOENT;
}

static inline int32_t get_conn(enum net_ip_protocol proto,
			       sa_family_t family,
			       struct net_buf *buf,
			       uint32_t *cache_value)
{
#if defined(CONFIG_NET_IPV4)
	if (family == AF_INET) {
		return check_hash(proto, family,
				  &NET_IPV4_BUF(buf)->src,
				  &NET_IPV4_BUF(buf)->dst,
				  NET_UDP_BUF(buf)->src_port,
				  NET_UDP_BUF(buf)->dst_port,
				  cache_value);
	}
#endif

#if defined(CONFIG_NET_IPV6)
	if (family == AF_INET6) {
		return check_hash(proto, family,
				  &NET_IPV6_BUF(buf)->src,
				  &NET_IPV6_BUF(buf)->dst,
				  NET_UDP_BUF(buf)->src_port,
				  NET_UDP_BUF(buf)->dst_port,
				  cache_value);
	}
#endif

	return -1;
}

static inline void cache_add_neg(uint32_t cache_value)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN && cache_value > 0; i++) {
		if (conn_cache_neg[i].value) {
			continue;
		}

		NET_DBG("Add to neg cache value 0x%x", cache_value);

		conn_cache_neg[i].value = cache_value;
		break;
	}
}

static inline bool cache_check_neg(uint32_t cache_value)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN && cache_value > 0; i++) {
		if (conn_cache_neg[i].value == cache_value) {
			NET_DBG("Cache neg [%d] value 0x%x found",
				i, cache_value);
			return true;
		}
	}

	return false;
}

static void cache_clear(void)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		conn_cache[i].idx = -1;
		conn_cache_neg[i].value = 0;
	}
}

static inline enum net_verdict cache_check(enum net_ip_protocol proto,
					   struct net_buf *buf,
					   uint32_t *cache_value,
					   int32_t *pos)
{
	*pos = get_conn(proto, net_nbuf_family(buf), buf, cache_value);
	if (*pos >= 0) {
		if (conn_cache[*pos].idx >= 0) {
			/* Connection is in the cache */
			struct net_conn *conn;

			conn = &conns[conn_cache[*pos].idx];

			NET_DBG("Cache %s listener for buf %p src port %u "
				"dst port %u family %d cache[%d] 0x%x",
				proto2str(proto), buf,
				ntohs(NET_CONN_BUF(buf)->src_port),
				ntohs(NET_CONN_BUF(buf)->dst_port),
				net_nbuf_family(buf), *pos,
				conn_cache[*pos].value);

			return conn->cb(conn, buf, conn->user_data);
		}
	} else if (*cache_value > 0) {
		if (cache_check_neg(*cache_value)) {
			NET_DBG("Drop by cache");
			return NET_DROP;
		}
	}

	return NET_CONTINUE;
}
#else
#define cache_clear(...)
#define cache_add_neg(...)
#define cache_check(...) NET_CONTINUE
#endif /* CONFIG_NET_CONN_CACHE */

int net_conn_unregister(struct net_conn_handle *handle)
{
	struct net_conn *conn = (struct net_conn *)handle;

	if (conn < &conns[0] || conn > &conns[CONFIG_NET_MAX_CONN]) {
		return -EINVAL;
	}

	if (!(conn->flags & NET_CONN_IN_USE)) {
		return -ENOENT;
	}

	NET_DBG("[%zu] connection handler %p removed",
		(conn - conns) / sizeof(*conn), conn);

	conn->flags = 0;

	return 0;
}

int net_conn_change_callback(struct net_conn_handle *handle,
			     net_conn_cb_t cb, void *user_data)
{
	struct net_conn *conn = (struct net_conn *)handle;

	if (conn < &conns[0] || conn > &conns[CONFIG_NET_MAX_CONN]) {
		return -EINVAL;
	}

	if (!(conn->flags & NET_CONN_IN_USE)) {
		return -ENOENT;
	}

	NET_DBG("[%zu] connection handler %p changed callback",
		(conn - conns) / sizeof(*conn), conn);

	conn->cb = cb;
	conn->user_data = user_data;

	return 0;
}

#if defined(CONFIG_NET_DEBUG_CONN)
static inline
void prepare_register_debug_print(char *dst, int dst_len,
				  char *src, int src_len,
				  const struct sockaddr *remote_addr,
				  const struct sockaddr *local_addr)
{
	if (remote_addr && remote_addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		snprintk(dst, dst_len, "%s",
			 net_sprint_ipv6_addr(&net_sin6(remote_addr)->
							sin6_addr));
#else
		snprintk(dst, dst_len, "%s", "?");
#endif

	} else if (remote_addr && remote_addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		snprintk(dst, dst_len, "%s",
			 net_sprint_ipv4_addr(&net_sin(remote_addr)->
							sin_addr));
#else
		snprintk(dst, dst_len, "%s", "?");
#endif

	} else {
		snprintk(dst, dst_len, "%s", "-");
	}

	if (local_addr && local_addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		snprintk(src, src_len, "%s",
			 net_sprint_ipv6_addr(&net_sin6(local_addr)->
							sin6_addr));
#else
		snprintk(src, src_len, "%s", "?");
#endif

	} else if (local_addr && local_addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		snprintk(src, src_len, "%s",
			 net_sprint_ipv4_addr(&net_sin(local_addr)->
							sin_addr));
#else
		snprintk(src, src_len, "%s", "?");
#endif

	} else {
		snprintk(src, src_len, "%s", "-");
	}
}
#endif /* CONFIG_NET_DEBUG_CONN */

int net_conn_register(enum net_ip_protocol proto,
		      const struct sockaddr *remote_addr,
		      const struct sockaddr *local_addr,
		      uint16_t remote_port,
		      uint16_t local_port,
		      net_conn_cb_t cb,
		      void *user_data,
		      struct net_conn_handle **handle)
{
	int i;
	uint8_t rank = 0;

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (conns[i].flags & NET_CONN_IN_USE) {
			continue;
		}

		if (remote_addr) {
			if (remote_addr->family != AF_INET &&
			    remote_addr->family != AF_INET6) {
				NET_ERR("Remote address family not set.");
				return -EINVAL;
			}

			conns[i].flags |= NET_CONN_REMOTE_ADDR_SET;

			memcpy(&conns[i].remote_addr, remote_addr,
			       sizeof(struct sockaddr));

#if defined(CONFIG_NET_IPV6)
			if (remote_addr->family == AF_INET6) {
				if (net_is_ipv6_addr_unspecified(
					    &net_sin6(remote_addr)->
							sin6_addr)) {
					rank |= NET_RANK_REMOTE_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_REMOTE_SPEC_ADDR;
				}
			}
#endif

#if defined(CONFIG_NET_IPV4)
			if (remote_addr->family == AF_INET) {
				if (!net_sin(remote_addr)->
							sin_addr.s_addr[0]) {
					rank |= NET_RANK_REMOTE_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_REMOTE_SPEC_ADDR;
				}
			}
#endif
		}

		if (local_addr) {
			if (local_addr->family != AF_INET &&
			    local_addr->family != AF_INET6) {
				NET_ERR("Local address family not set.");
				return -EINVAL;
			}

			conns[i].flags |= NET_CONN_LOCAL_ADDR_SET;

			memcpy(&conns[i].local_addr, local_addr,
			       sizeof(struct sockaddr));

#if defined(CONFIG_NET_IPV6)
			if (local_addr->family == AF_INET6) {
				if (net_is_ipv6_addr_unspecified(
					    &net_sin6(local_addr)->
							sin6_addr)) {
					rank |= NET_RANK_LOCAL_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_LOCAL_SPEC_ADDR;
				}
			}
#endif

#if defined(CONFIG_NET_IPV4)
			if (local_addr->family == AF_INET) {
				if (!net_sin(local_addr)->sin_addr.s_addr[0]) {
					rank |= NET_RANK_LOCAL_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_LOCAL_SPEC_ADDR;
				}
			}
#endif
		}

		if (remote_addr && local_addr) {
			if (remote_addr->family != local_addr->family) {
				NET_ERR("Address families different.");
				return -EINVAL;
			}
		}

		if (remote_port) {
			rank |= NET_RANK_REMOTE_PORT;
			net_sin(&conns[i].remote_addr)->sin_port =
				htons(remote_port);
		}

		if (local_port) {
			rank |= NET_RANK_LOCAL_PORT;
			net_sin(&conns[i].local_addr)->sin_port =
				htons(local_port);
		}

		conns[i].flags |= NET_CONN_IN_USE;
		conns[i].cb = cb;
		conns[i].user_data = user_data;
		conns[i].rank = rank;
		conns[i].proto = proto;

		/* Cache needs to be cleared if new entries are added. */
		cache_clear();

#if defined(CONFIG_NET_DEBUG_CONN)
		do {
			char dst[NET_IPV6_ADDR_LEN];
			char src[NET_IPV6_ADDR_LEN];

			prepare_register_debug_print(dst, sizeof(dst),
						     src, sizeof(src),
						     remote_addr,
						     local_addr);

			NET_DBG("[%d/%d/%u/0x%02x] remote %p/%s/%u "
				"local %p/%s/%u cb %p ud %p",
				i, local_addr->family, proto, rank,
				remote_addr, dst, remote_port,
				local_addr, src, local_port,
				cb, user_data);
		} while (0);
#endif /* CONFIG_NET_DEBUG_CONN */

		if (handle) {
			*handle = (struct net_conn_handle *)&conns[i];
		}

		return 0;
	}

	return -ENOENT;
}

static bool check_addr(struct net_buf *buf,
		       struct sockaddr *addr,
		       bool is_remote)
{
	if (addr->family != net_nbuf_family(buf)) {
		return false;
	}

#if defined(CONFIG_NET_IPV6)
	if (net_nbuf_family(buf) == AF_INET6 && addr->family == AF_INET6) {
		struct in6_addr *addr6;

		if (is_remote) {
			addr6 = &NET_IPV6_BUF(buf)->src;
		} else {
			addr6 = &NET_IPV6_BUF(buf)->dst;
		}

		if (!net_is_ipv6_addr_unspecified(
			    &net_sin6(addr)->sin6_addr)) {
			if (!net_ipv6_addr_cmp(&net_sin6(addr)->sin6_addr,
					       addr6)) {
				return false;
			}
		}

		return true;
	}
#endif /* CONFIG_NET_IPV6 */

#if defined(CONFIG_NET_IPV4)
	if (net_nbuf_family(buf) == AF_INET && addr->family == AF_INET) {
		struct in_addr *addr4;

		if (is_remote) {
			addr4 = &NET_IPV4_BUF(buf)->src;
		} else {
			addr4 = &NET_IPV4_BUF(buf)->dst;
		}

		if (net_sin(addr)->sin_addr.s_addr[0]) {
			if (!net_ipv4_addr_cmp(&net_sin(addr)->sin_addr,
					       addr4)) {
				return false;
			}
		}
	}
#endif /* CONFIG_NET_IPV4 */

	return true;
}

static inline void send_icmp_error(struct net_buf *buf)
{
	if (net_nbuf_family(buf) == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		net_icmpv6_send_error(buf, NET_ICMPV6_DST_UNREACH,
				      NET_ICMPV6_DST_UNREACH_NO_PORT, 0);
#endif /* CONFIG_NET_IPV6 */

	} else {

#if defined(CONFIG_NET_IPV4)
		net_icmpv4_send_error(buf, NET_ICMPV4_DST_UNREACH,
				      NET_ICMPV4_DST_UNREACH_NO_PORT);
#endif /* CONFIG_NET_IPV4 */
	}
}

enum net_verdict net_conn_input(enum net_ip_protocol proto, struct net_buf *buf)
{
	int i, best_match = -1;
	int16_t best_rank = -1;

#if defined(CONFIG_NET_CONN_CACHE)
	enum net_verdict verdict;
	uint32_t cache_value = 0;
	int32_t pos;

	verdict = cache_check(proto, buf, &cache_value, &pos);
	if (verdict != NET_CONTINUE) {
		return verdict;
	}
#endif

	if (IS_ENABLED(CONFIG_NET_DEBUG_CONN)) {
		uint16_t chksum;

		if (proto == IPPROTO_TCP) {
			chksum = NET_TCP_BUF(buf)->chksum;
		} else {
			chksum = NET_UDP_BUF(buf)->chksum;
		}

		NET_DBG("Check %s listener for buf %p src port %u dst port %u "
			"family %d chksum 0x%04x", proto2str(proto), buf,
			ntohs(NET_CONN_BUF(buf)->src_port),
			ntohs(NET_CONN_BUF(buf)->dst_port),
			net_nbuf_family(buf), ntohs(chksum));
	}

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (!(conns[i].flags & NET_CONN_IN_USE)) {
			continue;
		}

		if (conns[i].proto != proto) {
			continue;
		}

		if (net_sin(&conns[i].remote_addr)->sin_port) {
			if (net_sin(&conns[i].remote_addr)->sin_port !=
			    NET_CONN_BUF(buf)->src_port) {
				continue;
			}
		}

		if (net_sin(&conns[i].local_addr)->sin_port) {
			if (net_sin(&conns[i].local_addr)->sin_port !=
			    NET_CONN_BUF(buf)->dst_port) {
				continue;
			}
		}

		if (conns[i].flags & NET_CONN_REMOTE_ADDR_SET) {
			if (!check_addr(buf, &conns[i].remote_addr, true)) {
				continue;
			}
		}

		if (conns[i].flags & NET_CONN_LOCAL_ADDR_SET) {
			if (!check_addr(buf, &conns[i].local_addr, false)) {
				continue;
			}
		}

		/* If we have an existing best_match, and that one
		 * specifies a remote port, then we've matched to a
		 * LISTENING connection that should not override.
		 */
		if (best_match >= 0 &&
		    net_sin(&conns[best_match].remote_addr)->sin_port) {
			continue;
		}

		if (best_rank < conns[i].rank) {
			best_rank = conns[i].rank;
			best_match = i;
		}
	}

	if (best_match >= 0) {
#if defined(CONFIG_NET_CONN_CACHE)
		NET_DBG("[%d] match found cb %p ud %p rank 0x%02x cache 0x%x",
			best_match,
			conns[best_match].cb,
			conns[best_match].user_data,
			conns[best_match].rank,
			pos < 0 ? 0 : conn_cache[pos].value);

		if (pos >= 0) {
			conn_cache[pos].idx = best_match;
		}
#else
		NET_DBG("[%d] match found cb %p ud %p rank 0x%02x",
			best_match,
			conns[best_match].cb,
			conns[best_match].user_data,
			conns[best_match].rank);
#endif /* CONFIG_NET_CONN_CACHE */

		if (conns[best_match].cb(&conns[best_match], buf,
			     conns[best_match].user_data) == NET_DROP) {
			goto drop;
		}

		if (proto == IPPROTO_UDP) {
			net_stats_update_udp_recv();
		}

		return NET_OK;
	}

	NET_DBG("No match found.");

	cache_add_neg(cache_value);

#if defined(CONFIG_NET_IPV6)
	/* If the destination address is multicast address,
	 * we do not send ICMP error as that makes no sense.
	 */
	if (net_nbuf_family(buf) == AF_INET6 &&
	    net_is_ipv6_addr_mcast(&NET_IPV6_BUF(buf)->dst)) {
		;
	} else
#endif
#if defined(CONFIG_NET_IPV4)
	if (net_nbuf_family(buf) == AF_INET &&
	    net_is_ipv4_addr_mcast(&NET_IPV4_BUF(buf)->dst)) {
		;
	} else
#endif
	{
		send_icmp_error(buf);
	}

drop:
	if (proto == IPPROTO_UDP) {
		net_stats_update_udp_drop();
	}

	return NET_DROP;
}

void net_conn_init(void)
{
#if defined(CONFIG_NET_CONN_CACHE)
	do {
		int i;

		for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
			conn_cache[i].idx = -1;
		}
	} while (0);
#endif /* CONFIG_NET_CONN_CACHE */
}
