[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>
This commit is contained in:
parent
7c4a53e3f0
commit
3f442d3f60
|
@ -1060,6 +1060,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
|
||||||
struct tcp_options options;
|
struct tcp_options options;
|
||||||
size_t hlen;
|
size_t hlen;
|
||||||
uint16_t csum;
|
uint16_t csum;
|
||||||
|
uint32_t start_seq;
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
uint32_t ack;
|
uint32_t ack;
|
||||||
uint32_t win;
|
uint32_t win;
|
||||||
|
@ -1099,7 +1100,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
|
||||||
|
|
||||||
/* Parse parameters from header and strip header */
|
/* Parse parameters from header and strip header */
|
||||||
tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
|
tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
|
||||||
seq = ntohl ( tcphdr->seq );
|
seq = start_seq = ntohl ( tcphdr->seq );
|
||||||
ack = ntohl ( tcphdr->ack );
|
ack = ntohl ( tcphdr->ack );
|
||||||
win = ntohs ( tcphdr->win );
|
win = ntohs ( tcphdr->win );
|
||||||
flags = tcphdr->flags;
|
flags = tcphdr->flags;
|
||||||
|
@ -1125,10 +1126,6 @@ static int tcp_rx ( struct io_buffer *iobuf,
|
||||||
goto discard;
|
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 */
|
/* Handle ACK, if present */
|
||||||
if ( flags & TCP_ACK ) {
|
if ( flags & TCP_ACK ) {
|
||||||
if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) {
|
if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) {
|
||||||
|
@ -1155,6 +1152,12 @@ static int tcp_rx ( struct io_buffer *iobuf,
|
||||||
goto discard;
|
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 */
|
/* Enqueue received data */
|
||||||
tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );
|
tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );
|
||||||
|
|
||||||
|
|
Reference in New Issue