Thu 01 Sep 2011 07:51:18 PM UTC, comment #10:
I agree that it's a nice feature for lwIP to have, I was just curious why firefox (running on windows) would trigger a RST in such a normal condition. Maybe I did something wrong in the httpd, after all...
|
Thu 01 Sep 2011 07:38:37 PM UTC, comment #9:
Regarding the timeout, I think it is there to prevent a DoS attack where the other end refuses to send a FIN, thus leaving the connection open, and so consuming resources on the server. This makes it particularly important in lwIP where the resources are by definition small.
|
Thu 01 Sep 2011 07:09:03 PM UTC, comment #8:
Fixed by correcting seqno in RST sent in tcp_listen_input.
I've also fixed that tcp_listen_input doesn't even try to process RST segments (which should be the first check according to the RFC and we didn't do that, too).
|
Thu 01 Sep 2011 06:50:52 PM UTC, comment #7:
TCP RFC 793 says:
"If the state is LISTEN then [..] second check for an ACK [..] An acceptable reset segment should be formed
for any arriving ACK-bearing segment. The RST should be
formatted as follows:
<SEQ=SEG.ACK><CTL=RST>"
Thus the real bug is that we sent "<SEQ=SEG.ACK+1><CTL=RST>".
|
Thu 01 Sep 2011 08:11:03 AM UTC, comment #6:
The fix proposed in comment #3 works for me (tested with Sysinternals TcpView, the half open connections chance from close-wait to closed after receiving the RST with correct seqno).
BTW, the code has been in there since the initial CVS revision...
Still, I'm curious about the FIN_WAIT2 timeout: where does it come from? Do other stacks have such a timeout? Is the an additional RFC/spec (to the original TCP RFC) which suggests such a timeout?
|
Tue 30 Aug 2011 06:44:22 PM UTC, comment #5:
I'm perfectly OK with getting the RST to work. However, I just have been wondering about the timeout sinethe TCP RFC does not mention a timeout for FIN WAIT2.
Also, isn't a half-closed connection OK from the standard (it's horrible programming style, however).
I'll check the changed seqno tomorrow.
|
Tue 30 Aug 2011 03:16:53 PM UTC, comment #4:
I think we're in agreement, and the suggested fix from comment #3 sounds about right to me.
|
Tue 30 Aug 2011 03:13:32 PM UTC, comment #3:
1: The wrong seqno cause the peer end doesn't close connection succefully.
2: In my opinion, 20s is enough for FIN-WAIT-2 even if the device based on lwIP is working in wireless network.
For these two reasons, I suggest adjusting seqno to a proper value.
For the state of machine is LISTEN,
tcp_in.c#tcp_listen_input
- tcp_rst(ackno + 1, seqno + tcplen, ......);
+ tcp_rst(ackno, seqno + tcplen, ......);
Hope it will be OK then! But I don't know the reason that the origin author add 1, anyone know it please tell me!
|
Tue 30 Aug 2011 12:37:08 PM UTC, comment #2:
The RST packets have the wrong sequence number: they are one octet too large, and so are being ignored. Let's fix that, but leave the timeout as is.
|
Tue 30 Aug 2011 12:31:53 PM UTC, comment #1:
I think the interesting bit here is why doesn't the RST cause the other end to give up. There must be something wrong with it.
|
Wed 24 Aug 2011 09:03:55 AM UTC, original submission:
I observed this while adding support for HTTP/1.1 persistent connections (not checked in, yet):
The scenario is:
- using Firefox 6.0 (Windows XP), I loaded a webpage with embedded images (1 connection for the webpage, ~6 connections for the images)
- when the page is loaded, the connections stay open (firefox would re-use them if I load another page soon enough)
- after ~8 seconds, our webserver closes unused connections -> FIN is sent from lwIP to windows
- windows responds with ACK, but not with FIN (lwIP connections go to FIN_WAIT2 state)
- 100 seconds later, windows would send the FIN, but at that state, lwIP has already (silently) purged the pcbs (since the FIN_WAIT_TIMEOUT is 20 seconds
- since lwIP has already purged the connection, the FIN packet is passed to the listening pcb -> RST is returned
- the last step is repeated several times, since the RST does not seem to lead to windows giving up the connection, instead the FIN is retried
Now when I increase TCP_FIN_WAIT_TIMEOUT from 20 sec to 120 sec, it all works.
However, I'm not sure if this is OK since
a) I'm not sure where that 100 sec timeout before windows sends the FIN comes from (OS or browser?) and
b) I thought that the RST should be enough for windows to stop retrying the FIN - maybe the seq/ack no's are wrong?
I'll attach a pcap showing this.
|