diff options
| author | Michael Brown | 2009-06-23 02:29:43 +0200 |
|---|---|---|
| committer | Michael Brown | 2009-06-23 10:40:26 +0200 |
| commit | 558c1a45fe30ffe3d6c67b2321e0fc973f13e9b7 (patch) | |
| tree | 16153ed9464185891dabb5eaee235b318ff672bc /src/include | |
| parent | [settings] Fix setting_cmp() to handle nameless settings (diff) | |
| download | ipxe-558c1a45fe30ffe3d6c67b2321e0fc973f13e9b7.tar.gz ipxe-558c1a45fe30ffe3d6c67b2321e0fc973f13e9b7.tar.xz ipxe-558c1a45fe30ffe3d6c67b2321e0fc973f13e9b7.zip | |
[tcp] Improve robustness in the presence of duplicated received packets
gPXE responds to duplicated ACKs with an immediate retransmission,
which can lead to a sorceror's apprentice syndrome. It also responds
to out-of-range (or old duplicate) ACKs with a RST, which can cause
valid connections to be dropped.
Fix the sorceror's apprentice syndrome by leaving the retransmission
timer running (and so inhibiting the immediate retransmission) when we
receive a potential duplicate ACK. This seems to match the behaviour
of Linux observed via wireshark traces.
Fix the RST issue by sending RST only on out-of-range ACKs that occur
before the connection is fully established, as per RFC 793.
These problems were exposed during development of the 802.11 wireless
link layer; the 802.11 protocol has a failure mode that can easily
cause duplicated packets. The fixes were tested in a controlled way
by faking large numbers of duplicated packets in the rtl8139 driver.
Originally-fixed-by: Joshua Oreman <oremanj@rwcr.net>
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/gpxe/tcp.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/include/gpxe/tcp.h b/src/include/gpxe/tcp.h index 6fb673acc..7ae7eab99 100644 --- a/src/include/gpxe/tcp.h +++ b/src/include/gpxe/tcp.h @@ -229,6 +229,16 @@ struct tcp_options { TCP_STATE_SENT ( TCP_FIN ) ) ) \ == TCP_STATE_ACKED ( TCP_SYN ) ) +/** Have ever been fully established + * + * We have been fully established if we have both received a SYN and + * had our own SYN acked. + */ +#define TCP_HAS_BEEN_ESTABLISHED(state) \ + ( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN ) | \ + TCP_STATE_RCVD ( TCP_SYN ) ) ) \ + == ( TCP_STATE_ACKED ( TCP_SYN ) | TCP_STATE_RCVD ( TCP_SYN ) ) ) + /** Have closed gracefully * * We have closed gracefully if we have both received a FIN and had |
