/** @file
 * @brief Network context API
 *
 * An API for applications to define a network connection.
 */

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

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_ctx, CONFIG_NET_CONTEXT_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <zephyr/random/rand32.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>

#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/socket.h>
#include <zephyr/net/net_context.h>
#include <zephyr/net/net_offload.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/socket_can.h>

#include "connection.h"
#include "net_private.h"

#include "ipv6.h"
#include "ipv4.h"
#include "udp_internal.h"
#include "tcp_internal.h"
#include "net_stats.h"

#if IS_ENABLED(CONFIG_NET_TCP)
#include "tcp.h"
#endif

#ifndef EPFNOSUPPORT
/* Some old versions of newlib haven't got this defined in errno.h,
 * Just use EPROTONOSUPPORT in this case
 */
#define EPFNOSUPPORT EPROTONOSUPPORT
#endif

#define PKT_WAIT_TIME K_SECONDS(1)

#define NET_MAX_CONTEXT CONFIG_NET_MAX_CONTEXTS

static struct net_context contexts[NET_MAX_CONTEXT];

/* We need to lock the contexts array as these APIs are typically called
 * from applications which are usually run in task context.
 */
static struct k_sem contexts_lock;

#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
static int check_used_port(enum net_ip_protocol ip_proto,
			   uint16_t local_port,
			   const struct sockaddr *local_addr)

{
	int i;

	for (i = 0; i < NET_MAX_CONTEXT; i++) {
		if (!net_context_is_used(&contexts[i])) {
			continue;
		}

		if (!(net_context_get_ip_proto(&contexts[i]) == ip_proto &&
		      net_sin((struct sockaddr *)&
			      contexts[i].local)->sin_port == local_port)) {
			continue;
		}

		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    local_addr->sa_family == AF_INET6) {
			if (net_sin6_ptr(&contexts[i].local)->sin6_addr == NULL) {
				continue;
			}

			if (net_ipv6_addr_cmp(
				    net_sin6_ptr(&contexts[i].local)->
							     sin6_addr,
				    &((struct sockaddr_in6 *)
				      local_addr)->sin6_addr)) {
				return -EEXIST;
			}
		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
			   local_addr->sa_family == AF_INET) {
			if (net_sin_ptr(&contexts[i].local)->sin_addr == NULL) {
				continue;
			}

			if (net_ipv4_addr_cmp(
				    net_sin_ptr(&contexts[i].local)->
							      sin_addr,
				    &((struct sockaddr_in *)
				      local_addr)->sin_addr)) {
				return -EEXIST;
			}
		}
	}

	return 0;
}

static uint16_t find_available_port(struct net_context *context,
				    const struct sockaddr *addr)
{
	uint16_t local_port;

	do {
		local_port = sys_rand32_get() | 0x8000;
		if (local_port <= 1023U) {
			/* 0 - 1023 ports are reserved */
			continue;
		}
	} while (check_used_port(net_context_get_ip_proto(context),
				 htons(local_port), addr) == -EEXIST);

	return htons(local_port);
}
#else
#define check_used_port(...) 0
#define find_available_port(...) 0
#endif

bool net_context_port_in_use(enum net_ip_protocol ip_proto,
			   uint16_t local_port,
			   const struct sockaddr *local_addr)
{
	return check_used_port(ip_proto, htons(local_port), local_addr) != 0;
}

int net_context_get(sa_family_t family,
		    enum net_sock_type type,
		    uint16_t ip_proto,
		    struct net_context **context)
{
	int i, ret = -ENOENT;

	if (IS_ENABLED(CONFIG_NET_CONTEXT_CHECK)) {
		if (!IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
			NET_DBG("IPv4 disabled");
			return -EPFNOSUPPORT;
		}

		if (!IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
			NET_DBG("IPv6 disabled");
			return -EPFNOSUPPORT;
		}

		if (!IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
			NET_DBG("AF_CAN disabled");
			return -EPFNOSUPPORT;
		}

		if (type == SOCK_RAW) {
			if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
			    IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
				if (family != AF_PACKET && family != AF_CAN) {
					NET_DBG("Invalid family");
					return -EINVAL;
				}
			} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
				   !IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
				if (family != AF_PACKET) {
					NET_DBG("Invalid family");
					return -EINVAL;
				}
			} else if (!IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
				   IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
				if (family != AF_CAN) {
					NET_DBG("Invalid family");
					return -EINVAL;
				}
			}
		} else {
			if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
			    family == AF_PACKET && type == SOCK_DGRAM &&
			    ip_proto > 0) {
				goto check_context;
			} else if (family == AF_PACKET || family == AF_CAN) {
				NET_DBG("Invalid family");
				return -EPROTOTYPE;
			}
		}

		if (!IS_ENABLED(CONFIG_NET_UDP)) {
			if (type == SOCK_DGRAM) {
				NET_DBG("Datagram context disabled");
				return -EPROTOTYPE;
			}

			if (ip_proto == IPPROTO_UDP) {
				NET_DBG("UDP disabled");
				return -EPROTONOSUPPORT;
			}
		}

		if (!IS_ENABLED(CONFIG_NET_TCP)) {
			if (type == SOCK_STREAM) {
				NET_DBG("Stream context disabled");
				return -EPROTOTYPE;
			}

			if (ip_proto == IPPROTO_TCP) {
				NET_DBG("TCP disabled");
				return -EPROTONOSUPPORT;
			}
		}

		if (family != AF_INET && family != AF_INET6 &&
		    family != AF_PACKET && family != AF_CAN) {
			NET_DBG("Unknown address family %d", family);
			return -EAFNOSUPPORT;
		}

		if (type != SOCK_DGRAM && type != SOCK_STREAM &&
		    type != SOCK_RAW) {
			NET_DBG("Unknown context type");
			return -EPROTOTYPE;
		}

		if (type != SOCK_RAW && ip_proto != IPPROTO_UDP &&
		    ip_proto != IPPROTO_TCP) {
			NET_DBG("Unknown IP protocol %d", ip_proto);
			return -EPROTONOSUPPORT;
		}

		if ((type == SOCK_STREAM && ip_proto == IPPROTO_UDP) ||
		    (type == SOCK_DGRAM && ip_proto == IPPROTO_TCP)) {
			NET_DBG("Context type and protocol mismatch,"
				" type %d proto %d", type, ip_proto);
			return -EOPNOTSUPP;
		}

	check_context:
		if (!context) {
			NET_DBG("Invalid context");
			return -EINVAL;
		}
	}

	k_sem_take(&contexts_lock, K_FOREVER);

	for (i = 0; i < NET_MAX_CONTEXT; i++) {
		if (net_context_is_used(&contexts[i])) {
			continue;
		}

		memset(&contexts[i], 0, sizeof(contexts[i]));
	/* FIXME - Figure out a way to get the correct network interface
	 * as it is not known at this point yet.
	 */
		if (!net_if_is_ip_offloaded(net_if_get_default())
			&& ip_proto == IPPROTO_TCP) {
			if (net_tcp_get(&contexts[i]) < 0) {
				break;
			}
		}

		contexts[i].iface = -1;
		contexts[i].flags = 0U;
		atomic_set(&contexts[i].refcount, 1);

		net_context_set_family(&contexts[i], family);
		net_context_set_type(&contexts[i], type);
		net_context_set_ip_proto(&contexts[i], ip_proto);

#if defined(CONFIG_NET_CONTEXT_RCVTIMEO)
		contexts[i].options.rcvtimeo = K_FOREVER;
#endif
#if defined(CONFIG_NET_CONTEXT_SNDTIMEO)
		contexts[i].options.sndtimeo = K_FOREVER;
#endif

		if (IS_ENABLED(CONFIG_NET_IPV6) ||
		    IS_ENABLED(CONFIG_NET_IPV4)) {
			(void)memset(&contexts[i].remote, 0,
				     sizeof(struct sockaddr));
			(void)memset(&contexts[i].local, 0,
				     sizeof(struct sockaddr_ptr));
		}

		if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
			struct sockaddr_in6 *addr6 = (struct sockaddr_in6
						      *)&contexts[i].local;
			addr6->sin6_port = find_available_port(&contexts[i],
						    (struct sockaddr *)addr6);

			if (!addr6->sin6_port) {
				ret = -EADDRINUSE;
				break;
			}
		}

		if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
			struct sockaddr_in *addr = (struct sockaddr_in
						      *)&contexts[i].local;
			addr->sin_port = find_available_port(&contexts[i],
						    (struct sockaddr *)addr);

			if (!addr->sin_port) {
				ret = -EADDRINUSE;
				break;
			}
		}

