Socket interface: Added addref() and sockcaps() interfaces.

This commit is contained in:
Gregory Nutt 2017-07-13 13:36:18 -06:00
parent 833ee2275d
commit 5033a6def7
9 changed files with 299 additions and 171 deletions

View File

@ -64,6 +64,11 @@
# define __SOCKFD_OFFSET 0
#endif
/* Capabilities of a socket */
#define SOCKCAP_NONBLOCKING (1 << 0) /* Bit 0: Socket supports non-blocking
* operation. */
/****************************************************************************
* Public Types
****************************************************************************/
@ -94,6 +99,10 @@ typedef uint16_t sockopt_t;
typedef uint16_t socktimeo_t;
/* This type defines the type of the socket capabilities set */
typedef uint8_t sockcaps_t;
/* This callbacks are socket operations that may be performed on a socket of
* a given address family.
*/
@ -102,23 +111,25 @@ struct socket; /* Forward reference */
struct sock_intf_s
{
CODE int (*si_setup)(FAR struct socket *psock, int protocol);
CODE int (*si_bind)(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
CODE int (*si_listen)(FAR struct socket *psock, int backlog);
CODE int (*si_connect)(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
CODE int (*si_accept)(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
CODE ssize_t (*si_send)(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
CODE ssize_t (*si_sendto)(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
CODE ssize_t (*si_recvfrom)(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);
CODE int (*si_close)(FAR struct socket *psock);
CODE int (*si_setup)(FAR struct socket *psock, int protocol);
CODE sockcaps_t (*si_sockcaps)(FAR struct socket *psock);
CODE void (*si_addref)(FAR struct socket *psock);
CODE int (*si_bind)(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
CODE int (*si_listen)(FAR struct socket *psock, int backlog);
CODE int (*si_connect)(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
CODE int (*si_accept)(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
CODE ssize_t (*si_send)(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
CODE ssize_t (*si_sendto)(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
CODE ssize_t (*si_recvfrom)(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);
CODE int (*si_close)(FAR struct socket *psock);
};
/* This is the internal representation of a socket reference by a file

View File

@ -209,9 +209,8 @@ static void copy_base62(FAR char *dest, int len)
* that full path.
*
* Returned Value:
*
* Upon successful completion, mkstemp() returns an open file descriptor.
* Otherwise, -1 is returned if no suitable file could be created.
* Upon successful completion, mkstemp() returns an open file descriptor.
* Otherwise, -1 is returned if no suitable file could be created.
*
****************************************************************************/

View File

@ -57,19 +57,21 @@
* Private Function Prototypes
****************************************************************************/
static int local_setup(FAR struct socket *psock, int protocol);
static int local_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int local_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
static ssize_t local_send(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
static ssize_t local_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
static int local_close(FAR struct socket *psock);
static int local_setup(FAR struct socket *psock, int protocol);
static sockcaps_t local_sockcaps(FAR struct socket *psock);
static void local_addref(FAR struct socket *psock);
static int local_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int local_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
static ssize_t local_send(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
static ssize_t local_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
static int local_close(FAR struct socket *psock);
/****************************************************************************
* Public Data
@ -78,6 +80,8 @@ static int local_close(FAR struct socket *psock);
const struct sock_intf_s g_local_sockif =
{
local_setup, /* si_setup */
local_sockcaps, /* si_sockcaps */
local_addref, /* si_addref */
local_bind, /* si_bind */
local_listen, /* si_listen */
local_connect, /* si_connect */
@ -183,6 +187,53 @@ static int local_setup(FAR struct socket *psock, int protocol)
}
}
/****************************************************************************
* Name: local_sockcaps
*
* Description:
* Return the bit encoded capabilities of this socket.
*
* Parameters:
* psock - Socket structure of the socket whose capabilities are being
* queried.
*
* Returned Value:
* The set of socket cababilities is returned.
*
****************************************************************************/
static sockcaps_t local_sockcaps(FAR struct socket *psock)
{
return SOCKCAP_NONBLOCKING;
}
/****************************************************************************
* Name: local_addref
*
* Description:
* Increment the refernce count on the underlying connection structure.
*
* Parameters:
* psock - Socket structure of the socket whose reference count will be
* incremented.
*
* Returned Value:
* None
*
****************************************************************************/
static void local_addref(FAR struct socket *psock)
{
FAR struct local_conn_s *conn;
DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
psock->s_domain == PF_LOCAL);
conn = psock->s_conn;
DEBUGASSERT(conn->lc_crefs > 0 && conn->lc_crefs < 255);
conn->lc_crefs++;
}
/****************************************************************************
* Name: local_bind
*

View File

@ -55,20 +55,22 @@
* Private Function Prototypes
****************************************************************************/
static int pkt_setup(FAR struct socket *psock, int protocol);
static int pkt_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int pkt_listen(FAR struct socket *psock, int backlog);
static int pkt_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int pkt_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
static ssize_t pkt_send(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
static ssize_t pkt_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
static int pkt_close(FAR struct socket *psock);
static int pkt_setup(FAR struct socket *psock, int protocol);
static sockcaps_t pkt_sockcaps(FAR struct socket *psock);
static void pkt_addref(FAR struct socket *psock);
static int pkt_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int pkt_listen(FAR struct socket *psock, int backlog);
static int pkt_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int pkt_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
static ssize_t pkt_send(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
static ssize_t pkt_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
static int pkt_close(FAR struct socket *psock);
/****************************************************************************
* Public Data
@ -77,6 +79,8 @@ static int pkt_close(FAR struct socket *psock);
const struct sock_intf_s g_pkt_sockif =
{
pkt_setup, /* si_setup */
pkt_sockcaps, /* si_sockcaps */
pkt_addref, /* si_addref */
pkt_bind, /* si_bind */
pkt_listen, /* si_listen */
pkt_connect, /* si_connect */
@ -164,6 +168,53 @@ static int pkt_setup(FAR struct socket *psock, int protocol)
}
}
/****************************************************************************
* Name: pkt_sockcaps
*
* Description:
* Return the bit encoded capabilities of this socket.
*
* Parameters:
* psock - Socket structure of the socket whose capabilities are being
* queried.
*
* Returned Value:
* The set of socket cababilities is returned.
*
****************************************************************************/
static sockcaps_t pkt_sockcaps(FAR struct socket *psock)
{
return 0;
}
/****************************************************************************
* Name: pkt_addref
*
* Description:
* Increment the refernce count on the underlying connection structure.
*
* Parameters:
* psock - Socket structure of the socket whose reference count will be
* incremented.
*
* Returned Value:
* None
*
****************************************************************************/
static void pkt_addref(FAR struct socket *psock)
{
FAR struct pkt_conn_s *conn;
DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
psock->s_type == SOCK_RAW);
conn = psock->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
/****************************************************************************
* Name: pkt_connect
*

View File

@ -38,8 +38,6 @@
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 && \
(defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM))
#include <sys/types.h>
#include <sys/socket.h>
@ -56,6 +54,8 @@
#include "socket/socket.h"
#include "usrsock/usrsock.h"
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
/****************************************************************************
* Public Functions
****************************************************************************/
@ -129,9 +129,7 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock)
{
int errcode;
#if defined(NET_TCP_HAVE_STACK) || defined(CONFIG_NET_LOCAL_STREAM)
int ret;
#endif
DEBUGASSERT(psock != NULL && psock->s_conn != NULL && newsock != NULL);
@ -323,4 +321,4 @@ errout:
return ERROR;
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS && (CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM) */
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */

View File

@ -1648,7 +1648,7 @@ ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
#endif
}
break;
#endif /* CONFIG_NET_UDP || CONFIG_NET_LOCAL_DGRAM */
#endif /* CONFIG_NET_UDP */
#ifdef CONFIG_NET_USRSOCK
case SOCK_USRSOCK_TYPE:

View File

@ -58,17 +58,20 @@
* Private Function Prototypes
****************************************************************************/
static int inet_setup(FAR struct socket *psock, int protocol);
static int inet_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int inet_listen(FAR struct socket *psock, int backlog);
static int inet_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
static ssize_t inet_send(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
static ssize_t inet_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
static int inet_setup(FAR struct socket *psock, int protocol);
static sockcaps_t inet_sockcaps(FAR struct socket *psock);
static void inet_addref(FAR struct socket *psock);
static int inet_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int inet_listen(FAR struct socket *psock, int backlog);
static int inet_accept(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen,
FAR struct socket *newsock);
static ssize_t inet_send(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
static ssize_t inet_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
/****************************************************************************
* Public Data
@ -77,6 +80,8 @@ static ssize_t inet_sendto(FAR struct socket *psock, FAR const void *buf,
const struct sock_intf_s g_inet_sockif =
{
inet_setup, /* si_setup */
inet_sockcaps, /* si_sockcaps */
inet_addref, /* si_addref */
inet_bind, /* si_bind */
inet_listen, /* si_listen */
inet_connect, /* si_connect */
@ -317,6 +322,104 @@ static int inet_setup(FAR struct socket *psock, int protocol)
}
}
/****************************************************************************
* Name: inet_sockcaps
*
* Description:
* Return the bit encoded capabilities of this socket.
*
* Parameters:
* psock - Socket structure of the socket whose capabilities are being
* queried.
*
* Returned Value:
* The non-negative set of socket cababilities is returned.
*
****************************************************************************/
static sockcaps_t inet_sockcaps(FAR struct socket *psock)
{
switch (psock->s_type)
{
#ifdef NET_TCP_HAVE_STACK
case SOCK_STREAM:
#ifdef CONFIG_NET_TCP_READAHEAD
return SOCKCAP_NONBLOCKING;
#else
return 0;
#endif
#endif
#ifdef NET_UDP_HAVE_STACK
case SOCK_DGRAM:
#ifdef CONFIG_NET_UDP_READAHEAD
return SOCKCAP_NONBLOCKING;
#else
return 0;
#endif
#endif
#ifdef CONFIG_NET_USRSOCK
case SOCK_USRSOCK_TYPE:
return SOCKCAP_NONBLOCKING;
#endif
default:
return 0;
}
}
/****************************************************************************
* Name: inet_addref
*
* Description:
* Increment the refernce count on the underlying connection structure.
*
* Parameters:
* psock - Socket structure of the socket whose reference count will be
* incremented.
*
* Returned Value:
* None
*
****************************************************************************/
static void inet_addref(FAR struct socket *psock)
{
DEBUGASSERT(psock != NULL && psock->s_conn != NULL);
#ifdef NET_TCP_HAVE_STACK
if (psock->s_type == SOCK_STREAM)
{
FAR struct tcp_conn_s *conn = psock->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef NET_UDP_HAVE_STACK
if (psock->s_type == SOCK_DGRAM)
{
FAR struct udp_conn_s *conn = psock->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE)
{
FAR struct usrsock_conn_s *conn = psock->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
{
nerr("ERROR: Unsupported type: %d\n", psock->s_type);
}
}
/****************************************************************************
* Name: inet_bind
*

View File

@ -95,60 +95,16 @@ int net_clone(FAR struct socket *psock1, FAR struct socket *psock2)
* instance for TCP send */
#endif
/* Increment the reference count on the connection */
/* Increment the reference count on the socket */
DEBUGASSERT(psock2->s_conn);
psock2->s_crefs = 1; /* One reference on the new socket itself */
#ifdef CONFIG_NET_LOCAL
if (psock2->s_domain == PF_LOCAL)
{
FAR struct local_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->lc_crefs > 0 && conn->lc_crefs < 255);
conn->lc_crefs++;
}
else
#endif
#ifdef CONFIG_NET_PKT
if (psock2->s_type == SOCK_RAW)
{
FAR struct pkt_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef NET_TCP_HAVE_STACK
if (psock2->s_type == SOCK_STREAM)
{
FAR struct tcp_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef NET_UDP_HAVE_STACK
if (psock2->s_type == SOCK_DGRAM)
{
FAR struct udp_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef CONFIG_NET_USRSOCK
if (psock2->s_type == SOCK_USRSOCK_TYPE)
{
FAR struct usrsock_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
{
nerr("ERROR: Unsupported type: %d\n", psock2->s_type);
ret = -EBADF;
}
/* Increment the reference count on the underlying connection structure
* for this address family type.
*/
DEBUGASSERT(psock2->s_sockif != NULL && psock2->s_sockif->si_addref != NULL);
psock2->s_sockif->si_addref(psock2);
net_unlock();
return ret;

View File

@ -84,7 +84,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
/* Verify that the sockfd corresponds to valid, allocated socket */
if (!psock || psock->s_crefs <= 0)
if (psock == NULL || psock->s_crefs <= 0)
{
errcode = EBADF;
goto errout;
@ -140,38 +140,25 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
*/
{
sockcaps_t sockcaps;
/* This summarizes the behavior of all NuttX sockets */
ret = O_RDWR | O_SYNC | O_RSYNC;
#if defined(CONFIG_NET_LOCAL) || defined(CONFIG_NET_TCP_READAHEAD) || \
defined(CONFIG_NET_UDP_READAHEAD)
/* Unix domain sockets may be non-blocking. TCP/IP and UDP/IP
* sockets may also be non-blocking if read-ahead is enabled
*/
if ((0
#ifdef CONFIG_NET_LOCAL
|| psock->s_domain == PF_LOCAL /* Unix domain stream or datagram */
#endif
#ifdef CONFIG_NET_TCP_READAHEAD
|| psock->s_type == SOCK_STREAM /* IP or Unix domain stream */
#endif
#ifdef CONFIG_NET_UDP_READAHEAD
|| psock->s_type == SOCK_DGRAM /* IP or Unix domain datagram */
#endif
) && _SS_ISNONBLOCK(psock->s_flags))
{
ret |= O_NONBLOCK;
}
#endif /* CONFIG_NET_LOCAL || CONFIG_NET_TCP_READAHEAD || CONFIG_NET_UDP_READAHEAD */
DEBUGASSERT(psock->s_sockif != NULL &&
psock->s_sockif->si_sockcaps != NULL);
sockcaps = psock->s_sockif->si_sockcaps(psock);
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE && _SS_ISNONBLOCK(psock->s_flags))
if ((sockcaps & SOCKCAP_NONBLOCKING) != 0 &&
_SS_ISNONBLOCK(psock->s_flags))
{
ret |= O_NONBLOCK;
}
#endif
}
break;
@ -185,16 +172,19 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
*/
{
#if defined(CONFIG_NET_LOCAL) || defined(CONFIG_NET_TCP_READAHEAD) || \
defined(CONFIG_NET_UDP_READAHEAD) || defined(CONFIG_NET_USRSOCK)
/* Non-blocking is the only configurable option. And it applies
* only Unix domain sockets and to read operations on TCP/IP
* and UDP/IP sockets when read-ahead is enabled.
*/
int mode = va_arg(ap, int);
#if defined(CONFIG_NET_LOCAL_STREAM) || defined(CONFIG_NET_TCP_READAHEAD)
if (psock->s_type == SOCK_STREAM) /* IP or Unix domain stream */
sockcaps_t sockcaps;
DEBUGASSERT(psock->s_sockif != NULL &&
psock->s_sockif->si_sockcaps != NULL);
sockcaps = psock->s_sockif->si_sockcaps(psock);
if ((sockcaps & SOCKCAP_NONBLOCKING) != 0)
{
if ((mode & O_NONBLOCK) != 0)
{
@ -206,37 +196,6 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
}
}
else
#endif
#if defined(CONFIG_NET_LOCAL_DGRAM) || defined(CONFIG_NET_UDP_READAHEAD)
if (psock->s_type == SOCK_DGRAM) /* IP or Unix domain datagram */
{
if ((mode & O_NONBLOCK) != 0)
{
psock->s_flags |= _SF_NONBLOCK;
}
else
{
psock->s_flags &= ~_SF_NONBLOCK;
}
}
else
#endif
#if defined(CONFIG_NET_USRSOCK)
if (psock->s_type == SOCK_USRSOCK_TYPE) /* usrsock socket */
{
if ((mode & O_NONBLOCK) != 0)
{
psock->s_flags |= _SF_NONBLOCK;
}
else
{
psock->s_flags &= ~_SF_NONBLOCK;
}
}
else
#endif
#endif /* CONFIG_NET_LOCAL || CONFIG_NET_TCP_READAHEAD ||
CONFIG_NET_UDP_READAHEAD || CONFIG_NET_USRSOCK */
{
nerr("ERROR: Non-blocking not supported for this socket\n");
}