Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/TDSProxy/TDSConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ public TDSConnection(TDSProxyService service,
// forward from inside to outside, because it seems ODBC and OLEDB clients assume their SSL layer will deliver them
// complete packets. Gross!
outsideClient.NoDelay = false;
EnableKeepAlive(outsideClient.Client);

_outsideEP = (IPEndPoint)outsideClient.Client.RemoteEndPoint;
_outsideClient = outsideClient;
Expand All @@ -492,13 +493,30 @@ public TDSConnection(TDSProxyService service,
_insideEP = insideEndPoint;
_insideClient = new TcpClient(_insideEP.AddressFamily) {NoDelay = false};
_insideClient.Connect(insideEndPoint);
EnableKeepAlive(_insideClient.Client);
_insideStream = _insideClient.GetStream();
_insideActiveStream = _insideStream; // Start with plain stream, may upgrade to SSL later
_serverTlsConfig = listener.ServerTlsConfig;

_processingTask = ProcessConnection();
}

/// <summary>
/// Turn on TCP keep-alive so a peer that disappears without FIN or RST is noticed.
/// A link that is cut rather than closed leaves a blocking read waiting forever:
/// nothing arrives, no error is raised, and the connection pair is stranded until the
/// process is restarted. With keep-alive the socket faults after roughly 90 seconds
/// (60s idle, then 3 probes 10s apart), the catch in ProcessConnection runs, and
/// Close() tears down BOTH legs — so the client is told as well.
/// </summary>
static void EnableKeepAlive(Socket socket)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, 60);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, 10);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveRetryCount, 3);
}

~TDSConnection()
{
if (_state != StateEnum.Closed)
Expand Down
Loading