#if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
		k_sem_init(&contexts[i].recv_data_wait, 1, K_SEM_MAX_LIMIT);
#endif /* CONFIG_NET_CONTEXT_SYNC_RECV */

		k_mutex_init(&contexts[i].lock);

		contexts[i].flags |= NET_CONTEXT_IN_USE;
		*context = &contexts[i];

		ret = 0;
		break;
	}

	k_sem_give(&contexts_lock);

	/* FIXME - Figure out a way to get the correct network interface
	 * as it is not known at this point yet.
	 */
	if (!ret && IS_ENABLED(CONFIG_NET_OFFLOAD) &&
	    net_if_is_ip_offloaded(net_if_get_default())) {
		ret = net_offload_get(net_if_get_default(),
				      family,
				      type,
				      ip_proto,
				      context);
		if (ret < 0) {
			(*context)->flags &= ~NET_CONTEXT_IN_USE;
			*context = NULL;
		}

		return ret;
	}

	return ret;
}

int net_context_ref(struct net_context *context)
{
	int old_rc = atomic_inc(&context->refcount);

	return old_rc + 1;
}

int net_context_unref(struct net_context *context)
{
	int old_rc = atomic_dec(&context->refcount);

	if (old_rc != 1) {
		return old_rc - 1;
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	net_tcp_unref(context);

	if (context->conn_handler) {
		if (IS_ENABLED(CONFIG_NET_TCP) || IS_ENABLED(CONFIG_NET_UDP) ||
		    IS_ENABLED(CONFIG_NET_SOCKETS_CAN) ||
		    IS_ENABLED(CONFIG_NET_SOCKETS_PACKET)) {
			net_conn_unregister(context->conn_handler);
		}

		context->conn_handler = NULL;
	}

	net_context_set_state(context, NET_CONTEXT_UNCONNECTED);

	context->flags &= ~NET_CONTEXT_IN_USE;

	NET_DBG("Context %p released", context);

	k_mutex_unlock(&context->lock);

	return 0;
}

int net_context_put(struct net_context *context)
{
	int ret = 0;

	NET_ASSERT(context);

	if (!PART_OF_ARRAY(contexts, context)) {
		return -EINVAL;
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
		context->flags &= ~NET_CONTEXT_IN_USE;
		ret = net_offload_put(net_context_get_iface(context), context);
		goto unlock;
	}

	context->connect_cb = NULL;
	context->recv_cb = NULL;
	context->send_cb = NULL;

	/* net_tcp_put() will handle decrementing refcount on stack's behalf */
	net_tcp_put(context);

	/* Decrement refcount on user app's behalf */
	net_context_unref(context);

unlock:
	k_mutex_unlock(&context->lock);

	return ret;
}

/* If local address is not bound, bind it to INADDR_ANY and random port. */
static int bind_default(struct net_context *context)
{
	sa_family_t family = net_context_get_family(context);

	if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
		struct sockaddr_in6 addr6;

		if (net_sin6_ptr(&context->local)->sin6_addr) {
			return 0;
		}

		addr6.sin6_family = AF_INET6;
		memcpy(&addr6.sin6_addr, net_ipv6_unspecified_address(),
		       sizeof(addr6.sin6_addr));
		addr6.sin6_port =
			find_available_port(context,
					    (struct sockaddr *)&addr6);

		return net_context_bind(context, (struct sockaddr *)&addr6,
					sizeof(addr6));
	}

	if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
		struct sockaddr_in addr4;

		if (net_sin_ptr(&context->local)->sin_addr) {
			return 0;
		}

		addr4.sin_family = AF_INET;
		addr4.sin_addr.s_addr = INADDR_ANY;
		addr4.sin_port =
			find_available_port(context,
					    (struct sockaddr *)&addr4);

		return net_context_bind(context, (struct sockaddr *)&addr4,
					sizeof(addr4));
	}

	if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && family == AF_PACKET) {
		struct sockaddr_ll ll_addr;

		if (net_sll_ptr(&context->local)->sll_addr) {
			return 0;
		}

		ll_addr.sll_family = AF_PACKET;
		ll_addr.sll_protocol = htons(ETH_P_ALL);
		ll_addr.sll_ifindex = net_if_get_by_iface(net_if_get_default());

		return net_context_bind(context, (struct sockaddr *)&ll_addr,
					sizeof(ll_addr));
	}

	if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
		struct sockaddr_can can_addr;

		if (context->iface >= 0) {
			return 0;
		} else {
#if defined(CONFIG_NET_L2_CANBUS_RAW)
			struct net_if *iface;

			iface = net_if_get_first_by_type(
						&NET_L2_GET_NAME(CANBUS_RAW));
			if (!iface) {
				return -ENOENT;
			}

			can_addr.can_ifindex = net_if_get_by_iface(iface);
			context->iface = can_addr.can_ifindex;
#else
			return -ENOENT;
#endif
		}

		can_addr.can_family = AF_CAN;

		return net_context_bind(context, (struct sockaddr *)&can_addr,
					sizeof(can_addr));
	}

	return -EINVAL;
}

