summaryrefslogtreecommitdiffstats
path: root/src/net/tcp.c
diff options
context:
space:
mode:
authorMichael Brown2011-03-26 15:58:17 +0100
committerMichael Brown2011-03-26 16:02:41 +0100
commit3f442d3f601306f97d21a8716ea303ee053822d1 (patch)
tree5f23b4bc7fb819d1613bd9d385e9bfcdc221bd8c /src/net/tcp.c
parent[build] Include ipxe.lkrn in default build (diff)
downloadipxe-3f442d3f601306f97d21a8716ea303ee053822d1.tar.gz
ipxe-3f442d3f601306f97d21a8716ea303ee053822d1.tar.xz
ipxe-3f442d3f601306f97d21a8716ea303ee053822d1.zip
[tcp] Record ts_recent on first received packet
Commit 6861304 ("[tcp] Handle out-of-order received packets") introduced a regression in which ts_recent would not be updated until the first packet is received in the ESTABLISHED state, i.e. the timestamp from the SYN+ACK packet would be ignored. This causes the connection to be dropped by strictly-conforming TCP peers, such as FreeBSD. Fix by delaying the timestamp window check until after processing the received SYN flag. Reported-by: winders@sonnet.com Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/tcp.c')
-rw-r--r--src/net/tcp.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/net/tcp.c b/src/net/tcp.c
index 3e1aeedc..d9529882 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -1060,6 +1060,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
struct tcp_options options;
size_t hlen;
uint16_t csum;
+ uint32_t start_seq;
uint32_t seq;
uint32_t ack;
uint32_t win;
@@ -1099,7 +1100,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
/* Parse parameters from header and strip header */
tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
- seq = ntohl ( tcphdr->seq );
+ seq = start_seq = ntohl ( tcphdr->seq );
ack = ntohl ( tcphdr->ack );
win = ntohs ( tcphdr->win );
flags = tcphdr->flags;
@@ -1125,10 +1126,6 @@ static int tcp_rx ( struct io_buffer *iobuf,
goto discard;
}
- /* Update timestamp, if applicable */
- if ( options.tsopt && tcp_in_window ( tcp->rcv_ack, seq, seq_len ) )
- tcp->ts_recent = ntohl ( options.tsopt->tsval );
-
/* Handle ACK, if present */
if ( flags & TCP_ACK ) {
if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) {
@@ -1155,6 +1152,12 @@ static int tcp_rx ( struct io_buffer *iobuf,
goto discard;
}
+ /* Update timestamp, if applicable */
+ if ( options.tsopt &&
+ tcp_in_window ( tcp->rcv_ack, start_seq, seq_len ) ) {
+ tcp->ts_recent = ntohl ( options.tsopt->tsval );
+ }
+
/* Enqueue received data */
tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );