Переглянути джерело

[tcp] Update ts_recent whenever window is advanced

Commit 3f442d3 ("[tcp] Record ts_recent on first received packet")
failed to achieve its stated intention.

Fix this (and reduce the code size) by moving the ts_recent update to
tcp_rx_seq().  This is the code responsible for advancing the window,
called by both tcp_rx_syn() and tcp_rx_data(), and so the window check
is now redundant.

Reported-by: Frank Weed <zorbustheknight@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 роки тому
джерело
коміт
c4369eb6c2
1 змінених файлів з 22 додано та 9 видалено
  1. 22
    9
      src/net/tcp.c

+ 22
- 9
src/net/tcp.c Переглянути файл

@@ -74,7 +74,13 @@ struct tcp_connection {
74 74
 	 * Equivalent to RCV.WND in RFC 793 terminology.
75 75
 	 */
76 76
 	uint32_t rcv_win;
77
-	/** Most recent received timestamp
77
+	/** Received timestamp value
78
+	 *
79
+	 * Updated when a packet is received; copied to ts_recent when
80
+	 * the window is advanced.
81
+	 */
82
+	uint32_t ts_val;
83
+	/** Most recent received timestamp that advanced the window
78 84
 	 *
79 85
 	 * Equivalent to TS.Recent in RFC 1323 terminology.
80 86
 	 */
@@ -740,12 +746,24 @@ static void tcp_rx_opts ( struct tcp_connection *tcp, const void *data,
740 746
  * @v seq_len		Sequence space length to consume
741 747
  */
742 748
 static void tcp_rx_seq ( struct tcp_connection *tcp, uint32_t seq_len ) {
749
+
750
+	/* Sanity check */
751
+	assert ( seq_len > 0 );
752
+
753
+	/* Update acknowledgement number */
743 754
 	tcp->rcv_ack += seq_len;
755
+
756
+	/* Update window */
744 757
 	if ( tcp->rcv_win > seq_len ) {
745 758
 		tcp->rcv_win -= seq_len;
746 759
 	} else {
747 760
 		tcp->rcv_win = 0;
748 761
 	}
762
+
763
+	/* Update timestamp */
764
+	tcp->ts_recent = tcp->ts_val;
765
+
766
+	/* Mark ACK as pending */
749 767
 	tcp->flags |= TCP_ACK_PENDING;
750 768
 }
751 769
 
@@ -1060,7 +1078,6 @@ static int tcp_rx ( struct io_buffer *iobuf,
1060 1078
 	struct tcp_options options;
1061 1079
 	size_t hlen;
1062 1080
 	uint16_t csum;
1063
-	uint32_t start_seq;
1064 1081
 	uint32_t seq;
1065 1082
 	uint32_t ack;
1066 1083
 	uint32_t win;
@@ -1100,12 +1117,14 @@ static int tcp_rx ( struct io_buffer *iobuf,
1100 1117
 	
1101 1118
 	/* Parse parameters from header and strip header */
1102 1119
 	tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
1103
-	seq = start_seq = ntohl ( tcphdr->seq );
1120
+	seq = ntohl ( tcphdr->seq );
1104 1121
 	ack = ntohl ( tcphdr->ack );
1105 1122
 	win = ntohs ( tcphdr->win );
1106 1123
 	flags = tcphdr->flags;
1107 1124
 	tcp_rx_opts ( tcp, ( ( ( void * ) tcphdr ) + sizeof ( *tcphdr ) ),
1108 1125
 		      ( hlen - sizeof ( *tcphdr ) ), &options );
1126
+	if ( options.tsopt )
1127
+		tcp->ts_val = ntohl ( options.tsopt->tsval );
1109 1128
 	iob_pull ( iobuf, hlen );
1110 1129
 	len = iob_len ( iobuf );
1111 1130
 	seq_len = ( len + ( ( flags & TCP_SYN ) ? 1 : 0 ) +
@@ -1152,12 +1171,6 @@ static int tcp_rx ( struct io_buffer *iobuf,
1152 1171
 			goto discard;
1153 1172
 	}
1154 1173
 
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
-
1161 1174
 	/* Enqueue received data */
1162 1175
 	tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );
1163 1176
 

Завантаження…
Відмінити
Зберегти