In my project I have a thread that accepts tcp connections and spawns a new thread for each connected client. in those threads I'm calling BufStream.read_line() to process the received data line by line.
As the documentation / samples told me, I'm interpreting a read result of 0 bytes as closed / broken connections.
The strange thing is, that the last time this worked as intended was: Aug 4, 2024, 3:22 PM.
I have not updated the used tokio version since then and as far as I can tell have not changed any related code in a way that could have caused that feature to break.
Yesterday I've wrapped the read_line() call in a 10 minute timeout and sure enough the connections I expected to be closed / broken now show up as a timeout 10 minutes later.
Can somebody help me find out why this doesn't work anymore and how to restore the functionality please?
I would suggest looking at packet dumps; on most OSes, a read from a TCP stream is EOF if, and only if, the socket is cleanly closed via a FIN packet or dirtily closed via a RST packet in the TCP layer.
At the OS level, most TCP stacks will queue a FIN after a shutdown or a close (done on drop in Rust). They will send a RST if they receive a packet for a TCP stream that doesn't exist.
My guess is that you previously had a setup where clients were cleanly disconnecting (by sending FIN to indicate that they had no more data to send), but are now not doing so - either because there's been a firewalling change, or because they're rebooting instead of completing the transaction.
thanks for that idea. I've now tried to reproduce the issue with telnet running on my laptop, and found no matter if I disconnect nicely, or kill telnet with signal 19 (SIGSTOP) or 9 (SIGKILL) my rust tcp server always get's the coveted zero byte read telling it the connection was closed.
So I'll have to use the "real" production clients for debugging and see if I can reproduce the issue with them.
In the case of a process running on the local machine, you'll always get a FIN, because the process is terminated and thus the TCP stack sees the socket being closed. It's going to be either a production client where the TCP stack is terminating (not the client - something like a reboot), one that keeps the socket alive and doesn't close it, or a firewall dropping "bad" packets.
okey well the usual case is some clients rebooting - the strange thing is that 2 weeks ago the same machines seemed to have sent those close packages and now apparently they don't...