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 * 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 */
} }

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) 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);
} }

View file

@ -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;
} }

View file

@ -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! */