int net_context_bind(struct net_context *context, const struct sockaddr *addr,
		     socklen_t addrlen)
{
	int ret;

	NET_ASSERT(addr);
	NET_ASSERT(PART_OF_ARRAY(contexts, context));

	/* If we already have connection handler, then it effectively
	 * means that it's already bound to an interface/port, and we
	 * don't support rebinding connection to new address/port in
	 * the code below.
	 * TODO: Support rebinding.
	 */
	if (context->conn_handler) {
		return -EISCONN;
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) && addr->sa_family == AF_INET6) {
		struct net_if *iface = NULL;
		struct in6_addr *ptr;
		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;

		if (addrlen < sizeof(struct sockaddr_in6)) {
			return -EINVAL;
		}

		if (net_context_is_bound_to_iface(context)) {
			iface = net_context_get_iface(context);
		}

		if (net_ipv6_is_addr_mcast(&addr6->sin6_addr)) {
			struct net_if_mcast_addr *maddr;

			maddr = net_if_ipv6_maddr_lookup(&addr6->sin6_addr,
							 &iface);
			if (!maddr) {
				return -ENOENT;
			}

			ptr = &maddr->address.in6_addr;

		} else if (net_ipv6_is_addr_unspecified(&addr6->sin6_addr)) {
			if (iface == NULL) {
				iface = net_if_ipv6_select_src_iface(
					&net_sin6(&context->remote)->sin6_addr);
			}

			ptr = (struct in6_addr *)net_ipv6_unspecified_address();
		} else {
			struct net_if_addr *ifaddr;

			ifaddr = net_if_ipv6_addr_lookup(
					&addr6->sin6_addr,
					iface == NULL ? &iface : NULL);
			if (!ifaddr) {
				return -ENOENT;
			}

			ptr = &ifaddr->address.in6_addr;
		}

		if (!iface) {
			NET_ERR("Cannot bind to %s",
				net_sprint_ipv6_addr(&addr6->sin6_addr));

			return -EADDRNOTAVAIL;
		}

		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
		    net_if_is_ip_offloaded(iface)) {
			net_context_set_iface(context, iface);

			return net_offload_bind(iface,
						context,
						addr,
						addrlen);
		}

		k_mutex_lock(&context->lock, K_FOREVER);

		ret = 0;

		net_context_set_iface(context, iface);

		net_sin6_ptr(&context->local)->sin6_family = AF_INET6;
		net_sin6_ptr(&context->local)->sin6_addr = ptr;
		if (addr6->sin6_port) {
			ret = check_used_port(AF_INET6, addr6->sin6_port,
					      addr);
			if (!ret) {
				net_sin6_ptr(&context->local)->sin6_port =
					addr6->sin6_port;
			} else {
				NET_ERR("Port %d is in use!",
					ntohs(addr6->sin6_port));
				goto unlock_ipv6;
			}
		} else {
			addr6->sin6_port =
				net_sin6_ptr(&context->local)->sin6_port;
		}

		NET_DBG("Context %p binding to %s [%s]:%d iface %d (%p)",
			context,
			net_proto2str(AF_INET6,
				      net_context_get_ip_proto(context)),
			net_sprint_ipv6_addr(ptr),
			ntohs(addr6->sin6_port),
			net_if_get_by_iface(iface), iface);

	unlock_ipv6:
		k_mutex_unlock(&context->lock);

		return ret;
	}

	if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) {
		struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
		struct net_if *iface = NULL;
		struct net_if_addr *ifaddr;
		struct in_addr *ptr;

		if (addrlen < sizeof(struct sockaddr_in)) {
			return -EINVAL;
		}

		if (net_context_is_bound_to_iface(context)) {
			iface = net_context_get_iface(context);
		}

		if (net_ipv4_is_addr_mcast(&addr4->sin_addr)) {
			struct net_if_mcast_addr *maddr;

			maddr = net_if_ipv4_maddr_lookup(&addr4->sin_addr,
							 &iface);
			if (!maddr) {
				return -ENOENT;
			}

			ptr = &maddr->address.in_addr;

		} else if (addr4->sin_addr.s_addr == INADDR_ANY) {
			if (iface == NULL) {
				iface = net_if_ipv4_select_src_iface(
					&net_sin(&context->remote)->sin_addr);
			}

			ptr = (struct in_addr *)net_ipv4_unspecified_address();
		} else {
			ifaddr = net_if_ipv4_addr_lookup(
					&addr4->sin_addr,
					iface == NULL ? &iface : NULL);
			if (!ifaddr) {
				return -ENOENT;
			}

			ptr = &ifaddr->address.in_addr;
		}

		if (!iface) {
			NET_ERR("Cannot bind to %s",
				net_sprint_ipv4_addr(&addr4->sin_addr));

			return -EADDRNOTAVAIL;
		}

		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
		    net_if_is_ip_offloaded(iface)) {
			net_context_set_iface(context, iface);

			return net_offload_bind(iface,
						context,
						addr,
						addrlen);
		}

		k_mutex_lock(&context->lock, K_FOREVER);

		ret = 0;

		net_context_set_iface(context, iface);

		net_sin_ptr(&context->local)->sin_family = AF_INET;
		net_sin_ptr(&context->local)->sin_addr = ptr;
		if (addr4->sin_port) {
			ret = check_used_port(AF_INET, addr4->sin_port,
					      addr);
			if (!ret) {
				net_sin_ptr(&context->local)->sin_port =
					addr4->sin_port;
			} else {
				NET_ERR("Port %d is in use!",
					ntohs(addr4->sin_port));
				goto unlock_ipv4;
			}
		} else {
			addr4->sin_port =
				net_sin_ptr(&context->local)->sin_port;
		}

		NET_DBG("Context %p binding to %s %s:%d iface %d (%p)",
			context,
			net_proto2str(AF_INET,
				      net_context_get_ip_proto(context)),
			net_sprint_ipv4_addr(ptr),
			ntohs(addr4->sin_port),
			net_if_get_by_iface(iface), iface);

	unlock_ipv4:
		k_mutex_unlock(&context->lock);

		return ret;
	}

	if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
	    addr->sa_family == AF_PACKET) {
		struct sockaddr_ll *ll_addr = (struct sockaddr_ll *)addr;
		struct net_if *iface = NULL;

		if (addrlen < sizeof(struct sockaddr_ll)) {
			return -EINVAL;
		}

		if (ll_addr->sll_ifindex < 0) {
			return -EINVAL;
		}

		iface = net_if_get_by_index(ll_addr->sll_ifindex);
		if (!iface) {
			NET_ERR("Cannot bind to interface index %d",
				ll_addr->sll_ifindex);
			return -EADDRNOTAVAIL;
		}

		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
		    net_if_is_ip_offloaded(iface)) {
			net_context_set_iface(context, iface);

			return net_offload_bind(iface,
						context,
						addr,
						addrlen);
		}

		k_mutex_lock(&context->lock, K_FOREVER);

		net_context_set_iface(context, iface);

		net_sll_ptr(&context->local)->sll_family = AF_PACKET;
		net_sll_ptr(&context->local)->sll_ifindex =
			ll_addr->sll_ifindex;
		net_sll_ptr(&context->local)->sll_protocol =
			ll_addr->sll_protocol;
		net_sll_ptr(&context->local)->sll_addr =
			net_if_get_link_addr(iface)->addr;
		net_sll_ptr(&context->local)->sll_halen =
			net_if_get_link_addr(iface)->len;

		NET_DBG("Context %p bind to type 0x%04x iface[%d] %p addr %s",
			context, htons(net_context_get_ip_proto(context)),
			ll_addr->sll_ifindex, iface,
			net_sprint_ll_addr(
				net_sll_ptr(&context->local)->sll_addr,
				net_sll_ptr(&context->local)->sll_halen));

		k_mutex_unlock(&context->lock);

		return 0;
	}

	if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && addr->sa_family == AF_CAN) {
		struct sockaddr_can *can_addr = (struct sockaddr_can *)addr;
		struct net_if *iface = NULL;

		if (addrlen < sizeof(struct sockaddr_can)) {
			return -EINVAL;
		}

		if (can_addr->can_ifindex < 0) {
			return -EINVAL;
		}

		iface = net_if_get_by_index(can_addr->can_ifindex);
		if (!iface) {
			NET_ERR("Cannot bind to interface index %d",
				can_addr->can_ifindex);
			return -EADDRNOTAVAIL;
		}

		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
		    net_if_is_ip_offloaded(iface)) {
			net_context_set_iface(context, iface);

			return net_offload_bind(iface,
						context,
						addr,
						addrlen);
		}

		k_mutex_lock(&context->lock, K_FOREVER);

		net_context_set_iface(context, iface);
		net_context_set_family(context, AF_CAN);

		net_can_ptr(&context->local)->can_family = AF_CAN;
		net_can_ptr(&context->local)->can_ifindex =
			can_addr->can_ifindex;

		NET_DBG("Context %p binding to %d iface[%d] %p",
			context, net_context_get_ip_proto(context),
			can_addr->can_ifindex, iface);

		k_mutex_unlock(&context->lock);

		return 0;
	}

	return -EINVAL;
}

static inline struct net_context *find_context(void *conn_handler)
{
	int i;

	for (i = 0; i < NET_MAX_CONTEXT; i++) {
		if (!net_context_is_used(&contexts[i])) {
			continue;
		}

		if (contexts[i].conn_handler == conn_handler) {
			return &contexts[i];
		}
	}

	return NULL;
}

int net_context_listen(struct net_context *context, int backlog)
{
	ARG_UNUSED(backlog);

	NET_ASSERT(PART_OF_ARRAY(contexts, context));

	if (!net_context_is_used(context)) {
		return -EBADF;
	}

	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
		return net_offload_listen(net_context_get_iface(context),
					  context, backlog);
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	if (net_tcp_listen(context) >= 0) {
		k_mutex_unlock(&context->lock);
		return 0;
	}

	k_mutex_unlock(&context->lock);

	return -EOPNOTSUPP;
}

#if defined(CONFIG_NET_IPV4)
int net_context_create_ipv4_new(struct net_context *context,
				struct net_pkt *pkt,
				const struct in_addr *src,
				const struct in_addr *dst)
{
	if (!src) {
		NET_ASSERT(((
			struct sockaddr_in_ptr *)&context->local)->sin_addr);

		src = ((struct sockaddr_in_ptr *)&context->local)->sin_addr;
	}

	if (net_ipv4_is_addr_unspecified(src)
	    || net_ipv4_is_addr_mcast(src)) {
		src = net_if_ipv4_select_src_addr(net_pkt_iface(pkt),
						  (struct in_addr *)dst);
		/* If src address is still unspecified, do not create pkt */
		if (net_ipv4_is_addr_unspecified(src)) {
			NET_DBG("DROP: src addr is unspecified");
			return -EINVAL;
		}
	}

	net_pkt_set_ipv4_ttl(pkt, net_context_get_ipv4_ttl(context));

	return net_ipv4_create(pkt, src, dst);
}
#endif /* CONFIG_NET_IPV4 */

