3 ms·
It's not a TCP problem. It's a problem with the linux implementation of TCP.
by gonzo 13y ago
It's not a TCP problem. It's a problem with the linux implementation of TCP.
- noselasd 13y agoNo, it's not even that. The linked article (http://www.cliffc.org/blog/2013/08/15/tcp-is-unreliable/ http://www.cliffc.org/blog/2013/08/15/tcp-is-unreliable/) at the bottom tells you what's actually going on. The only thing slightly fishy is that the peer application didn't receive any connection attempt, but if you're anyway quite overloaded, e.g. running out of file descriptors, that may well happen.
- notacoward 13y agoThe FIN/SO_LINGER problem is real, and often misunderstood, but I don't think that was quite the whole story here. SO_LINGER would flag the error some of the time, but not always (see Mistake #2). Even if it did, avoiding the problem altogether (see Mistake #1) would be better than flagging it after the fact. Even with SO_LINGER on and the kernel's RST issues fixed, the app would still be erroneous.
- dap 13y agoI still don't get how this can happen as described. If the client is using a blocking connect and checking for errors (as the author says it is), I don't see how that can succeed without the remote side at least seeing the connection. As you say, the receiver could be overloaded and ignore the connection, but the client should get a connect failure in that case.
- noselasd 13y agoThe remote kernel sees the connection fine. It accepts it, receives the data, the client closes its end. What might not happen is, in a very resource strained condition, is for the remote application to get the data. There's no relation between you doing a connect() and the remote doing an accept() in TCP, it's handled asynchronously by the kernel. (Traditionally the backlog argument to listen() controlled this behavior, but that backlog argument is by and large ignored on modern operating systems) The caveat here is that you close() the socket when you're done. close() does not, by default, wait until the remote end also closed its end. In the scenario described above, the remote end would eventually signal an error, but if you shoved the data into the remote kernel buffers, close and forget about that connection, your app will never see that error.