diff options
author | Michael Brown <mcb30@ipxe.org> | 2011-03-26 14:58:17 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2011-03-26 15:02:41 +0000 |
commit | 3f442d3f601306f97d21a8716ea303ee053822d1 (patch) | |
tree | 5f23b4bc7fb819d1613bd9d385e9bfcdc221bd8c /src/net/tcp.c | |
parent | 7c4a53e3f063a2bee4bdec44338fc3c5658f70af (diff) | |
download | ipxe-3f442d3f601306f97d21a8716ea303ee053822d1.tar.gz |
[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.c | 13 |
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 ) ); |