diff options
| author | David Gibson <david@gibson.dropbear.id.au> | 2026-05-28 15:02:08 +1000 |
|---|---|---|
| committer | Stefano Brivio <sbrivio@redhat.com> | 2026-06-04 06:35:18 +0200 |
| commit | 4a6187008f1ac3db2e221b3b21151f4d72fa8821 (patch) | |
| tree | d4581b17ef4017cd39dfd183a1f258ea6c08eef5 | |
| parent | 1d475b1dbf22dac4a9fda3ebb444b0343392c5c3 (diff) | |
| download | passt-4a6187008f1ac3db2e221b3b21151f4d72fa8821.tar passt-4a6187008f1ac3db2e221b3b21151f4d72fa8821.tar.gz passt-4a6187008f1ac3db2e221b3b21151f4d72fa8821.tar.bz2 passt-4a6187008f1ac3db2e221b3b21151f4d72fa8821.tar.lz passt-4a6187008f1ac3db2e221b3b21151f4d72fa8821.tar.xz passt-4a6187008f1ac3db2e221b3b21151f4d72fa8821.tar.zst passt-4a6187008f1ac3db2e221b3b21151f4d72fa8821.zip | |
tcp_splice: Improve EOF exit condition for the loop
In tcp_splice_forward() we exit the forwarding loop if we have an EOF on
the read side. However, this potentially leaves data in the pipe, even if
the write side hasn't yet blocked. It's not clear to me whether this could
leave data indefinitely in the pipe with no events to keep it moving,
but it's not clear to me that it couldn't either.
Stay in the loop until either the write side blocks or we've emptied
the pipe.
Secondly, this test is after several tests on how much we wrote which
might also cause a retry. However, if we've reached EOF and the pipe is
empty, there's nothing more to do, regardless of how much we wrote, so
we should exit, regardless of those conditions. So move this exit test
above the retry conditions.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
| -rw-r--r-- | tcp_splice.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/tcp_splice.c b/tcp_splice.c index 25e5d09..943dc21 100644 --- a/tcp_splice.c +++ b/tcp_splice.c @@ -543,15 +543,16 @@ retry: break; } + if (conn->events & FIN_RCVD(fromsidei) && + !conn->pending[fromsidei]) + break; + if (never_read && written == (long)(c->tcp.pipe_size)) goto retry; if (!never_read && written > 0 && written < conn->pending[fromsidei]) goto retry; - - if (conn->events & FIN_RCVD(fromsidei)) - break; } if (!conn->pending[fromsidei] && |
