diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 93a6deadc88..7dee03d5ae4 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -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 diff --git a/libc/stdlib/lib_mkstemp.c b/libc/stdlib/lib_mkstemp.c index 498d424e373..1e85f2b2d84 100644 --- a/libc/stdlib/lib_mkstemp.c +++ b/libc/stdlib/lib_mkstemp.c @@ -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. * ****************************************************************************/ diff --git a/net/local/local_sockif.c b/net/local/local_sockif.c index 1b8d42b6408..56c4b513a96 100644 --- a/net/local/local_sockif.c +++ b/net/local/local_sockif.c @@ -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 * diff --git a/net/pkt/pkt_sockif.c b/net/pkt/pkt_sockif.c index ded05d6ea89..ae2542d619f 100644 --- a/net/pkt/pkt_sockif.c +++ b/net/pkt/pkt_sockif.c @@ -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 * diff --git a/net/socket/accept.c b/net/socket/accept.c index 093b16e438d..48b76d15e04 100644 --- a/net/socket/accept.c +++ b/net/socket/accept.c @@ -38,8 +38,6 @@ ****************************************************************************/ #include -#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 && \ - (defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM)) #include #include @@ -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 */ diff --git a/net/socket/inet_recvfrom.c b/net/socket/inet_recvfrom.c index 3e29b93e4ba..d908e12cd40 100644 --- a/net/socket/inet_recvfrom.c +++ b/net/socket/inet_recvfrom.c @@ -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: diff --git a/net/socket/inet_sockif.c b/net/socket/inet_sockif.c index f1c1f9ae636..6ef3f8b824c 100644 --- a/net/socket/inet_sockif.c +++ b/net/socket/inet_sockif.c @@ -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 * diff --git a/net/socket/net_clone.c b/net/socket/net_clone.c index 5c417027747..7ab3852574d 100644 --- a/net/socket/net_clone.c +++ b/net/socket/net_clone.c @@ -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; diff --git a/net/socket/net_vfcntl.c b/net/socket/net_vfcntl.c index 79df78379bc..d96988515f0 100644 --- a/net/socket/net_vfcntl.c +++ b/net/socket/net_vfcntl.c @@ -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"); }