Using SIO_KEEPALIVE_VALS to check for an unplugged network cable

Started by pcMike, August 24, 2007, 04:59:58 AM

Previous topic - Next topic

pcMike

I have some socket code which was failing to detect when a network cable is unplugged, because the recv() function was not returning zero as I had expected.

After researching it a bit I found the solution is to set the SIO_KEEPALIVE_VALS by using the WSAIoctl function.
But MS doesnt explain the values in detail, and another problem I encountered was MASM32's include files do not have a definition for SIO_KEEPALIVE_VALS, so I had to search for the value and manually define it.

After I finally got it working, I figured I would share my results in case anyone else searchs for the solution:

SIO_KEEPALIVE_VALS equ 2550136836

keepalive_cfg     dd 1,15000,500         ; on/off, , KeepAliveTime, KeepAliveInterval
keepalive_bytes  dd 0                         ; 0 means send 1 out-of-sequence byte

The above settings will check that the connection is alive by sending 1 byte every 15 seconds while the connection is idle, and if there is no reply it will keep retrying for another 5 seconds before giving up.

The KeepAliveTime specifies the timeout, in milliseconds, with no activity until the first keep-alive packet is sent. The KeepAliveInterval specifies the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received. When no acknowlegement is received, up to 9 additional keep-alive probes will be sent, and if there is still no acknowlegement the socket is considered to be disconnected.

The default settings when a TCP socket is initialized sets the KeepAliveTime to 2 hours and the KeepAliveInterval to 1 second. The number of keep-alive probes cannot be changed and is set to 10.

Here is the code:

invoke WSAIoctl, wshandle, SIO_KEEPALIVE_VALS, offset keepalive_cfg, sizeof keepalive_cfg, NULL, 0, offset keepalive_bytes, NULL, NULL
.if eax!=NULL
   print "Set SIO_KEEPALIVE_VALS failed"
   jmp error_exit
.endif

You will need to include ws2_32.inc and ws2_32.lib, and WSAIoctl requres that WSAStartup sets WinSock version 2.xx.


Regards,  Mike
[edited: I had the Time and Interval values mixed up]