Skip to content

Commit

Permalink
tcp: Clear ACK_FROM_TAP_DUE also on unchanged ACK sequence from peer
Browse files Browse the repository at this point in the history
Since commit cc6d828 ("tcp: Reset ACK_FROM_TAP_DUE flag only as
needed, update timer"), we don't clear ACK_FROM_TAP_DUE whenever we
process an ACK segment, but, more correctly, only if we're really not
waiting for a further ACK segment, that is, only if the acknowledged
sequence matches what we sent.

In the new function implementing this, tcp_update_seqack_from_tap(),
we also reset the retransmission counter and store the updated ACK
sequence. Both should be done iff forward progress is acknowledged,
implied by the fact that the new ACK sequence is greater than the
one we previously stored.

At that point, it looked natural to also include the statements that
clear and set the ACK_FROM_TAP_DUE flag inside the same conditional
block: if we're not making forward progress, the need for an ACK, or
lack thereof, should remain unchanged.

There might be cases where this isn't true, though: without the
previous commit 4e73e9b ("tcp: Don't special case the handling
of the ack of a syn"), this would happen if a tap-side client
initiated a connection, and the server didn't send any data.

At that point we would never, in the established state of the
connection, call tcp_update_seqack_from_tap() with reported forward
progress.

That issue itself is fixed by the previous commit, now, but clearing
ACK_FROM_TAP_DUE only on ACK sequence progress doesn't really follow
any logic.

Clear the ACK_FROM_TAP_DUE flag regardless of reported forward
progress. If we clear it when it's already unset, conn_flag() will do
nothing with it.

This doesn't fix any known functional issue, rather a conceptual one.

Fixes: cc6d828 ("tcp: Reset ACK_FROM_TAP_DUE flag only as needed, update timer")
Reported-by: David Gibson <[email protected]>
Analysed-by: David Gibson <[email protected]>
Signed-off-by: Stefano Brivio <[email protected]>
  • Loading branch information
sbrivio-rh committed Mar 29, 2023
1 parent 4e73e9b commit 33d88f7
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1610,10 +1610,12 @@ static int tcp_update_seqack_wnd(const struct ctx *c, struct tcp_tap_conn *conn,
static void tcp_update_seqack_from_tap(const struct ctx *c,
struct tcp_tap_conn *conn, uint32_t seq)
{
if (seq == conn->seq_to_tap)
conn_flag(c, conn, ~ACK_FROM_TAP_DUE);

if (SEQ_GT(seq, conn->seq_ack_from_tap)) {
if (seq == conn->seq_to_tap)
conn_flag(c, conn, ~ACK_FROM_TAP_DUE);
else
/* Forward progress, but more data to acknowledge: reschedule */
if (SEQ_LT(seq, conn->seq_to_tap))
conn_flag(c, conn, ACK_FROM_TAP_DUE);

conn->retrans = 0;
Expand Down

0 comments on commit 33d88f7

Please sign in to comment.