Ani
Ani

Reputation: 113462

Inconsistent TCP Keep-Alive Frequency

I've configured a TCP socket in a .NET application to send Keep-Alive packets every 15 minutes. Note that in the .NET world, it's only possible to manipulate this parameter (as opposed to simply enabling Keep-Alives) using the low-level Socket.IOControl API to pass in bytes representing a native struct.

Observe a Wireshark capture of outgoing Keep-Alives below:

Wireshark Capture

Everything went as planned between 12:35 and 14:05 (Keep-Alives were sent every 15 minutes), but after that, the frequency with which these packets were sent began to vary wildly (24 minutes, 15 minutes, 29 minutes, 1 hour 4 minutes). The application was behaving completely as expected during this period with the exception of this inconsistency.

Shortly after this period, the Keep-Alive span reverted to 15 minutes again.


FYI, the code I've written to set the parameter is as below:

private void SetKeepAlive(uint time, uint interval, SocketOptionLevel level)
{
    // The native structure for this is defined in mstcpip.h as:
    //struct tcp_keepalive {
    //u_long onoff;
    //u_long keepalivetime;
    //u_long keepaliveinterval;
    //};

    var inValue = new[] { Convert.ToUInt32(true), time, interval }
                    .SelectMany(BitConverter.GetBytes)
                    .ToArray();

    var outValue = new byte[sizeof(uint)];

    Socket.SetSocketOption(level, SocketOptionName.KeepAlive, true);
    Socket.IOControl(IOControlCode.KeepAliveValues, inValue, outValue);
 }

...called with the equivalent of:

SetKeepAlive(900000, 1000, SocketOptionLevel.Socket);

The purpose of these Keep-Alives is to prevent some of our network hardware from dropping the connection after a timeout (around 30 minutes), so we can't afford for these intervals to vary so wildly. It's also a bit of a pain for us to build in application-level heart-beating and other such user-land solutions - too many systems would need to change.

What could be causing this inconsistent behaviour?

Upvotes: 1

Views: 1311

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123551

From RFC 1122 section 4.2.3.6:

Keep-alive packets MUST only be sent when no data or acknowledgement packets have been received for the connection within an interval.

This means, if that in your case a keep-alive packet will be sent 15 minutes after the last data packet was sent or received by your application. It will only be sent every 15 minutes if your application is idle.

Upvotes: 2

Related Questions