improve ipv6 error handling
This commit is contained in:
parent
20c2499797
commit
0130209cdc
|
@ -13,7 +13,9 @@ namespace Emby.Common.Implementations.Net
|
|||
public Socket Socket { get; private set; }
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public NetSocket(Socket socket, ILogger logger)
|
||||
public bool DualMode { get; private set; }
|
||||
|
||||
public NetSocket(Socket socket, ILogger logger, bool isDualMode)
|
||||
{
|
||||
if (socket == null)
|
||||
{
|
||||
|
@ -26,6 +28,7 @@ namespace Emby.Common.Implementations.Net
|
|||
|
||||
Socket = socket;
|
||||
_logger = logger;
|
||||
DualMode = isDualMode;
|
||||
}
|
||||
|
||||
public IpEndPointInfo LocalEndPoint
|
||||
|
@ -81,7 +84,7 @@ namespace Emby.Common.Implementations.Net
|
|||
private SocketAcceptor _acceptor;
|
||||
public void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed)
|
||||
{
|
||||
_acceptor = new SocketAcceptor(_logger, Socket, onAccept, isClosed);
|
||||
_acceptor = new SocketAcceptor(_logger, Socket, onAccept, isClosed, DualMode);
|
||||
|
||||
_acceptor.StartAccept();
|
||||
}
|
||||
|
|
|
@ -11,8 +11,9 @@ namespace Emby.Common.Implementations.Net
|
|||
private readonly Socket _originalSocket;
|
||||
private readonly Func<bool> _isClosed;
|
||||
private readonly Action<ISocket> _onAccept;
|
||||
private readonly bool _isDualMode;
|
||||
|
||||
public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed)
|
||||
public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed, bool isDualMode)
|
||||
{
|
||||
if (logger == null)
|
||||
{
|
||||
|
@ -34,6 +35,7 @@ namespace Emby.Common.Implementations.Net
|
|||
_logger = logger;
|
||||
_originalSocket = originalSocket;
|
||||
_isClosed = isClosed;
|
||||
_isDualMode = isDualMode;
|
||||
_onAccept = onAccept;
|
||||
}
|
||||
|
||||
|
@ -115,7 +117,7 @@ namespace Emby.Common.Implementations.Net
|
|||
if (acceptSocket != null)
|
||||
{
|
||||
//ProcessAccept(acceptSocket);
|
||||
_onAccept(new NetSocket(acceptSocket, _logger));
|
||||
_onAccept(new NetSocket(acceptSocket, _logger, _isDualMode));
|
||||
}
|
||||
|
||||
// Accept the next connection request
|
||||
|
|
|
@ -46,21 +46,11 @@ namespace Emby.Common.Implementations.Net
|
|||
socket.DualMode = true;
|
||||
}
|
||||
|
||||
return new NetSocket(socket, _logger);
|
||||
return new NetSocket(socket, _logger, dualMode);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
if (dualMode)
|
||||
{
|
||||
_logger.Error("Error creating dual mode socket: {0}. Will retry with ipv4-only.", ex.SocketErrorCode);
|
||||
|
||||
if (ex.SocketErrorCode == SocketError.AddressFamilyNotSupported)
|
||||
{
|
||||
return CreateSocket(IpAddressFamily.InterNetwork, socketType, protocolType, false);
|
||||
}
|
||||
}
|
||||
|
||||
throw;
|
||||
throw new SocketCreateException(ex.SocketErrorCode.ToString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1305,19 +1305,49 @@ namespace Emby.Server.Core
|
|||
|
||||
public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
|
||||
{
|
||||
var addresses = NetworkManager.GetLocalIpAddresses().ToList();
|
||||
var list = new List<IpAddressInfo>();
|
||||
var addresses = ServerConfigurationManager
|
||||
.Configuration
|
||||
.LocalNetworkAddresses
|
||||
.Select(NormalizeConfiguredLocalAddress)
|
||||
.Where(i => i != null)
|
||||
.ToList();
|
||||
|
||||
foreach (var address in addresses)
|
||||
if (addresses.Count == 0)
|
||||
{
|
||||
var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false);
|
||||
if (valid)
|
||||
addresses.AddRange(NetworkManager.GetLocalIpAddresses());
|
||||
|
||||
var list = new List<IpAddressInfo>();
|
||||
|
||||
foreach (var address in addresses)
|
||||
{
|
||||
list.Add(address);
|
||||
var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false);
|
||||
if (valid)
|
||||
{
|
||||
list.Add(address);
|
||||
}
|
||||
}
|
||||
|
||||
addresses = list;
|
||||
}
|
||||
|
||||
return list;
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private IpAddressInfo NormalizeConfiguredLocalAddress(string address)
|
||||
{
|
||||
var index = address.Trim('/').IndexOf('/');
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
address = address.Substring(index + 1);
|
||||
}
|
||||
|
||||
IpAddressInfo result;
|
||||
if (NetworkManager.TryParseIpAddress(address.Trim('/'), out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||
|
@ -1553,7 +1583,8 @@ namespace Emby.Server.Core
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
var process = ProcessFactory.Create(new ProcessOptions {
|
||||
var process = ProcessFactory.Create(new ProcessOptions
|
||||
{
|
||||
FileName = url,
|
||||
EnableRaisingEvents = true,
|
||||
UseShellExecute = true,
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace MediaBrowser.Model.Net
|
|||
{
|
||||
public interface ISocket : IDisposable
|
||||
{
|
||||
bool DualMode { get; }
|
||||
IpEndPointInfo LocalEndPoint { get; }
|
||||
IpEndPointInfo RemoteEndPoint { get; }
|
||||
void Close();
|
||||
|
@ -13,4 +14,15 @@ namespace MediaBrowser.Model.Net
|
|||
|
||||
void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed);
|
||||
}
|
||||
|
||||
public class SocketCreateException : Exception
|
||||
{
|
||||
public SocketCreateException(string errorCode, Exception originalException)
|
||||
: base(errorCode, originalException)
|
||||
{
|
||||
ErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public string ErrorCode { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace SocketHttpListener.Net
|
|||
Dictionary<HttpConnection, HttpConnection> unregistered;
|
||||
private readonly ILogger _logger;
|
||||
private bool _closed;
|
||||
private readonly bool _enableDualMode;
|
||||
private bool _enableDualMode;
|
||||
private readonly ICryptoProvider _cryptoProvider;
|
||||
private readonly IStreamFactory _streamFactory;
|
||||
private readonly ISocketFactory _socketFactory;
|
||||
|
@ -65,7 +65,23 @@ namespace SocketHttpListener.Net
|
|||
|
||||
private void CreateSocket()
|
||||
{
|
||||
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
|
||||
try
|
||||
{
|
||||
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
|
||||
}
|
||||
catch (SocketCreateException ex)
|
||||
{
|
||||
if (_enableDualMode && endpoint.IpAddress.Equals(IpAddressInfo.IPv6Any) && string.Equals(ex.ErrorCode, "AddressFamilyNotSupported", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
endpoint = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port);
|
||||
_enableDualMode = false;
|
||||
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
sock.Bind(endpoint);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user