Send RST when dropping established connections after idle timeout
Currently, tcp connections going to a VM's public IP get dropped when idle after 4 minutes (configurable).
However, neither the client nor the server get sent a RST packet, meaning both must fall back on keep-alives or retransmission timeouts to notice that the connection is dead.
This is pretty far from the standard which specifies:
1) established connection idle timeout MUST be at least 2 hours
2) established connections MAY be abandoned without RST packet sent, but strongly encouraged not to
The 2nd part is actually worse than the first, causing clients to attempt retransmits for a long time (depending on tcp retransmission settings), and servers to keep resources allocated for a connection that is no longer good.
Simon O commented
Jebus, this is actually by design?
What clown thought that was a good idea?
Philip Rieck commented
For the love of god, fix this.
Steve Brown commented
I have also found this to be a serious problem. The Static NAT (SNAT) table management process that underpins static PIPs should do a RST when timing out an ephemeral port. Otherwise, the VM that uses the PIP ends up having stale sockets that are still ESTABLISHED, which cause loss of connectivity when a new outbound connection to the same remote host is attempted after the timeout period.
John Hargrove commented
This is a very big issue for Azure-hosted web applications and Chrome. Chrome reuses connections it has open to web servers. Since Azure does not tell the browser the connection is killed (no RST), Chrome thinks it is valid and attempts to reuse the connection. This results in a failure after a long period of time (20 seconds). Chrome will do this for every connection it has open to the server (as many as 6), until it eventually opens a fresh connection. This results in a load time of the Azure-hosted website in __excess of 2 minutes__. I cannot stress enough how horrible that is. This is not a Chrome issue. It is an Azure issue. My customers use Chrome, and we host their applications on Azure. I am running out of options and will soon be forced to migrate to another provider if this is not fixed.
The standard in this case is RFC 5382, which states that "In such cases, the value of the "established connection idle-timeout" MUST NOT be less than 2 hours 4 minutes."
The RFC is more equivocal about sending RST packets, "When a NAT abandons a live connection, for example due to a timeout expiring, the NAT MAY either send TCP RST packets to the endpoints or MAY silently abandon the connection," but I agree with Marc that this seems like the larger practical issue, and I'd rather have a RST packet than a shorter timeout. Even if the RST cannot be sent proactively, it appears that packets from the client are simply going into the void when they should be getting RST responses.