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
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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! */
|
||||
|
||||
|
|
Loading…
Reference in New Issue