Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

linux

tcp

sockets

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?
like image 962
CCoder Avatar asked Dec 11 '12 16:12

CCoder


1 Answers

  • 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".]
like image 123
Nicholas Wilson Avatar answered Oct 23 '22 09:10

Nicholas Wilson