/** @file * @brief Network context definitions * * 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 */ #ifndef ZEPHYR_INCLUDE_NET_NET_CONTEXT_H_ #define ZEPHYR_INCLUDE_NET_NET_CONTEXT_H_ /** * @brief Application network context * @defgroup net_context Application network context * @since 1.0 * @version 0.8.0 * @ingroup networking * @{ */ #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** Is this context used or not */ #define NET_CONTEXT_IN_USE BIT(0) /** @cond INTERNAL_HIDDEN */ /** State of the context (bits 1 & 2 in the flags) */ enum net_context_state { NET_CONTEXT_IDLE = 0, NET_CONTEXT_UNCONNECTED = 0, NET_CONTEXT_CONFIGURING = 1, NET_CONTEXT_CONNECTING = 1, NET_CONTEXT_READY = 2, NET_CONTEXT_CONNECTED = 2, NET_CONTEXT_LISTENING = 3, }; /** @endcond */ /** * The address family, connection type and IP protocol are * stored into a bit field to save space. */ /** Protocol family of this connection */ #define NET_CONTEXT_FAMILY (BIT(3) | BIT(4) | BIT(5)) /** Type of the connection (datagram / stream / raw) */ #define NET_CONTEXT_TYPE (BIT(6) | BIT(7)) /** Remote address set */ #define NET_CONTEXT_REMOTE_ADDR_SET BIT(8) /** Is the socket accepting connections */ #define NET_CONTEXT_ACCEPTING_SOCK BIT(9) /** Is the socket closing / closed */ #define NET_CONTEXT_CLOSING_SOCK BIT(10) /** Context is bound to a specific interface */ #define NET_CONTEXT_BOUND_TO_IFACE BIT(11) struct net_context; /** * @typedef net_context_recv_cb_t * @brief Network data receive callback. * * @details The recv callback is called after a network data packet is * received. This callback is called by RX thread so its stack and execution * context is used here. Keep processing in the callback minimal to reduce the * time spent blocked while handling packets. * * @param context The context to use. * @param pkt Network buffer that is received. If the pkt is not NULL, * then the callback will own the buffer and it needs to unref the pkt * as soon as it has finished working with it. On EOF, pkt will be NULL. * @param ip_hdr a pointer to relevant IP (v4 or v6) header. * @param proto_hdr a pointer to relevant protocol (udp or tcp) header. * @param status Value is set to 0 if some data or the connection is * at EOF, <0 if there was an error receiving data, in this case the * pkt parameter is set to NULL. * @param user_data The user data given in net_recv() call. */ typedef void (*net_context_recv_cb_t)(struct net_context *context, struct net_pkt *pkt, union net_ip_header *ip_hdr, union net_proto_header *proto_hdr, int status, void *user_data); /** * @typedef net_context_send_cb_t * @brief Network data send callback. * * @details The send callback is called after a network data packet is sent. * This callback is called by TX thread so its stack and execution context is * used here. Keep processing in the callback minimal to reduce the time spent * blocked while handling packets. * * @param context The context to use. * @param status Value is set to >= 0: amount of data that was sent, * < 0 there was an error sending data. * @param user_data The user data given in net_send() call. */ typedef void (*net_context_send_cb_t)(struct net_context *context, int status, void *user_data); /** * @typedef net_tcp_accept_cb_t * @brief Accept callback * * @details The accept callback is called after a successful connection was * established or if there was an error while we were waiting for a connection * attempt. This callback is called by RX thread so its stack and execution * context is used here. Keep processing in the callback minimal to reduce the * time spent blocked while handling packets. * * @param new_context The context to use. * @param addr The peer address. * @param addrlen Length of the peer address. * @param status The status code, 0 on success, < 0 otherwise * @param user_data The user data given in net_context_accept() call. */ typedef void (*net_tcp_accept_cb_t)(struct net_context *new_context, struct sockaddr *addr, socklen_t addrlen, int status, void *user_data); /** * @typedef net_context_connect_cb_t * @brief Connection callback. * * @details The connect callback is called after a connection is being * established. * For TCP connections, this callback is called by RX thread so its stack and * execution context is used here. The callback is called after the TCP * connection was established or if the connection failed. Keep processing in * the callback minimal to reduce the time spent blocked while handling * packets. * For UDP connections, this callback is called immediately by * net_context_connect() function. UDP is a connectionless protocol so the * connection can be thought of being established immediately. * * @param context The context to use. * @param status Status of the connection establishment. This is 0 * if the connection was established successfully, <0 if there was an * error. * @param user_data The user data given in net_context_connect() call. */ typedef void (*net_context_connect_cb_t)(struct net_context *context, int status, void *user_data); /* The net_pkt_get_slab_func_t is here in order to avoid circular * dependency between net_pkt.h and net_context.h */ /** * @typedef net_pkt_get_slab_func_t * * @brief Function that is called to get the slab that is used * for net_pkt allocations. * * @return Pointer to valid struct k_mem_slab instance. */ typedef struct k_mem_slab *(*net_pkt_get_slab_func_t)(void); /* The net_pkt_get_pool_func_t is here in order to avoid circular * dependency between net_pkt.h and net_context.h */ /** * @typedef net_pkt_get_pool_func_t * * @brief Function that is called to get the pool that is used * for net_buf allocations. * * @return Pointer to valid struct net_buf_pool instance. */ typedef struct net_buf_pool *(*net_pkt_get_pool_func_t)(void); struct net_tcp; struct net_conn_handle; /** * Note that we do not store the actual source IP address in the context * because the address is already set in the network interface struct. * If there is no such source address there, the packet cannot be sent * anyway. This saves 12 bytes / context in IPv6. */ __net_socket struct net_context { /** First member of the structure to allow to put contexts into a FIFO. */ void *fifo_reserved; /** User data associated with a context. */ void *user_data; /** Reference count */ atomic_t refcount; /** Internal lock for protecting this context from multiple access. */ struct k_mutex lock; /** Local endpoint address. Note that the values are in network byte * order. */ struct sockaddr_ptr local; /** Remote endpoint address. Note that the values are in network byte * order. */ struct sockaddr remote; /** Connection handle */ struct net_conn_handle *conn_handler; /** Receive callback to be called when desired packet * has been received. */ net_context_recv_cb_t recv_cb; /** Send callback to be called when the packet has been sent * successfully. */ net_context_send_cb_t send_cb; /** Connect callback to be called when a connection has been * established. */ net_context_connect_cb_t connect_cb; #if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) /** Get TX net_buf pool for this context. */ net_pkt_get_slab_func_t tx_slab; /** Get DATA net_buf pool for this context. */ net_pkt_get_pool_func_t data_pool; #endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */ #if defined(CONFIG_NET_TCP) /** TCP connection information */ void *tcp; #endif /* CONFIG_NET_TCP */ #if defined(CONFIG_NET_CONTEXT_SYNC_RECV) /** * Semaphore to signal synchronous recv call completion. */ struct k_sem recv_data_wait; #endif /* CONFIG_NET_CONTEXT_SYNC_RECV */ #if defined(CONFIG_NET_SOCKETS) /** BSD socket private data */ void *socket_data; /** Per-socket packet or connection queues */ union { struct k_fifo recv_q; struct k_fifo accept_q; }; struct { /** Condition variable used when receiving data */ struct k_condvar recv; /** Mutex used by condition variable */ struct k_mutex *lock; } cond; #endif /* CONFIG_NET_SOCKETS */ #if defined(CONFIG_NET_OFFLOAD) /** context for use by offload drivers */ void *offload_context; #endif /* CONFIG_NET_OFFLOAD */ #if defined(CONFIG_NET_SOCKETS_CAN) int can_filter_id; #endif /* CONFIG_NET_SOCKETS_CAN */ /** Option values */ struct { #if defined(CONFIG_NET_CONTEXT_PRIORITY) /** Priority of the network data sent via this net_context */ uint8_t priority; #endif #if defined(CONFIG_NET_CONTEXT_TXTIME) /** When to send the packet out */ bool txtime; #endif #if defined(CONFIG_SOCKS) /** Socks proxy address */ struct { struct sockaddr addr; socklen_t addrlen; } proxy; #endif #if defined(CONFIG_NET_CONTEXT_CLAMP_PORT_RANGE) /** Restrict local port range between these values. * The option takes an uint32_t value with the high 16 bits * set to the upper range bound, and the low 16 bits set to * the lower range bound. Range bounds are inclusive. The * 16-bit values should be in host byte order. * The lower bound has to be less than the upper bound when * both bounds are not zero. Otherwise, setting the option * fails with EINVAL. * If either bound is outside of the global local port range, * or is zero, then that bound has no effect. */ uint32_t port_range; #endif #if defined(CONFIG_NET_CONTEXT_RCVTIMEO) /** Receive timeout */ k_timeout_t rcvtimeo; #endif #if defined(CONFIG_NET_CONTEXT_SNDTIMEO) /** Send timeout */ k_timeout_t sndtimeo; #endif #if defined(CONFIG_NET_CONTEXT_RCVBUF) /** Receive buffer maximum size */ uint16_t rcvbuf; #endif #if defined(CONFIG_NET_CONTEXT_SNDBUF) /** Send buffer maximum size */ uint16_t sndbuf; #endif #if defined(CONFIG_NET_CONTEXT_DSCP_ECN) /** * DSCP (Differentiated Services Code point) and * ECN (Explicit Congestion Notification) values. */ uint8_t dscp_ecn; #endif #if defined(CONFIG_NET_CONTEXT_REUSEADDR) /** Re-use address (SO_REUSEADDR) flag on a socket. */ bool reuseaddr; #endif #if defined(CONFIG_NET_CONTEXT_REUSEPORT) /** Re-use port (SO_REUSEPORT) flag on a socket. */ bool reuseport; #endif #if defined(CONFIG_NET_IPV4_MAPPING_TO_IPV6) /** Support v4-mapped-on-v6 addresses */ bool ipv6_v6only; #endif #if defined(CONFIG_NET_CONTEXT_RECV_PKTINFO) /** Receive network packet information in recvmsg() call */ bool recv_pktinfo; #endif #if defined(CONFIG_NET_IPV6) /** * Source address selection preferences. Currently used only for IPv6, * see RFC 5014 for details. */ uint16_t addr_preferences; #endif #if defined(CONFIG_NET_IPV6) || defined(CONFIG_NET_IPV4) union { /** * IPv6 multicast output network interface for this context/socket. * Only allowed for SOCK_DGRAM or SOCK_RAW type sockets. */ uint8_t ipv6_mcast_ifindex; /** * IPv4 multicast output network interface for this context/socket. * Only allowed for SOCK_DGRAM type sockets. */ uint8_t ipv4_mcast_ifindex; }; #endif /* CONFIG_NET_IPV6 || CONFIG_NET_IPV4 */ #if defined(CONFIG_NET_CONTEXT_TIMESTAMPING) /** Enable RX, TX or both timestamps of packets send through sockets. */ uint8_t timestamping; #endif } options; /** Protocol (UDP, TCP or IEEE 802.3 protocol value) */ uint16_t proto; /** Flags for the context */ uint16_t flags; /** Network interface assigned to this context */ int8_t iface; /** IPv6 hop limit or IPv4 ttl for packets sent via this context. */ union { struct { uint8_t ipv6_hop_limit; /**< IPv6 hop limit */ uint8_t ipv6_mcast_hop_limit; /**< IPv6 multicast hop limit */ }; struct { uint8_t ipv4_ttl; /**< IPv4 TTL */ uint8_t ipv4_mcast_ttl; /**< IPv4 multicast TTL */ }; }; #if defined(CONFIG_SOCKS) /** Is socks proxy enabled */ bool proxy_enabled; #endif }; /** * @brief Is this context used or not. * * @param context Network context. * * @return True if the context is currently in use, False otherwise. */ static inline bool net_context_is_used(struct net_context *context) { NET_ASSERT(context); return context->flags & NET_CONTEXT_IN_USE; } /** * @brief Is this context bound to a network interface. * * @param context Network context. * * @return True if the context is bound to network interface, False otherwise. */ static inline bool net_context_is_bound_to_iface(struct net_context *context) { NET_ASSERT(context); return context->flags & NET_CONTEXT_BOUND_TO_IFACE; } /** * @brief Is this context is accepting data now. * * @param context Network context. * * @return True if the context is accepting connections, False otherwise. */ static inline bool net_context_is_accepting(struct net_context *context) { NET_ASSERT(context); return context->flags & NET_CONTEXT_ACCEPTING_SOCK; } /** * @brief Set this context to accept data now. * * @param context Network context. * @param accepting True if accepting, False if not */ static inline void net_context_set_accepting(struct net_context *context, bool accepting) { NET_ASSERT(context); if (accepting) { context->flags |= NET_CONTEXT_ACCEPTING_SOCK; } else { context->flags &= (uint16_t)~NET_CONTEXT_ACCEPTING_SOCK; } } /** * @brief Is this context closing. * * @param context Network context. * * @return True if the context is closing, False otherwise. */ static inline bool net_context_is_closing(struct net_context *context) { NET_ASSERT(context); return context->flags & NET_CONTEXT_CLOSING_SOCK; } /** * @brief Set this context to closing. * * @param context Network context. * @param closing True if closing, False if not */ static inline void net_context_set_closing(struct net_context *context, bool closing) { NET_ASSERT(context); if (closing) { context->flags |= NET_CONTEXT_CLOSING_SOCK; } else { context->flags &= (uint16_t)~NET_CONTEXT_CLOSING_SOCK; } } /** @cond INTERNAL_HIDDEN */ #define NET_CONTEXT_STATE_SHIFT 1 #define NET_CONTEXT_STATE_MASK 0x03 /** @endcond */ /** * @brief Get state for this network context. * * @details This function returns the state of the context. * * @param context Network context. * * @return Network state. */ static inline enum net_context_state net_context_get_state(struct net_context *context) { NET_ASSERT(context); return (enum net_context_state) ((context->flags >> NET_CONTEXT_STATE_SHIFT) & NET_CONTEXT_STATE_MASK); } /** * @brief Set state for this network context. * * @details This function sets the state of the context. * * @param context Network context. * @param state New network context state. */ static inline void net_context_set_state(struct net_context *context, enum net_context_state state) { NET_ASSERT(context); context->flags &= ~(NET_CONTEXT_STATE_MASK << NET_CONTEXT_STATE_SHIFT); context->flags |= ((state & NET_CONTEXT_STATE_MASK) << NET_CONTEXT_STATE_SHIFT); } /** * @brief Get address family for this network context. * * @details This function returns the address family (IPv4 or IPv6) * of the context. * * @param context Network context. * * @return Network state. */ static inline sa_family_t net_context_get_family(struct net_context *context) { NET_ASSERT(context); return ((context->flags & NET_CONTEXT_FAMILY) >> 3); } /** * @brief Set address family for this network context. * * @details This function sets the address family (IPv4, IPv6 or AF_PACKET) * of the context. * * @param context Network context. * @param family Address family (AF_INET, AF_INET6, AF_PACKET, AF_CAN) */ static inline void net_context_set_family(struct net_context *context, sa_family_t family) { uint8_t flag = 0U; NET_ASSERT(context); if (family == AF_UNSPEC || family == AF_INET || family == AF_INET6 || family == AF_PACKET || family == AF_CAN) { /* Family is in BIT(4), BIT(5) and BIT(6) */ flag = (uint8_t)(family << 3); } context->flags |= flag; } /** * @brief Get context type for this network context. * * @details This function returns the context type (stream, datagram or raw) * of the context. * * @param context Network context. * * @return Network context type. */ static inline enum net_sock_type net_context_get_type(struct net_context *context) { NET_ASSERT(context); return (enum net_sock_type)((context->flags & NET_CONTEXT_TYPE) >> 6); } /** * @brief Set context type for this network context. * * @details This function sets the context type (stream or datagram) * of the context. * * @param context Network context. * @param type Context type (SOCK_STREAM or SOCK_DGRAM) */ static inline void net_context_set_type(struct net_context *context, enum net_sock_type type) { uint16_t flag = 0U; NET_ASSERT(context); if (type == SOCK_DGRAM || type == SOCK_STREAM || type == SOCK_RAW) { /* Type is in BIT(6) and BIT(7)*/ flag = (uint16_t)(type << 6); } context->flags |= flag; } /** * @brief Set CAN filter id for this network context. * * @details This function sets the CAN filter id of the context. * * @param context Network context. * @param filter_id CAN filter id */ #if defined(CONFIG_NET_SOCKETS_CAN) static inline void net_context_set_can_filter_id(struct net_context *context, int filter_id) { NET_ASSERT(context); context->can_filter_id = filter_id; } #else static inline void net_context_set_can_filter_id(struct net_context *context, int filter_id) { ARG_UNUSED(context); ARG_UNUSED(filter_id); } #endif /** * @brief Get CAN filter id for this network context. * * @details This function gets the CAN filter id of the context. * * @param context Network context. * * @return Filter id of this network context */ #if defined(CONFIG_NET_SOCKETS_CAN) static inline int net_context_get_can_filter_id(struct net_context *context) { NET_ASSERT(context); return context->can_filter_id; } #else static inline int net_context_get_can_filter_id(struct net_context *context) { ARG_UNUSED(context); return -1; } #endif /** * @brief Get context IP protocol for this network context. * * @details This function returns the IP protocol (UDP / TCP / * IEEE 802.3 protocol value) of the context. * * @param context Network context. * * @return Network context IP protocol. */ static inline uint16_t net_context_get_proto(struct net_context *context) { return context->proto; } /** * @brief Set context IP protocol for this network context. * * @details This function sets the context IP protocol (UDP / TCP) * of the context. * * @param context Network context. * @param proto Context IP protocol (IPPROTO_UDP, IPPROTO_TCP or IEEE 802.3 * protocol value) */ static inline void net_context_set_proto(struct net_context *context, uint16_t proto) { context->proto = proto; } /** * @brief Get network interface for this context. * * @details This function returns the used network interface. * * @param context Network context. * * @return Context network interface if context is bind to interface, * NULL otherwise. */ static inline struct net_if *net_context_get_iface(struct net_context *context) { NET_ASSERT(context); return net_if_get_by_index(context->iface); } /** * @brief Set network interface for this context. * * @details This function binds network interface to this context. * * @param context Network context. * @param iface Network interface. */ static inline void net_context_set_iface(struct net_context *context, struct net_if *iface) { NET_ASSERT(iface); context->iface = (uint8_t)net_if_get_by_iface(iface); } /** * @brief Bind network interface to this context. * * @details This function binds network interface to this context. * * @param context Network context. * @param iface Network interface. */ static inline void net_context_bind_iface(struct net_context *context, struct net_if *iface) { NET_ASSERT(iface); context->flags |= NET_CONTEXT_BOUND_TO_IFACE; net_context_set_iface(context, iface); } /** * @brief Get IPv4 TTL (time-to-live) value for this context. * * @details This function returns the IPv4 TTL (time-to-live) value that is * set to this context. * * @param context Network context. * * @return IPv4 TTL value */ static inline uint8_t net_context_get_ipv4_ttl(struct net_context *context) { return context->ipv4_ttl; } /** * @brief Set IPv4 TTL (time-to-live) value for this context. * * @details This function sets the IPv4 TTL (time-to-live) value for * this context. * * @param context Network context. * @param ttl IPv4 time-to-live value. */ static inline void net_context_set_ipv4_ttl(struct net_context *context, uint8_t ttl) { context->ipv4_ttl = ttl; } /** * @brief Get IPv4 multicast TTL (time-to-live) value for this context. * * @details This function returns the IPv4 multicast TTL (time-to-live) value * that is set to this context. * * @param context Network context. * * @return IPv4 multicast TTL value */ static inline uint8_t net_context_get_ipv4_mcast_ttl(struct net_context *context) { return context->ipv4_mcast_ttl; } /** * @brief Set IPv4 multicast TTL (time-to-live) value for this context. * * @details This function sets the IPv4 multicast TTL (time-to-live) value for * this context. * * @param context Network context. * @param ttl IPv4 multicast time-to-live value. */ static inline void net_context_set_ipv4_mcast_ttl(struct net_context *context, uint8_t ttl) { context->ipv4_mcast_ttl = ttl; } /** * @brief Get IPv6 hop limit value for this context. * * @details This function returns the IPv6 hop limit value that is set to this * context. * * @param context Network context. * * @return IPv6 hop limit value */ static inline uint8_t net_context_get_ipv6_hop_limit(struct net_context *context) { return context->ipv6_hop_limit; } /** * @brief Set IPv6 hop limit value for this context. * * @details This function sets the IPv6 hop limit value for this context. * * @param context Network context. * @param hop_limit IPv6 hop limit value. */ static inline void net_context_set_ipv6_hop_limit(struct net_context *context, uint8_t hop_limit) { context->ipv6_hop_limit = hop_limit; } /** * @brief Get IPv6 multicast hop limit value for this context. * * @details This function returns the IPv6 multicast hop limit value * that is set to this context. * * @param context Network context. * * @return IPv6 multicast hop limit value */ static inline uint8_t net_context_get_ipv6_mcast_hop_limit(struct net_context *context) { return context->ipv6_mcast_hop_limit; } /** * @brief Set IPv6 multicast hop limit value for this context. * * @details This function sets the IPv6 multicast hop limit value for * this context. * * @param context Network context. * @param hop_limit IPv6 multicast hop limit value. */ static inline void net_context_set_ipv6_mcast_hop_limit(struct net_context *context, uint8_t hop_limit) { context->ipv6_mcast_hop_limit = hop_limit; } /** * @brief Enable or disable socks proxy support for this context. * * @details This function either enables or disables socks proxy support for * this context. * * @param context Network context. * @param enable Enable socks proxy or disable it. */ #if defined(CONFIG_SOCKS) static inline void net_context_set_proxy_enabled(struct net_context *context, bool enable) { context->proxy_enabled = enable; } #else static inline void net_context_set_proxy_enabled(struct net_context *context, bool enable) { ARG_UNUSED(context); ARG_UNUSED(enable); } #endif /** * @brief Is socks proxy support enabled or disabled for this context. * * @details This function returns current socks proxy status for * this context. * * @param context Network context. * * @return True if socks proxy is enabled for this context, False otherwise */ #if defined(CONFIG_SOCKS) static inline bool net_context_is_proxy_enabled(struct net_context *context) { return context->proxy_enabled; } #else static inline bool net_context_is_proxy_enabled(struct net_context *context) { ARG_UNUSED(context); return false; } #endif /** * @brief Get network context. * * @details Network context is used to define the connection 5-tuple * (protocol, remote address, remote port, source address and source * port). Random free port number will be assigned to source port when * context is created. This is similar as BSD socket() function. * The context will be created with a reference count of 1. * * @param family IP address family (AF_INET or AF_INET6) * @param type Type of the socket, SOCK_STREAM or SOCK_DGRAM * @param ip_proto IP protocol, IPPROTO_UDP or IPPROTO_TCP. For raw socket * access, the value is the L2 protocol value from IEEE 802.3 (see ethernet.h) * @param context The allocated context is returned to the caller. * * @return 0 if ok, < 0 if error */ int net_context_get(sa_family_t family, enum net_sock_type type, uint16_t ip_proto, struct net_context **context); /** * @brief Close and unref a network context. * * @details This releases the context. It is not possible to send or * receive data via this context after this call. This is similar as * BSD shutdown() function. For legacy compatibility, this function * will implicitly decrement the reference count and possibly destroy * the context either now or when it reaches a final state. * * @param context The context to be closed. * * @return 0 if ok, < 0 if error */ int net_context_put(struct net_context *context); /** * @brief Take a reference count to a net_context, preventing destruction * * @details Network contexts are not recycled until their reference * count reaches zero. Note that this does not prevent any "close" * behavior that results from errors or net_context_put. It simply * prevents the context from being recycled for further use. * * @param context The context on which to increment the reference count * * @return The new reference count */ int net_context_ref(struct net_context *context); /** * @brief Decrement the reference count to a network context * * @details Decrements the refcount. If it reaches zero, the context * will be recycled. Note that this does not cause any * network-visible "close" behavior (i.e. future packets to this * connection may see TCP RST or ICMP port unreachable responses). See * net_context_put() for that. * * @param context The context on which to decrement the reference count * * @return The new reference count, zero if the context was destroyed */ int net_context_unref(struct net_context *context); /** * @brief Create IPv4 packet in provided net_pkt from context * * @param context Network context for a connection * @param pkt Network packet * @param src Source address, or NULL to choose a default * @param dst Destination IPv4 address * * @return Return 0 on success, negative errno otherwise. */ #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); #else static inline int net_context_create_ipv4_new(struct net_context *context, struct net_pkt *pkt, const struct in_addr *src, const struct in_addr *dst) { return -1; } #endif /* CONFIG_NET_IPV4 */ /** * @brief Create IPv6 packet in provided net_pkt from context * * @param context Network context for a connection * @param pkt Network packet * @param src Source address, or NULL to choose a default from context * @param dst Destination IPv6 address * * @return Return 0 on success, negative errno otherwise. */ #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); #else static inline int net_context_create_ipv6_new(struct net_context *context, struct net_pkt *pkt, const struct in6_addr *src, const struct in6_addr *dst) { ARG_UNUSED(context); ARG_UNUSED(pkt); ARG_UNUSED(src); ARG_UNUSED(dst); return -1; } #endif /* CONFIG_NET_IPV6 */ /** * @brief Assign a socket a local address. * * @details This is similar as BSD bind() function. * * @param context The context to be assigned. * @param addr Address to assigned. * @param addrlen Length of the address. * * @return 0 if ok, < 0 if error */ int net_context_bind(struct net_context *context, const struct sockaddr *addr, socklen_t addrlen); /** * @brief Mark the context as a listening one. * * @details This is similar as BSD listen() function. * * @param context The context to use. * @param backlog The size of the pending connections backlog. * * @return 0 if ok, < 0 if error */ int net_context_listen(struct net_context *context, int backlog); /** * @brief Create a network connection. * * @details The net_context_connect function creates a network * connection to the host specified by addr. After the * connection is established, the user-supplied callback (cb) * is executed. cb is called even if the timeout was set to * K_FOREVER. cb is not called if the timeout expires. * For datagram sockets (SOCK_DGRAM), this function only sets * the peer address. * This function is similar to the BSD connect() function. * * @param context The network context. * @param addr The peer address to connect to. * @param addrlen Peer address length. * @param cb Callback function. Set to NULL if not required. * @param timeout The timeout value for the connection. Possible values: * * K_NO_WAIT: this function will return immediately, * * K_FOREVER: this function will block until the * connection is established, * * >0: this function will wait the specified ms. * @param user_data Data passed to the callback function. * * @return 0 on success. * @return -EINVAL if an invalid parameter is passed as an argument. * @return -ENOTSUP if the operation is not supported or implemented. * @return -ETIMEDOUT if the connect operation times out. */ 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); /** * @brief Accept a network connection attempt. * * @details Accept a connection being established. This function * will return immediately if the timeout is set to K_NO_WAIT. * In this case the context will call the supplied callback when ever * there is a connection established to this context. This is "a register * handler and forget" type of call (async). * If the timeout is set to K_FOREVER, the function will wait * until the connection is established. Timeout value > 0, will wait as * many ms. * After the connection is established a caller-supplied callback is called. * The callback is called even if timeout was set to K_FOREVER, the * callback is called before this function will return in this case. * The callback is not called if the timeout expires. * This is similar as BSD accept() function. * * @param context The context to use. * @param cb Caller-supplied callback function. * @param timeout Timeout for the connection. Possible values * are K_FOREVER, K_NO_WAIT, >0. * @param user_data Caller-supplied user data. * * @return 0 if ok, < 0 if error */ int net_context_accept(struct net_context *context, net_tcp_accept_cb_t cb, k_timeout_t timeout, void *user_data); /** * @brief Send data to a peer. * * @details This function can be used to send network data to a peer * connection. After the network buffer is sent, a caller-supplied * callback is called. Note that the callback might be called after this * function has returned. For context of type SOCK_DGRAM, the destination * address must have been set by the call to net_context_connect(). * This is similar as BSD send() function. * * @param context The network context to use. * @param buf The data buffer to send * @param len Length of the buffer * @param cb Caller-supplied callback function. * @param timeout Currently this value is not used. * @param user_data Caller-supplied user data. * * @return 0 if ok, < 0 if error */ 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); /** * @brief Send data to a peer specified by address. * * @details This function can be used to send network data to a peer * specified by address. This variant can only be used for datagram * connections of type SOCK_DGRAM. After the network buffer is sent, * a caller-supplied callback is called. Note that the callback might be * called after this function has returned. * This is similar as BSD sendto() function. * * @param context The network context to use. * @param buf The data buffer to send * @param len Length of the buffer * @param dst_addr Destination address. * @param addrlen Length of the address. * @param cb Caller-supplied callback function. * @param timeout Currently this value is not used. * @param user_data Caller-supplied user data. * * @return numbers of bytes sent on success, a negative errno otherwise */ 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); /** * @brief Send data in iovec to a peer specified in msghdr struct. * * @details This function has similar semantics as Posix sendmsg() call. * For unconnected socket, the msg_name field in msghdr must be set. For * connected socket the msg_name should be set to NULL, and msg_namelen to 0. * After the network buffer is sent, a caller-supplied callback is called. * Note that the callback might be called after this function has returned. * * @param context The network context to use. * @param msghdr The data to send * @param flags Flags for the sending. * @param cb Caller-supplied callback function. * @param timeout Currently this value is not used. * @param user_data Caller-supplied user data. * * @return numbers of bytes sent on success, a negative errno otherwise */ 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); /** * @brief Receive network data from a peer specified by context. * * @details This function can be used to register a callback function * that is called by the network stack when network data has been received * for this context. As this function registers a callback, then there * is no need to call this function multiple times if timeout is set to * K_NO_WAIT. * If callback function or user data changes, then the function can be called * multiple times to register new values. * This function will return immediately if the timeout is set to K_NO_WAIT. * If the timeout is set to K_FOREVER, the function will wait until the * network buffer is received. Timeout value > 0 will wait as many ms. * After the network buffer is received, a caller-supplied callback is * called. The callback is called even if timeout was set to K_FOREVER, * the callback is called before this function will return in this case. * The callback is not called if the timeout expires. The timeout functionality * can be compiled out if synchronous behavior is not needed. The sync call * logic requires some memory that can be saved if only async way of call is * used. If CONFIG_NET_CONTEXT_SYNC_RECV is not set, then the timeout parameter * value is ignored. * This is similar as BSD recv() function. * Note that net_context_bind() should be called before net_context_recv(). * Default random port number is assigned to local port. Only bind() will * update connection information from context. If recv() is called before * bind() call, it may refuse to bind to a context which already has * a connection associated. * * @param context The network context to use. * @param cb Caller-supplied callback function. * @param timeout Caller-supplied timeout. Possible values * are K_FOREVER, K_NO_WAIT, >0. * @param user_data Caller-supplied user data. * * @return 0 if ok, < 0 if error */ int net_context_recv(struct net_context *context, net_context_recv_cb_t cb, k_timeout_t timeout, void *user_data); /** * @brief Update TCP receive window for context. * * @details This function should be used by an application which * doesn't fully process incoming data in its receive callback, * but for example, queues it. In this case, receive callback * should decrease the window (call this function with a negative * value) by the size of queued data, and function(s) which dequeue * data - with positive value corresponding to the dequeued size. * For example, if receive callback gets a packet with the data * size of 256 and queues it, it should call this function with * delta of -256. If a function extracts 10 bytes of the queued * data, it should call it with delta of 10. * * @param context The TCP network context to use. * @param delta Size, in bytes, by which to increase TCP receive * window (negative value to decrease). * * @return 0 if ok, < 0 if error */ int net_context_update_recv_wnd(struct net_context *context, int32_t delta); /** @brief Network context options. These map to BSD socket option values. */ enum net_context_option { NET_OPT_PRIORITY = 1, /**< Context priority */ NET_OPT_TXTIME = 2, /**< TX time */ NET_OPT_SOCKS5 = 3, /**< SOCKS5 */ NET_OPT_RCVTIMEO = 4, /**< Receive timeout */ NET_OPT_SNDTIMEO = 5, /**< Send timeout */ NET_OPT_RCVBUF = 6, /**< Receive buffer */ NET_OPT_SNDBUF = 7, /**< Send buffer */ NET_OPT_DSCP_ECN = 8, /**< DSCP ECN */ NET_OPT_REUSEADDR = 9, /**< Re-use address */ NET_OPT_REUSEPORT = 10, /**< Re-use port */ NET_OPT_IPV6_V6ONLY = 11, /**< Share IPv4 and IPv6 port space */ NET_OPT_RECV_PKTINFO = 12, /**< Receive packet information */ NET_OPT_MCAST_TTL = 13, /**< IPv4 multicast TTL */ NET_OPT_MCAST_HOP_LIMIT = 14, /**< IPv6 multicast hop limit */ NET_OPT_UNICAST_HOP_LIMIT = 15, /**< IPv6 unicast hop limit */ NET_OPT_TTL = 16, /**< IPv4 unicast TTL */ NET_OPT_ADDR_PREFERENCES = 17, /**< IPv6 address preference */ NET_OPT_TIMESTAMPING = 18, /**< Packet timestamping */ NET_OPT_MCAST_IFINDEX = 19, /**< IPv6 multicast output network interface index */ NET_OPT_MTU = 20, /**< IPv4 socket path MTU */ NET_OPT_LOCAL_PORT_RANGE = 21, /**< Clamp local port range */ }; /** * @brief Set an connection option for this context. * * @param context The network context to use. * @param option Option to set * @param value Option value * @param len Option length * * @return 0 if ok, <0 if error */ int net_context_set_option(struct net_context *context, enum net_context_option option, const void *value, size_t len); /** * @brief Get connection option value for this context. * * @param context The network context to use. * @param option Option to set * @param value Option value * @param len Option length (returned to caller) * * @return 0 if ok, <0 if error */ int net_context_get_option(struct net_context *context, enum net_context_option option, void *value, size_t *len); /** * @typedef net_context_cb_t * @brief Callback used while iterating over network contexts * * @param context A valid pointer on current network context * @param user_data A valid pointer on some user data or NULL */ typedef void (*net_context_cb_t)(struct net_context *context, void *user_data); /** * @brief Go through all the network connections and call callback * for each network context. * * @param cb User-supplied callback function to call. * @param user_data User specified data. */ void net_context_foreach(net_context_cb_t cb, void *user_data); /** * @brief Set custom network buffer pools for context send operations * * Set custom network buffer pools used by the IP stack to allocate * network buffers used by the context when sending data to the * network. Using dedicated buffers may help make send operations on * a given context more reliable, e.g. not be subject to buffer * starvation due to operations on other network contexts. Buffer pools * are set per context, but several contexts may share the same buffers. * Note that there's no support for per-context custom receive packet * pools. * * @param context Context that will use the given net_buf pools. * @param tx_pool Pointer to the function that will return TX pool * to the caller. The TX pool is used when sending data to network. * There is one TX net_pkt for each network packet that is sent. * @param data_pool Pointer to the function that will return DATA pool * to the caller. The DATA pool is used to store data that is sent to * the network. */ #if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) static inline void net_context_setup_pools(struct net_context *context, net_pkt_get_slab_func_t tx_slab, net_pkt_get_pool_func_t data_pool) { NET_ASSERT(context); context->tx_slab = tx_slab; context->data_pool = data_pool; } #else #define net_context_setup_pools(context, tx_pool, data_pool) #endif /** * @brief Check if a port is in use (bound) * * This function checks if a port is bound with respect to the specified * @p ip_proto and @p local_addr. * * @param ip_proto the IP protocol * @param local_port the port to check * @param local_addr the network address * * @return true if the port is bound * @return false if the port is not bound */ bool net_context_port_in_use(enum net_ip_protocol ip_proto, uint16_t local_port, const struct sockaddr *local_addr); #ifdef __cplusplus } #endif /** * @} */ #endif /* ZEPHYR_INCLUDE_NET_NET_CONTEXT_H_ */