From ec063fef6aee1b4e9700371611055e70a6782ab1 Mon Sep 17 00:00:00 2001 From: Allen Byron Penner <7310089+ByronAP@users.noreply.github.com> Date: Wed, 16 Oct 2019 09:27:10 -0400 Subject: [PATCH 1/4] Update RunTime.cs add IsSocketReuseAvailable to Helpers.RunTime --- src/Titanium.Web.Proxy/Helpers/RunTime.cs | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/Titanium.Web.Proxy/Helpers/RunTime.cs b/src/Titanium.Web.Proxy/Helpers/RunTime.cs index b2d1e9847..378d1ceda 100644 --- a/src/Titanium.Web.Proxy/Helpers/RunTime.cs +++ b/src/Titanium.Web.Proxy/Helpers/RunTime.cs @@ -41,6 +41,62 @@ public static class RunTime public static bool IsUwpOnWindows => IsWindows && UwpHelper.IsRunningAsUwp(); public static bool IsMac => isRunningOnMac; + + /// + /// Is socket reuse available to use? + /// + public static bool IsSocketReuseAvailable => isSocketReuseAvailable(); + + private static bool? _isSocketReuseAvailable; + + private static bool isSocketReuseAvailable() + { + // use the cached value if we have one + if (_isSocketReuseAvailable != null) + return _isSocketReuseAvailable.Value; + + try + { + if (IsWindows) + { + // since we are on windows just return true + // store the result in our static object so we don't have to be bothered going through all this more than once + _isSocketReuseAvailable = true; + return true; + } + + // get the currently running framework name and version (EX: .NETFramework,Version=v4.5.1) (Ex: .NETCoreApp,Version=v2.0) + string ver = Assembly.GetEntryAssembly()?.GetCustomAttribute()?.FrameworkName; + + if (ver == null) + return false; // play it safe if we can not figure out what the framework is + + // make sure we are on .NETCoreApp + ver = ver.ToLower(); // make everything lowercase to simplify comparison + if (ver.Contains(".netcoreapp")) + { + var versionString = ver.Replace(".netcoreapp,version=v", ""); + var versionArr = versionString.Split('.'); + var majorVersion = Convert.ToInt32(versionArr[0]); + + var result = majorVersion >= 3; // version 3 and up supports socket reuse + + // store the result in our static object so we don't have to be bothered going through all this more than once + _isSocketReuseAvailable = result; + return result; + } + + // store the result in our static object so we don't have to be bothered going through all this more than once + _isSocketReuseAvailable = false; + return false; + } + catch + { + // store the result in our static object so we don't have to be bothered going through all this more than once + _isSocketReuseAvailable = false; + return false; + } + } // https://github.com/qmatteoq/DesktopBridgeHelpers/blob/master/DesktopBridge.Helpers/Helpers.cs private class UwpHelper From 3ad8b0d46c669afd3744e534a4b38408b2142883 Mon Sep 17 00:00:00 2001 From: Allen Byron Penner <7310089+ByronAP@users.noreply.github.com> Date: Wed, 16 Oct 2019 09:30:05 -0400 Subject: [PATCH 2/4] Update ProxyServer.cs enable socket reuse based on framework via RunTime.IsSocketReuseAvailable --- src/Titanium.Web.Proxy/ProxyServer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Titanium.Web.Proxy/ProxyServer.cs b/src/Titanium.Web.Proxy/ProxyServer.cs index 433b2db4e..0126a9358 100644 --- a/src/Titanium.Web.Proxy/ProxyServer.cs +++ b/src/Titanium.Web.Proxy/ProxyServer.cs @@ -654,8 +654,7 @@ private void listen(ProxyEndPoint endPoint) { endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port); - // linux/macOS has a bug with socket reuse in .net core. - if (ReuseSocket && RunTime.IsWindows) + if (ReuseSocket && RunTime.IsSocketReuseAvailable) { endPoint.Listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } From ba6f89e803384a0413f35d87f44a89cd2b2debf7 Mon Sep 17 00:00:00 2001 From: Allen Byron Penner <7310089+ByronAP@users.noreply.github.com> Date: Wed, 16 Oct 2019 09:32:16 -0400 Subject: [PATCH 3/4] Update TcpConnectionFactory.cs enable socket reuse based on framework via RunTime.IsSocketReuseAvailable --- src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs index aac630cfb..8f45b0608 100644 --- a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs +++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs @@ -315,8 +315,7 @@ private async Task createServerConnection(string remoteHost tcpClient.SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000; tcpClient.LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds); - // linux has a bug with socket reuse in .net core. - if (proxyServer.ReuseSocket && RunTime.IsWindows) + if (proxyServer.ReuseSocket && RunTime.IsSocketReuseAvailable) { tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } From 532339b5a05aa25ec9d047c16995a50fb8d0faf0 Mon Sep 17 00:00:00 2001 From: Allen Byron Penner <7310089+ByronAP@users.noreply.github.com> Date: Wed, 16 Oct 2019 10:09:08 -0400 Subject: [PATCH 4/4] Update RunTime.cs fix missing usings --- src/Titanium.Web.Proxy/Helpers/RunTime.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Titanium.Web.Proxy/Helpers/RunTime.cs b/src/Titanium.Web.Proxy/Helpers/RunTime.cs index 378d1ceda..a03cbbb7f 100644 --- a/src/Titanium.Web.Proxy/Helpers/RunTime.cs +++ b/src/Titanium.Web.Proxy/Helpers/RunTime.cs @@ -1,6 +1,8 @@ -using System; +using System; +using System.Reflection; using System.Text; using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace Titanium.Web.Proxy.Helpers {