#if defined(CONFIG_NET_IPV6)
int net_context_create_ipv6_new(struct net_context *context,
				struct net_pkt *pkt,
				const struct in6_addr *src,
				const struct in6_addr *dst)
{
	if (!src) {
		NET_ASSERT(((
			struct sockaddr_in6_ptr *)&context->local)->sin6_addr);

		src = ((struct sockaddr_in6_ptr *)&context->local)->sin6_addr;
	}

	if (net_ipv6_is_addr_unspecified(src)
	    || net_ipv6_is_addr_mcast(src)) {
		src = net_if_ipv6_select_src_addr(net_pkt_iface(pkt),
						  (struct in6_addr *)dst);
	}

	net_pkt_set_ipv6_hop_limit(pkt,
				   net_context_get_ipv6_hop_limit(context));

	return net_ipv6_create(pkt, src, dst);
}
#endif /* CONFIG_NET_IPV6 */

int net_context_connect(struct net_context *context,
			const struct sockaddr *addr,
			socklen_t addrlen,
			net_context_connect_cb_t cb,
			k_timeout_t timeout,
			void *user_data)
{
	struct sockaddr *laddr = NULL;
	struct sockaddr local_addr __unused;
	uint16_t lport, rport;
	int ret;

	NET_ASSERT(addr);
	NET_ASSERT(PART_OF_ARRAY(contexts, context));

	k_mutex_lock(&context->lock, K_FOREVER);

	if (!net_context_is_used(context)) {
		ret = -EBADF;
		goto unlock;
	}

	if (addr->sa_family != net_context_get_family(context)) {
		NET_ASSERT(addr->sa_family == net_context_get_family(context),
			   "Family mismatch %d should be %d",
			   addr->sa_family,
			   net_context_get_family(context));
		ret = -EINVAL;
		goto unlock;
	}

	if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
	    addr->sa_family == AF_PACKET) {
		ret = -EOPNOTSUPP;
		goto unlock;
	}

	if (net_context_get_state(context) == NET_CONTEXT_LISTENING) {
		ret = -EOPNOTSUPP;
		goto unlock;
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_context_get_family(context) == AF_INET6) {
		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)
							&context->remote;

		if (addrlen < sizeof(struct sockaddr_in6)) {
			ret = -EINVAL;
			goto unlock;
		}

		if (net_context_get_ip_proto(context) == IPPROTO_TCP &&
		    net_ipv6_is_addr_mcast(&addr6->sin6_addr)) {
			ret = -EADDRNOTAVAIL;
			goto unlock;
		}

		memcpy(&addr6->sin6_addr, &net_sin6(addr)->sin6_addr,
		       sizeof(struct in6_addr));

		addr6->sin6_port = net_sin6(addr)->sin6_port;
		addr6->sin6_family = AF_INET6;

		if (!net_ipv6_is_addr_unspecified(&addr6->sin6_addr)) {
			context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;
		} else {
			context->flags &= ~NET_CONTEXT_REMOTE_ADDR_SET;
		}

		rport = addr6->sin6_port;

		/* The binding must be done after we have set the remote
		 * address but before checking the local address. Otherwise
		 * the laddr might not be set properly which would then cause
		 * issues when doing net_tcp_connect(). This issue was seen
		 * with socket tests and when connecting to loopback interface.
		 */
		ret = bind_default(context);
		if (ret) {
			goto unlock;
		}

		net_sin6_ptr(&context->local)->sin6_family = AF_INET6;
		net_sin6(&local_addr)->sin6_family = AF_INET6;
		net_sin6(&local_addr)->sin6_port = lport =
			net_sin6((struct sockaddr *)&context->local)->sin6_port;

		if (net_sin6_ptr(&context->local)->sin6_addr) {
			net_ipaddr_copy(&net_sin6(&local_addr)->sin6_addr,
				     net_sin6_ptr(&context->local)->sin6_addr);

			laddr = &local_addr;
		}
	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
		   net_context_get_family(context) == AF_INET) {
		struct sockaddr_in *addr4 = (struct sockaddr_in *)
							&context->remote;

		if (addrlen < sizeof(struct sockaddr_in)) {
			ret = -EINVAL;
			goto unlock;
		}

		/* FIXME - Add multicast and broadcast address check */

		memcpy(&addr4->sin_addr, &net_sin(addr)->sin_addr,
		       sizeof(struct in_addr));

		addr4->sin_port = net_sin(addr)->sin_port;
		addr4->sin_family = AF_INET;

		if (addr4->sin_addr.s_addr) {
			context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;
		} else {
			context->flags &= ~NET_CONTEXT_REMOTE_ADDR_SET;
		}

		rport = addr4->sin_port;

		ret = bind_default(context);
		if (ret) {
			goto unlock;
		}

		net_sin_ptr(&context->local)->sin_family = AF_INET;
		net_sin(&local_addr)->sin_family = AF_INET;
		net_sin(&local_addr)->sin_port = lport =
			net_sin((struct sockaddr *)&context->local)->sin_port;

		if (net_sin_ptr(&context->local)->sin_addr) {
			net_ipaddr_copy(&net_sin(&local_addr)->sin_addr,
				       net_sin_ptr(&context->local)->sin_addr);

			laddr = &local_addr;
		}
	} else {
		ret = -EINVAL; /* Not IPv4 or IPv6 */
		goto unlock;
	}

	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
		ret = net_offload_connect(
			net_context_get_iface(context),
			context,
			addr,
			addrlen,
			cb,
			timeout,
			user_data);
		goto unlock;
	}

	if (IS_ENABLED(CONFIG_NET_UDP) &&
	    net_context_get_type(context) == SOCK_DGRAM) {
		if (cb) {
			cb(context, 0, user_data);
		}

		ret = 0;
	} else if (IS_ENABLED(CONFIG_NET_TCP) &&
		   net_context_get_type(context) == SOCK_STREAM) {
		ret = net_tcp_connect(context, addr, laddr, rport, lport,
				      timeout, cb, user_data);
	} else {
		ret = -ENOTSUP;
	}

unlock:
	k_mutex_unlock(&context->lock);

	return ret;
}

int net_context_accept(struct net_context *context,
		       net_tcp_accept_cb_t cb,
		       k_timeout_t timeout,
		       void *user_data)
{
	int ret = 0;

	NET_ASSERT(PART_OF_ARRAY(contexts, context));

	if (!net_context_is_used(context)) {
		return -EBADF;
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
		ret = net_offload_accept(
			net_context_get_iface(context),
			context,
			cb,
			timeout,
			user_data);
		goto unlock;
	}

	if ((net_context_get_state(context) != NET_CONTEXT_LISTENING) &&
	    (net_context_get_type(context) != SOCK_STREAM)) {
		NET_DBG("Invalid socket, state %d type %d",
			net_context_get_state(context),
			net_context_get_type(context));
		ret = -EINVAL;
		goto unlock;
	}

	if (net_context_get_ip_proto(context) == IPPROTO_TCP) {
		ret = net_tcp_accept(context, cb, user_data);
		goto unlock;
	}

unlock:
	k_mutex_unlock(&context->lock);

	return ret;
}


