You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When requesting a web page from the cyw43439 based http-server example (using wget, curl, or a browser), I am observing a wireshark log similar to the following excerpt:
After the server pico_w has transmitted the web page of 1244 bytes, the client sends an ACK segment (❶).
At nearly the same time the server already sends its FIN+ACK (➋), which the client acknowledges
(➌, the client uses the ACK number 1192, which is 1191+1, hence the ACK refers to the server's FIN+ACK).
In the server's log a slightly different order can be observed: The ACK (1) is received (resp. processed) after the FIN+ACK (2).
As client and server send ❶ and ➋ independently, it can happen that ❶ is captured in the wireshark log before ➋, but on the server side ❶ is received and processed slightly after ➋.
Since the server is in FinWait1 state, when ❶ is received, ControlBlock.rcvFinWait1 (control.go:246) is called. Because the hasAck switch case applies, FinWait2 state is entered.
Wouldn't it be more correct if ❶ would be ignored by rcvFinWait1, since it does not acknowledge the FIN, but a previous date segment? The server could wait some more time until ➌ arrives, which contains the matching FIN and ACK.
The first case expression of the switch statement in ControlBlock.rcvFinWait1 already contains the
sub condition seg.ACK == tcb.snd.NXT. I think moving this condition to the initialization of hasAck would change the behaviour so that TimeWait is entered directly from FinWait1:
It would make sure that only an ACK that actually acknowledges the FIN previously sent by the server is accepted. With this change, I am observing the following transition in Pico W's log:
0.904 INFO TCP:tx-statechange port=80 old=Established new=FinWait1 txflags=[FIN,ACK]
0.015 INFO TCP:rx-statechange port=80 old=FinWait1 new=TimeWait rxflags=[FIN,ACK]
If you suggest me to provide a pull request, I will be happy to do so.
(BTW, it appears that if keeping track of acknowledgments / retransmission was already implemented (or is it implemented?), the ACK observed here would have been consumed earlier, so this behavior would likely not be observable).
Sure! feel free to provide a PR. I've been busy with other gnarly bugs on seqs and have not had time to look into this particular issue. Right now I'm looking at a bug where the TCP connection remains forever open in FinWait2.
As for retransmission logic in seqs, as far as I recall there is none or very basic support for certain cases, though I have been thinking it would be nice to have.
When requesting a web page from the cyw43439 based http-server example (using wget, curl, or a browser), I am observing a wireshark log similar to the following excerpt:
After the server
pico_w
has transmitted the web page of 1244 bytes, the client sends an ACK segment (❶).At nearly the same time the server already sends its FIN+ACK (➋), which the client acknowledges
(➌, the client uses the ACK number 1192, which is 1191+1, hence the ACK refers to the server's FIN+ACK).
In the server's log a slightly different order can be observed: The ACK (1) is received (resp. processed) after the FIN+ACK (2).
As client and server send ❶ and ➋ independently, it can happen that ❶ is captured in the wireshark log before ➋, but on the server side ❶ is received and processed slightly after ➋.
Since the server is in FinWait1 state, when ❶ is received,
ControlBlock.rcvFinWait1
(control.go:246) is called. Because thehasAck
switch case applies, FinWait2 state is entered.Wouldn't it be more correct if ❶ would be ignored by
rcvFinWait1
, since it does not acknowledge the FIN, but a previous date segment? The server could wait some more time until ➌ arrives, which contains the matching FIN and ACK.The first
case
expression of the switch statement inControlBlock.rcvFinWait1
already contains thesub condition
seg.ACK == tcb.snd.NXT
. I think moving this condition to the initialization ofhasAck
would change the behaviour so that TimeWait is entered directly from FinWait1:hasAck := flags&FlagACK != 0
hasAck := flags&FlagACK != 0 && seg.ACK == tcb.snd.NXT
It would make sure that only an ACK that actually acknowledges the FIN previously sent by the server is accepted. With this change, I am observing the following transition in Pico W's log:
As an example, I have attached a patch containing the change to
rcvFinWait1
, and a test case. finwait1_ignore_data_ack.patch.gzThe text was updated successfully, but these errors were encountered: