diff --git a/Emby.Common.Implementations/Net/SocketFactory.cs b/Emby.Common.Implementations/Net/SocketFactory.cs
index 1242520971..79310e0173 100644
--- a/Emby.Common.Implementations/Net/SocketFactory.cs
+++ b/Emby.Common.Implementations/Net/SocketFactory.cs
@@ -33,18 +33,35 @@ namespace Emby.Common.Implementations.Net
public ISocket CreateSocket(IpAddressFamily family, MediaBrowser.Model.Net.SocketType socketType, MediaBrowser.Model.Net.ProtocolType protocolType, bool dualMode)
{
- var addressFamily = family == IpAddressFamily.InterNetwork
- ? AddressFamily.InterNetwork
- : AddressFamily.InterNetworkV6;
-
- var socket = new Socket(addressFamily, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
-
- if (dualMode)
+ try
{
- socket.DualMode = true;
- }
+ var addressFamily = family == IpAddressFamily.InterNetwork
+ ? AddressFamily.InterNetwork
+ : AddressFamily.InterNetworkV6;
- return new NetSocket(socket, _logger);
+ var socket = new Socket(addressFamily, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
+
+ if (dualMode)
+ {
+ socket.DualMode = true;
+ }
+
+ return new NetSocket(socket, _logger);
+ }
+ 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;
+ }
}
#region ISocketFactory Members
diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs
index 858b1ae9ec..16108522c3 100644
--- a/Emby.Dlna/Main/DlnaEntryPoint.cs
+++ b/Emby.Dlna/Main/DlnaEntryPoint.cs
@@ -158,7 +158,9 @@ namespace Emby.Dlna.Main
{
if (_communicationsServer == null)
{
- _communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger)
+ var enableMultiSocketBinding = _environmentInfo.OperatingSystem == OperatingSystem.Windows;
+
+ _communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger, enableMultiSocketBinding)
{
IsShared = true
};
diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs
index 5d8ca15bba..b709861d5f 100644
--- a/RSSDP/SsdpCommunicationsServer.cs
+++ b/RSSDP/SsdpCommunicationsServer.cs
@@ -52,6 +52,7 @@ namespace Rssdp.Infrastructure
private int _MulticastTtl;
private bool _IsShared;
+ private readonly bool _enableMultiSocketBinding;
#endregion
@@ -75,8 +76,8 @@ namespace Rssdp.Infrastructure
/// Minimum constructor.
///
/// The argument is null.
- public SsdpCommunicationsServer(ISocketFactory socketFactory, INetworkManager networkManager, ILogger logger)
- : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive, networkManager, logger)
+ public SsdpCommunicationsServer(ISocketFactory socketFactory, INetworkManager networkManager, ILogger logger, bool enableMultiSocketBinding)
+ : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive, networkManager, logger, enableMultiSocketBinding)
{
}
@@ -85,7 +86,7 @@ namespace Rssdp.Infrastructure
///
/// The argument is null.
/// The argument is less than or equal to zero.
- public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive, INetworkManager networkManager, ILogger logger)
+ public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive, INetworkManager networkManager, ILogger logger, bool enableMultiSocketBinding)
{
if (socketFactory == null) throw new ArgumentNullException("socketFactory");
if (multicastTimeToLive <= 0) throw new ArgumentOutOfRangeException("multicastTimeToLive", "multicastTimeToLive must be greater than zero.");
@@ -102,6 +103,7 @@ namespace Rssdp.Infrastructure
_MulticastTtl = multicastTimeToLive;
_networkManager = networkManager;
_logger = logger;
+ _enableMultiSocketBinding = enableMultiSocketBinding;
}
#endregion
@@ -199,16 +201,22 @@ namespace Rssdp.Infrastructure
if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetwork)
{
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));
+
+ // If sending to the loopback address, filter the socket list as well
+ if (destination.IpAddress.Equals(IpAddressInfo.Loopback))
+ {
+ sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || i.LocalIPAddress.Equals(IpAddressInfo.Loopback));
+ }
}
else if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
{
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));
- }
- // If sending to the loopback address, filter the socket list as well
- if (destination.IpAddress.Equals(IpAddressInfo.Loopback))
- {
- sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || i.LocalIPAddress.Equals(IpAddressInfo.Loopback));
+ // If sending to the loopback address, filter the socket list as well
+ if (destination.IpAddress.Equals(IpAddressInfo.IPv6Loopback))
+ {
+ sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || i.LocalIPAddress.Equals(IpAddressInfo.IPv6Loopback));
+ }
}
return sockets.ToList();
@@ -353,15 +361,18 @@ namespace Rssdp.Infrastructure
sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IpAddressInfo.Any, _LocalPort));
- foreach (var address in _networkManager.GetLocalIpAddresses().ToList())
+ if (_enableMultiSocketBinding)
{
- try
+ foreach (var address in _networkManager.GetLocalIpAddresses().ToList())
{
- sockets.Add(_SocketFactory.CreateSsdpUdpSocket(address, _LocalPort));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in CreateSsdpUdpSocket. IPAddress: {0}", ex, address);
+ try
+ {
+ sockets.Add(_SocketFactory.CreateSsdpUdpSocket(address, _LocalPort));
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in CreateSsdpUdpSocket. IPAddress: {0}", ex, address);
+ }
}
}