static int get_context_priority(struct net_context *context,
				void *value, size_t *len)
{
#if defined(CONFIG_NET_CONTEXT_PRIORITY)
	*((uint8_t *)value) = context->options.priority;

	if (len) {
		*len = sizeof(uint8_t);
	}

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int get_context_proxy(struct net_context *context,
			     void *value, size_t *len)
{
#if defined(CONFIG_SOCKS)
	struct sockaddr *addr = (struct sockaddr *)value;

	if (!value || !len) {
		return -EINVAL;
	}

	if (*len < context->options.proxy.addrlen) {
		return -EINVAL;
	}

	*len = MIN(context->options.proxy.addrlen, *len);

	memcpy(addr, &context->options.proxy.addr, *len);

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int get_context_txtime(struct net_context *context,
			      void *value, size_t *len)
{
#if defined(CONFIG_NET_CONTEXT_TXTIME)
	*((bool *)value) = context->options.txtime;

	if (len) {
		*len = sizeof(bool);
	}

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int get_context_rcvtimeo(struct net_context *context,
				void *value, size_t *len)
{
#if defined(CONFIG_NET_CONTEXT_RCVTIMEO)
	*((k_timeout_t *)value) = context->options.rcvtimeo;

	if (len) {
		*len = sizeof(k_timeout_t);
	}

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int get_context_sndtimeo(struct net_context *context,
				void *value, size_t *len)
{
#if defined(CONFIG_NET_CONTEXT_SNDTIMEO)
	*((k_timeout_t *)value) = context->options.sndtimeo;

	if (len) {
		*len = sizeof(k_timeout_t);
	}

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int get_context_rcvbuf(struct net_context *context,
			      void *value, size_t *len)
{
#if defined(CONFIG_NET_CONTEXT_RCVBUF)
	*((int *)value) = context->options.rcvbuf;

	if (len) {
		*len = sizeof(int);
	}
	return 0;
#else
	return -ENOTSUP;
#endif
}

static int get_context_sndbuf(struct net_context *context,
				void *value, size_t *len)
{
#if defined(CONFIG_NET_CONTEXT_SNDBUF)
	*((int *)value) = context->options.sndbuf;

	if (len) {
		*len = sizeof(int);
	}
	return 0;
#else
	return -ENOTSUP;
#endif
}

/* If buf is not NULL, then use it. Otherwise read the data to be written
 * to net_pkt from msghdr.
 */
static int context_write_data(struct net_pkt *pkt, const void *buf,
			      int buf_len, const struct msghdr *msghdr)
{
	int ret = 0;

	if (msghdr) {
		int i;

		for (i = 0; i < msghdr->msg_iovlen; i++) {
			int len = MIN(msghdr->msg_iov[i].iov_len, buf_len);

			ret = net_pkt_write(pkt, msghdr->msg_iov[i].iov_base,
					    len);
			if (ret < 0) {
				break;
			}

			buf_len -= len;
			if (buf_len == 0) {
				break;
			}
		}
	} else {
		ret = net_pkt_write(pkt, buf, buf_len);
	}

	return ret;
}

static int context_setup_udp_packet(struct net_context *context,
				    struct net_pkt *pkt,
				    const void *buf,
				    size_t len,
				    const struct msghdr *msg,
				    const struct sockaddr *dst_addr,
				    socklen_t addrlen)
{
	int ret = -EINVAL;
	uint16_t dst_port = 0U;

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_context_get_family(context) == AF_INET6) {
		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)dst_addr;

		dst_port = addr6->sin6_port;

		ret = net_context_create_ipv6_new(context, pkt,
						  NULL, &addr6->sin6_addr);
	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
		   net_context_get_family(context) == AF_INET) {
		struct sockaddr_in *addr4 = (struct sockaddr_in *)dst_addr;

		dst_port = addr4->sin_port;

		ret = net_context_create_ipv4_new(context, pkt,
						  NULL, &addr4->sin_addr);
	}

	if (ret < 0) {
		return ret;
	}

	ret = bind_default(context);
	if (ret) {
		return ret;
	}

	ret = net_udp_create(pkt,
			     net_sin((struct sockaddr *)
				     &context->local)->sin_port,
			     dst_port);
	if (ret) {
		return ret;
	}

	ret = context_write_data(pkt, buf, len, msg);
	if (ret) {
		return ret;
	}

	return 0;
}

static void context_finalize_packet(struct net_context *context,
				    struct net_pkt *pkt)
{
	/* This function is meant to be temporary: once all moved to new
	 * API, it will be up to net_send_data() to finalize the packet.
	 */

	net_pkt_cursor_init(pkt);

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_context_get_family(context) == AF_INET6) {
		net_ipv6_finalize(pkt, net_context_get_ip_proto(context));
	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
		   net_context_get_family(context) == AF_INET) {
		net_ipv4_finalize(pkt, net_context_get_ip_proto(context));
	}
}

static struct net_pkt *context_alloc_pkt(struct net_context *context,
					 size_t len, k_timeout_t timeout)
{
	struct net_pkt *pkt;

#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL)
	if (context->tx_slab) {
		pkt = net_pkt_alloc_from_slab(context->tx_slab(), timeout);
		if (!pkt) {
			return NULL;
		}

		net_pkt_set_iface(pkt, net_context_get_iface(context));
		net_pkt_set_family(pkt, net_context_get_family(context));
		net_pkt_set_context(pkt, context);

		if (net_pkt_alloc_buffer(pkt, len,
					 net_context_get_ip_proto(context),
					 timeout)) {
			net_pkt_unref(pkt);
			return NULL;
		}

		return pkt;
	}
#endif
	pkt = net_pkt_alloc_with_buffer(net_context_get_iface(context), len,
					net_context_get_family(context),
					net_context_get_ip_proto(context),
					timeout);
	if (pkt) {
		net_pkt_set_context(pkt, context);
	}

	return pkt;
}

static void set_pkt_txtime(struct net_pkt *pkt, const struct msghdr *msghdr)
{
	struct cmsghdr *cmsg;

	for (cmsg = CMSG_FIRSTHDR(msghdr); cmsg != NULL;
	     cmsg = CMSG_NXTHDR(msghdr, cmsg)) {
		if (cmsg->cmsg_len == CMSG_LEN(sizeof(uint64_t)) &&
		    cmsg->cmsg_level == SOL_SOCKET &&
		    cmsg->cmsg_type == SCM_TXTIME) {
			uint64_t txtime = *(uint64_t *)CMSG_DATA(cmsg);

			net_pkt_set_txtime(pkt, txtime);
			break;
		}
	}
}

static int context_sendto(struct net_context *context,
			  const void *buf,
			  size_t len,
			  const struct sockaddr *dst_addr,
			  socklen_t addrlen,
			  net_context_send_cb_t cb,
			  k_timeout_t timeout,
			  void *user_data,
			  bool sendto)
{
	const struct msghdr *msghdr = NULL;
	struct net_if *iface;
	struct net_pkt *pkt;
	size_t tmp_len;
	int ret;

	NET_ASSERT(PART_OF_ARRAY(contexts, context));

	if (!net_context_is_used(context)) {
		return -EBADF;
	}

	if (sendto && addrlen == 0 && dst_addr == NULL && buf != NULL) {
		/* User wants to call sendmsg */
		msghdr = buf;
	}

	if (!msghdr && !dst_addr) {
		return -EDESTADDRREQ;
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_context_get_family(context) == AF_INET6) {
		const struct sockaddr_in6 *addr6 =
			(const struct sockaddr_in6 *)dst_addr;

		if (msghdr) {
			addr6 = msghdr->msg_name;
			addrlen = msghdr->msg_namelen;

			if (!addr6) {
				addr6 = net_sin6(&context->remote);
				addrlen = sizeof(struct sockaddr_in6);
			}

			/* For sendmsg(), the dst_addr is NULL so set it here.
			 */
			dst_addr = (const struct sockaddr *)addr6;
		}

		if (addrlen < sizeof(struct sockaddr_in6)) {
			return -EINVAL;
		}

		if (net_ipv6_is_addr_unspecified(&addr6->sin6_addr)) {
			return -EDESTADDRREQ;
		}

		/* If application has not yet set the destination address
		 * i.e., by not calling connect(), then set the interface
		 * here so that the packet gets sent to the correct network
		 * interface. This issue can be seen if there are multiple
		 * network interfaces and we are trying to send data to
		 * second or later network interface.
		 */
		if (net_ipv6_is_addr_unspecified(
				&net_sin6(&context->remote)->sin6_addr) &&
		    !net_context_is_bound_to_iface(context)) {
			iface = net_if_ipv6_select_src_iface(&addr6->sin6_addr);
			net_context_set_iface(context, iface);
		}

	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
		   net_context_get_family(context) == AF_INET) {
		const struct sockaddr_in *addr4 =
			(const struct sockaddr_in *)dst_addr;

		if (msghdr) {
			addr4 = msghdr->msg_name;
			addrlen = msghdr->msg_namelen;

			if (!addr4) {
				addr4 = net_sin(&context->remote);
				addrlen = sizeof(struct sockaddr_in);
			}

			/* For sendmsg(), the dst_addr is NULL so set it here.
			 */
			dst_addr = (const struct sockaddr *)addr4;
		}

		if (addrlen < sizeof(struct sockaddr_in)) {
			return -EINVAL;
		}

		if (!addr4->sin_addr.s_addr) {
			return -EDESTADDRREQ;
		}

		/* If application has not yet set the destination address
		 * i.e., by not calling connect(), then set the interface
		 * here so that the packet gets sent to the correct network
		 * interface. This issue can be seen if there are multiple
		 * network interfaces and we are trying to send data to
		 * second or later network interface.
		 */
		if (net_sin(&context->remote)->sin_addr.s_addr == 0U &&
		    !net_context_is_bound_to_iface(context)) {
			iface = net_if_ipv4_select_src_iface(&addr4->sin_addr);
			net_context_set_iface(context, iface);
		}

	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
		   net_context_get_family(context) == AF_PACKET) {
		struct sockaddr_ll *ll_addr = (struct sockaddr_ll *)dst_addr;

		if (msghdr) {
			ll_addr = msghdr->msg_name;
			addrlen = msghdr->msg_namelen;

			if (!ll_addr) {
				ll_addr = (struct sockaddr_ll *)
							(&context->remote);
				addrlen = sizeof(struct sockaddr_ll);
			}

			/* For sendmsg(), the dst_addr is NULL so set it here.
			 */
			dst_addr = (const struct sockaddr *)ll_addr;
		}

		if (addrlen < sizeof(struct sockaddr_ll)) {
			return -EINVAL;
		}

		iface = net_context_get_iface(context);
		if (iface == NULL) {
			if (ll_addr->sll_ifindex < 0) {
				return -EDESTADDRREQ;
			}

			iface = net_if_get_by_index(ll_addr->sll_ifindex);
			if (iface == NULL) {
				NET_ERR("Cannot bind to interface index %d",
					ll_addr->sll_ifindex);
				return -EDESTADDRREQ;
			}
		}

		if (net_context_get_type(context) == SOCK_DGRAM) {
			context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;

			/* The user must set the protocol in send call */

			/* For sendmsg() call, we might have set ll_addr to
			 * point to remote addr.
			 */
			if ((void *)&context->remote != (void *)ll_addr) {
				memcpy((struct sockaddr_ll *)&context->remote,
				       ll_addr, sizeof(struct sockaddr_ll));
			}
		}

	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
		   net_context_get_family(context) == AF_CAN) {
		struct sockaddr_can *can_addr = (struct sockaddr_can *)dst_addr;

		if (msghdr) {
			can_addr = msghdr->msg_name;
			addrlen = msghdr->msg_namelen;

			if (!can_addr) {
				can_addr = (struct sockaddr_can *)
							(&context->remote);
				addrlen = sizeof(struct sockaddr_can);
			}

			/* For sendmsg(), the dst_addr is NULL so set it here.
			 */
			dst_addr = (const struct sockaddr *)can_addr;
		}

		if (addrlen < sizeof(struct sockaddr_can)) {
			return -EINVAL;
		}

		if (can_addr->can_ifindex < 0) {
			/* The index should have been set in bind */
			can_addr->can_ifindex =
				net_can_ptr(&context->local)->can_ifindex;
		}

		if (can_addr->can_ifindex < 0) {
			return -EDESTADDRREQ;
		}

		iface = net_if_get_by_index(can_addr->can_ifindex);
		if (!iface) {
			NET_ERR("Cannot bind to interface index %d",
				can_addr->can_ifindex);
			return -EDESTADDRREQ;
		}
	} else {
		NET_DBG("Invalid protocol family %d",
			net_context_get_family(context));
		return -EINVAL;
	}

	if (msghdr && len == 0) {
		int i;

		for (i = 0; i < msghdr->msg_iovlen; i++) {
			len += msghdr->msg_iov[i].iov_len;
		}
	}

	iface = net_context_get_iface(context);
	if (iface && !net_if_is_up(iface)) {
		return -ENETDOWN;
	}

	pkt = context_alloc_pkt(context, len, PKT_WAIT_TIME);
	if (!pkt) {
		NET_ERR("Failed to allocate net_pkt");
		return -ENOBUFS;
	}

	tmp_len = net_pkt_available_payload_buffer(
				pkt, net_context_get_ip_proto(context));
	if (tmp_len < len) {
		if (net_context_get_type(context) == SOCK_DGRAM) {
			NET_ERR("Available payload buffer (%zu) is not enough for requested DGRAM (%zu)",
				tmp_len, len);
			return -ENOMEM;
		}
		len = tmp_len;
	}

	context->send_cb = cb;
	context->user_data = user_data;

	if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) {
		uint8_t priority;

		get_context_priority(context, &priority, NULL);
		net_pkt_set_priority(pkt, priority);
	}

	/* If there is ancillary data in msghdr, then we need to add that
	 * to net_pkt as there is no other way to store it.
	 */
	if (msghdr && msghdr->msg_control && msghdr->msg_controllen) {
		if (IS_ENABLED(CONFIG_NET_CONTEXT_TXTIME)) {
			bool is_txtime;

			get_context_txtime(context, &is_txtime, NULL);
			if (is_txtime) {
				set_pkt_txtime(pkt, msghdr);
			}
		}
	}

	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
		ret = context_write_data(pkt, buf, len, msghdr);
		if (ret < 0) {
			goto fail;
		}

		net_pkt_cursor_init(pkt);

		if (sendto) {
			ret = net_offload_sendto(net_context_get_iface(context),
						 pkt, dst_addr, addrlen, cb,
						 timeout, user_data);
		} else {
			ret = net_offload_send(net_context_get_iface(context),
					       pkt, cb, timeout, user_data);
		}
	} else if (IS_ENABLED(CONFIG_NET_UDP) &&
	    net_context_get_ip_proto(context) == IPPROTO_UDP) {
		ret = context_setup_udp_packet(context, pkt, buf, len, msghdr,
					       dst_addr, addrlen);
		if (ret < 0) {
			goto fail;
		}

		context_finalize_packet(context, pkt);

		ret = net_send_data(pkt);
	} else if (IS_ENABLED(CONFIG_NET_TCP) &&
		   net_context_get_ip_proto(context) == IPPROTO_TCP) {

		ret = context_write_data(pkt, buf, len, msghdr);
		if (ret < 0) {
			goto fail;
		}

		net_pkt_cursor_init(pkt);
		ret = net_tcp_queue_data(context, pkt);
		if (ret < 0) {
			goto fail;
		}

		ret = net_tcp_send_data(context, cb, user_data);
	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
		   net_context_get_family(context) == AF_PACKET) {
		ret = context_write_data(pkt, buf, len, msghdr);
		if (ret < 0) {
			goto fail;
		}

		net_pkt_cursor_init(pkt);

		if (net_context_get_ip_proto(context) == IPPROTO_RAW) {
			/* Pass to L2: */
			ret = net_send_data(pkt);
		} else {
			net_if_queue_tx(net_pkt_iface(pkt), pkt);
		}
	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
		   net_context_get_family(context) == AF_CAN &&
		   net_context_get_ip_proto(context) == CAN_RAW) {
		ret = context_write_data(pkt, buf, len, msghdr);
		if (ret < 0) {
			goto fail;
		}

		net_pkt_cursor_init(pkt);

		ret = net_send_data(pkt);
	} else {
		NET_DBG("Unknown protocol while sending packet: %d",
		net_context_get_ip_proto(context));
		ret = -EPROTONOSUPPORT;
	}

	if (ret < 0) {
		goto fail;
	}

	return len;
fail:
	net_pkt_unref(pkt);

	return ret;
}

