From 5ec54db2d68fac0ae01e321f098f75296d5385db Mon Sep 17 00:00:00 2001 From: Clemens Vasters Date: Tue, 3 Sep 2024 13:09:50 +0200 Subject: [PATCH] Adding KeepAliveInterval option and settings for ctrl channel --- CONFIG.md | 13 +++++++++++++ .../Configuration/CommandLineSettings.cs | 2 ++ .../Configuration/Config.cs | 18 ++++++++++++++++++ .../RemoteForwardBridge.cs | 1 + .../ConfigTest.cs | 6 +++++- 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CONFIG.md b/CONFIG.md index 426c88b..756e6c5 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -254,6 +254,14 @@ file. The connection string can be set via the AZURE_BRIDGE_CONNECTIONSTRING environment variable. +### **-a keepalive_interval** + +Specifies the interval (in seconds) between keepalive messages sent on the +"control connection" through which the listener accepts new connections. +The default is 30 seconds. The value is the maximum interval during which +a disconnected listener can go unnoticed by the remote forwarder and the +automatic reconnection mechanism is triggered. + ### -h **-?** @@ -325,6 +333,11 @@ the -L and -T command line options above. should bind local port forwardings to the wildcard address, thus allowing remote hosts to connect to forwarded ports. The argument must be "true" or "false". The default is "false". +* **KeepAliveInterval** - Specifies the interval (in seconds) between keepalive + messages sent on the "control connection" through which the listener accepts + new connections. The default is 30 seconds. The value is the maximum interval + during which a disconnected listener can go unnoticed by the remote forwarder and + the automatic reconnection mechanism is triggered. * **LocalForward** - Specifies that a (set of) TCP ports on the local machine shall be forwarded via the Azure Relay. Each entry can have four properties, "BindAddress", "Port", "LocalSocket", and "RelayName". See [below](#localforward-properties) for diff --git a/src/Microsoft.Azure.Relay.Bridge/Configuration/CommandLineSettings.cs b/src/Microsoft.Azure.Relay.Bridge/Configuration/CommandLineSettings.cs index 6b22105..2e290b7 100644 --- a/src/Microsoft.Azure.Relay.Bridge/Configuration/CommandLineSettings.cs +++ b/src/Microsoft.Azure.Relay.Bridge/Configuration/CommandLineSettings.cs @@ -22,6 +22,8 @@ public class CommandLineSettings #endif [Option(CommandOptionType.NoValue, LongName = "svc", ShortName = "svc", Description = "Reserved for background service invocation")] public bool? ServiceRun { get; set; } + [Option(CommandOptionType.SingleValue, ShortName = "a", Description = "Keepalive interval in seconds (default 30)")] + public int? KeepAliveInterval { get; set; } [Option(CommandOptionType.SingleValue, ShortName = "b", Description = "Source address of forwarding connections.")] public string BindAddress { get; set; } [Option(CommandOptionType.SingleValue, ShortName = "e", Description = "Relay endpoint URI")] diff --git a/src/Microsoft.Azure.Relay.Bridge/Configuration/Config.cs b/src/Microsoft.Azure.Relay.Bridge/Configuration/Config.cs index 5284aa5..e61fc11 100644 --- a/src/Microsoft.Azure.Relay.Bridge/Configuration/Config.cs +++ b/src/Microsoft.Azure.Relay.Bridge/Configuration/Config.cs @@ -432,6 +432,16 @@ public string LogFileName } } + /// + /// Specifies the number of seconds that the control connection to the + /// Azure Relay server may be inactive before it is "pinged" and therefore + /// checked. The default is 30 seconds. You can specify a shorter interval + /// if you are using a problematic network that disconnects idle connections + /// frequently. The value is the maximum number of seconds that a disconnected + /// listener will go undetected. + /// + public int KeepAliveInterval { get; set; } = 30; + /// /// Specifies that a TCP port on the remote machine be bound to /// a name on the Azure Relay. @@ -573,6 +583,10 @@ public static Config LoadConfig(CommandLineSettings commandLineSettings) { config.AzureRelayConnectionString = commandLineSettings.ConnectionString; } + if (commandLineSettings.KeepAliveInterval.HasValue) + { + config.KeepAliveInterval = commandLineSettings.KeepAliveInterval.Value; + } if (commandLineSettings.LocalForward != null) { @@ -1132,6 +1146,10 @@ private void Merge(Config otherConfig) { this.LogLevel = otherConfig.LogLevel; } + if (otherConfig.KeepAliveInterval != 30) + { + this.KeepAliveInterval = otherConfig.KeepAliveInterval; + } if (this.ClearAllForwardings.HasValue && this.ClearAllForwardings.Value) { diff --git a/src/Microsoft.Azure.Relay.Bridge/RemoteForwardBridge.cs b/src/Microsoft.Azure.Relay.Bridge/RemoteForwardBridge.cs index 457b6bf..e9a2f8f 100644 --- a/src/Microsoft.Azure.Relay.Bridge/RemoteForwardBridge.cs +++ b/src/Microsoft.Azure.Relay.Bridge/RemoteForwardBridge.cs @@ -86,6 +86,7 @@ public async Task Open() { this.listener = new HybridConnectionListener(connectionString.ToString()); } + this.listener.KeepAliveInterval = TimeSpan.FromSeconds(config.KeepAliveInterval); this.listener.Online += (s, e) => { Online?.Invoke(this, e); }; this.listener.Offline += (s, e) => { Offline?.Invoke(this, e); }; this.listener.Connecting += (s, e) => { Connecting?.Invoke(this, e); }; diff --git a/test/unit/Microsoft.Azure.Relay.Bridge.Tests/ConfigTest.cs b/test/unit/Microsoft.Azure.Relay.Bridge.Tests/ConfigTest.cs index 369c78c..1c84876 100644 --- a/test/unit/Microsoft.Azure.Relay.Bridge.Tests/ConfigTest.cs +++ b/test/unit/Microsoft.Azure.Relay.Bridge.Tests/ConfigTest.cs @@ -52,7 +52,8 @@ string CreateMaxCommandLine() " -H baz5:http/service.example.com" + " -H abc/def:http/service.example.com/foo" + " -H ghi/jkl:http/service1.example.com/foo;http/service2.example.com/foo" + - " -v"; + " -v" + + " -a 60"; } string CreateMaxConfig() @@ -69,6 +70,7 @@ string CreateMaxConfig() "ClearAllForwardings : false " + textWriter.NewLine + "ConnectionAttempts : 1 " + textWriter.NewLine + "ConnectTimeout : 60 " + textWriter.NewLine + + "KeepAliveInterval : 60 " + textWriter.NewLine + "ExitOnForwardFailure : true " + textWriter.NewLine + "LocalForward : " + textWriter.NewLine + " - BindAddress : 127.0.100.1" + textWriter.NewLine + @@ -700,6 +702,7 @@ public void ConfigBadConnectTimeoutTest() } private static void CheckMaxCommandLine(Config config) { + Assert.Equal(60, config.KeepAliveInterval); Assert.Equal("Endpoint=sb://cvrelay.servicebus.windows.net/;SharedAccessKeyName=send;SharedAccessKey=abcdefgh;", config.AzureRelayConnectionString); Assert.Equal("sb://cvrelay.servicebus.windows.net/", config.AzureRelayEndpoint); Assert.Equal("send", config.AzureRelaySharedAccessKeyName); @@ -778,6 +781,7 @@ private static void CheckMaxCommandLine(Config config) private static void CheckMaxConfig(Config config) { + Assert.Equal(60, config.KeepAliveInterval); Assert.Equal("inet", config.AddressFamily); Assert.Equal("Endpoint=sb://cvrelay.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=P0CQgKxRl8S0ABAlmbitHDEWfwWUQzKB34J0w48SB/w=;", config.AzureRelayConnectionString); Assert.Equal("sb://cvrelay.servicebus.windows.net/", config.AzureRelayEndpoint);