Socket I/F: Add address family support for poll() and sendfile()

This commit is contained in:
Gregory Nutt
2017-07-14 10:57:38 -06:00
parent 0134d0fef7
commit 8bf8c3fa86
9 changed files with 1038 additions and 843 deletions
+9
View File
@@ -123,11 +123,20 @@ struct sock_intf_s
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);
#ifndef CONFIG_DISABLE_POLL
CODE int (*si_poll)(FAR struct socket *psock,
FAR struct pollfd *fds, bool setup);
#endif
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);
#ifdef CONFIG_NET_SENDFILE
CODE ssize_t (*si_sendfile)(FAR struct socket *psock,
FAR struct file *infile, FAR off_t *offset,
size_t count)
#endif
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);
+54
View File
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -67,6 +68,10 @@ static int local_getsockname(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
static int local_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
#ifndef CONFIG_DISABLE_POLL
static int local_poll(FAR struct socket *psock,
FAR struct pollfd *fds, bool setup);
#endif
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,
@@ -88,8 +93,14 @@ const struct sock_intf_s g_local_sockif =
local_listen, /* si_listen */
local_connect, /* si_connect */
local_accept, /* si_accept */
#ifndef CONFIG_DISABLE_POLL
local_poll, /* si_poll */
#endif
local_send, /* si_send */
local_sendto, /* si_sendto */
#ifdef CONFIG_NET_SENDFILE
NULL, /* si_sendfile */
#endif
local_recvfrom, /* si_recvfrom */
local_close /* si_close */
};
@@ -465,6 +476,49 @@ static int local_connect(FAR struct socket *psock,
}
}
/****************************************************************************
* Name: local_poll
*
* Description:
* The standard poll() operation redirects operations on socket descriptors
* to local_poll which, indiectly, calls to function.
*
* Input Parameters:
* psock - An instance of the internal socket structure.
* fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events.
* setup - true: Setup up the poll; false: Teardown the poll
*
* Returned Value:
* 0: Success; Negated errno on failure
*
****************************************************************************/
#ifndef CONFIG_DISABLE_POLL
static int local_poll(FAR struct socket *psock, FAR struct pollfd *fds,
bool setup)
{
#ifndef HAVE_LOCAL_POLL
return -ENOSYS;
#else
/* Check if we are setting up or tearing down the poll */
if (setup)
{
/* Perform the TCP/IP poll() setup */
return local_pollsetup(psock, fds);
}
else
{
/* Perform the TCP/IP poll() teardown */
return loal_pollteardown(psock, fds);
}
#endif /* HAVE_LOCAL_POLL */
}
#endif /* !CONFIG_DISABLE_POLL */
/****************************************************************************
* Name: local_send
*
+37
View File
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
@@ -70,6 +71,10 @@ 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);
#ifndef CONFIG_DISABLE_POLL
static int pkt_poll(FAR struct socket *psock,
FAR struct pollfd *fds, bool setup);
#endif
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,
@@ -91,8 +96,14 @@ const struct sock_intf_s g_pkt_sockif =
pkt_listen, /* si_listen */
pkt_connect, /* si_connect */
pkt_accept, /* si_accept */
#ifndef CONFIG_DISABLE_POLL
pkt_poll, /* si_poll */
#endif
pkt_send, /* si_send */
pkt_sendto, /* si_sendto */
#ifdef CONFIG_NET_SENDFILE
NULL, /* si_sendfile */
#endif
pkt_recvfrom, /* si_recvfrom */
pkt_close /* si_close */
};
@@ -445,6 +456,32 @@ int pkt_listen(FAR struct socket *psock, int backlog)
return -EOPNOTSUPP;
}
/****************************************************************************
* Name: pkt_poll
*
* Description:
* The standard poll() operation redirects operations on socket descriptors
* to net_poll which, indiectly, calls to function.
*
* Input Parameters:
* psock - An instance of the internal socket structure.
* fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events.
* setup - true: Setup up the poll; false: Teardown the poll
*
* Returned Value:
* 0: Success; Negated errno on failure
*
****************************************************************************/
#ifndef CONFIG_DISABLE_POLL
static int pkt_poll(FAR struct socket *psock, FAR struct pollfd *fds,
bool setup)
{
return -ENOSYS;
}
#endif /* !CONFIG_DISABLE_POLL */
/****************************************************************************
* Name: pkt_send
*
+8
View File
@@ -57,6 +57,14 @@ ifeq ($(CONFIG_NET_IPv6),y)
SOCK_CSRCS += ipv6_getsockname.c
endif
ifeq ($(CONFIG_NET_SENDFILE),y)
ifeq ($(CONFIG_NET_TCP),y)
ifneq ($(CONFIG_NET_TCP_NO_STACK),y)
SOCK_CSRCS += inet_sendfile.c
endif
endif
endif
# TCP/IP support
ifeq ($(CONFIG_NET_TCP),y)
File diff suppressed because it is too large Load Diff
+150
View File
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -69,6 +70,10 @@ 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);
#ifndef CONFIG_DISABLE_POLL
static int inet_poll(FAR struct socket *psock,
FAR struct pollfd *fds, bool setup);
#endif
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,
@@ -89,8 +94,18 @@ const struct sock_intf_s g_inet_sockif =
inet_listen, /* si_listen */
inet_connect, /* si_connect */
inet_accept, /* si_accept */
#ifndef CONFIG_DISABLE_POLL
inet_poll, /* si_poll */
#endif
inet_send, /* si_send */
inet_sendto, /* si_sendto */
#ifdef CONFIG_NET_SENDFILE
#if defined(CONFIG_NET_TCP) && defined(NET_TCP_HAVE_STACK)
inet_sendfile, /* si_sendfile */
#else
NULL, /* si_sendfile */
#endif
#endif
inet_recvfrom, /* si_recvfrom */
inet_close /* si_close */
};
@@ -862,6 +877,141 @@ errout_with_lock:
#endif /* CONFIG_NET_TCP */
}
/****************************************************************************
* Name: inet_pollsetup
*
* Description:
* Setup to monitor events on one socket
*
* Input Parameters:
* psock - The 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
*
****************************************************************************/
#if defined(HAVE_TCP_POLL) || defined(HAVE_UDP_POLL)
static inline int inet_pollsetup(FAR struct socket *psock,
FAR struct pollfd *fds)
{
#ifdef HAVE_TCP_POLL
if (psock->s_type == SOCK_STREAM)
{
return tcp_pollsetup(psock, fds);
}
else
#endif /* HAVE_TCP_POLL */
#ifdef HAVE_UDP_POLL
if (psock->s_type != SOCK_STREAM)
{
return udp_pollsetup(psock, fds);
}
else
#endif /* HAVE_UDP_POLL */
{
return -ENOSYS;
}
}
#endif /* HAVE_TCP_POLL || HAVE_UDP_POLL */
/****************************************************************************
* Name: inet_pollteardown
*
* Description:
* Teardown monitoring of events on an socket
*
* Input Parameters:
* psock - The TCP/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
*
****************************************************************************/
#if defined(HAVE_TCP_POLL) || defined(HAVE_UDP_POLL)
static inline int inet_pollteardown(FAR struct socket *psock,
FAR struct pollfd *fds)
{
#ifdef HAVE_TCP_POLL
if (psock->s_type == SOCK_STREAM)
{
return tcp_pollteardown(psock, fds);
}
else
#endif /* HAVE_TCP_POLL */
#ifdef HAVE_UDP_POLL
if (psock->s_type == SOCK_DGRAM)
{
return udp_pollteardown(psock, fds);
}
else
#endif /* HAVE_UDP_POLL */
{
return -ENOSYS;
}
}
#endif /* HAVE_TCP_POLL || HAVE_UDP_POLL */
/****************************************************************************
* Name: inet_poll
*
* Description:
* The standard poll() operation redirects operations on socket descriptors
* to net_poll which, indiectly, calls to function.
*
* Input Parameters:
* psock - An instance of the internal socket structure.
* fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events.
* setup - true: Setup up the poll; false: Teardown the poll
*
* Returned Value:
* 0: Success; Negated errno on failure
*
****************************************************************************/
#ifndef CONFIG_DISABLE_POLL
static int inet_poll(FAR struct socket *psock, FAR struct pollfd *fds,
bool setup)
{
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE)
{
/* Perform usrsock setup/teardown. */
return usrsock_poll(psock, fds, setup);
}
else
#endif
#if defined(HAVE_TCP_POLL) || defined(HAVE_UDP_POLL)
/* Check if we are setting up or tearing down the poll */
if (setup)
{
/* Perform the TCP/IP poll() setup */
return inet_pollsetup(psock, fds);
}
else
{
/* Perform the TCP/IP poll() teardown */
return inet_pollteardown(psock, fds);
}
#else
{
return -ENOSYS;
}
#endif /* HAVE_TCP_POLL || !HAVE_UDP_POLL */
}
#endif /* !CONFIG_DISABLE_POLL */
/****************************************************************************
* Name: inet_send
*
+10 -191
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* net/socket/net_poll.c
*
* Copyright (C) 2008-2009, 2011-2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2011-2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,173 +39,15 @@
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include "tcp/tcp.h"
#include "udp/udp.h"
#include "local/local.h"
#include <nuttx/net/net.h>
#include "socket/socket.h"
#include "usrsock/usrsock.h"
#if defined(CONFIG_NET) && !defined(CONFIG_DISABLE_POLL)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Network polling can only be supported if poll support is provided by TCP,
* UDP, or LOCAL sockets.
*/
#undef HAVE_NET_POLL
#if defined(HAVE_TCP_POLL) || defined(HAVE_UDP_POLL) || \
defined(HAVE_LOCAL_POLL) || defined(CONFIG_NET_USRSOCK)
# define HAVE_NET_POLL 1
#endif
#ifdef HAVE_NET_POLL
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: net_pollsetup
*
* Description:
* Setup to monitor events on one socket
*
* Input Parameters:
* psock - The 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
*
****************************************************************************/
static inline int net_pollsetup(FAR struct socket *psock,
FAR struct pollfd *fds)
{
#if defined(HAVE_TCP_POLL) || defined(HAVE_LOCAL_POLL)
if (psock->s_type == SOCK_STREAM)
{
#ifdef HAVE_LOCAL_POLL
#ifdef HAVE_TCP_POLL
if (psock->s_domain == PF_LOCAL)
#endif
{
return local_pollsetup(psock, fds);
}
#endif /* HAVE_LOCAL_POLL */
#ifdef HAVE_TCP_POLL
#ifdef HAVE_LOCAL_POLL
else
#endif
{
return tcp_pollsetup(psock, fds);
}
#endif /* HAVE_TCP_POLL */
}
#endif /* HAVE_TCP_POLL || HAVE_LOCAL_POLL */
#if defined(HAVE_UDP_POLL) || defined(HAVE_LOCAL_POLL)
if (psock->s_type != SOCK_STREAM)
{
#ifdef HAVE_LOCAL_POLL
#ifdef HAVE_UDP_POLL
if (psock->s_domain == PF_LOCAL)
#endif
{
return local_pollsetup(psock, fds);
}
#endif /* HAVE_LOCAL_POLL */
#ifdef HAVE_UDP_POLL
#ifdef HAVE_LOCAL_POLL
else
#endif
{
return udp_pollsetup(psock, fds);
}
#endif /* HAVE_UDP_POLL */
}
#endif /* HAVE_UDP_POLL || HAVE_LOCAL_POLL */
return -ENOSYS;
}
/****************************************************************************
* Name: net_pollteardown
*
* Description:
* Teardown monitoring of events on an socket
*
* Input Parameters:
* psock - The TCP/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
*
****************************************************************************/
static inline int net_pollteardown(FAR struct socket *psock,
FAR struct pollfd *fds)
{
#if defined(HAVE_TCP_POLL) || defined(HAVE_LOCAL_POLL)
if (psock->s_type == SOCK_STREAM)
{
#ifdef HAVE_LOCAL_POLL
#ifdef HAVE_TCP_POLL
if (psock->s_domain == PF_LOCAL)
#endif
{
return local_pollteardown(psock, fds);
}
#endif /* HAVE_LOCAL_POLL */
#ifdef HAVE_TCP_POLL
#ifdef HAVE_LOCAL_POLL
else
#endif
{
return tcp_pollteardown(psock, fds);
}
#endif /* HAVE_TCP_POLL */
}
#endif /* HAVE_TCP_POLL || HAVE_LOCAL_POLL */
#if defined(HAVE_UDP_POLL) || defined(HAVE_LOCAL_POLL)
if (psock->s_type != SOCK_STREAM)
{
#ifdef HAVE_LOCAL_POLL
#ifdef HAVE_UDP_POLL
if (psock->s_domain == PF_LOCAL)
#endif
{
return local_pollteardown(psock, fds);
}
#endif /* HAVE_LOCAL_POLL */
#ifdef HAVE_UDP_POLL
#ifdef HAVE_LOCAL_POLL
else
#endif
{
return udp_pollteardown(psock, fds);
}
#endif /* HAVE_UDP_POLL */
}
#endif /* HAVE_UDP_POLL || HAVE_LOCAL_POLL */
return -ENOSYS;
}
#endif /* HAVE_NET_POLL */
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -230,37 +72,12 @@ static inline int net_pollteardown(FAR struct socket *psock,
int psock_poll(FAR struct socket *psock, FAR struct pollfd *fds, bool setup)
{
#ifndef HAVE_NET_POLL
return -ENOSYS;
#else
int ret;
DEBUGASSERT(psock != NULL && fds != NULL);
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE)
{
/* Perform usrsock setup/teardown. */
/* Let the address family's poll() method handle the operation */
return usrsock_poll(psock, fds, setup);
}
#endif
/* Check if we are setting up or tearing down the poll */
if (setup)
{
/* Perform the TCP/IP poll() setup */
ret = net_pollsetup(psock, fds);
}
else
{
/* Perform the TCP/IP poll() teardown */
ret = net_pollteardown(psock, fds);
}
return ret;
#endif /* HAVE_NET_POLL */
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_poll != NULL);
return psock->s_sockif->si_poll(psock, fds, setup);
}
/****************************************************************************
@@ -288,6 +105,8 @@ int net_poll(int sockfd, struct pollfd *fds, bool setup)
#else
FAR struct socket *psock;
DEBUGASSERT(fds != NULL);
/* Get the underlying socket structure and verify that the sockfd
* corresponds to valid, allocated socket
*/
+27 -652
View File
File diff suppressed because it is too large Load Diff
+26
View File
@@ -500,6 +500,32 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
int inet_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
socklen_t addrlen);
/****************************************************************************
* Name: inet_sendfile
*
* Description:
* The inet_sendfile() call may be used only when the INET socket is in a
* connected state (so that the intended recipient is known).
*
* Parameters:
* psock An instance of the internal socket structure.
* buf Data to send
* len Length of data to send
* flags Send flags
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* a negated errno value is returned. See sendfile() for a list
* appropriate error return values.
*
****************************************************************************/
#if defined(CONFIG_NET_SENDFILE) && defined(CONFIG_NET_TCP) && \
defined(NET_TCP_HAVE_STACK)
ssize_t inet_sendfile(FAR struct socket *psock, FAR struct file *infile,
FAR off_t *offset, size_t count);
#endif
/****************************************************************************
* Name: inet_recvfrom
*