From 5b0c1829084b8f54cd5356880d82b75723badf81 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 14:31:17 +0100 Subject: [PATCH 1/5] Added logging and broadcast = true Not intended for merge into the fork. --- Emby.Server.Implementations/Net/SocketFactory.cs | 15 ++++++++++++++- MediaBrowser.Model/Net/ISocketFactory.cs | 5 ++++- RSSDP/SsdpCommunicationsServer.cs | 14 +++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index 1777216584..bed79a9adc 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -4,6 +4,7 @@ using System; using System.Net; using System.Net.Sockets; using MediaBrowser.Model.Net; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Net { @@ -67,7 +68,7 @@ namespace Emby.Server.Implementations.Net /// The multicast time to live value for the acceptSocket. /// The number of the local port to bind to. /// - public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) + public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger _logger) { if (ipAddress == null) { @@ -89,6 +90,8 @@ namespace Emby.Server.Implementations.Net throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort)); } + _logger.LogError("Created"); + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try @@ -100,6 +103,8 @@ namespace Emby.Server.Implementations.Net { } + _logger.LogError("Exclusive false"); + try { // seeing occasional exceptions thrown on qnap @@ -110,8 +115,14 @@ namespace Emby.Server.Implementations.Net { } + _logger.LogError("Reused"); + try { + retVal.EnableBroadcast = true; // CHANGE + + _logger.LogError("Broadcast"); + // retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); @@ -120,6 +131,8 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; + _logger.LogError("Sorted"); + return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 363abefc19..3a19590a9b 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System.Net; +using Microsoft.Extensions.Logging; namespace MediaBrowser.Model.Net { @@ -22,7 +23,9 @@ namespace MediaBrowser.Model.Net /// The multicast IP address to bind to. /// The multicast time to live value. Actually a maximum number of network hops for UDP packets. /// The local port to bind to. + /// /// A implementation. - ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); + ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger logger); + } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 8fde700e0c..34b67a945f 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,9 +338,12 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort, _logger); - _ = ListenToSocketInternal(socket); + // TODO: remove this try and logging - testing purposes only. + _logger.LogError("Socket Created."); + + _ = ListenToSocketInternal(socket, _logger); return socket; } @@ -374,16 +377,16 @@ namespace Rssdp.Infrastructure foreach (var socket in sockets) { - _ = ListenToSocketInternal(socket); + _ = ListenToSocketInternal(socket, _logger); } return sockets; } - private async Task ListenToSocketInternal(ISocket socket) + private async Task ListenToSocketInternal(ISocket socket, ILogger logger) { var cancelled = false; - var receiveBuffer = new byte[8192]; + var receiveBuffer = new byte[8192]; while (!cancelled && !IsDisposed) { @@ -393,6 +396,7 @@ namespace Rssdp.Infrastructure if (result.ReceivedBytes > 0) { + _logger.LogError("processing..."); // Strange cannot convert compiler error here if I don't explicitly // assign or cast to Action first. Assignment is easier to read, // so went with that. From c07d8abfd57fbdc67ad2a0189e1c6149b8244a65 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 17:11:02 +0100 Subject: [PATCH 2/5] Removed debugging info --- .../Net/SocketFactory.cs | 18 ++++-------------- MediaBrowser.Model/Net/ISocketFactory.cs | 3 +-- RSSDP/SsdpCommunicationsServer.cs | 13 ++++--------- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index bed79a9adc..e79a63ff25 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -20,6 +20,7 @@ namespace Emby.Server.Implementations.Net var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { + retVal.EnableBroadcast = true; retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); @@ -47,6 +48,7 @@ namespace Emby.Server.Implementations.Net var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { + retVal.EnableBroadcast = true; retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); @@ -68,7 +70,7 @@ namespace Emby.Server.Implementations.Net /// The multicast time to live value for the acceptSocket. /// The number of the local port to bind to. /// - public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger _logger) + public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) { if (ipAddress == null) { @@ -90,8 +92,6 @@ namespace Emby.Server.Implementations.Net throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort)); } - _logger.LogError("Created"); - var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try @@ -103,8 +103,6 @@ namespace Emby.Server.Implementations.Net { } - _logger.LogError("Exclusive false"); - try { // seeing occasional exceptions thrown on qnap @@ -115,14 +113,9 @@ namespace Emby.Server.Implementations.Net { } - _logger.LogError("Reused"); - try { - retVal.EnableBroadcast = true; // CHANGE - - _logger.LogError("Broadcast"); - + retVal.EnableBroadcast = true; // retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); @@ -130,9 +123,6 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; - - _logger.LogError("Sorted"); - return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 3a19590a9b..c4e1540645 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -23,9 +23,8 @@ namespace MediaBrowser.Model.Net /// The multicast IP address to bind to. /// The multicast time to live value. Actually a maximum number of network hops for UDP packets. /// The local port to bind to. - /// /// A implementation. - ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger logger); + ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 34b67a945f..0ff56ebacf 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,12 +338,8 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort, _logger); - - // TODO: remove this try and logging - testing purposes only. - _logger.LogError("Socket Created."); - - _ = ListenToSocketInternal(socket, _logger); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + _ = ListenToSocketInternal(socket); return socket; } @@ -377,13 +373,13 @@ namespace Rssdp.Infrastructure foreach (var socket in sockets) { - _ = ListenToSocketInternal(socket, _logger); + _ = ListenToSocketInternal(socket); } return sockets; } - private async Task ListenToSocketInternal(ISocket socket, ILogger logger) + private async Task ListenToSocketInternal(ISocket socket) { var cancelled = false; var receiveBuffer = new byte[8192]; @@ -396,7 +392,6 @@ namespace Rssdp.Infrastructure if (result.ReceivedBytes > 0) { - _logger.LogError("processing..."); // Strange cannot convert compiler error here if I don't explicitly // assign or cast to Action first. Assignment is easier to read, // so went with that. From f01baad05e5abc8875fa36f9075f8684857115e7 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 17:23:16 +0100 Subject: [PATCH 3/5] Sending multicasts out of Sockets without setting the broadcast to true - causes the error "Bad value for ai_flags" on some systems (#3404) The underlying cause looks to be https://github.com/dotnet/runtime/issues/28630. Basically, it's an access denied bug. It looks like multicasts need the same access rights as broadcasts on some systems. --- Emby.Server.Implementations/Net/SocketFactory.cs | 2 +- MediaBrowser.Model/Net/ISocketFactory.cs | 2 -- RSSDP/SsdpCommunicationsServer.cs | 5 +++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index e79a63ff25..0781a0e333 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -4,7 +4,6 @@ using System; using System.Net; using System.Net.Sockets; using MediaBrowser.Model.Net; -using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Net { @@ -123,6 +122,7 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; + return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index c4e1540645..363abefc19 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -1,7 +1,6 @@ #pragma warning disable CS1591 using System.Net; -using Microsoft.Extensions.Logging; namespace MediaBrowser.Model.Net { @@ -25,6 +24,5 @@ namespace MediaBrowser.Model.Net /// The local port to bind to. /// A implementation. ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); - } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 0ff56ebacf..3c52a0c2f4 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,7 +338,8 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + _ = ListenToSocketInternal(socket); return socket; @@ -382,7 +383,7 @@ namespace Rssdp.Infrastructure private async Task ListenToSocketInternal(ISocket socket) { var cancelled = false; - var receiveBuffer = new byte[8192]; + var receiveBuffer = new byte[8192]; while (!cancelled && !IsDisposed) { From 27f6e1ddc8924c108787a2f5f7622ed910e5cb72 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 26 Jun 2020 15:22:39 +0100 Subject: [PATCH 4/5] Update SsdpCommunicationsServer.cs --- RSSDP/SsdpCommunicationsServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 3c52a0c2f4..8fde700e0c 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -339,7 +339,7 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); - + _ = ListenToSocketInternal(socket); return socket; From 2272363197660939ec5474ea76fca2f9445993be Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 26 Jun 2020 15:24:46 +0100 Subject: [PATCH 5/5] Update SsdpCommunicationsServer.cs --- RSSDP/SsdpCommunicationsServer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 8fde700e0c..a4be32e7d2 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -339,7 +339,6 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); - _ = ListenToSocketInternal(socket); return socket;