int net_context_send(struct net_context *context,
		     const void *buf,
		     size_t len,
		     net_context_send_cb_t cb,
		     k_timeout_t timeout,
		     void *user_data)
{
	socklen_t addrlen;
	int ret = 0;

	k_mutex_lock(&context->lock, K_FOREVER);

	if (!(context->flags & NET_CONTEXT_REMOTE_ADDR_SET) ||
	    !net_sin(&context->remote)->sin_port) {
		ret = -EDESTADDRREQ;
		goto unlock;
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_context_get_family(context) == AF_INET6) {
		addrlen = sizeof(struct sockaddr_in6);
	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
		   net_context_get_family(context) == AF_INET) {
		addrlen = sizeof(struct sockaddr_in);
	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
		   net_context_get_family(context) == AF_PACKET) {
		ret = -EOPNOTSUPP;
		goto unlock;
	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
		   net_context_get_family(context) == AF_CAN) {
		addrlen = sizeof(struct sockaddr_can);
	} else {
		addrlen = 0;
	}

	ret = context_sendto(context, buf, len, &context->remote,
			     addrlen, cb, timeout, user_data, false);
unlock:
	k_mutex_unlock(&context->lock);

	return ret;
}

int net_context_sendmsg(struct net_context *context,
			const struct msghdr *msghdr,
			int flags,
			net_context_send_cb_t cb,
			k_timeout_t timeout,
			void *user_data)
{
	int ret;

	k_mutex_lock(&context->lock, K_FOREVER);

	ret = context_sendto(context, msghdr, 0, NULL, 0,
			     cb, timeout, user_data, true);

	k_mutex_unlock(&context->lock);

	return ret;
}

