Browse Source

[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 years ago
parent
commit
c4369eb6c2
1 changed files with 22 additions and 9 deletions
  1. 22
    9
      src/net/tcp.c

+ 22
- 9
src/net/tcp.c View File

74
 	 * Equivalent to RCV.WND in RFC 793 terminology.
74
 	 * Equivalent to RCV.WND in RFC 793 terminology.
75
 	 */
75
 	 */
76
 	uint32_t rcv_win;
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
 	 * Equivalent to TS.Recent in RFC 1323 terminology.
85
 	 * Equivalent to TS.Recent in RFC 1323 terminology.
80
 	 */
86
 	 */
740
  * @v seq_len		Sequence space length to consume
746
  * @v seq_len		Sequence space length to consume
741
  */
747
  */
742
 static void tcp_rx_seq ( struct tcp_connection *tcp, uint32_t seq_len ) {
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
 	tcp->rcv_ack += seq_len;
754
 	tcp->rcv_ack += seq_len;
755
+
756
+	/* Update window */
744
 	if ( tcp->rcv_win > seq_len ) {
757
 	if ( tcp->rcv_win > seq_len ) {
745
 		tcp->rcv_win -= seq_len;
758
 		tcp->rcv_win -= seq_len;
746
 	} else {
759
 	} else {
747
 		tcp->rcv_win = 0;
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
 	tcp->flags |= TCP_ACK_PENDING;
767
 	tcp->flags |= TCP_ACK_PENDING;
750
 }
768
 }
751
 
769
 
1060
 	struct tcp_options options;
1078
 	struct tcp_options options;
1061
 	size_t hlen;
1079
 	size_t hlen;
1062
 	uint16_t csum;
1080
 	uint16_t csum;
1063
-	uint32_t start_seq;
1064
 	uint32_t seq;
1081
 	uint32_t seq;
1065
 	uint32_t ack;
1082
 	uint32_t ack;
1066
 	uint32_t win;
1083
 	uint32_t win;
1100
 	
1117
 	
1101
 	/* Parse parameters from header and strip header */
1118
 	/* Parse parameters from header and strip header */
1102
 	tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
1119
 	tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
1103
-	seq = start_seq = ntohl ( tcphdr->seq );
1120
+	seq = ntohl ( tcphdr->seq );
1104
 	ack = ntohl ( tcphdr->ack );
1121
 	ack = ntohl ( tcphdr->ack );
1105
 	win = ntohs ( tcphdr->win );
1122
 	win = ntohs ( tcphdr->win );
1106
 	flags = tcphdr->flags;
1123
 	flags = tcphdr->flags;
1107
 	tcp_rx_opts ( tcp, ( ( ( void * ) tcphdr ) + sizeof ( *tcphdr ) ),
1124
 	tcp_rx_opts ( tcp, ( ( ( void * ) tcphdr ) + sizeof ( *tcphdr ) ),
1108
 		      ( hlen - sizeof ( *tcphdr ) ), &options );
1125
 		      ( hlen - sizeof ( *tcphdr ) ), &options );
1126
+	if ( options.tsopt )
1127
+		tcp->ts_val = ntohl ( options.tsopt->tsval );
1109
 	iob_pull ( iobuf, hlen );
1128
 	iob_pull ( iobuf, hlen );
1110
 	len = iob_len ( iobuf );
1129
 	len = iob_len ( iobuf );
1111
 	seq_len = ( len + ( ( flags & TCP_SYN ) ? 1 : 0 ) +
1130
 	seq_len = ( len + ( ( flags & TCP_SYN ) ? 1 : 0 ) +
1152
 			goto discard;
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
 	/* Enqueue received data */
1174
 	/* Enqueue received data */
1162
 	tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );
1175
 	tcp_rx_enqueue ( tcp, seq, flags, iob_disown ( iobuf ) );
1163
 
1176
 

Loading…
Cancel
Save