aboutsummaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2014-03-05 17:30:06 +0000
committerMichael Brown <mcb30@ipxe.org>2014-03-07 17:30:01 +0000
commit859664ea2a9201332da5320fe38081365c0f032a (patch)
treec619008e347edb79de3acd409933151e67f516d2 /src/net
parentf17a30d547b40bcd4298161f77ee14258508acf8 (diff)
downloadipxe-859664ea2a9201332da5320fe38081365c0f032a.zip
ipxe-859664ea2a9201332da5320fe38081365c0f032a.tar.gz
ipxe-859664ea2a9201332da5320fe38081365c0f032a.tar.bz2
[tcp] Update window even if ACK does not acknowledge new data
iPXE currently ignores ACKs which do not acknowledge any new data. (In particular, it does not stop the retransmission timer; this is done to prevent an immediate retransmission if a duplicate ACK is received while the transmit queue is non-empty.) If a peer provides a window size of zero and later sends a duplicate ACK to update the window size, this update will therefore be ignored and iPXE will never be able to transmit data. Fix by updating the window size even for ACKs which do not acknowledge new data. Reported-by: Wissam Shoukair <wissams@mellanox.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net')
-rw-r--r--src/net/tcp.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/net/tcp.c b/src/net/tcp.c
index 548bd4d..3fbcfd0 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -890,6 +890,9 @@ static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack,
}
}
+ /* Update window size */
+ tcp->snd_win = win;
+
/* Ignore ACKs that don't actually acknowledge any new data.
* (In particular, do not stop the retransmission timer; this
* avoids creating a sorceror's apprentice syndrome when a
@@ -911,10 +914,9 @@ static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack,
pending_put ( &tcp->pending_flags );
}
- /* Update SEQ and sent counters, and window size */
+ /* Update SEQ and sent counters */
tcp->snd_seq = ack;
tcp->snd_sent = 0;
- tcp->snd_win = win;
/* Remove any acknowledged data from transmit queue */
tcp_process_tx_queue ( tcp, len, NULL, 1 );