What socket error do I get when TCP keep-alive breaks the connection?

c, linux, sockets, tcp

Solution

- `select()` itself does not return an error if an error is signalled for one of the sockets it is selecting for. [Indeed, the API can't indicate per-socket errors this way, because two different sockets could each acquire a pending error during a single call of `select()`. Which one would `select()` return?]

- After each iteration of the `select()` loop, you instead use the FD_ISSET macro to attempt a `read()` on each socket marked readable.

- Any time a socket has a pending error set, its read event (and write event) are signalled, and `select()` returns, allowing you to pick up timed-out errors due to keep-alive immediately. Note that select marking a socket for read does not indicate that there is data to read, only that an attempt to read will not block. If the socket has a pending error to retrieve, reading will not block. Both `read(2)` and `write(2)` first retrieve any pending error on the socket before even attempting to handle any data.

A descriptor shall be considered ready for reading when a call to an input function with O_NONBLOCK clear would not block, whether or not the function would transfer data successfully. (The function might return data, an end-of-file indication, or an error other than one indicating that it is blocked, and in each of these cases the descriptor shall be considered ready for reading.) [POSIX:select()]

- Finally, what error is returned? Crucially, it depends on how the keepalive failed. You'll get `ETIMEDOUT` if the other end vanishes totally. If a packet delivery error occurs, you'll get that through instead (so if the keep-alive packet gets an ICMP error reply, like "host unreachable", you'll have `EHOSTUNREACH` delivered). [For more details on these cases, see Stevens, "Unix Network Programming, vol 1".]

Problem

I have a set of TCP sockets with keep-alive (interval 1 min), controlled by a `select(2)` loop (selecting for read). - Will `select(2)` return an error if keep-alive timeout has happened for one of the sockets in the set? - Which error will `read(2)` return?

Original source