int net_context_sendto(struct net_context *context,
		       const void *buf,
		       size_t len,
		       const struct sockaddr *dst_addr,
		       socklen_t addrlen,
		       net_context_send_cb_t cb,
		       k_timeout_t timeout,
		       void *user_data)
{
	int ret;

	k_mutex_lock(&context->lock, K_FOREVER);

	ret = context_sendto(context, buf, len, dst_addr, addrlen,
			     cb, timeout, user_data, true);

	k_mutex_unlock(&context->lock);

	return ret;
}

enum net_verdict net_context_packet_received(struct net_conn *conn,
					     struct net_pkt *pkt,
					     union net_ip_header *ip_hdr,
					     union net_proto_header *proto_hdr,
					     void *user_data)
{
	struct net_context *context = find_context(conn);
	enum net_verdict verdict = NET_DROP;

	NET_ASSERT(context);
	NET_ASSERT(net_pkt_iface(pkt));

	k_mutex_lock(&context->lock, K_FOREVER);

	net_context_set_iface(context, net_pkt_iface(pkt));
	net_pkt_set_context(pkt, context);

	/* If there is no callback registered, then we can only drop
	 * the packet.
	 */
	if (!context->recv_cb) {
		goto unlock;
	}

	if (net_context_get_ip_proto(context) == IPPROTO_TCP) {
		net_stats_update_tcp_recv(net_pkt_iface(pkt),
					  net_pkt_remaining_data(pkt));
	}

#if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
	k_sem_give(&context->recv_data_wait);
#endif /* CONFIG_NET_CONTEXT_SYNC_RECV */

	k_mutex_unlock(&context->lock);

	context->recv_cb(context, pkt, ip_hdr, proto_hdr, 0, user_data);

	verdict = NET_OK;

	return verdict;

unlock:
	k_mutex_unlock(&context->lock);

	return verdict;
}

#if defined(CONFIG_NET_UDP)
static int recv_udp(struct net_context *context,
		    net_context_recv_cb_t cb,
		    k_timeout_t timeout,
		    void *user_data)
{
	struct sockaddr local_addr = {
		.sa_family = net_context_get_family(context),
	};
	struct sockaddr *laddr = NULL;
	uint16_t lport = 0U;
	int ret;

	ARG_UNUSED(timeout);

	if (context->conn_handler) {
		net_conn_unregister(context->conn_handler);
		context->conn_handler = NULL;
	}

	ret = bind_default(context);
	if (ret) {
		return ret;
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_context_get_family(context) == AF_INET6) {
		if (net_sin6_ptr(&context->local)->sin6_addr) {
			net_ipaddr_copy(&net_sin6(&local_addr)->sin6_addr,
				     net_sin6_ptr(&context->local)->sin6_addr);

			laddr = &local_addr;
		}

		net_sin6(&local_addr)->sin6_port =
			net_sin6((struct sockaddr *)&context->local)->sin6_port;
		lport = net_sin6((struct sockaddr *)&context->local)->sin6_port;
	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
		   net_context_get_family(context) == AF_INET) {
		if (net_sin_ptr(&context->local)->sin_addr) {
			net_ipaddr_copy(&net_sin(&local_addr)->sin_addr,
				      net_sin_ptr(&context->local)->sin_addr);

			laddr = &local_addr;
		}

		lport = net_sin((struct sockaddr *)&context->local)->sin_port;
	}

	context->recv_cb = cb;

	ret = net_conn_register(net_context_get_ip_proto(context),
				net_context_get_family(context),
				context->flags & NET_CONTEXT_REMOTE_ADDR_SET ?
							&context->remote : NULL,
				laddr,
				ntohs(net_sin(&context->remote)->sin_port),
				ntohs(lport),
				context,
				net_context_packet_received,
				user_data,
				&context->conn_handler);

	return ret;
}
#else
#define recv_udp(...) 0
#endif /* CONFIG_NET_UDP */

static enum net_verdict net_context_raw_packet_received(
					struct net_conn *conn,
					struct net_pkt *pkt,
					union net_ip_header *ip_hdr,
					union net_proto_header *proto_hdr,
					void *user_data)
{
	struct net_context *context = find_context(conn);

	NET_ASSERT(context);
	NET_ASSERT(net_pkt_iface(pkt));

	/* If there is no callback registered, then we can only drop
	 * the packet.
	 */

	if (!context->recv_cb) {
		return NET_DROP;
	}

	net_context_set_iface(context, net_pkt_iface(pkt));
	net_pkt_set_context(pkt, context);

	context->recv_cb(context, pkt, ip_hdr, proto_hdr, 0, user_data);

#if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
	k_sem_give(&context->recv_data_wait);
#endif /* CONFIG_NET_CONTEXT_SYNC_RECV */

	return NET_OK;
}

static int recv_raw(struct net_context *context,
		    net_context_recv_cb_t cb,
		    k_timeout_t timeout,
		    struct sockaddr *local_addr,
		    void *user_data)
{
	int ret;

	ARG_UNUSED(timeout);

	context->recv_cb = cb;

	if (context->conn_handler) {
		net_conn_unregister(context->conn_handler);
		context->conn_handler = NULL;
	}

	ret = bind_default(context);
	if (ret) {
		return ret;
	}

	ret = net_conn_register(net_context_get_ip_proto(context),
				net_context_get_family(context),
				NULL, local_addr, 0, 0,
				context,
				net_context_raw_packet_received,
				user_data,
				&context->conn_handler);

	return ret;
}

