Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions net/inet/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
SOCK_CSRCS += inet_txdrain.c

ifeq ($(CONFIG_NET_IPv4),y)
SOCK_CSRCS += inet_sockif.c inet_recvfrom.c inet_close.c
SOCK_CSRCS += inet_sockif.c
SOCK_CSRCS += inet_globals.c
else ifeq ($(CONFIG_NET_IPv6),y)
SOCK_CSRCS += inet_sockif.c inet_recvfrom.c inet_close.c
SOCK_CSRCS += inet_sockif.c
SOCK_CSRCS += inet_globals.c
endif

Expand Down
35 changes: 0 additions & 35 deletions net/inet/inet.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,41 +240,6 @@ int ipv6_getpeername(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
#endif

/****************************************************************************
* Name: inet_recvfrom
*
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* and AF_INET6 address families. inet_recvfrom() receives messages from
* a socket, and may be used to receive data on a socket whether or not it
* is connection-oriented.
*
* If 'from' is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'fromlen' is
* initialized to the size of the buffer associated with from, and
* modified on return to indicate the actual size of the address stored
* there.
*
* Input Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recvfrom() for the list of appropriate error values).
*
****************************************************************************/

ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);

/****************************************************************************
* Name: inet_close
*
Expand Down
243 changes: 241 additions & 2 deletions net/inet/inet_sockif.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ static ssize_t inet_sendto(FAR struct socket *psock, FAR const void *buf,
static ssize_t inet_sendfile(FAR struct socket *psock, FAR struct file *infile,
FAR off_t *offset, size_t count);
#endif
static ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);

/****************************************************************************
* Private Data
Expand Down Expand Up @@ -1113,13 +1116,15 @@ static ssize_t inet_send(FAR struct socket *psock, FAR const void *buf,
{
/* UDP/IP packet send */

ret = psock_udp_send(psock, buf, len);
ret = _SS_ISCONNECTED(psock->s_flags) ?
psock_udp_sendto(psock, buf, len, 0, NULL, 0) : -ENOTCONN;
}
#endif /* NET_UDP_HAVE_STACK */
#elif defined(NET_UDP_HAVE_STACK)
/* Only UDP/IP packet send */

ret = psock_udp_send(psock, buf, len);
ret = _SS_ISCONNECTED(psock->s_flags) ?
psock_udp_sendto(psock, buf, len, 0, NULL, 0) : -ENOTCONN;
#else
ret = -ENOSYS;
#endif /* CONFIG_NET_6LOWPAN */
Expand Down Expand Up @@ -1272,12 +1277,246 @@ static ssize_t inet_sendfile(FAR struct socket *psock,
}
#endif

/****************************************************************************
* Name: inet_recvfrom
*
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* and AF_INET6 address families. inet_recvfrom() receives messages from
* a socket, and may be used to receive data on a socket whether or not it
* is connection-oriented.
*
* If 'from' is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'fromlen' is
* initialized to the size of the buffer associated with from, and
* modified on return to indicate the actual size of the address stored
* there.
*
* Input Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recvfrom() for the list of appropriate error values).
*
****************************************************************************/

static ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen)
{
ssize_t ret;

/* If a 'from' address has been provided, verify that it is large
* enough to hold this address family.
*/

if (from)
{
socklen_t minlen;

/* Get the minimum socket length */

switch (psock->s_domain)
{
#ifdef CONFIG_NET_IPv4
case PF_INET:
{
minlen = sizeof(struct sockaddr_in);
}
break;
#endif

#ifdef CONFIG_NET_IPv6
case PF_INET6:
{
minlen = sizeof(struct sockaddr_in6);
}
break;
#endif

default:
DEBUGPANIC();
return -EINVAL;
}

if (*fromlen < minlen)
{
return -EINVAL;
}
}

/* Read from the network interface driver buffer.
* Or perform the TCP/IP or UDP recv() operation.
*/

switch (psock->s_type)
{
#ifdef CONFIG_NET_TCP
case SOCK_STREAM:
{
#ifdef NET_TCP_HAVE_STACK
ret = psock_tcp_recvfrom(psock, buf, len, from, fromlen);
#else
ret = -ENOSYS;
#endif
}
break;
#endif /* CONFIG_NET_TCP */

#ifdef CONFIG_NET_UDP
case SOCK_DGRAM:
{
#ifdef NET_UDP_HAVE_STACK
ret = psock_udp_recvfrom(psock, buf, len, from, fromlen);
#else
ret = -ENOSYS;
#endif
}
break;
#endif /* CONFIG_NET_UDP */

default:
{
nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
ret = -ENOSYS;
}
break;
}

return ret;
}

