]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tcp] Record ts_recent on first received packet
authorMichael Brown <mcb30@ipxe.org>
Sat, 26 Mar 2011 14:58:17 +0000 (14:58 +0000)
committerMichael Brown <mcb30@ipxe.org>
Sat, 26 Mar 2011 15:02:41 +0000 (15:02 +0000)
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>
src/net/tcp.c

index 3e1aeedc7e1b0059ec444503e4dd205e398b4599..d9529882d1aa210bd5ddf38bb5f3b8e369f7a771 100644 (file)
@@ -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 ) );