net/tcp: fix send deadlock if disconnect

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an
2021-12-15 21:26:18 +08:00
committed by Xiang Xiao
parent 0aecfe8691
commit 0ee7400fdf
2 changed files with 17 additions and 4 deletions
+14 -2
View File
@@ -1033,14 +1033,15 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
bool nonblock; bool nonblock;
int ret = OK; int ret = OK;
if (psock == NULL || psock->s_conn == NULL) if (psock == NULL || psock->s_type != SOCK_STREAM ||
psock->s_conn == NULL)
{ {
nerr("ERROR: Invalid socket\n"); nerr("ERROR: Invalid socket\n");
ret = -EBADF; ret = -EBADF;
goto errout; goto errout;
} }
if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags)) if (!_SS_ISCONNECTED(psock->s_flags))
{ {
nerr("ERROR: Not connected\n"); nerr("ERROR: Not connected\n");
ret = -ENOTCONN; ret = -ENOTCONN;
@@ -1100,6 +1101,17 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
net_lock(); net_lock();
/* Now that we have the network locked, we need to check the connection
* state again to ensure the connection is still valid.
*/
if (!_SS_ISCONNECTED(psock->s_flags))
{
nerr("ERROR: No longer connected\n");
ret = -ENOTCONN;
goto errout_with_lock;
}
/* Allocate resources to receive a callback */ /* Allocate resources to receive a callback */
if (psock->s_sndcb == NULL) if (psock->s_sndcb == NULL)
+3 -2
View File
@@ -463,7 +463,8 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
/* Verify that the sockfd corresponds to valid, allocated socket */ /* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_conn == NULL) if (psock == NULL || psock->s_type != SOCK_STREAM ||
psock->s_conn == NULL)
{ {
nerr("ERROR: Invalid socket\n"); nerr("ERROR: Invalid socket\n");
ret = -EBADF; ret = -EBADF;
@@ -475,7 +476,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
* guarantee the state won't change until we have the network locked. * guarantee the state won't change until we have the network locked.
*/ */
if (psock->s_type != SOCK_STREAM) if (!_SS_ISCONNECTED(psock->s_flags))
{ {
nerr("ERROR: Not connected\n"); nerr("ERROR: Not connected\n");
ret = -ENOTCONN; ret = -ENOTCONN;