#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: inet_close
*
* Description:
* Performs the close operation on an AF_INET or AF_INET6 socket instance
*
* Input Parameters:
* psock Socket instance
*
* Returned Value:
* 0 on success; -1 on error with errno set appropriately.
*
* Assumptions:
*
****************************************************************************/

int inet_close(FAR struct socket *psock)
{
/* Perform some pre-close operations for the AF_INET/AF_INET6 address
* types.
*/

switch (psock->s_type)
{
#ifdef CONFIG_NET_TCP
case SOCK_STREAM:
{
#ifdef NET_TCP_HAVE_STACK
FAR struct tcp_conn_s *conn = psock->s_conn;
int ret;

/* Is this the last reference to the connection structure (there
* could be more if the socket was dup'ed).
*/

if (conn->crefs <= 1)
{
/* Yes... Clost the socket */

ret = tcp_close(psock);
if (ret < 0)
{
/* This would normally occur only if there is a timeout
* from a lingering close.
*/

nerr("ERROR: tcp_close failed: %d\n", ret);
return ret;
}
}
else
{
/* No.. Just decrement the reference count */

conn->crefs--;

/* Stop monitor for this socket only */

tcp_close_monitor(psock);
}
#else
nwarn("WARNING: SOCK_STREAM support is not available in this "
"configuration\n");
return -EAFNOSUPPORT;
#endif /* NET_TCP_HAVE_STACK */
}
break;
#endif /* CONFIG_NET_TCP */

#ifdef CONFIG_NET_UDP
case SOCK_DGRAM:
{
#ifdef NET_UDP_HAVE_STACK
FAR struct udp_conn_s *conn = psock->s_conn;
int ret;

/* Is this the last reference to the connection structure (there
* could be more if the socket was dup'ed).
*/

if (conn->crefs <= 1)
{
/* Yes... Clost the socket */

ret = udp_close(psock);
if (ret < 0)
{
/* This would normally occur only if there is a timeout
* from a lingering close.
*/

nerr("ERROR: udp_close failed: %d\n", ret);
return ret;
}
}
else
{
/* No.. Just decrement the reference count */

conn->crefs--;
}
#else
nwarn("WARNING: SOCK_DGRAM support is not available in this "
"configuration\n");
return -EAFNOSUPPORT;
#endif /* NET_UDP_HAVE_STACK */
}
break;
#endif /* CONFIG_NET_UDP */

default:
return -EBADF;
}

return OK;
}

/****************************************************************************
* Name: inet_sockif
*
Expand Down
4 changes: 2 additions & 2 deletions net/tcp/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ifneq ($(CONFIG_NET_TCP_NO_STACK),y)

# Socket layer

SOCK_CSRCS += tcp_connect.c tcp_accept.c
SOCK_CSRCS += tcp_connect.c tcp_accept.c tcp_recvfrom.c

ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y)
SOCK_CSRCS += tcp_send_buffered.c
Expand All @@ -66,7 +66,7 @@ endif
# Transport layer

NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_finddev.c tcp_timer.c
NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c
NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c tcp_close.c
NET_CSRCS += tcp_monitor.c tcp_callback.c tcp_backlog.c tcp_ipselect.c
NET_CSRCS += tcp_recvwindow.c tcp_netpoll.c

Expand Down
Loading