Skip to content

Commit

Permalink
Add TcpKeepAlive option and enable it by default. (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmds authored Oct 5, 2024
1 parent cfa7caf commit ee05d70
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 2 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,13 @@ class SshClientSettings
string HostName { get; set; } = "";
int Port { get; set; } = 22;

IReadOnlyList<Credential> Credentials { get; set; } = DefaultCredentials;
List<Credential> Credentials { get; set; } = DefaultCredentials;

bool AutoConnect { get; set; } = true;
bool AutoReconnect { get; set; } = false;

bool TcpKeepAlive { get; set; } = true;

List<string> GlobalKnownHostsFilePaths { get; set; } = DefaultGlobalKnownHostsFilePaths;
List<string> UserKnownHostsFilePaths { get; set; } = DefaultUserKnownHostsFilePaths;
HostAuthentication? HostAuthentication { get; set; } // not called when known to be trusted/revoked.
Expand Down
2 changes: 2 additions & 0 deletions src/Tmds.Ssh/SshClientSettings.Defaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ partial class SshClientSettings

private static bool DefaultHashKnownHosts => false;

private static bool DefaultTcpKeepAlive => true;

// Algorithms are in **order of preference**.
private readonly static List<Name> EmptyList = [];
internal readonly static List<Name> SupportedKeyExchangeAlgorithms = [ AlgorithmNames.EcdhSha2Nistp256, AlgorithmNames.EcdhSha2Nistp384, AlgorithmNames.EcdhSha2Nistp521 ];
Expand Down
1 change: 1 addition & 0 deletions src/Tmds.Ssh/SshClientSettings.SshConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ internal static async ValueTask<SshClientSettings> LoadFromConfigAsync(string? u
MinimumRSAKeySize = sshConfig.RequiredRSASize ?? DefaultMinimumRSAKeySize,
Credentials = DetermineCredentials(sshConfig),
HashKnownHosts = sshConfig.HashKnownHosts ?? DefaultHashKnownHosts,
TcpKeepAlive = sshConfig.TcpKeepAlive ?? DefaultTcpKeepAlive
};
if (sshConfig.UserKnownHostsFiles is not null)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Tmds.Ssh/SshClientSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ public Dictionary<string, string>? EnvironmentVariables
}
}

public bool TcpKeepAlive { get; set; } = DefaultTcpKeepAlive;

public int MinimumRSAKeySize { get; set; } = DefaultMinimumRSAKeySize; // TODO throw if <0.

// Currently these settings are not exposed.
Expand Down
6 changes: 5 additions & 1 deletion src/Tmds.Ssh/SshConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public struct AlgorithmList
public StrictHostKeyChecking? HostKeyChecking { get; set; }
public bool? HashKnownHosts { get; set; }
public List<string>? SendEnv { get; set; }
public bool? TcpKeepAlive { get; set; }

internal static ValueTask<SshConfig> DetermineConfigForHost(string? userName, string host, int? port, IReadOnlyDictionary<SshConfigOption, SshConfigOptionValue>? options, IReadOnlyList<string> configFiles, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -442,6 +443,10 @@ private static void HandleMatchedKeyword(SshConfig config, ReadOnlySpan<char> ke
config.Compression ??= ParseYesNoKeywordValue(keyword, ref remainder);
break;

case "tcpkeepalive":
config.TcpKeepAlive ??= ParseYesNoKeywordValue(keyword, ref remainder);
break;

/* The following options are unsupported,
we have some basic handling that checks the option value indicates the feature is disabled */
case "permitlocalcommand":
Expand Down Expand Up @@ -536,7 +541,6 @@ we have some basic handling that checks the option value indicates the feature i
// case "streamlocalbindunlink":
// case "serveralivecountmax":
// case "serveraliveinterval":
// case "tcpkeepalive":
// case "setenv":
// case "tag":
// case "proxycommand":
Expand Down
5 changes: 5 additions & 0 deletions src/Tmds.Ssh/SshSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ private async Task<SshConnection> EstablishConnectionAsync(CancellationToken ct)
ConnectionInfo.IPAddress = (socket.RemoteEndPoint as IPEndPoint)?.Address;
socket.NoDelay = true;

if (_settings.TcpKeepAlive)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
}

Logger.ConnectionEstablished();

return new SocketSshConnection(Logger, _sequencePool, socket);
Expand Down

0 comments on commit ee05d70

Please sign in to comment.