[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