You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/01/16 17:42:46 UTC
[incubator-nuttx] branch master updated: net/tcp/sendfile: NET_TCP_WRITE_BUFFERS and NET_SENDFILE were inconsistent with each other: tcp_sendfile() reads data directly from a file and does not use NET_TCP_WRITE_BUFFERS data flow even if CONFIG_NET_TCP_WRITE_BUFFERS option is enabled. Despite this, tcp_sendfile relied on NET_TCP_WRITE_BUFFERS specific flow control variables that were idle during sendfile operation. Thus it was a total inconsistency.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 0f080cd net/tcp/sendfile: NET_TCP_WRITE_BUFFERS and NET_SENDFILE were inconsistent with each other: tcp_sendfile() reads data directly from a file and does not use NET_TCP_WRITE_BUFFERS data flow even if CONFIG_NET_TCP_WRITE_BUFFERS option is enabled. Despite this, tcp_sendfile relied on NET_TCP_WRITE_BUFFERS specific flow control variables that were idle during sendfile operation. Thus it was a total inconsistency.
0f080cd is described below
commit 0f080cdeaf206253319256482a5cab850473d505
Author: Alexander Lunev <al...@mail.ru>
AuthorDate: Sun Jan 16 07:40:08 2022 +0300
net/tcp/sendfile: NET_TCP_WRITE_BUFFERS and NET_SENDFILE were inconsistent with each other:
tcp_sendfile() reads data directly from a file and does not use NET_TCP_WRITE_BUFFERS data flow
even if CONFIG_NET_TCP_WRITE_BUFFERS option is enabled.
Despite this, tcp_sendfile relied on NET_TCP_WRITE_BUFFERS specific flow control variables that
were idle during sendfile operation. Thus it was a total inconsistency.
E.g. because of the issue, TCP socket used by sendfile() operation never issued
FIN packet on close() command, and the TCP connection hung up.
As a result of the fix, simultaneously enabled CONFIG_NET_TCP_WRITE_BUFFERS and
CONFIG_NET_SENDFILE options can coexist.
---
net/tcp/tcp.h | 4 ++++
net/tcp/tcp_appsend.c | 23 ++++++++++++++++-------
net/tcp/tcp_sendfile.c | 6 ++++++
net/tcp/tcp_timer.c | 5 +++++
4 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h
index 273db14..3992d6b 100644
--- a/net/tcp/tcp.h
+++ b/net/tcp/tcp.h
@@ -287,6 +287,10 @@ struct tcp_conn_s
uint8_t keepretries; /* Number of retries attempted */
#endif
+#if defined(CONFIG_NET_SENDFILE) && defined(CONFIG_NET_TCP_WRITE_BUFFERS)
+ bool sendfile; /* True if sendfile operation is in progress */
+#endif
+
/* connevents is a list of callbacks for each socket the uses this
* connection (there can be more that one in the event that the the socket
* was dup'ed). It is used with the network monitor to handle
diff --git a/net/tcp/tcp_appsend.c b/net/tcp/tcp_appsend.c
index 467d567..82c7c9f 100644
--- a/net/tcp/tcp_appsend.c
+++ b/net/tcp/tcp_appsend.c
@@ -226,9 +226,19 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
else
{
-#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
+ /* The application cannot send more than what is allowed by the
+ * MSS (the minimum of the MSS and the available window).
+ */
+
DEBUGASSERT(dev->d_sndlen <= conn->mss);
-#else
+
+#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS) || defined(CONFIG_NET_SENDFILE)
+
+#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
+ if (conn->sendfile)
+ {
+#endif
+
/* If d_sndlen > 0, the application has data to be sent. */
if (dev->d_sndlen > 0)
@@ -241,15 +251,14 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
*/
conn->tx_unacked += dev->d_sndlen;
+ }
- /* The application cannot send more than what is allowed by the
- * MSS (the minimum of the MSS and the available window).
- */
+ conn->nrtx = 0;
- DEBUGASSERT(dev->d_sndlen <= conn->mss);
+#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
}
+#endif
- conn->nrtx = 0;
#endif
/* Then handle the rest of the operation just as for the rexmit case */
diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c
index 87d902f..a1dac31 100644
--- a/net/tcp/tcp_sendfile.c
+++ b/net/tcp/tcp_sendfile.c
@@ -495,6 +495,9 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
*/
net_lock();
+#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
+ conn->sendfile = true;
+#endif
memset(&state, 0, sizeof(struct sendfile_s));
/* This semaphore is used for signaling and, hence, should not have
@@ -574,6 +577,9 @@ errout_datacb:
errout_locked:
nxsem_destroy(&state.snd_sem);
+#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
+ conn->sendfile = false;
+#endif
net_unlock();
/* Return the current file position */
diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c
index a206a09..a8e93f4 100644
--- a/net/tcp/tcp_timer.c
+++ b/net/tcp/tcp_timer.c
@@ -269,7 +269,12 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
else if (
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
+# ifdef CONFIG_NET_SENDFILE
+ (!conn->sendfile && conn->expired > 0) ||
+ (conn->sendfile && conn->nrtx >= TCP_MAXRTX) ||
+# else
conn->expired > 0 ||
+# endif
#else
conn->nrtx >= TCP_MAXRTX ||
#endif