On 06.06.2018 16:23, Joel Cunningham
wrote:
On
06.06.2018 11:42, R. Diez wrote:
[..]
The trouble is, this changes the connection state
(pcb->state) from
ESTABLISHED to FIN_WAIT_1, which then turns quickly into
FIN_WAIT_2.
Afterwards, TCP keep-alive does not work anymore, because of
this logic
in tcp_slowtmr():
/* Check if KEEPALIVE should be sent */
if (ip_get_option(pcb, SOF_KEEPALIVE) &&
((pcb->state == ESTABLISHED) ||
(pcb->state == CLOSE_WAIT))) {
If I then pull the server's Ethernet cable while the
connection is
transferring data, the connection never times out on the
client.
I am no TCP/IP expert. Is there an error in my reasoning
regarding
half-closed connections? Can TCP keep-alive packets, whatever
they are,
still be sent and/or received on half-closed TCP connections?
Half-opened connections should be usable like you did it, yes.
I'm not sure about keepalives though.
Technically, keepalives are just empty ACKs, so that should
work.
However, I'm not sure wether tcp keepalive is meant to work on
half-open connections.
In order to move from ESTABLISHED to FIN_WAIT_1 and ultimately
FIN_WAIT_2, your application would have had to shutdown the TX
pathway (either a call to shutdown() or close()). In this
scenario, TCP can no longer send data packets, so you couldn't
detect a half-open connection by sending data. Since the
connection is in a receive only state, either a FIN_WAIT_2 timeout
or TCP keepalives with no data could be used.
I believe keepalives are used in this case, I found some evidence
with a quick google.
Right. The RFCs I read don't speak about tcp states, so it seems OK
to continue keepalives in the FIN_WAIT states.
It might even be OK in CLOSE_WAIT, as RFC 1122 says keepalive
packets must only be sent "when no data or acknowledgement packets
have been received".
A more
exhaustive study of other stacks would be a good to confirm this
behavior.
A quick look at the Linux sources tells me they continue keepalives
in all states...
https://stackoverflow.com/questions/18110239/does-tcp-endpoint-that-has-sent-a-fin-still-send-keepalive
https://social.msdn.microsoft.com/Forums/en-US/d20e5e67-d23c-42a5-95c5-ba80f4263546/keepalive-packets-continue-being-sent-after-client-closes-server-socket-is-closewait-client
Here's some findings on a FIN_WAIT_2 timeout:
https://serverfault.com/questions/738300/why-are-connections-in-fin-wait2-state-not-closed-by-the-linux-kernel
https://www.akronohio.gov/manual/misc/fin_wait_2.html
I don't believe a FIN_WAIT_2 timeout is implemented in LwIP.
No, we don't have that. We always said it's OK for a connection to
stay in FIN_WAIT_2. However, it seems we must handle this
differently depending on wether the user has called "shutdown" or
"close". Then we can implement a timeout.
I'm also
thinking this issue may not be that common since tcp_alloc would
reap the half-open connection eventually to prevent pcb exhaustion
I don't think tcp_alloc will kill pcbs in FIN_WAIT_2 unless they
have a lower priority. A timeout on FIN_WAIT_2 *does* make sense!
Simon
|