diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-12-04 16:55:02 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-12-04 16:55:02 -0500 |
| commit | 8c8f2aaba5e4bf573efe2730b5450a8c07abe1b3 (patch) | |
| tree | 34ed236696c0400c1d209985fe6450ac8adc8360 /RSSDP | |
| parent | 598f1cf2bddebbd167ed70470e54a2504ca4c0a7 (diff) | |
first pass at binding to multiple network addresses
Diffstat (limited to 'RSSDP')
| -rw-r--r-- | RSSDP/ISsdpCommunicationsServer.cs | 3 | ||||
| -rw-r--r-- | RSSDP/RSSDP.csproj | 5 | ||||
| -rw-r--r-- | RSSDP/ReadOnlyEnumerable.cs | 46 | ||||
| -rw-r--r-- | RSSDP/RequestReceivedEventArgs.cs | 9 | ||||
| -rw-r--r-- | RSSDP/SsdpCommunicationsServer.cs | 175 | ||||
| -rw-r--r-- | RSSDP/SsdpDevice.cs | 2 | ||||
| -rw-r--r-- | RSSDP/SsdpDevicePublisherBase.cs | 31 |
7 files changed, 164 insertions, 107 deletions
diff --git a/RSSDP/ISsdpCommunicationsServer.cs b/RSSDP/ISsdpCommunicationsServer.cs index 462f33fe6..eea5e0ed6 100644 --- a/RSSDP/ISsdpCommunicationsServer.cs +++ b/RSSDP/ISsdpCommunicationsServer.cs @@ -46,7 +46,8 @@ namespace Rssdp.Infrastructure /// </summary> /// <param name="messageData">A byte array containing the data to send.</param> /// <param name="destination">A <see cref="IpEndPointInfo"/> representing the destination address for the data. Can be either a multicast or unicast destination.</param> - Task SendMessage(byte[] messageData, IpEndPointInfo destination); + /// <param name="fromLocalIpAddress">A <see cref="IpEndPointInfo"/> The local ip address to send from, or .Any if sending from all available</param> + Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress); /// <summary> /// Sends a message to the SSDP multicast address and port. diff --git a/RSSDP/RSSDP.csproj b/RSSDP/RSSDP.csproj index d60f6ea44..ef1f32207 100644 --- a/RSSDP/RSSDP.csproj +++ b/RSSDP/RSSDP.csproj @@ -50,7 +50,6 @@ <Compile Include="ISsdpDevicePublisher.cs" /> <Compile Include="IUPnPDeviceValidator.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="ReadOnlyEnumerable.cs" /> <Compile Include="RequestReceivedEventArgs.cs" /> <Compile Include="ResponseReceivedEventArgs.cs" /> <Compile Include="SsdpCommunicationsServer.cs" /> @@ -70,6 +69,10 @@ <Compile Include="UPnP10DeviceValidator.cs" /> </ItemGroup> <ItemGroup> + <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj"> + <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project> + <Name>MediaBrowser.Common</Name> + </ProjectReference> <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj"> <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project> <Name>MediaBrowser.Model</Name> diff --git a/RSSDP/ReadOnlyEnumerable.cs b/RSSDP/ReadOnlyEnumerable.cs deleted file mode 100644 index 1a69f8837..000000000 --- a/RSSDP/ReadOnlyEnumerable.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Rssdp -{ - internal sealed class ReadOnlyEnumerable<T> : System.Collections.Generic.IEnumerable<T> - { - - #region Fields - - private IEnumerable<T> _Items; - - #endregion - - #region Constructors - - public ReadOnlyEnumerable(IEnumerable<T> items) - { - if (items == null) throw new ArgumentNullException("items"); - - _Items = items; - } - - #endregion - - #region IEnumerable<T> Members - - public IEnumerator<T> GetEnumerator() - { - return _Items.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return _Items.GetEnumerator(); - } - - #endregion - } -} diff --git a/RSSDP/RequestReceivedEventArgs.cs b/RSSDP/RequestReceivedEventArgs.cs index fb4fac871..03c059634 100644 --- a/RSSDP/RequestReceivedEventArgs.cs +++ b/RSSDP/RequestReceivedEventArgs.cs @@ -22,17 +22,18 @@ namespace Rssdp.Infrastructure #endregion - #region Constructors + public IpAddressInfo LocalIpAddress { get; private set; } + + #region Constructors /// <summary> /// Full constructor. /// </summary> - /// <param name="message">The <see cref="HttpRequestMessage"/> that was received.</param> - /// <param name="receivedFrom">A <see cref="UdpEndPoint"/> representing the sender's address (sometimes used for replies).</param> - public RequestReceivedEventArgs(HttpRequestMessage message, IpEndPointInfo receivedFrom) + public RequestReceivedEventArgs(HttpRequestMessage message, IpEndPointInfo receivedFrom, IpAddressInfo localIpAddress) { _Message = message; _ReceivedFrom = receivedFrom; + LocalIpAddress = localIpAddress; } #endregion diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 4de47f3d3..5d8ca15bb 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -5,6 +5,8 @@ using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; namespace Rssdp.Infrastructure @@ -38,12 +40,13 @@ namespace Rssdp.Infrastructure private IUdpSocket _BroadcastListenSocket; private object _SendSocketSynchroniser = new object(); - private IUdpSocket _SendSocket; + private List<IUdpSocket> _sendSockets; private HttpRequestParser _RequestParser; private HttpResponseParser _ResponseParser; - + private readonly ILogger _logger; private ISocketFactory _SocketFactory; + private readonly INetworkManager _networkManager; private int _LocalPort; private int _MulticastTtl; @@ -71,22 +74,18 @@ namespace Rssdp.Infrastructure /// <summary> /// Minimum constructor. /// </summary> - /// <param name="socketFactory">An implementation of the <see cref="ISocketFactory"/> interface that can be used to make new unicast and multicast sockets. Cannot be null.</param> /// <exception cref="System.ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception> - public SsdpCommunicationsServer(ISocketFactory socketFactory) - : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive) + public SsdpCommunicationsServer(ISocketFactory socketFactory, INetworkManager networkManager, ILogger logger) + : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive, networkManager, logger) { } /// <summary> /// Full constructor. /// </summary> - /// <param name="socketFactory">An implementation of the <see cref="ISocketFactory"/> interface that can be used to make new unicast and multicast sockets. Cannot be null.</param> - /// <param name="localPort">The specific local port to use for all sockets created by this instance. Specify zero to indicate the system should choose a free port itself.</param> - /// <param name="multicastTimeToLive">The multicast time to live value for multicast sockets. Technically this is a number of router hops, not a 'Time'. Must be greater than zero.</param> /// <exception cref="System.ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">The <paramref name="multicastTimeToLive"/> argument is less than or equal to zero.</exception> - public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive) + public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive, INetworkManager networkManager, ILogger logger) { if (socketFactory == null) throw new ArgumentNullException("socketFactory"); if (multicastTimeToLive <= 0) throw new ArgumentOutOfRangeException("multicastTimeToLive", "multicastTimeToLive must be greater than zero."); @@ -101,6 +100,8 @@ namespace Rssdp.Infrastructure _ResponseParser = new HttpResponseParser(); _MulticastTtl = multicastTimeToLive; + _networkManager = networkManager; + _logger = logger; } #endregion @@ -148,25 +149,72 @@ namespace Rssdp.Infrastructure /// </summary> /// <param name="messageData">A byte array containing the data to send.</param> /// <param name="destination">A <see cref="IpEndPointInfo"/> representing the destination address for the data. Can be either a multicast or unicast destination.</param> + /// <param name="fromLocalIpAddress">A <see cref="IpEndPointInfo"/> The local ip address to send from, or .Any if sending from all available</param> /// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="messageData"/> argument is null.</exception> /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception> - public async Task SendMessage(byte[] messageData, IpEndPointInfo destination) + public async Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress) { if (messageData == null) throw new ArgumentNullException("messageData"); ThrowIfDisposed(); - EnsureSendSocketCreated(); + var sockets = GetSendSockets(fromLocalIpAddress, destination); + + if (sockets.Count == 0) + { + return; + } // SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP. for (var i = 0; i < SsdpConstants.UdpResendCount; i++) { - await SendMessageIfSocketNotDisposed(messageData, destination).ConfigureAwait(false); + var tasks = sockets.Select(s => SendFromSocket(s, messageData, destination)).ToArray(); + await Task.WhenAll(tasks).ConfigureAwait(false); await Task.Delay(100).ConfigureAwait(false); } } + private async Task SendFromSocket(IUdpSocket socket, byte[] messageData, IpEndPointInfo destination) + { + try + { + await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending socket message from {0} to {1}", ex, socket.LocalIPAddress.ToString(), destination.ToString()); + } + } + + private List<IUdpSocket> GetSendSockets(IpAddressInfo fromLocalIpAddress, IpEndPointInfo destination) + { + EnsureSendSocketCreated(); + + lock (_SendSocketSynchroniser) + { + var sockets = _sendSockets.Where(i => i.LocalIPAddress.AddressFamily == fromLocalIpAddress.AddressFamily); + + // Send from the Any socket and the socket with the matching address + if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetwork) + { + sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress)); + } + 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)); + } + + return sockets.ToList(); + } + } + /// <summary> /// Sends a message to the SSDP multicast address and port. /// </summary> @@ -185,7 +233,10 @@ namespace Rssdp.Infrastructure { await SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo { - IpAddress = new IpAddressInfo { Address = SsdpConstants.MulticastLocalAdminAddress }, + IpAddress = new IpAddressInfo + { + Address = SsdpConstants.MulticastLocalAdminAddress + }, Port = SsdpConstants.MulticastPort }).ConfigureAwait(false); @@ -204,10 +255,16 @@ namespace Rssdp.Infrastructure lock (_SendSocketSynchroniser) { - var socket = _SendSocket; - _SendSocket = null; - if (socket != null) - socket.Dispose(); + if (_sendSockets != null) + { + var sockets = _sendSockets.ToList(); + _sendSockets = null; + + foreach (var socket in sockets) + { + socket.Dispose(); + } + } } } @@ -247,8 +304,16 @@ namespace Rssdp.Infrastructure lock (_SendSocketSynchroniser) { - if (_SendSocket != null) - _SendSocket.Dispose(); + if (_sendSockets != null) + { + var sockets = _sendSockets.ToList(); + _sendSockets = null; + + foreach (var socket in sockets) + { + socket.Dispose(); + } + } } } } @@ -257,16 +322,20 @@ namespace Rssdp.Infrastructure #region Private Methods - private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination) + private async Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination) { - var socket = _SendSocket; - if (socket != null) + var sockets = _sendSockets; + if (sockets != null) { - return _SendSocket.SendAsync(messageData, messageData.Length, destination); + sockets = sockets.ToList(); + + foreach (var socket in sockets) + { + await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false); + } } ThrowIfDisposed(); - return Task.FromResult(true); } private IUdpSocket ListenForBroadcastsAsync() @@ -278,13 +347,30 @@ namespace Rssdp.Infrastructure return socket; } - private IUdpSocket CreateSocketAndListenForResponsesAsync() + private List<IUdpSocket> CreateSocketAndListenForResponsesAsync() { - _SendSocket = _SocketFactory.CreateSsdpUdpSocket(_LocalPort); + var sockets = new List<IUdpSocket>(); - ListenToSocket(_SendSocket); + sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IpAddressInfo.Any, _LocalPort)); - return _SendSocket; + foreach (var address in _networkManager.GetLocalIpAddresses().ToList()) + { + try + { + sockets.Add(_SocketFactory.CreateSsdpUdpSocket(address, _LocalPort)); + } + catch (Exception ex) + { + _logger.ErrorException("Error in CreateSsdpUdpSocket. IPAddress: {0}", ex, address); + } + } + + foreach (var socket in sockets) + { + ListenToSocket(socket); + } + + return sockets; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "t", Justification = "Capturing task to local variable removes compiler warning, task is not otherwise required.")] @@ -305,7 +391,7 @@ namespace Rssdp.Infrastructure // 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. - ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.RemoteEndPoint); + ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.RemoteEndPoint, result.LocalIPAddress); } } catch (ObjectDisposedException) @@ -322,19 +408,19 @@ namespace Rssdp.Infrastructure private void EnsureSendSocketCreated() { - if (_SendSocket == null) + if (_sendSockets == null) { lock (_SendSocketSynchroniser) { - if (_SendSocket == null) + if (_sendSockets == null) { - _SendSocket = CreateSocketAndListenForResponsesAsync(); + _sendSockets = CreateSocketAndListenForResponsesAsync(); } } } } - private void ProcessMessage(string data, IpEndPointInfo endPoint) + private void ProcessMessage(string data, IpEndPointInfo endPoint, IpAddressInfo receivedOnLocalIpAddress) { //Responses start with the HTTP version, prefixed with HTTP/ while //requests start with a method which can vary and might be one we haven't @@ -347,7 +433,10 @@ namespace Rssdp.Infrastructure { responseMessage = _ResponseParser.Parse(data); } - catch (ArgumentException) { } // Ignore invalid packets. + catch (ArgumentException ex) + { + // Ignore invalid packets. + } if (responseMessage != null) OnResponseReceived(responseMessage, endPoint); @@ -359,23 +448,31 @@ namespace Rssdp.Infrastructure { requestMessage = _RequestParser.Parse(data); } - catch (ArgumentException) { } // Ignore invalid packets. + catch (ArgumentException ex) + { + // Ignore invalid packets. + } if (requestMessage != null) - OnRequestReceived(requestMessage, endPoint); + { + OnRequestReceived(requestMessage, endPoint, receivedOnLocalIpAddress); + } } } - private void OnRequestReceived(HttpRequestMessage data, IpEndPointInfo endPoint) + private void OnRequestReceived(HttpRequestMessage data, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnLocalIpAddress) { //SSDP specification says only * is currently used but other uri's might //be implemented in the future and should be ignored unless understood. //Section 4.2 - http://tools.ietf.org/html/draft-cai-ssdp-v1-03#page-11 - if (data.RequestUri.ToString() != "*") return; + if (data.RequestUri.ToString() != "*") + { + return; + } var handlers = this.RequestReceived; if (handlers != null) - handlers(this, new RequestReceivedEventArgs(data, endPoint)); + handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnLocalIpAddress)); } private void OnResponseReceived(HttpResponseMessage data, IpEndPointInfo endPoint) diff --git a/RSSDP/SsdpDevice.cs b/RSSDP/SsdpDevice.cs index 8a4992239..a595742d0 100644 --- a/RSSDP/SsdpDevice.cs +++ b/RSSDP/SsdpDevice.cs @@ -64,7 +64,7 @@ namespace Rssdp this.Icons = new List<SsdpDeviceIcon>(); _Devices = new List<SsdpDevice>(); - this.Devices = new ReadOnlyEnumerable<SsdpDevice>(_Devices); + this.Devices = new ReadOnlyCollection<SsdpDevice>(_Devices); _CustomResponseHeaders = new CustomHttpHeadersCollection(); _CustomProperties = new SsdpDevicePropertiesCollection(); } diff --git a/RSSDP/SsdpDevicePublisherBase.cs b/RSSDP/SsdpDevicePublisherBase.cs index 7737733f7..ee3335957 100644 --- a/RSSDP/SsdpDevicePublisherBase.cs +++ b/RSSDP/SsdpDevicePublisherBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Net.Http; using System.Text; @@ -25,7 +26,7 @@ namespace Rssdp.Infrastructure private bool _SupportPnpRootDevice; private IList<SsdpRootDevice> _Devices; - private ReadOnlyEnumerable<SsdpRootDevice> _ReadOnlyDevices; + private IReadOnlyList<SsdpRootDevice> _ReadOnlyDevices; private ITimer _RebroadcastAliveNotificationsTimer; private ITimerFactory _timerFactory; @@ -62,7 +63,7 @@ namespace Rssdp.Infrastructure _SupportPnpRootDevice = true; _timerFactory = timerFactory; _Devices = new List<SsdpRootDevice>(); - _ReadOnlyDevices = new ReadOnlyEnumerable<SsdpRootDevice>(_Devices); + _ReadOnlyDevices = new ReadOnlyCollection<SsdpRootDevice>(_Devices); _RecentSearchRequests = new Dictionary<string, SearchRequest>(StringComparer.OrdinalIgnoreCase); _Random = new Random(); _DeviceValidator = new Upnp10DeviceValidator(); //Should probably inject this later, but for now we only support 1.0. @@ -236,17 +237,17 @@ namespace Rssdp.Infrastructure #region Search Related Methods - private void ProcessSearchRequest(string mx, string searchTarget, IpEndPointInfo endPoint) + private void ProcessSearchRequest(string mx, string searchTarget, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnlocalIpAddress) { if (String.IsNullOrEmpty(searchTarget)) { - WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString())); + WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", remoteEndPoint.ToString())); return; } - WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget)); + WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", remoteEndPoint.ToString(), searchTarget)); - if (IsDuplicateSearchRequest(searchTarget, endPoint)) + if (IsDuplicateSearchRequest(searchTarget, remoteEndPoint)) { WriteTrace("Search Request is Duplicate, ignoring."); return; @@ -294,7 +295,7 @@ namespace Rssdp.Infrastructure foreach (var device in deviceList) { - SendDeviceSearchResponses(device, endPoint); + SendDeviceSearchResponses(device, remoteEndPoint, receivedOnlocalIpAddress); } } else @@ -307,19 +308,19 @@ namespace Rssdp.Infrastructure return _Devices.Union(_Devices.SelectManyRecursive<SsdpDevice>((d) => d.Devices)); } - private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint) + private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress) { bool isRootDevice = (device as SsdpRootDevice) != null; if (isRootDevice) { - SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint); + SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress); if (this.SupportPnpRootDevice) - SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint); + SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress); } - SendSearchResponse(device.Udn, device, device.Udn, endPoint); + SendSearchResponse(device.Udn, device, device.Udn, endPoint, receivedOnlocalIpAddress); - SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint); + SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint, receivedOnlocalIpAddress); } private static string GetUsn(string udn, string fullDeviceType) @@ -327,7 +328,7 @@ namespace Rssdp.Infrastructure return String.Format("{0}::{1}", udn, fullDeviceType); } - private async void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, IpEndPointInfo endPoint) + private async void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress) { var rootDevice = device.ToRootDevice(); @@ -349,7 +350,7 @@ namespace Rssdp.Infrastructure try { - await _CommsServer.SendMessage(System.Text.Encoding.UTF8.GetBytes(message), endPoint).ConfigureAwait(false); + await _CommsServer.SendMessage(System.Text.Encoding.UTF8.GetBytes(message), endPoint, receivedOnlocalIpAddress).ConfigureAwait(false); } catch (Exception ex) { @@ -674,7 +675,7 @@ namespace Rssdp.Infrastructure //else if (!e.Message.Headers.Contains("MAN")) // WriteTrace("Ignoring search request - missing MAN header."); //else - ProcessSearchRequest(GetFirstHeaderValue(e.Message.Headers, "MX"), GetFirstHeaderValue(e.Message.Headers, "ST"), e.ReceivedFrom); + ProcessSearchRequest(GetFirstHeaderValue(e.Message.Headers, "MX"), GetFirstHeaderValue(e.Message.Headers, "ST"), e.ReceivedFrom, e.LocalIpAddress); } } |
