SMBServer: TCP KeepAlive is now used to detect dead clients

This commit is contained in:
Tal Aloni 2017-03-04 12:59:22 +02:00
parent 84affda0ff
commit 241e06c38d
2 changed files with 21 additions and 0 deletions

View file

@ -112,6 +112,8 @@ namespace SMBLibrary.Server
return;
}
// Windows will set the TCP keepalive timeout to 120 seconds for an SMB connection
SocketUtils.SetKeepAlive(clientSocket, TimeSpan.FromMinutes(2));
ConnectionState state = new ConnectionState(Log);
// Disable the Nagle Algorithm for this tcp socket:
clientSocket.NoDelay = true;

View file

@ -8,6 +8,25 @@ namespace Utilities
{
public class SocketUtils
{
public static void SetKeepAlive(Socket socket, TimeSpan timeout)
{
// The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second.
SetKeepAlive(socket, true, timeout, TimeSpan.FromSeconds(1));
}
/// <param name="timeout">the timeout, in milliseconds, with no activity until the first keep-alive packet is sent</param>
/// <param name="interval">the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received</param>
public static void SetKeepAlive(Socket socket, bool enable, TimeSpan timeout, TimeSpan interval)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
// https://msdn.microsoft.com/en-us/library/dd877220.aspx
byte[] tcp_keepalive = new byte[12];
LittleEndianWriter.WriteUInt32(tcp_keepalive, 0, Convert.ToUInt32(enable));
LittleEndianWriter.WriteUInt32(tcp_keepalive, 4, (uint)timeout.TotalMilliseconds);
LittleEndianWriter.WriteUInt32(tcp_keepalive, 8, (uint)interval.TotalMilliseconds);
socket.IOControl(IOControlCode.KeepAliveValues, tcp_keepalive, null);
}
/// <summary>
/// Socket will be forcefully closed, all pending data will be ignored, and socket will be deallocated.
/// </summary>