Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TCP, recv function hanging despite KEEPALIVE

Is TCP keepalive (with small timeouts) preventing client from hanging on recv, after the server is dead?

The scenario:

Server and client running on separate machines:

  1. Clients connects to a server through TCP with KEEPALIVE option
  2. Client sends "Hello server" and waits for a response
  3. Server receives "Hello server" and responds "Hello client"
  4. Client receives response, sleeps 10s and steps 2-4 are repeated (step 1 is now skipped - connection is preserved)

During the client sleep, the server is plugged off, now:

  1. Client wakes up
  2. Sends "Hello server" and waits for a response
  3. After 20 minutes recv gives up - I was expecting KEEPALIVE to break the recv function after 45 seconds:

Setting KEEPALIVE options:

void TCPclient::setkeepalive()
{
   int optval;
   socklen_t optlen = sizeof(optval);

   /* Check the status for the keepalive option */
   if(getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
        throw std::string("getsockopt");
   }

   optval = 1;
   optlen = sizeof(optval);
   if(setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
      close(s);
      exit(EXIT_FAILURE);
   }

    optval = 2;
    if (setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &optval, optlen) < 0) {
        throw std::string("setsockopt");
    }

    optval = 15;
    if (setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &optval, optlen) < 0) {
        throw std::string("setsockopt");
    }

    optval = 15;
    if (setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &optval, optlen) < 0) {
        throw std::string("setsockopt");
    }   
}

linux 3.2.0-84-generic

like image 936
Michal Avatar asked Jun 26 '15 15:06

Michal


1 Answers

Keepalive becomes active when the line has been idle for 15 secs. In your case Keepalive kick off timeout is 15 secs, the sleep is 10 secs, which means "Hello server" will be the next command to be sent after the server is killed.

Your Linux will try to retransmit the message several times. Keepalive still won't be triggered. The connection will break after the limit of retries is reached - that will take 10-30 minutes.

like image 75
MMA Avatar answered Oct 05 '22 23:10

MMA