Browse Source

[tcp] Update received sequence number before delivering received data

iPXE currently updates the TCP sequence number after delivering the
data to the application via xfer_deliver_iob().  If the application
responds to the received data by transmitting more data, this would
result in a stale ACK number appearing in the transmitted packet,
which potentially causes retransmissions and also gives the
undesirable appearance of violating causality (by sending a response
to a message that we claim not to have yet received).

Reported-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
9ff8229693
1 changed files with 10 additions and 8 deletions
  1. 10
    8
      src/net/tcp.c

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

702
 	if ( ( tcp->rcv_ack - seq ) > 0 )
702
 	if ( ( tcp->rcv_ack - seq ) > 0 )
703
 		return 0;
703
 		return 0;
704
 
704
 
705
+	/* Acknowledge SYN */
706
+	tcp_rx_seq ( tcp, 1 );
707
+
705
 	/* Mark SYN as received and start sending ACKs with each packet */
708
 	/* Mark SYN as received and start sending ACKs with each packet */
706
 	tcp->tcp_state |= ( TCP_STATE_SENT ( TCP_ACK ) |
709
 	tcp->tcp_state |= ( TCP_STATE_SENT ( TCP_ACK ) |
707
 			    TCP_STATE_RCVD ( TCP_SYN ) );
710
 			    TCP_STATE_RCVD ( TCP_SYN ) );
708
 
711
 
709
-	/* Acknowledge SYN */
710
-	tcp_rx_seq ( tcp, 1 );
711
-
712
 	return 0;
712
 	return 0;
713
 }
713
 }
714
 
714
 
809
 	iob_pull ( iobuf, already_rcvd );
809
 	iob_pull ( iobuf, already_rcvd );
810
 	len -= already_rcvd;
810
 	len -= already_rcvd;
811
 
811
 
812
+	/* Acknowledge new data */
813
+	tcp_rx_seq ( tcp, len );
814
+
812
 	/* Deliver data to application */
815
 	/* Deliver data to application */
813
 	if ( ( rc = xfer_deliver_iob ( &tcp->xfer, iobuf ) ) != 0 ) {
816
 	if ( ( rc = xfer_deliver_iob ( &tcp->xfer, iobuf ) ) != 0 ) {
814
 		DBGC ( tcp, "TCP %p could not deliver %08x..%08x: %s\n",
817
 		DBGC ( tcp, "TCP %p could not deliver %08x..%08x: %s\n",
816
 		return rc;
819
 		return rc;
817
 	}
820
 	}
818
 
821
 
819
-	/* Acknowledge new data */
820
-	tcp_rx_seq ( tcp, len );
821
-
822
 	return 0;
822
 	return 0;
823
 }
823
 }
824
 
824
 
835
 	if ( ( tcp->rcv_ack - seq ) > 0 )
835
 	if ( ( tcp->rcv_ack - seq ) > 0 )
836
 		return 0;
836
 		return 0;
837
 
837
 
838
-	/* Mark FIN as received and acknowledge it */
839
-	tcp->tcp_state |= TCP_STATE_RCVD ( TCP_FIN );
838
+	/* Acknowledge FIN */
840
 	tcp_rx_seq ( tcp, 1 );
839
 	tcp_rx_seq ( tcp, 1 );
841
 
840
 
841
+	/* Mark FIN as received */
842
+	tcp->tcp_state |= TCP_STATE_RCVD ( TCP_FIN );
843
+
842
 	/* Close connection */
844
 	/* Close connection */
843
 	tcp_close ( tcp, 0 );
845
 	tcp_close ( tcp, 0 );
844
 
846
 

Loading…
Cancel
Save