net: Implement shutdown() interface and tcp shutdown
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
fcdba7a3ef
commit
8819eeaf15
@ -167,6 +167,7 @@ struct sock_intf_s
|
|||||||
CODE int (*si_ioctl)(FAR struct socket *psock,
|
CODE int (*si_ioctl)(FAR struct socket *psock,
|
||||||
int cmd, unsigned long arg);
|
int cmd, unsigned long arg);
|
||||||
CODE int (*si_socketpair)(FAR struct socket *psocks[2]);
|
CODE int (*si_socketpair)(FAR struct socket *psocks[2]);
|
||||||
|
CODE int (*si_shutdown)(FAR struct socket *psock, int how);
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
CODE int (*si_getsockopt)(FAR struct socket *psock, int level,
|
CODE int (*si_getsockopt)(FAR struct socket *psock, int level,
|
||||||
int option, FAR void *value, FAR socklen_t *value_len);
|
int option, FAR void *value, FAR socklen_t *value_len);
|
||||||
|
@ -366,6 +366,7 @@ SYSCALL_LOOKUP(munmap, 2)
|
|||||||
SYSCALL_LOOKUP(sendto, 6)
|
SYSCALL_LOOKUP(sendto, 6)
|
||||||
SYSCALL_LOOKUP(sendmsg, 3)
|
SYSCALL_LOOKUP(sendmsg, 3)
|
||||||
SYSCALL_LOOKUP(setsockopt, 5)
|
SYSCALL_LOOKUP(setsockopt, 5)
|
||||||
|
SYSCALL_LOOKUP(shutdown, 2)
|
||||||
SYSCALL_LOOKUP(socket, 3)
|
SYSCALL_LOOKUP(socket, 3)
|
||||||
SYSCALL_LOOKUP(socketpair, 4)
|
SYSCALL_LOOKUP(socketpair, 4)
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,7 +26,7 @@ CSRCS += lib_inetntop.c lib_inetpton.c lib_inetnetwork.c
|
|||||||
CSRCS += lib_etherntoa.c lib_etheraton.c
|
CSRCS += lib_etherntoa.c lib_etheraton.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_NET),y)
|
ifeq ($(CONFIG_NET),y)
|
||||||
CSRCS += lib_accept.c lib_shutdown.c
|
CSRCS += lib_accept.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_NET_LOOPBACK),y)
|
ifeq ($(CONFIG_NET_LOOPBACK),y)
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* libs/libc/net/lib_shutdown.c
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership. The
|
|
||||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Included Files
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: shutdown
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* The shutdown() function will cause all or part of a full-duplex
|
|
||||||
* connection on the socket associated with the file descriptor socket to
|
|
||||||
* be shut down.
|
|
||||||
*
|
|
||||||
* The shutdown() function disables subsequent send and/or receive
|
|
||||||
* operations on a socket, depending on the value of the how argument.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* sockfd - Specifies the file descriptor of the socket.
|
|
||||||
* how - Specifies the type of shutdown. The values are as follows:
|
|
||||||
*
|
|
||||||
* SHUT_RD - Disables further receive operations.
|
|
||||||
* SHUT_WR - Disables further send operations.
|
|
||||||
* SHUT_RDWR - Disables further send and receive operations.
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* Upon successful completion, shutdown() will return 0; otherwise, -1 will
|
|
||||||
* be returned and errno set to indicate the error.
|
|
||||||
*
|
|
||||||
* EBADF - The socket argument is not a valid file descriptor.
|
|
||||||
* EINVAL - The how argument is invalid.
|
|
||||||
* ENOTCONN - The socket is not connected.
|
|
||||||
* ENOTSOCK - The socket argument does not refer to a socket.
|
|
||||||
* ENOBUFS - Insufficient resources were available in the system to
|
|
||||||
* perform the operation.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
int shutdown(int sockfd, int how)
|
|
||||||
{
|
|
||||||
/* REVISIT: Not implemented. */
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_NET */
|
|
@ -86,7 +86,8 @@ const struct sock_intf_s g_can_sockif =
|
|||||||
can_recvmsg, /* si_recvmsg */
|
can_recvmsg, /* si_recvmsg */
|
||||||
can_close, /* si_close */
|
can_close, /* si_close */
|
||||||
NULL, /* si_ioctl */
|
NULL, /* si_ioctl */
|
||||||
NULL /* si_socketpair */
|
NULL, /* si_socketpair */
|
||||||
|
NULL /* si_shutdown */
|
||||||
#if defined(CONFIG_NET_SOCKOPTS) && defined(CONFIG_NET_CANPROTO_OPTIONS)
|
#if defined(CONFIG_NET_SOCKOPTS) && defined(CONFIG_NET_CANPROTO_OPTIONS)
|
||||||
, can_getsockopt /* si_getsockopt */
|
, can_getsockopt /* si_getsockopt */
|
||||||
, can_setsockopt /* si_setsockopt */
|
, can_setsockopt /* si_setsockopt */
|
||||||
|
@ -91,6 +91,7 @@ static ssize_t inet_recvmsg(FAR struct socket *psock,
|
|||||||
static int inet_ioctl(FAR struct socket *psock,
|
static int inet_ioctl(FAR struct socket *psock,
|
||||||
int cmd, unsigned long arg);
|
int cmd, unsigned long arg);
|
||||||
static int inet_socketpair(FAR struct socket *psocks[2]);
|
static int inet_socketpair(FAR struct socket *psocks[2]);
|
||||||
|
static int inet_shutdown(FAR struct socket *psock, int how);
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
static int inet_getsockopt(FAR struct socket *psock, int level,
|
static int inet_getsockopt(FAR struct socket *psock, int level,
|
||||||
int option, FAR void *value, FAR socklen_t *value_len);
|
int option, FAR void *value, FAR socklen_t *value_len);
|
||||||
@ -123,7 +124,8 @@ static const struct sock_intf_s g_inet_sockif =
|
|||||||
inet_recvmsg, /* si_recvmsg */
|
inet_recvmsg, /* si_recvmsg */
|
||||||
inet_close, /* si_close */
|
inet_close, /* si_close */
|
||||||
inet_ioctl, /* si_ioctl */
|
inet_ioctl, /* si_ioctl */
|
||||||
inet_socketpair /* si_socketpair */
|
inet_socketpair, /* si_socketpair */
|
||||||
|
inet_shutdown /* si_shutdown */
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
, inet_getsockopt /* si_getsockopt */
|
, inet_getsockopt /* si_getsockopt */
|
||||||
, inet_setsockopt /* si_setsockopt */
|
, inet_setsockopt /* si_setsockopt */
|
||||||
@ -1980,6 +1982,41 @@ errout:
|
|||||||
#endif /* CONFIG_NET_TCP || CONFIG_NET_UDP */
|
#endif /* CONFIG_NET_TCP || CONFIG_NET_UDP */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: inet_shutdown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Performs the shutdown operation on an AF_INET or AF_INET6 socket
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* psock Socket instance
|
||||||
|
* how Specifies the type of shutdown
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: Success; Negated errno on failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int inet_shutdown(FAR struct socket *psock, int how)
|
||||||
|
{
|
||||||
|
switch (psock->s_type)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NET_TCP
|
||||||
|
case SOCK_STREAM:
|
||||||
|
#ifdef NET_TCP_HAVE_STACK
|
||||||
|
return tcp_shutdown(psock, how);
|
||||||
|
#else
|
||||||
|
nwarn("WARNING: SOCK_STREAM support is not available in this "
|
||||||
|
"configuration\n");
|
||||||
|
return -EAFNOSUPPORT;
|
||||||
|
#endif /* NET_TCP_HAVE_STACK */
|
||||||
|
#endif /* CONFIG_NET_TCP */
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: inet_sendfile
|
* Name: inet_sendfile
|
||||||
*
|
*
|
||||||
|
@ -72,6 +72,7 @@ static int local_close(FAR struct socket *psock);
|
|||||||
static int local_ioctl(FAR struct socket *psock,
|
static int local_ioctl(FAR struct socket *psock,
|
||||||
int cmd, unsigned long arg);
|
int cmd, unsigned long arg);
|
||||||
static int local_socketpair(FAR struct socket *psocks[2]);
|
static int local_socketpair(FAR struct socket *psocks[2]);
|
||||||
|
static int local_shutdown(FAR struct socket *psock, int how);
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
static int local_getsockopt(FAR struct socket *psock, int level,
|
static int local_getsockopt(FAR struct socket *psock, int level,
|
||||||
int option, FAR void *value, FAR socklen_t *value_len);
|
int option, FAR void *value, FAR socklen_t *value_len);
|
||||||
@ -99,7 +100,8 @@ const struct sock_intf_s g_local_sockif =
|
|||||||
local_recvmsg, /* si_recvmsg */
|
local_recvmsg, /* si_recvmsg */
|
||||||
local_close, /* si_close */
|
local_close, /* si_close */
|
||||||
local_ioctl, /* si_ioctl */
|
local_ioctl, /* si_ioctl */
|
||||||
local_socketpair /* si_socketpair */
|
local_socketpair, /* si_socketpair */
|
||||||
|
local_shutdown /* si_shutdown */
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
, local_getsockopt /* si_getsockopt */
|
, local_getsockopt /* si_getsockopt */
|
||||||
, local_setsockopt /* si_setsockopt */
|
, local_setsockopt /* si_setsockopt */
|
||||||
@ -958,6 +960,35 @@ errout:
|
|||||||
#endif /* CONFIG_NET_LOCAL_STREAM || CONFIG_NET_LOCAL_DGRAM */
|
#endif /* CONFIG_NET_LOCAL_STREAM || CONFIG_NET_LOCAL_DGRAM */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: local_shutdown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The shutdown() function will cause all or part of a full-duplex
|
||||||
|
* connection on the socket associated with the file descriptor socket to
|
||||||
|
* be shut down.
|
||||||
|
*
|
||||||
|
* The shutdown() function disables subsequent send and/or receive
|
||||||
|
* operations on a socket, depending on the value of the how argument.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* sockfd - Specifies the file descriptor of the socket.
|
||||||
|
* how - Specifies the type of shutdown. The values are as follows:
|
||||||
|
*
|
||||||
|
* SHUT_RD - Disables further receive operations.
|
||||||
|
* SHUT_WR - Disables further send operations.
|
||||||
|
* SHUT_RDWR - Disables further send and receive operations.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int local_shutdown(FAR struct socket *psock, int how)
|
||||||
|
{
|
||||||
|
/* TODO: implement this. */
|
||||||
|
|
||||||
|
nerr("ERROR: local_shutdown is not implemented");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
SOCK_CSRCS += accept.c bind.c connect.c getsockname.c getpeername.c
|
SOCK_CSRCS += accept.c bind.c connect.c getsockname.c getpeername.c
|
||||||
SOCK_CSRCS += listen.c recv.c recvfrom.c send.c sendto.c socket.c
|
SOCK_CSRCS += listen.c recv.c recvfrom.c send.c sendto.c socket.c
|
||||||
SOCK_CSRCS += socketpair.c net_close.c recvmsg.c sendmsg.c
|
SOCK_CSRCS += socketpair.c net_close.c recvmsg.c sendmsg.c shutdown.c
|
||||||
SOCK_CSRCS += net_dup2.c net_sockif.c net_poll.c net_fstat.c
|
SOCK_CSRCS += net_dup2.c net_sockif.c net_poll.c net_fstat.c
|
||||||
|
|
||||||
# Socket options
|
# Socket options
|
||||||
|
146
net/socket/shutdown.c
Normal file
146
net/socket/shutdown.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* net/socket/shutdown.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <nuttx/net/net.h>
|
||||||
|
|
||||||
|
#include "socket/socket.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: psock_shutdown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The shutdown() function will cause all or part of a full-duplex
|
||||||
|
* connection on the socket associated with the file descriptor socket to
|
||||||
|
* be shut down.
|
||||||
|
*
|
||||||
|
* The shutdown() function disables subsequent send and/or receive
|
||||||
|
* operations on a socket, depending on the value of the how argument.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* sockfd - Specifies the file descriptor of the socket.
|
||||||
|
* how - Specifies the type of shutdown. The values are as follows:
|
||||||
|
*
|
||||||
|
* SHUT_RD - Disables further receive operations.
|
||||||
|
* SHUT_WR - Disables further send operations.
|
||||||
|
* SHUT_RDWR - Disables further send and receive operations.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* EINVAL - The how argument is invalid.
|
||||||
|
* ENOTCONN - The socket is not connected.
|
||||||
|
* ENOTSOCK - The socket argument does not refer to a socket.
|
||||||
|
* ENOBUFS - Insufficient resources were available in the system to
|
||||||
|
* perform the operation.
|
||||||
|
* EOPNOTSUPP - The operation is not supported for this socket's protocol.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int psock_shutdown(FAR struct socket *psock, int how)
|
||||||
|
{
|
||||||
|
/* Verify that the psock corresponds to valid, allocated socket */
|
||||||
|
|
||||||
|
if (psock == NULL || psock->s_conn == NULL)
|
||||||
|
{
|
||||||
|
return -EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let the address family's shutdown() method handle the operation */
|
||||||
|
|
||||||
|
if (psock->s_sockif && psock->s_sockif->si_shutdown)
|
||||||
|
{
|
||||||
|
return psock->s_sockif->si_shutdown(psock, how);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: shutdown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The shutdown() function will cause all or part of a full-duplex
|
||||||
|
* connection on the socket associated with the file descriptor socket to
|
||||||
|
* be shut down.
|
||||||
|
*
|
||||||
|
* The shutdown() function disables subsequent send and/or receive
|
||||||
|
* operations on a socket, depending on the value of the how argument.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* sockfd - Specifies the file descriptor of the socket.
|
||||||
|
* how - Specifies the type of shutdown. The values are as follows:
|
||||||
|
*
|
||||||
|
* SHUT_RD - Disables further receive operations.
|
||||||
|
* SHUT_WR - Disables further send operations.
|
||||||
|
* SHUT_RDWR - Disables further send and receive operations.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Upon successful completion, shutdown() will return 0; otherwise, -1 will
|
||||||
|
* be returned and errno set to indicate the error.
|
||||||
|
*
|
||||||
|
* EBADF - The socket argument is not a valid file descriptor.
|
||||||
|
* EINVAL - The how argument is invalid.
|
||||||
|
* ENOTCONN - The socket is not connected.
|
||||||
|
* ENOTSOCK - The socket argument does not refer to a socket.
|
||||||
|
* ENOBUFS - Insufficient resources were available in the system to
|
||||||
|
* perform the operation.
|
||||||
|
* EOPNOTSUPP - The operation is not supported for this socket's protocol
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int shutdown(int sockfd, int how)
|
||||||
|
{
|
||||||
|
FAR struct socket *psock;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Get the underlying socket structure */
|
||||||
|
|
||||||
|
ret = sockfd_socket(sockfd, &psock);
|
||||||
|
|
||||||
|
/* Then let psock_shutdown() do all of the work */
|
||||||
|
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
ret = psock_shutdown(psock, how);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
_SO_SETERRNO(psock, -ret);
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -53,7 +53,7 @@ endif
|
|||||||
NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_finddev.c tcp_timer.c
|
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 tcp_close.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_monitor.c tcp_callback.c tcp_backlog.c tcp_ipselect.c
|
||||||
NET_CSRCS += tcp_recvwindow.c tcp_netpoll.c tcp_ioctl.c
|
NET_CSRCS += tcp_recvwindow.c tcp_netpoll.c tcp_ioctl.c tcp_shutdown.c
|
||||||
|
|
||||||
# TCP write buffering
|
# TCP write buffering
|
||||||
|
|
||||||
|
@ -344,8 +344,9 @@ struct tcp_conn_s
|
|||||||
FAR struct devif_callback_s *connevents;
|
FAR struct devif_callback_s *connevents;
|
||||||
FAR struct devif_callback_s *connevents_tail;
|
FAR struct devif_callback_s *connevents_tail;
|
||||||
|
|
||||||
/* Reference to TCP close callback instance */
|
/* Reference to TCP shutdown/close callback instance */
|
||||||
|
|
||||||
|
FAR struct devif_callback_s *shdcb;
|
||||||
FAR struct devif_callback_s *clscb;
|
FAR struct devif_callback_s *clscb;
|
||||||
struct work_s clswork;
|
struct work_s clswork;
|
||||||
|
|
||||||
@ -767,6 +768,23 @@ void tcp_lost_connection(FAR struct tcp_conn_s *conn,
|
|||||||
|
|
||||||
int tcp_close(FAR struct socket *psock);
|
int tcp_close(FAR struct socket *psock);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tcp_shutdown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Gracefully shutdown a TCP connection by sending a SYN
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* psock - An instance of the internal socket structure.
|
||||||
|
* how - Specifies the type of shutdown.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called from normal user-level logic
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int tcp_shutdown(FAR struct socket *psock, int how);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tcp_ipv4_select
|
* Name: tcp_ipv4_select
|
||||||
*
|
*
|
||||||
|
168
net/tcp/tcp_shutdown.c
Normal file
168
net/tcp/tcp_shutdown.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* net/tcp/tcp_shutdown.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#ifdef CONFIG_NET_TCP
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <nuttx/net/net.h>
|
||||||
|
#include <nuttx/net/netdev.h>
|
||||||
|
#include <nuttx/net/tcp.h>
|
||||||
|
|
||||||
|
#include "netdev/netdev.h"
|
||||||
|
#include "devif/devif.h"
|
||||||
|
#include "tcp/tcp.h"
|
||||||
|
#include "socket/socket.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tcp_shutdown_eventhandler
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint16_t tcp_shutdown_eventhandler(FAR struct net_driver_s *dev,
|
||||||
|
FAR void *pvpriv, uint16_t flags)
|
||||||
|
{
|
||||||
|
FAR struct tcp_conn_s *conn = pvpriv;
|
||||||
|
|
||||||
|
ninfo("flags: %04x\n", flags);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
|
||||||
|
/* We don't need the send callback anymore. */
|
||||||
|
|
||||||
|
if (conn->sndcb != NULL)
|
||||||
|
{
|
||||||
|
conn->sndcb->flags = 0;
|
||||||
|
conn->sndcb->event = NULL;
|
||||||
|
|
||||||
|
/* The callback will be freed by tcp_free. */
|
||||||
|
|
||||||
|
conn->sndcb = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dev->d_len = 0;
|
||||||
|
flags = (flags & ~TCP_NEWDATA) | TCP_CLOSE;
|
||||||
|
|
||||||
|
if (conn->shdcb != NULL)
|
||||||
|
{
|
||||||
|
tcp_callback_free(conn, conn->shdcb);
|
||||||
|
conn->shdcb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tcp_send_fin
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send a FIN for TCP connection
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* conn - TCP connection structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called from normal user-level logic
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int tcp_send_fin(FAR struct socket *psock)
|
||||||
|
{
|
||||||
|
FAR struct tcp_conn_s *conn;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
/* Interrupts are disabled here to avoid race conditions */
|
||||||
|
|
||||||
|
net_lock();
|
||||||
|
|
||||||
|
conn = (FAR struct tcp_conn_s *)psock->s_conn;
|
||||||
|
DEBUGASSERT(conn != NULL);
|
||||||
|
|
||||||
|
if ((conn->tcpstateflags == TCP_ESTABLISHED ||
|
||||||
|
conn->tcpstateflags == TCP_SYN_SENT ||
|
||||||
|
conn->tcpstateflags == TCP_SYN_RCVD))
|
||||||
|
{
|
||||||
|
if ((conn->shdcb = tcp_callback_alloc(conn)) == NULL)
|
||||||
|
{
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up to receive TCP data event callbacks */
|
||||||
|
|
||||||
|
conn->shdcb->flags = TCP_POLL;
|
||||||
|
conn->shdcb->event = tcp_shutdown_eventhandler;
|
||||||
|
conn->shdcb->priv = conn; /* reference for event handler to free cb */
|
||||||
|
|
||||||
|
/* Notify the device driver of the availability of TX data */
|
||||||
|
|
||||||
|
tcp_send_txnotify(psock, conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
net_unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tcp_shutdown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Gracefully shutdown a TCP connection by sending a FIN
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* psock - An instance of the internal socket structure.
|
||||||
|
* how - Specifies the type of shutdown.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called from normal user-level logic
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int tcp_shutdown(FAR struct socket *psock, int how)
|
||||||
|
{
|
||||||
|
if (!(how & SHUT_WR))
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcp_unlisten(psock->s_conn); /* No longer accepting connections */
|
||||||
|
|
||||||
|
return tcp_send_fin(psock);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NET_TCP */
|
@ -67,7 +67,8 @@ const struct sock_intf_s g_usrsock_sockif =
|
|||||||
usrsock_recvmsg, /* si_recvmsg */
|
usrsock_recvmsg, /* si_recvmsg */
|
||||||
usrsock_sockif_close, /* si_close */
|
usrsock_sockif_close, /* si_close */
|
||||||
usrsock_ioctl, /* si_ioctl */
|
usrsock_ioctl, /* si_ioctl */
|
||||||
NULL /* si_socketpair */
|
NULL, /* si_socketpair */
|
||||||
|
NULL /* si_shutdown */
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
, usrsock_getsockopt /* si_getsockopt */
|
, usrsock_getsockopt /* si_getsockopt */
|
||||||
, usrsock_setsockopt /* si_setsockopt */
|
, usrsock_setsockopt /* si_setsockopt */
|
||||||
|
@ -152,6 +152,7 @@
|
|||||||
"shmctl","sys/shm.h","defined(CONFIG_MM_SHM)","int","int","int","FAR struct shmid_ds *"
|
"shmctl","sys/shm.h","defined(CONFIG_MM_SHM)","int","int","int","FAR struct shmid_ds *"
|
||||||
"shmdt","sys/shm.h","defined(CONFIG_MM_SHM)","int","FAR const void *"
|
"shmdt","sys/shm.h","defined(CONFIG_MM_SHM)","int","FAR const void *"
|
||||||
"shmget","sys/shm.h","defined(CONFIG_MM_SHM)","int","key_t","size_t","int"
|
"shmget","sys/shm.h","defined(CONFIG_MM_SHM)","int","key_t","size_t","int"
|
||||||
|
"shutdown","sys/socket.h","defined(CONFIG_NET)","int","int","int"
|
||||||
"sigaction","signal.h","","int","int","FAR const struct sigaction *","FAR struct sigaction *"
|
"sigaction","signal.h","","int","int","FAR const struct sigaction *","FAR struct sigaction *"
|
||||||
"sigpending","signal.h","","int","FAR sigset_t *"
|
"sigpending","signal.h","","int","FAR sigset_t *"
|
||||||
"sigprocmask","signal.h","","int","int","FAR const sigset_t *","FAR sigset_t *"
|
"sigprocmask","signal.h","","int","int","FAR const sigset_t *","FAR sigset_t *"
|
||||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
Reference in New Issue
Block a user