net/inet and net/tcp: Fix tcp close flow; free the connection after all tcp close process finished.

This commit is contained in:
zhangyuan7 2019-08-30 06:43:45 -06:00 committed by Gregory Nutt
parent 2236916be6
commit b33fc302f0
4 changed files with 26 additions and 17 deletions

View File

@ -1,7 +1,7 @@
/****************************************************************************
* net/inet/inet_close.c
*
* Copyright (C) 2007-2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2017, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -127,10 +127,13 @@ static uint16_t tcp_close_eventhandler(FAR struct net_driver_s *dev,
if (pstate != NULL)
{
/* Wake up the waiting thread with a successful result */
if (conn->tcpstateflags == TCP_CLOSED)
{
/* Wake up the waiting thread with a successful result */
pstate->cl_result = OK;
goto end_wait;
pstate->cl_result = OK;
goto end_wait;
}
}
/* Otherwise, nothing is waiting on the close event and we can perform
@ -566,7 +569,8 @@ int inet_close(FAR struct socket *psock)
tcp_close_monitor(psock);
}
#else
nwarn("WARNING: SOCK_STREAM support is not available in this configuration\n");
nwarn("WARNING: SOCK_STREAM support is not available in this "
"configuration\n");
return -EAFNOSUPPORT;
#endif /* NET_TCP_HAVE_STACK */
}
@ -606,7 +610,8 @@ int inet_close(FAR struct socket *psock)
conn->crefs--;
}
#else
nwarn("WARNING: SOCK_DGRAM support is not available in this configuration\n");
nwarn("WARNING: SOCK_DGRAM support is not available in this "
"configuration\n");
return -EAFNOSUPPORT;
#endif /* NET_UDP_HAVE_STACK */
}

View File

@ -143,11 +143,14 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
else if ((result & TCP_CLOSE) != 0)
{
conn->tcpstateflags = TCP_FIN_WAIT_1;
conn->unacked = 1;
conn->nrtx = 0;
conn->unacked = 1;
conn->nrtx = 0;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
conn->sndseq_max = tcp_getsequence(conn->sndseq) + 1;
#endif
ninfo("TCP state: TCP_FIN_WAIT_1\n");
dev->d_sndlen = 0;
dev->d_sndlen = 0;
tcp_send(dev, conn, TCP_FIN | TCP_ACK, hdrlen);
}

View File

@ -524,7 +524,7 @@ found:
*/
ninfo("sndseq: %08x->%08x unackseq: %08x new unacked: %d\n",
conn->sndseq, ackseq, unackseq, conn->unacked);
tcp_getsequence(conn->sndseq), ackseq, unackseq, conn->unacked);
tcp_setsequence(conn->sndseq, ackseq);
/* Do RTT estimation, unless we have done retransmissions. */
@ -785,6 +785,9 @@ found:
conn->tcpstateflags = TCP_LAST_ACK;
conn->unacked = 1;
conn->nrtx = 0;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
conn->sndseq_max = tcp_getsequence(conn->sndseq) + 1;
#endif
ninfo("TCP state: TCP_LAST_ACK\n");
tcp_send(dev, conn, TCP_FIN | TCP_ACK, tcpiplen);
@ -932,11 +935,10 @@ found:
if ((tcp->flags & TCP_FIN) != 0)
{
if ((flags & TCP_ACKDATA) != 0)
if ((flags & TCP_ACKDATA) != 0 && conn->unacked == 0)
{
conn->tcpstateflags = TCP_TIME_WAIT;
conn->timer = 0;
conn->unacked = 0;
ninfo("TCP state: TCP_TIME_WAIT\n");
}
else
@ -950,10 +952,9 @@ found:
tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
else if ((flags & TCP_ACKDATA) != 0)
else if ((flags & TCP_ACKDATA) != 0 && conn->unacked == 0)
{
conn->tcpstateflags = TCP_FIN_WAIT_2;
conn->unacked = 0;
ninfo("TCP state: TCP_FIN_WAIT_2\n");
goto drop;
}

View File

@ -81,7 +81,7 @@ FAR char *getenv(FAR const char *name)
/* Verify that a string was passed */
if (!name)
if (name == NULL)
{
ret = EINVAL;
goto errout;
@ -95,7 +95,7 @@ FAR char *getenv(FAR const char *name)
/* Check if the variable exists */
if (!group || (pvar = env_findvar(group, name)) == NULL)
if (group == NULL || (pvar = env_findvar(group, name)) == NULL)
{
ret = ENOENT;
goto errout_with_lock;
@ -104,7 +104,7 @@ FAR char *getenv(FAR const char *name)
/* It does! Get the value sub-string from the name=value string */
pvalue = strchr(pvar, '=');
if (!pvalue)
if (pvalue == NULL)
{
/* The name=value string has no '=' This is a bug! */