int net_context_recv(struct net_context *context,
		     net_context_recv_cb_t cb,
		     k_timeout_t timeout,
		     void *user_data)
{
	int ret;
	NET_ASSERT(context);

	if (!net_context_is_used(context)) {
		return -EBADF;
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
		ret = net_offload_recv(
			net_context_get_iface(context),
			context, cb, timeout, user_data);
		goto unlock;
	}

	if (IS_ENABLED(CONFIG_NET_UDP) &&
	    net_context_get_ip_proto(context) == IPPROTO_UDP) {
		ret = recv_udp(context, cb, timeout, user_data);
	} else if (IS_ENABLED(CONFIG_NET_TCP) &&
		   net_context_get_ip_proto(context) == IPPROTO_TCP) {
		ret = net_tcp_recv(context, cb, user_data);
	} else {
		if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
		    net_context_get_family(context) == AF_PACKET) {
			struct sockaddr_ll addr;

			addr.sll_family = AF_PACKET;
			addr.sll_ifindex =
				net_sll_ptr(&context->local)->sll_ifindex;
			addr.sll_protocol =
				net_sll_ptr(&context->local)->sll_protocol;
			addr.sll_halen =
				net_sll_ptr(&context->local)->sll_halen;

			memcpy(addr.sll_addr,
			       net_sll_ptr(&context->local)->sll_addr,
			       MIN(addr.sll_halen, sizeof(addr.sll_addr)));

			ret = recv_raw(context, cb, timeout,
				       (struct sockaddr *)&addr, user_data);
		} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
			   net_context_get_family(context) == AF_CAN) {
			struct sockaddr_can local_addr = {
				.can_family = AF_CAN,
			};

			ret = recv_raw(context, cb, timeout,
				       (struct sockaddr *)&local_addr,
				       user_data);
			if (ret == -EALREADY) {
				/* This is perfectly normal for CAN sockets.
				 * The SocketCAN will dispatch the packet to
				 * correct net_context listener.
				 */
				ret = 0;
			}
		} else {
			ret = -EPROTOTYPE;
		}
	}

	if (ret < 0) {
		goto unlock;
	}

#if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
	if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
		int ret;

		/* Make sure we have the lock, then the
		 * net_context_packet_received() callback will release the
		 * semaphore when data has been received.
		 */
		k_sem_reset(&context->recv_data_wait);

		k_mutex_unlock(&context->lock);

		ret = k_sem_take(&context->recv_data_wait, timeout);

		k_mutex_lock(&context->lock, K_FOREVER);

		if (ret == -EAGAIN) {
			ret = -ETIMEDOUT;
			goto unlock;
		}
	}
#endif /* CONFIG_NET_CONTEXT_SYNC_RECV */

unlock:
	k_mutex_unlock(&context->lock);

	return ret;
}

int net_context_update_recv_wnd(struct net_context *context,
				int32_t delta)
{
	int ret;

	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
		net_if_is_ip_offloaded(net_context_get_iface(context))) {
		return 0;
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	ret = net_tcp_update_recv_wnd(context, delta);

	k_mutex_unlock(&context->lock);

	return ret;
}

static int set_context_priority(struct net_context *context,
				const void *value, size_t len)
{
#if defined(CONFIG_NET_CONTEXT_PRIORITY)
	if (len > sizeof(uint8_t)) {
		return -EINVAL;
	}

	context->options.priority = *((uint8_t *)value);

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int set_context_txtime(struct net_context *context,
			      const void *value, size_t len)
{
#if defined(CONFIG_NET_CONTEXT_TXTIME)
	if (len > sizeof(bool)) {
		return -EINVAL;
	}

	context->options.txtime = *((bool *)value);

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int set_context_proxy(struct net_context *context,
			     const void *value, size_t len)
{
#if defined(CONFIG_SOCKS)
	struct sockaddr *addr = (struct sockaddr *)value;

	if (len > NET_SOCKADDR_MAX_SIZE) {
		return -EINVAL;
	}

	if (addr->sa_family != net_context_get_family(context)) {
		return -EINVAL;
	}

	context->options.proxy.addrlen = len;
	memcpy(&context->options.proxy.addr, addr, len);

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int set_context_rcvtimeo(struct net_context *context,
				const void *value, size_t len)
{
#if defined(CONFIG_NET_CONTEXT_RCVTIMEO)
	if (len != sizeof(k_timeout_t)) {
		return -EINVAL;
	}

	context->options.rcvtimeo = *((k_timeout_t *)value);

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int set_context_sndtimeo(struct net_context *context,
				const void *value, size_t len)
{
#if defined(CONFIG_NET_CONTEXT_SNDTIMEO)
	if (len != sizeof(k_timeout_t)) {
		return -EINVAL;
	}

	context->options.sndtimeo = *((k_timeout_t *)value);

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int set_context_rcvbuf(struct net_context *context,
				const void *value, size_t len)
{
#if defined(CONFIG_NET_CONTEXT_RCVBUF)
	int rcvbuf_value = *((int *)value);

	if (len != sizeof(int)) {
		return -EINVAL;
	}

	if ((rcvbuf_value < 0) || (rcvbuf_value > UINT16_MAX)) {
		return -EINVAL;
	}

	context->options.rcvbuf = (uint16_t) rcvbuf_value;

	return 0;
#else
	return -ENOTSUP;
#endif
}

static int set_context_sndbuf(struct net_context *context,
				const void *value, size_t len)
{
#if defined(CONFIG_NET_CONTEXT_SNDBUF)
	int sndbuf_value = *((int *)value);

	if (len != sizeof(int)) {
		return -EINVAL;
	}

	if ((sndbuf_value < 0) || (sndbuf_value > UINT16_MAX)) {
		return -EINVAL;
	}

	context->options.sndbuf = (uint16_t) sndbuf_value;
	return 0;
#else
	return -ENOTSUP;
#endif
}

int net_context_set_option(struct net_context *context,
			   enum net_context_option option,
			   const void *value, size_t len)
{
	int ret = 0;

	NET_ASSERT(context);

	if (!PART_OF_ARRAY(contexts, context)) {
		return -EINVAL;
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	switch (option) {
	case NET_OPT_PRIORITY:
		ret = set_context_priority(context, value, len);
		break;
	case NET_OPT_TXTIME:
		ret = set_context_txtime(context, value, len);
		break;
	case NET_OPT_SOCKS5:
		ret = set_context_proxy(context, value, len);
		break;
	case NET_OPT_RCVTIMEO:
		ret = set_context_rcvtimeo(context, value, len);
		break;
	case NET_OPT_SNDTIMEO:
		ret = set_context_sndtimeo(context, value, len);
		break;
	case NET_OPT_RCVBUF:
		ret = set_context_rcvbuf(context, value, len);
		break;
	case NET_OPT_SNDBUF:
		ret = set_context_sndbuf(context, value, len);
		break;
	}

	k_mutex_unlock(&context->lock);

	return ret;
}

int net_context_get_option(struct net_context *context,
			    enum net_context_option option,
			    void *value, size_t *len)
{
	int ret = 0;

	NET_ASSERT(context);

	if (!PART_OF_ARRAY(contexts, context)) {
		return -EINVAL;
	}

	k_mutex_lock(&context->lock, K_FOREVER);

	switch (option) {
	case NET_OPT_PRIORITY:
		ret = get_context_priority(context, value, len);
		break;
	case NET_OPT_TXTIME:
		ret = get_context_txtime(context, value, len);
		break;
	case NET_OPT_SOCKS5:
		ret = get_context_proxy(context, value, len);
		break;
	case NET_OPT_RCVTIMEO:
		ret = get_context_rcvtimeo(context, value, len);
		break;
	case NET_OPT_SNDTIMEO:
		ret = get_context_sndtimeo(context, value, len);
		break;
	case NET_OPT_RCVBUF:
		ret = get_context_rcvbuf(context, value, len);
		break;
	case NET_OPT_SNDBUF:
		ret = get_context_sndbuf(context, value, len);
		break;
	}

	k_mutex_unlock(&context->lock);

	return ret;
}

void net_context_foreach(net_context_cb_t cb, void *user_data)
{
	int i;

	k_sem_take(&contexts_lock, K_FOREVER);

	for (i = 0; i < NET_MAX_CONTEXT; i++) {
		if (!net_context_is_used(&contexts[i])) {
			continue;
		}

		k_mutex_lock(&contexts[i].lock, K_FOREVER);

		cb(&contexts[i], user_data);

		k_mutex_unlock(&contexts[i].lock);
	}

	k_sem_give(&contexts_lock);
}

const char *net_context_state(struct net_context *context)
{
	switch (net_context_get_state(context)) {
	case NET_CONTEXT_IDLE:
		return "IDLE";
	case NET_CONTEXT_CONNECTING:
		return "CONNECTING";
	case NET_CONTEXT_CONNECTED:
		return "CONNECTED";
	case NET_CONTEXT_LISTENING:
		return "LISTENING";
	}

	return NULL;
}

void net_context_init(void)
{
	k_sem_init(&contexts_lock, 1, K_SEM_MAX_LIMIT);
}
