From aa23da0dc44afbfe47a83d2dda0644472ad4e0e4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 9 Mar 2016 12:40:29 -0500 Subject: ipv6 fixes --- .../Connect/ConnectManager.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Connect') diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index d7477225c..618b7ffc5 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -81,6 +81,12 @@ namespace MediaBrowser.Server.Implementations.Connect if (!ip.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && !ip.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { + // Handle ipv6 + if (ip.IndexOf(':') != -1) + { + ip = "[" + ip + "]"; + } + ip = (_appHost.EnableHttps ? "https://" : "http://") + ip; } @@ -316,7 +322,7 @@ namespace MediaBrowser.Server.Implementations.Connect try { - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); var json = _json.SerializeToString(_data); @@ -324,7 +330,7 @@ namespace MediaBrowser.Server.Implementations.Connect lock (_dataFileLock) { - _fileSystem.WriteAllText(path, encrypted, Encoding.UTF8); + _fileSystem.WriteAllText(path, encrypted, Encoding.UTF8); } } catch (Exception ex) @@ -341,7 +347,7 @@ namespace MediaBrowser.Server.Implementations.Connect { lock (_dataFileLock) { - var encrypted = _fileSystem.ReadAllText(path, Encoding.UTF8); + var encrypted = _fileSystem.ReadAllText(path, Encoding.UTF8); var json = _encryption.DecryptString(encrypted); @@ -381,7 +387,7 @@ namespace MediaBrowser.Server.Implementations.Connect { await UpdateConnectInfo().ConfigureAwait(false); } - + await _operationLock.WaitAsync().ConfigureAwait(false); try @@ -480,7 +486,7 @@ namespace MediaBrowser.Server.Implementations.Connect { await UpdateConnectInfo().ConfigureAwait(false); } - + await _operationLock.WaitAsync().ConfigureAwait(false); try -- cgit v1.2.3 From 22730746eb5242fa71de34f35898c031e7a565de Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 25 Mar 2016 01:39:49 -0400 Subject: ipv6 update --- .../HttpClientManager/HttpClientManager.cs | 19 +++++++++++++++++++ MediaBrowser.Common/Net/HttpRequestOptions.cs | 1 + .../Connect/ConnectEntryPoint.cs | 4 +++- 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/Connect') diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index c30cdf1a7..f9dbd766f 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -126,6 +126,23 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager } } + private void AddIpv4Option(HttpWebRequest request, HttpRequestOptions options) + { + if (!options.PreferIpv4) + { + return; + } + + request.ServicePoint.BindIPEndPointDelegate = (servicePount, remoteEndPoint, retryCount) => + { + if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork) + { + return new IPEndPoint(IPAddress.Any, 0); + } + throw new InvalidOperationException("no IPv4 address"); + }; + } + private WebRequest GetRequest(HttpRequestOptions options, string method, bool enableHttpCompression) { var request = CreateWebRequest(options.Url); @@ -133,6 +150,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager if (httpWebRequest != null) { + AddIpv4Option(httpWebRequest, options); + AddRequestHeaders(httpWebRequest, options); httpWebRequest.AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None; diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs index 8c1f63e53..75368a5fc 100644 --- a/MediaBrowser.Common/Net/HttpRequestOptions.cs +++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs @@ -96,6 +96,7 @@ namespace MediaBrowser.Common.Net public TimeSpan CacheLength { get; set; } public int TimeoutMs { get; set; } + public bool PreferIpv4 { get; set; } private string GetHeaderValue(string name) { diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 12de5f6ef..9462674c3 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -70,7 +70,9 @@ namespace MediaBrowser.Server.Implementations.Connect LogErrors = logErrors, // Seeing block length errors with our server - EnableHttpCompression = false + EnableHttpCompression = false, + + PreferIpv4 = true }).ConfigureAwait(false)) { -- cgit v1.2.3 From e619a0dc9057d6a1458bd7a67e376d11a3a1be0f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 25 Mar 2016 12:23:48 -0400 Subject: update connection --- .../Connect/ConnectEntryPoint.cs | 123 +++++++++++++-------- .../Connect/ConnectManager.cs | 22 ++-- 2 files changed, 87 insertions(+), 58 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Connect') diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 9462674c3..1b951374e 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Net; using System; using System.IO; using System.Net; +using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -47,46 +48,26 @@ namespace MediaBrowser.Server.Implementations.Connect _timer = new PeriodicTimer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); } - private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.emby.media/service/ip" }; + private readonly string[] _ipLookups = + { + "http://bot.whatismyipaddress.com", + "https://connect.emby.media/service/ip" + }; private async void TimerCallback(object state) { - var index = 0; + IPAddress validIpAddress = null; foreach (var ipLookupUrl in _ipLookups) { try { - // Sometimes whatismyipaddress might fail, but it won't do us any good having users raise alarms over it. - var logErrors = index > 0; - -#if DEBUG - logErrors = true; -#endif - using (var stream = await _httpClient.Get(new HttpRequestOptions - { - Url = ipLookupUrl, - UserAgent = "Emby/" + _appHost.ApplicationVersion, - LogErrors = logErrors, - - // Seeing block length errors with our server - EnableHttpCompression = false, + validIpAddress = await GetIpAddress(ipLookupUrl).ConfigureAwait(false); - PreferIpv4 = true - - }).ConfigureAwait(false)) + // Try to find the ipv4 address, if present + if (validIpAddress.AddressFamily == AddressFamily.InterNetwork) { - using (var reader = new StreamReader(stream)) - { - var address = await reader.ReadToEndAsync().ConfigureAwait(false); - - if (IsValid(address, ipLookupUrl)) - { - ((ConnectManager)_connectManager).OnWanAddressResolved(address); - CacheAddress(address); - return; - } - } + break; } } catch (HttpException) @@ -96,8 +77,66 @@ namespace MediaBrowser.Server.Implementations.Connect { _logger.ErrorException("Error getting connection info", ex); } + } + + // If this produced an ipv6 address, try again + if (validIpAddress == null || validIpAddress.AddressFamily == AddressFamily.InterNetworkV6) + { + foreach (var ipLookupUrl in _ipLookups) + { + try + { + validIpAddress = await GetIpAddress(ipLookupUrl, true).ConfigureAwait(false); + + // Try to find the ipv4 address, if present + if (validIpAddress.AddressFamily == AddressFamily.InterNetwork) + { + break; + } + } + catch (HttpException) + { + } + catch (Exception ex) + { + _logger.ErrorException("Error getting connection info", ex); + } + } + } - index++; + if (validIpAddress != null) + { + ((ConnectManager)_connectManager).OnWanAddressResolved(validIpAddress); + CacheAddress(validIpAddress); + } + } + + private async Task GetIpAddress(string lookupUrl, bool preferIpv4 = false) + { + // Sometimes whatismyipaddress might fail, but it won't do us any good having users raise alarms over it. + var logErrors = false; + +#if DEBUG + logErrors = true; +#endif + using (var stream = await _httpClient.Get(new HttpRequestOptions + { + Url = lookupUrl, + UserAgent = "Emby/" + _appHost.ApplicationVersion, + LogErrors = logErrors, + + // Seeing block length errors with our server + EnableHttpCompression = false, + PreferIpv4 = preferIpv4 + + }).ConfigureAwait(false)) + { + using (var reader = new StreamReader(stream)) + { + var addressString = await reader.ReadToEndAsync().ConfigureAwait(false); + + return IPAddress.Parse(addressString); + } } } @@ -106,14 +145,14 @@ namespace MediaBrowser.Server.Implementations.Connect get { return Path.Combine(_appPaths.DataPath, "wan.txt"); } } - private void CacheAddress(string address) + private void CacheAddress(IPAddress address) { var path = CacheFilePath; try { _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - _fileSystem.WriteAllText(path, address, Encoding.UTF8); + _fileSystem.WriteAllText(path, address.ToString(), Encoding.UTF8); } catch (Exception ex) { @@ -128,10 +167,11 @@ namespace MediaBrowser.Server.Implementations.Connect try { var endpoint = _fileSystem.ReadAllText(path, Encoding.UTF8); + IPAddress ipAddress; - if (IsValid(endpoint, "cache")) + if (IPAddress.TryParse(endpoint, out ipAddress)) { - ((ConnectManager)_connectManager).OnWanAddressResolved(endpoint); + ((ConnectManager)_connectManager).OnWanAddressResolved(ipAddress); } } catch (IOException) @@ -144,19 +184,6 @@ namespace MediaBrowser.Server.Implementations.Connect } } - private bool IsValid(string address, string source) - { - IPAddress ipAddress; - var valid = IPAddress.TryParse(address, out ipAddress); - - if (!valid) - { - _logger.Error("{0} is not a valid ip address. Source: {1}", address, source); - } - - return valid; - } - public void Dispose() { if (_timer != null) diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 618b7ffc5..ac0d2c569 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -19,6 +19,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Net; +using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -53,7 +54,7 @@ namespace MediaBrowser.Server.Implementations.Connect get { return _data.AccessKey; } } - public string DiscoveredWanIpAddress { get; private set; } + private IPAddress DiscoveredWanIpAddress { get; set; } public string WanIpAddress { @@ -61,9 +62,16 @@ namespace MediaBrowser.Server.Implementations.Connect { var address = _config.Configuration.WanDdns; - if (string.IsNullOrWhiteSpace(address)) + if (string.IsNullOrWhiteSpace(address) && DiscoveredWanIpAddress != null) { - address = DiscoveredWanIpAddress; + if (DiscoveredWanIpAddress.AddressFamily == AddressFamily.InterNetworkV6) + { + address = "[" + DiscoveredWanIpAddress + "]"; + } + else + { + address = DiscoveredWanIpAddress.ToString(); + } } return address; @@ -81,12 +89,6 @@ namespace MediaBrowser.Server.Implementations.Connect if (!ip.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && !ip.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { - // Handle ipv6 - if (ip.IndexOf(':') != -1) - { - ip = "[" + ip + "]"; - } - ip = (_appHost.EnableHttps ? "https://" : "http://") + ip; } @@ -130,7 +132,7 @@ namespace MediaBrowser.Server.Implementations.Connect LoadCachedData(); } - internal void OnWanAddressResolved(string address) + internal void OnWanAddressResolved(IPAddress address) { DiscoveredWanIpAddress = address; -- cgit v1.2.3