Browse Source

[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>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
3f442d3f60
1 changed files with 8 additions and 5 deletions
  1. 8
    5
      src/net/tcp.c

+ 8
- 5
src/net/tcp.c View File

1060
 	struct tcp_options options;
1060
 	struct tcp_options options;
1061
 	size_t hlen;
1061
 	size_t hlen;
1062
 	uint16_t csum;
1062
 	uint16_t csum;
1063
+	uint32_t start_seq;
1063
 	uint32_t seq;
1064
 	uint32_t seq;
1064
 	uint32_t ack;
1065
 	uint32_t ack;
1065
 	uint32_t win;
1066
 	uint32_t win;
1099
 	
1100
 	
1100
 	/* Parse parameters from header and strip header */
1101
 	/* Parse parameters from header and strip header */
1101
 	tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
1102
 	tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
1102
-	seq = ntohl ( tcphdr->seq );
1103
+	seq = start_seq = ntohl ( tcphdr->seq );
1103
 	ack = ntohl ( tcphdr->ack );
1104
 	ack = ntohl ( tcphdr->ack );
1104
 	win = ntohs ( tcphdr->win );
1105
 	win = ntohs ( tcphdr->win );
1105
 	flags = tcphdr->flags;
1106
 	flags = tcphdr->flags;
1125
 		goto discard;
1126
 		goto discard;
1126
 	}
1127
 	}
1127
 
1128
 
1128
-	/* Update timestamp, if applicable */
1129
-	if ( options.tsopt && tcp_in_window ( tcp->rcv_ack, seq, seq_len ) )
1130
-		tcp->ts_recent = ntohl ( options.tsopt->tsval );
1131
-
1132
 	/* Handle ACK, if present */
1129
 	/* Handle ACK, if present */
1133
 	if ( flags & TCP_ACK ) {
1130
 	if ( flags & TCP_ACK ) {
1134
 		if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) {
1131
 		if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) {
1155
 			goto discard;
1152
 			goto discard;
1156
 	}
1153
 	}
1157
 
1154
 
1155
+	/* Update timestamp, if applicable */
1156
+	if ( options.tsopt &&
1157
+	     tcp_in_window ( tcp->rcv_ack, start_seq, seq_len ) ) {
1158
+		tcp->ts_recent = ntohl ( options.tsopt->tsval );
1159
+	}
1160
+
1158
 	/* Enqueue received data */
1161
 	/* Enqueue received data */
1159
 	tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );
1162
 	tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );
1160
 
1163
 

Loading…
Cancel
Save