net/inet and net/tcp: Fix tcp close flow; free the connection after all tcp close process finished.
This commit is contained in:
parent
2236916be6
commit
b33fc302f0
4 changed files with 26 additions and 17 deletions
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/inet/inet_close.c
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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)
|
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;
|
pstate->cl_result = OK;
|
||||||
goto end_wait;
|
goto end_wait;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, nothing is waiting on the close event and we can perform
|
/* 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);
|
tcp_close_monitor(psock);
|
||||||
}
|
}
|
||||||
#else
|
#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;
|
return -EAFNOSUPPORT;
|
||||||
#endif /* NET_TCP_HAVE_STACK */
|
#endif /* NET_TCP_HAVE_STACK */
|
||||||
}
|
}
|
||||||
|
@ -606,7 +610,8 @@ int inet_close(FAR struct socket *psock)
|
||||||
conn->crefs--;
|
conn->crefs--;
|
||||||
}
|
}
|
||||||
#else
|
#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;
|
return -EAFNOSUPPORT;
|
||||||
#endif /* NET_UDP_HAVE_STACK */
|
#endif /* NET_UDP_HAVE_STACK */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
else if ((result & TCP_CLOSE) != 0)
|
||||||
{
|
{
|
||||||
conn->tcpstateflags = TCP_FIN_WAIT_1;
|
conn->tcpstateflags = TCP_FIN_WAIT_1;
|
||||||
conn->unacked = 1;
|
conn->unacked = 1;
|
||||||
conn->nrtx = 0;
|
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");
|
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);
|
tcp_send(dev, conn, TCP_FIN | TCP_ACK, hdrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -524,7 +524,7 @@ found:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ninfo("sndseq: %08x->%08x unackseq: %08x new unacked: %d\n",
|
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);
|
tcp_setsequence(conn->sndseq, ackseq);
|
||||||
|
|
||||||
/* Do RTT estimation, unless we have done retransmissions. */
|
/* Do RTT estimation, unless we have done retransmissions. */
|
||||||
|
@ -785,6 +785,9 @@ found:
|
||||||
conn->tcpstateflags = TCP_LAST_ACK;
|
conn->tcpstateflags = TCP_LAST_ACK;
|
||||||
conn->unacked = 1;
|
conn->unacked = 1;
|
||||||
conn->nrtx = 0;
|
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");
|
ninfo("TCP state: TCP_LAST_ACK\n");
|
||||||
|
|
||||||
tcp_send(dev, conn, TCP_FIN | TCP_ACK, tcpiplen);
|
tcp_send(dev, conn, TCP_FIN | TCP_ACK, tcpiplen);
|
||||||
|
@ -932,11 +935,10 @@ found:
|
||||||
|
|
||||||
if ((tcp->flags & TCP_FIN) != 0)
|
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->tcpstateflags = TCP_TIME_WAIT;
|
||||||
conn->timer = 0;
|
conn->timer = 0;
|
||||||
conn->unacked = 0;
|
|
||||||
ninfo("TCP state: TCP_TIME_WAIT\n");
|
ninfo("TCP state: TCP_TIME_WAIT\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -950,10 +952,9 @@ found:
|
||||||
tcp_send(dev, conn, TCP_ACK, tcpiplen);
|
tcp_send(dev, conn, TCP_ACK, tcpiplen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((flags & TCP_ACKDATA) != 0)
|
else if ((flags & TCP_ACKDATA) != 0 && conn->unacked == 0)
|
||||||
{
|
{
|
||||||
conn->tcpstateflags = TCP_FIN_WAIT_2;
|
conn->tcpstateflags = TCP_FIN_WAIT_2;
|
||||||
conn->unacked = 0;
|
|
||||||
ninfo("TCP state: TCP_FIN_WAIT_2\n");
|
ninfo("TCP state: TCP_FIN_WAIT_2\n");
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ FAR char *getenv(FAR const char *name)
|
||||||
|
|
||||||
/* Verify that a string was passed */
|
/* Verify that a string was passed */
|
||||||
|
|
||||||
if (!name)
|
if (name == NULL)
|
||||||
{
|
{
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
goto errout;
|
goto errout;
|
||||||
|
@ -95,7 +95,7 @@ FAR char *getenv(FAR const char *name)
|
||||||
|
|
||||||
/* Check if the variable exists */
|
/* Check if the variable exists */
|
||||||
|
|
||||||
if (!group || (pvar = env_findvar(group, name)) == NULL)
|
if (group == NULL || (pvar = env_findvar(group, name)) == NULL)
|
||||||
{
|
{
|
||||||
ret = ENOENT;
|
ret = ENOENT;
|
||||||
goto errout_with_lock;
|
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 */
|
/* It does! Get the value sub-string from the name=value string */
|
||||||
|
|
||||||
pvalue = strchr(pvar, '=');
|
pvalue = strchr(pvar, '=');
|
||||||
if (!pvalue)
|
if (pvalue == NULL)
|
||||||
{
|
{
|
||||||
/* The name=value string has no '=' This is a bug! */
|
/* The name=value string has no '=' This is a bug! */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue