2014-06-25 02:12:49 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* net/udp/udp.h
|
|
|
|
*
|
2018-01-23 01:32:02 +01:00
|
|
|
* Copyright (C) 2014-2015, 2018 Gregory Nutt. All rights reserved.
|
2014-06-25 02:12:49 +02:00
|
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
|
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
|
|
* used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef __NET_UDP_UDP_H
|
|
|
|
#define __NET_UDP_UDP_H
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
2018-01-23 14:32:17 +01:00
|
|
|
#include <sys/socket.h>
|
2015-01-28 20:41:24 +01:00
|
|
|
#include <queue.h>
|
|
|
|
|
2018-01-23 01:32:02 +01:00
|
|
|
#include <nuttx/clock.h>
|
2015-01-28 20:41:24 +01:00
|
|
|
#include <nuttx/net/ip.h>
|
2014-06-25 02:12:49 +02:00
|
|
|
|
2015-01-30 13:08:26 +01:00
|
|
|
#ifdef CONFIG_NET_UDP_READAHEAD
|
2017-05-09 15:34:59 +02:00
|
|
|
# include <nuttx/mm/iob.h>
|
2015-01-30 13:08:26 +01:00
|
|
|
#endif
|
|
|
|
|
2018-09-09 23:01:44 +02:00
|
|
|
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
|
|
|
|
# include <nuttx/wqueue.h>
|
|
|
|
#endif
|
|
|
|
|
2017-03-31 16:58:14 +02:00
|
|
|
#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
|
2014-06-25 02:12:49 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Pre-processor Definitions
|
|
|
|
****************************************************************************/
|
2017-03-31 16:58:14 +02:00
|
|
|
|
|
|
|
#define NET_UDP_HAVE_STACK 1
|
|
|
|
|
2015-01-30 14:09:25 +01:00
|
|
|
/* Conditions for support UDP poll/select operations */
|
|
|
|
|
|
|
|
#if !defined(CONFIG_DISABLE_POLL) && CONFIG_NSOCKET_DESCRIPTORS > 0 && \
|
|
|
|
defined(CONFIG_NET_UDP_READAHEAD)
|
|
|
|
# define HAVE_UDP_POLL
|
|
|
|
#endif
|
2014-06-25 02:12:49 +02:00
|
|
|
|
2018-01-23 01:32:02 +01:00
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
|
|
|
/* UDP write buffer dump macros */
|
|
|
|
|
|
|
|
# ifdef CONFIG_DEBUG_FEATURES
|
2018-01-23 02:33:14 +01:00
|
|
|
# define UDP_WBDUMP(msg,wrb,len,offset) \
|
2018-01-23 01:32:02 +01:00
|
|
|
udp_wrbuffer_dump(msg,wrb,len,offset)
|
|
|
|
# else
|
2018-01-23 02:33:14 +01:00
|
|
|
# define UDP_WBDUMP(msg,wrb,len,offset)
|
2018-01-23 01:32:02 +01:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2015-01-17 14:42:09 +01:00
|
|
|
/* Allocate a new UDP data callback */
|
2014-06-29 02:36:09 +02:00
|
|
|
|
2017-07-05 19:01:16 +02:00
|
|
|
#define udp_callback_alloc(dev,conn) \
|
|
|
|
devif_callback_alloc((dev), &(conn)->list)
|
|
|
|
#define udp_callback_free(dev,conn,cb) \
|
|
|
|
devif_conn_callback_free((dev), (cb), &(conn)->list)
|
2014-06-29 02:36:09 +02:00
|
|
|
|
net/udp: Resolve race condition in connection-less UDP sockets with read-ahead buffering.
In connection-mode UDP sockets, a remote address is retained in the UDP connection structure. This determines both there send() will send the packets and which packets recv() will accept.
This same mechanism is used for connection-less UDP sendto: A temporary remote address is written into the connection structure to support the sendto() operation. That address persists until the next recvfrom() when it is reset to accept any address.
When UDP read-ahead buffering is enabled, however, that means that the old, invalid remote address can be left in the connection structure for some time. This can cause read-ahead buffer to fail, dropping UDP packets.
Shortening the time between when he remote address is reset (i.e., immediately after the sendto() completes) is not a solution, that does not eliminate the race condition; in only makes it smaller.
With this change, a flag was added to the connection structure to indicate if the UDP socket is in connection mode or if it is connection-less. This change effects only UDP receive operations: The remote address in the UDP connection is always ignored if the UDP socket is not in connection-mode.
No for connection-mode sockets, that remote address behaves as before. But for connection-less sockets, it is only used by sendto().
2018-05-13 17:57:34 +02:00
|
|
|
/* Definitions for the UDP connection struct flag field */
|
|
|
|
|
|
|
|
#define _UDP_FLAG_CONNECTMODE (1 << 0) /* Bit 0: UDP connection-mode */
|
|
|
|
|
|
|
|
#define _UDP_ISCONNECTMODE(f) (((f) & _UDP_FLAG_CONNECTMODE) != 0)
|
|
|
|
|
2014-06-25 02:12:49 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Public Type Definitions
|
|
|
|
****************************************************************************/
|
|
|
|
|
2016-05-30 17:31:44 +02:00
|
|
|
/* Representation of a UDP connection */
|
2014-07-05 22:40:29 +02:00
|
|
|
|
|
|
|
struct devif_callback_s; /* Forward reference */
|
2015-01-15 22:06:46 +01:00
|
|
|
struct udp_hdr_s; /* Forward reference */
|
2014-07-05 22:40:29 +02:00
|
|
|
|
|
|
|
struct udp_conn_s
|
|
|
|
{
|
|
|
|
dq_entry_t node; /* Supports a doubly linked list */
|
2015-01-16 17:01:54 +01:00
|
|
|
union ip_binding_u u; /* IP address binding */
|
2014-11-21 21:21:30 +01:00
|
|
|
uint16_t lport; /* Bound local port number (network byte order) */
|
|
|
|
uint16_t rport; /* Remote port number (network byte order) */
|
net/udp: Resolve race condition in connection-less UDP sockets with read-ahead buffering.
In connection-mode UDP sockets, a remote address is retained in the UDP connection structure. This determines both there send() will send the packets and which packets recv() will accept.
This same mechanism is used for connection-less UDP sendto: A temporary remote address is written into the connection structure to support the sendto() operation. That address persists until the next recvfrom() when it is reset to accept any address.
When UDP read-ahead buffering is enabled, however, that means that the old, invalid remote address can be left in the connection structure for some time. This can cause read-ahead buffer to fail, dropping UDP packets.
Shortening the time between when he remote address is reset (i.e., immediately after the sendto() completes) is not a solution, that does not eliminate the race condition; in only makes it smaller.
With this change, a flag was added to the connection structure to indicate if the UDP socket is in connection mode or if it is connection-less. This change effects only UDP receive operations: The remote address in the UDP connection is always ignored if the UDP socket is not in connection-mode.
No for connection-mode sockets, that remote address behaves as before. But for connection-less sockets, it is only used by sendto().
2018-05-13 17:57:34 +02:00
|
|
|
uint8_t flags; /* See _UDP_FLAG_* definitions */
|
2016-02-26 13:45:37 +01:00
|
|
|
uint8_t domain; /* IP domain: PF_INET or PF_INET6 */
|
2014-07-05 22:40:29 +02:00
|
|
|
uint8_t ttl; /* Default time-to-live */
|
|
|
|
uint8_t crefs; /* Reference counts on this instance */
|
|
|
|
|
2018-06-25 23:07:53 +02:00
|
|
|
#ifdef CONFIG_NET_UDP_BINDTODEVICE
|
|
|
|
uint8_t boundto; /* Index of the interface we are bound to.
|
|
|
|
* Unbound: 0, Bound: 1-MAX_IFINDEX */
|
|
|
|
#endif
|
|
|
|
|
2015-01-30 13:08:26 +01:00
|
|
|
#ifdef CONFIG_NET_UDP_READAHEAD
|
|
|
|
/* Read-ahead buffering.
|
|
|
|
*
|
|
|
|
* readahead - A singly linked list of type struct iob_qentry_s
|
|
|
|
* where the UDP/IP read-ahead data is retained.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct iob_queue_s readahead; /* Read-ahead buffering */
|
|
|
|
#endif
|
|
|
|
|
2018-03-30 20:03:34 +02:00
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
2018-01-23 01:32:02 +01:00
|
|
|
/* Write buffering
|
|
|
|
*
|
|
|
|
* write_q - The queue of unsent I/O buffers. The head of this
|
|
|
|
* list may be partially sent. FIFO ordering.
|
|
|
|
*/
|
|
|
|
|
|
|
|
sq_queue_t write_q; /* Write buffering for UDP packets */
|
|
|
|
FAR struct net_driver_s *dev; /* Last device */
|
|
|
|
#endif
|
|
|
|
|
2014-07-05 22:40:29 +02:00
|
|
|
/* Defines the list of UDP callbacks */
|
|
|
|
|
2015-01-17 21:13:56 +01:00
|
|
|
FAR struct devif_callback_s *list;
|
2014-07-05 22:40:29 +02:00
|
|
|
};
|
|
|
|
|
2018-01-23 01:32:02 +01:00
|
|
|
/* This structure supports UDP write buffering. It is simply a container
|
|
|
|
* for a IOB list and associated destination address.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
|
|
|
struct udp_wrbuffer_s
|
|
|
|
{
|
2018-01-23 14:32:17 +01:00
|
|
|
sq_entry_t wb_node; /* Supports a singly linked list */
|
|
|
|
struct sockaddr_storage wb_dest; /* Destination address */
|
2018-01-23 01:32:02 +01:00
|
|
|
#ifdef CONFIG_NET_SOCKOPTS
|
2018-06-16 20:16:13 +02:00
|
|
|
clock_t wb_start; /* Start time for timeout calculation */
|
2018-01-23 01:32:02 +01:00
|
|
|
#endif
|
2018-01-23 14:32:17 +01:00
|
|
|
struct iob_s *wb_iob; /* Head of the I/O buffer chain */
|
2018-01-23 01:32:02 +01:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2014-06-25 02:12:49 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Public Data
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
# define EXTERN extern "C"
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#else
|
|
|
|
# define EXTERN extern
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Public Function Prototypes
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-01-28 20:41:24 +01:00
|
|
|
struct sockaddr; /* Forward reference */
|
|
|
|
struct socket; /* Forward reference */
|
2015-01-15 22:06:46 +01:00
|
|
|
struct net_driver_s; /* Forward reference */
|
2015-01-30 14:09:25 +01:00
|
|
|
struct pollfd; /* Forward reference */
|
2014-07-05 22:40:29 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2015-01-17 20:07:48 +01:00
|
|
|
* Name: udp_initialize
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Initialize the UDP connection structures. Called once and only from
|
|
|
|
* the UIP layer.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2014-06-26 17:32:39 +02:00
|
|
|
|
2014-06-25 02:55:01 +02:00
|
|
|
void udp_initialize(void);
|
2014-07-05 22:40:29 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2015-01-17 20:07:48 +01:00
|
|
|
* Name: udp_alloc
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Allocate a new, uninitialized UDP connection structure. This is
|
|
|
|
* normally something done by the implementation of the socket() API
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-01-17 20:07:48 +01:00
|
|
|
FAR struct udp_conn_s *udp_alloc(uint8_t domain);
|
2014-07-05 22:40:29 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2015-01-17 20:07:48 +01:00
|
|
|
* Name: udp_free
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Free a UDP connection structure that is no longer in use. This should be
|
|
|
|
* done by the implementation of close().
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
void udp_free(FAR struct udp_conn_s *conn);
|
|
|
|
|
|
|
|
/****************************************************************************
|
2015-01-17 20:07:48 +01:00
|
|
|
* Name: udp_active
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Find a connection structure that is the appropriate
|
2015-01-17 14:42:09 +01:00
|
|
|
* connection to be used within the provided UDP/IP header
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-01-15 22:06:46 +01:00
|
|
|
* Called from network stack logic with the network stack locked
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-01-15 22:06:46 +01:00
|
|
|
FAR struct udp_conn_s *udp_active(FAR struct net_driver_s *dev,
|
|
|
|
FAR struct udp_hdr_s *udp);
|
2014-07-05 22:40:29 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2015-01-17 20:07:48 +01:00
|
|
|
* Name: udp_nextconn
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Traverse the list of allocated UDP connections
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-01-15 22:06:46 +01:00
|
|
|
* Called from network stack logic with the network stack locked
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2014-07-01 02:03:58 +02:00
|
|
|
FAR struct udp_conn_s *udp_nextconn(FAR struct udp_conn_s *conn);
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2014-07-05 22:40:29 +02:00
|
|
|
/****************************************************************************
|
2015-01-17 20:07:48 +01:00
|
|
|
* Name: udp_bind
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
2015-01-17 14:42:09 +01:00
|
|
|
* This function implements the low-level parts of the standard UDP bind()
|
|
|
|
* operation.
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* This function is called from normal user level code.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-01-17 21:13:56 +01:00
|
|
|
int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr);
|
2014-07-05 22:40:29 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2015-01-17 20:07:48 +01:00
|
|
|
* Name: udp_connect
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
2018-04-25 16:43:38 +02:00
|
|
|
* This function simply assigns a remote address to UDP "connection"
|
|
|
|
* structure. This function is called as part of the implementation of:
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
2018-04-25 16:43:38 +02:00
|
|
|
* - connect(). If connect() is called for a SOCK_DGRAM socket, then
|
|
|
|
* this logic performs the moral equivalent of connect() operation
|
|
|
|
* for the UDP socket.
|
|
|
|
* - recvfrom() and sendto(). This function is called to set the
|
|
|
|
* remote address of the peer.
|
|
|
|
*
|
|
|
|
* The function will automatically allocate an unused local port for the
|
|
|
|
* new connection if the socket is not yet bound to a local address.
|
|
|
|
* However, another port can be chosen by using the udp_bind() call,
|
|
|
|
* after the udp_connect() function has been called.
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Input Parameters:
|
2018-04-25 16:43:38 +02:00
|
|
|
* conn - A reference to UDP connection structure. A value of NULL will
|
|
|
|
* disconnect from any previously connected address.
|
2014-07-05 22:40:29 +02:00
|
|
|
* addr - The address of the remote host.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2018-04-25 16:43:38 +02:00
|
|
|
* This function is called (indirectly) from user code. Interrupts may
|
|
|
|
* be enabled.
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-01-17 21:13:56 +01:00
|
|
|
int udp_connect(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr);
|
2014-07-05 22:40:29 +02:00
|
|
|
|
2015-01-17 14:42:09 +01:00
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: udp_ipv4_select
|
2015-01-17 14:42:09 +01:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Configure to send or receive an UDP IPv4 packet
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_IPv4
|
|
|
|
void udp_ipv4_select(FAR struct net_driver_s *dev);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: udp_ipv6_select
|
2015-01-17 14:42:09 +01:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Configure to send or receive an UDP IPv6 packet
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_IPv6
|
|
|
|
void udp_ipv6_select(FAR struct net_driver_s *dev);
|
|
|
|
#endif
|
|
|
|
|
2014-07-05 22:40:29 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_poll
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Poll a UDP "connection" structure for availability of TX data
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2014-07-05 22:40:29 +02:00
|
|
|
* dev - The device driver structure to use in the send operation
|
|
|
|
* conn - The UDP "connection" to poll for TX data
|
|
|
|
*
|
2018-02-01 17:00:02 +01:00
|
|
|
* Returned Value:
|
2014-07-05 22:40:29 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-01-15 22:06:46 +01:00
|
|
|
* Called from network stack logic with the network stack locked
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2014-06-28 00:48:12 +02:00
|
|
|
void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn);
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2018-09-15 21:22:45 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: psock_udp_cansend
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* psock_udp_cansend() returns a value indicating if a write to the socket
|
|
|
|
* would block. It is still possible that the write may block if another
|
|
|
|
* write occurs first.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* psock An instance of the internal socket structure.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* -ENOSYS (Function not implemented, always have to wait to send).
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
int psock_udp_cansend(FAR struct socket *psock);
|
|
|
|
;
|
2014-07-05 22:40:29 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_send
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Set-up to send a UDP packet
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2014-07-05 22:40:29 +02:00
|
|
|
* dev - The device driver structure to use in the send operation
|
|
|
|
* conn - The UDP "connection" structure holding port information
|
|
|
|
*
|
2018-02-01 17:00:02 +01:00
|
|
|
* Returned Value:
|
2014-07-05 22:40:29 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-01-15 22:06:46 +01:00
|
|
|
* Called from network stack logic with the network stack locked
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2014-06-28 00:48:12 +02:00
|
|
|
void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn);
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2018-06-25 20:41:28 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_setsockopt
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* udp_setsockopt() sets the UDP-protocol option specified by the
|
|
|
|
* 'option' argument to the value pointed to by the 'value' argument for
|
|
|
|
* the socket specified by the 'psock' argument.
|
|
|
|
*
|
|
|
|
* See <netinet/udp.h> for the a complete list of values of UDP protocol
|
|
|
|
* options.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* psock Socket structure of socket to operate on
|
|
|
|
* option identifies the option to set
|
|
|
|
* value Points to the argument value
|
|
|
|
* value_len The length of the argument value
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Returns zero (OK) on success. On failure, it returns a negated errno
|
|
|
|
* value to indicate the nature of the error. See psock_setcockopt() for
|
|
|
|
* the list of possible error values.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_UDPPROTO_OPTIONS
|
|
|
|
int udp_setsockopt(FAR struct socket *psock, int option,
|
|
|
|
FAR const void *value, socklen_t value_len);
|
|
|
|
#endif
|
|
|
|
|
2018-01-23 01:32:02 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_wrbuffer_initialize
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Initialize the list of free write buffers
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Called once early initialization.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
|
|
|
void udp_wrbuffer_initialize(void);
|
|
|
|
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_wrbuffer_alloc
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Allocate a UDP write buffer by taking a pre-allocated buffer from
|
|
|
|
* the free list. This function is called from UDP logic when a buffer
|
|
|
|
* of UDP data is about to sent
|
|
|
|
*
|
2018-02-01 17:00:02 +01:00
|
|
|
* Input Parameters:
|
2018-01-23 01:32:02 +01:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Called from user logic with the network locked.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
|
|
|
struct udp_wrbuffer_s;
|
|
|
|
|
|
|
|
FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void);
|
|
|
|
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_wrbuffer_release
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Release a UDP write buffer by returning the buffer to the free list.
|
|
|
|
* This function is called from user logic after it is consumed the
|
|
|
|
* buffered data.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Called from network stack logic with the network stack locked
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
|
|
|
void udp_wrbuffer_release(FAR struct udp_wrbuffer_s *wrb);
|
|
|
|
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_wrbuffer_test
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Check if there is room in the write buffer. Does not reserve any space.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* None.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
|
|
|
int udp_wrbuffer_test(void);
|
|
|
|
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_wrbuffer_dump
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Dump the contents of a write buffer.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
|
|
|
#ifdef CONFIG_DEBUG_FEATURES
|
|
|
|
void udp_wrbuffer_dump(FAR const char *msg, FAR struct udp_wrbuffer_s *wrb,
|
|
|
|
unsigned int len, unsigned int offset);
|
|
|
|
#else
|
|
|
|
# define udp_wrbuffer_dump(msg,wrb)
|
|
|
|
#endif
|
|
|
|
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
|
|
|
|
2014-07-05 22:40:29 +02:00
|
|
|
/****************************************************************************
|
2015-01-15 22:06:46 +01:00
|
|
|
* Name: udp_ipv4_input
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
2015-01-15 22:06:46 +01:00
|
|
|
* Handle incoming UDP input in an IPv4 packet
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2014-07-05 22:40:29 +02:00
|
|
|
* dev - The device driver structure containing the received UDP packet
|
|
|
|
*
|
2018-02-01 17:00:02 +01:00
|
|
|
* Returned Value:
|
2014-07-05 22:40:29 +02:00
|
|
|
* OK The packet has been processed and can be deleted
|
|
|
|
* ERROR Hold the packet and try again later. There is a listening socket
|
|
|
|
* but no receive in place to catch the packet yet.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-01-15 22:06:46 +01:00
|
|
|
* Called from network stack logic with the network stack locked
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2015-01-15 22:06:46 +01:00
|
|
|
#ifdef CONFIG_NET_IPv4
|
|
|
|
int udp_ipv4_input(FAR struct net_driver_s *dev);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_ipv6_input
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Handle incoming UDP input in an IPv6 packet
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2018-11-03 00:50:01 +01:00
|
|
|
* dev - The device driver structure containing the received UDP packet
|
|
|
|
* iplen - The size of the IPv6 header. This may be larger than
|
|
|
|
* IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
|
|
|
|
* present.
|
2015-01-15 22:06:46 +01:00
|
|
|
*
|
2018-02-01 17:00:02 +01:00
|
|
|
* Returned Value:
|
2015-01-15 22:06:46 +01:00
|
|
|
* OK The packet has been processed and can be deleted
|
|
|
|
* ERROR Hold the packet and try again later. There is a listening socket
|
|
|
|
* but no receive in place to catch the packet yet.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Called from network stack logic with the network stack locked
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_IPv6
|
2018-11-03 00:50:01 +01:00
|
|
|
int udp_ipv6_input(FAR struct net_driver_s *dev, unsigned int iplen);
|
2015-01-15 22:06:46 +01:00
|
|
|
#endif
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2015-05-29 18:45:41 +02:00
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: udp_find_laddr_device
|
2015-05-29 18:45:41 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Select the network driver to use with the UDP transaction using the
|
|
|
|
* locally bound IP address.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* conn - UDP connection structure (not currently used).
|
|
|
|
*
|
|
|
|
* Returned Value:
|
2018-07-04 15:35:51 +02:00
|
|
|
* A pointer to the network driver to use. NULL is returned if driver is
|
|
|
|
* not bound to any local device.
|
2015-05-29 18:45:41 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn);
|
|
|
|
|
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: udp_find_raddr_device
|
2015-05-29 18:45:41 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Select the network driver to use with the UDP transaction using the
|
|
|
|
* remote IP address.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* conn - UDP connection structure (not currently used).
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* A pointer to the network driver to use.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn);
|
|
|
|
|
2014-07-05 22:40:29 +02:00
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: udp_callback
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Inform the application holding the UDP socket of a change in state.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* OK if packet has been processed, otherwise ERROR.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-01-15 22:06:46 +01:00
|
|
|
* Called from network stack logic with the network stack locked
|
2014-07-05 22:40:29 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
2014-06-25 02:55:01 +02:00
|
|
|
|
2014-06-28 00:48:12 +02:00
|
|
|
uint16_t udp_callback(FAR struct net_driver_s *dev,
|
2014-06-25 02:55:01 +02:00
|
|
|
FAR struct udp_conn_s *conn, uint16_t flags);
|
|
|
|
|
2015-08-12 03:17:55 +02:00
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: psock_udp_send
|
2015-08-12 03:17:55 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Implements send() for connected UDP sockets
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
ssize_t psock_udp_send(FAR struct socket *psock, FAR const void *buf,
|
|
|
|
size_t len);
|
|
|
|
|
2015-01-28 20:41:24 +01:00
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: psock_udp_sendto
|
2015-01-28 20:41:24 +01:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* This function implements the UDP-specific logic of the standard
|
|
|
|
* sendto() socket operation.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* psock A pointer to a NuttX-specific, internal socket structure
|
|
|
|
* buf Data to send
|
|
|
|
* len Length of data to send
|
|
|
|
* flags Send flags
|
|
|
|
* to Address of recipient
|
|
|
|
* tolen The length of the address structure
|
|
|
|
*
|
|
|
|
* NOTE: All input parameters were verified by sendto() before this
|
|
|
|
* function was called.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* On success, returns the number of characters sent. On error,
|
|
|
|
* a negated errno value is returned. See the description in
|
|
|
|
* net/socket/sendto.c for the list of appropriate return value.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|
|
|
size_t len, int flags, FAR const struct sockaddr *to,
|
|
|
|
socklen_t tolen);
|
|
|
|
|
2015-01-30 14:09:25 +01:00
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: udp_pollsetup
|
2015-01-30 14:09:25 +01:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Setup to monitor events on one UDP/IP socket
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* psock - The UDP/IP socket of interest
|
|
|
|
* fds - The structure describing the events to be monitored, OR NULL if
|
|
|
|
* this is a request to stop monitoring events.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* 0: Success; Negated errno on failure
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef HAVE_UDP_POLL
|
|
|
|
int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
2017-04-22 00:33:14 +02:00
|
|
|
* Name: udp_pollteardown
|
2015-01-30 14:09:25 +01:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Teardown monitoring of events on an UDP/IP socket
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
2018-01-23 01:32:02 +01:00
|
|
|
* psock - The UDP/IP socket of interest
|
2015-01-30 14:09:25 +01:00
|
|
|
* fds - The structure describing the events to be monitored, OR NULL if
|
|
|
|
* this is a request to stop monitoring events.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* 0: Success; Negated errno on failure
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef HAVE_UDP_POLL
|
|
|
|
int udp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
|
|
|
|
#endif
|
|
|
|
|
2018-09-09 17:21:39 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_notifier_setup
|
|
|
|
*
|
|
|
|
* Description:
|
2018-09-09 23:01:44 +02:00
|
|
|
* Set up to perform a callback to the worker function when an UDP data
|
|
|
|
* is added to the read-ahead buffer. The worker function will execute
|
2018-09-11 16:49:39 +02:00
|
|
|
* on the low priority worker thread.
|
2018-09-09 19:57:25 +02:00
|
|
|
*
|
2018-09-09 17:21:39 +02:00
|
|
|
* Input Parameters:
|
2018-09-11 16:49:39 +02:00
|
|
|
* worker - The worker function to execute on the low priority work
|
|
|
|
* queue when data is available in the UDP read-ahead buffer.
|
2018-09-09 17:21:39 +02:00
|
|
|
* conn - The UDP connection where read-ahead data is needed.
|
2018-09-09 23:01:44 +02:00
|
|
|
* arg - A user-defined argument that will be available to the worker
|
|
|
|
* function when it runs.
|
2018-09-09 17:21:39 +02:00
|
|
|
*
|
|
|
|
* Returned Value:
|
2018-09-11 16:49:39 +02:00
|
|
|
* > 0 - The notification is in place. The returned value is a key that
|
|
|
|
* may be used later in a call to udp_notifier_teardown().
|
|
|
|
* == 0 - There is already buffered read-ahead data. No notification
|
|
|
|
* will be provided.
|
|
|
|
* < 0 - An unexpected error occurred and no notification will occur.
|
|
|
|
* The returned value is a negated errno value that indicates the
|
2018-09-09 17:21:39 +02:00
|
|
|
* nature of the failure.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
|
2018-09-09 23:01:44 +02:00
|
|
|
int udp_notifier_setup(worker_t worker, FAR struct udp_conn_s *conn,
|
|
|
|
FAR void *arg);
|
2018-09-09 17:21:39 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_notifier_teardown
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Eliminate a UDP read-ahead notification previously setup by
|
|
|
|
* udp_notifier_setup(). This function should only be called if the
|
|
|
|
* notification should be aborted prior to the notification. The
|
2018-09-11 16:49:39 +02:00
|
|
|
* notification will automatically be torn down after the notification.
|
2018-09-09 17:21:39 +02:00
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* key - The key value returned from a previous call to
|
|
|
|
* udp_notifier_setup().
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
|
|
|
* any failure.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
|
|
|
|
int udp_notifier_teardown(int key);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: udp_notifier_signal
|
|
|
|
*
|
|
|
|
* Description:
|
2018-09-11 16:49:39 +02:00
|
|
|
* Read-ahead data has been buffered. Notify all threads waiting for
|
2018-09-09 17:21:39 +02:00
|
|
|
* read-ahead data to become available.
|
|
|
|
*
|
2018-09-09 23:01:44 +02:00
|
|
|
* When read-ahead data becomes available, *all* of the workers waiting
|
|
|
|
* for read-ahead data will be executed. If there are multiple workers
|
|
|
|
* waiting for read-ahead data then only the first to execute will get the
|
|
|
|
* data. Others will need to call udp_notifier_setup() once again.
|
2018-09-09 19:57:25 +02:00
|
|
|
*
|
2018-09-09 17:21:39 +02:00
|
|
|
* Input Parameters:
|
|
|
|
* conn - The UDP connection where read-ahead data was just buffered.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
|
|
|
|
void udp_notifier_signal(FAR struct udp_conn_s *conn);
|
|
|
|
#endif
|
|
|
|
|
2014-06-25 02:12:49 +02:00
|
|
|
#undef EXTERN
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-03-31 16:58:14 +02:00
|
|
|
#endif /* CONFIG_NET_UDP && !CONFIG_NET_UDP_NO_STACK */
|
2014-06-25 02:12:49 +02:00
|
|
|
#endif /* __NET_UDP_UDP_H */
|