[gPXE-devel] [tcp] Fix error ACK number in FIN packet.

Guo-Fu Tseng cooldavid at cooldavid.org
Wed May 19 06:16:51 EDT 2010


Dear all:
    In recent TCP stack testing, I've found that the FIN packet is in-correct
while downloading with HTTP. The attach shows the data before and after this is
fixed.

The patch is also push at:
http://git.etherboot.org/?p=people/cooldavid/gpxe.git;a=shortlog;h=refs/heads/finfix

diff --git a/src/net/tcp.c b/src/net/tcp.c
index a061962..e9583f1 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -34,6 +34,22 @@ struct tcp_connection {
 	struct xfer_interface xfer;
 	/** Data transfer interface closed flag */
 	int xfer_closed;
+	/** ACK pending
+	 *
+	 * Prevent sending un-updated ACK number in FIN.
+	 *
+	 * If the call path is:
+	 *      tcp_rx()->tcp_rx_data()->...Upper layer...->tcp_xfer_close().
+	 *
+	 *      Which is at lease happened in HTTP while received expected
+	 *      length of data.
+	 *
+	 * Sending FIN in tcp_xfer_close() in this case, will cause error ACK
+	 * number, since the ACK number have not updated by that time.
+	 * Later trying to send a correct one in tcp_rx() will fail too, due
+	 * to the TCP state already changed.
+	 */
+	int ack_pending;
 
 	/** Remote socket address */
 	struct sockaddr_tcpip peer;
@@ -978,6 +994,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
 			goto discard;
 	}
 
+	tcp->ack_pending = !!len;
 	/* Handle new data, if any */
 	tcp_rx_data ( tcp, seq, iobuf );
 	seq += len;
@@ -1008,6 +1025,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
 	 */
 	tcp_xmit ( tcp, ( ( start_seq != seq ) ||
 			  ( ( seq - tcp->rcv_ack ) > tcp->rcv_win ) ) );
+	tcp->ack_pending = 0;
 
 	/* If this packet was the last we expect to receive, set up
 	 * timer to expire and cause the connection to be freed.
@@ -1053,7 +1071,8 @@ static void tcp_xfer_close ( struct xfer_interface *xfer,
int rc ) {
 	tcp_close ( tcp, rc );
 
 	/* Transmit FIN, if possible */
-	tcp_xmit ( tcp, 0 );
+	if ( ! tcp->ack_pending )
+		tcp_xmit ( tcp, 0 );
 }
 
 /**

-------------- next part --------------
A non-text attachment was scrubbed...
Name: finerr.cap
Type: application/octet-stream
Size: 128173 bytes
Desc: not available
Url : http://etherboot.org/pipermail/gpxe-devel/attachments/20100519/d1ecfac5/attachment-0002.obj 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: finfixed.cap
Type: application/octet-stream
Size: 117401 bytes
Desc: not available
Url : http://etherboot.org/pipermail/gpxe-devel/attachments/20100519/d1ecfac5/attachment-0003.obj 


More information about the gPXE-devel mailing list