@ -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 < IPAddress > 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 ( I sValid( endpoint , "cache" ) )
if ( I PAddress. 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 )