aboutsummaryrefslogtreecommitdiff
path: root/Mono.Nat
diff options
context:
space:
mode:
authorstefan <stefan@hegedues.at>2018-09-12 19:26:21 +0200
committerstefan <stefan@hegedues.at>2018-09-12 19:26:21 +0200
commit48facb797ed912e4ea6b04b17d1ff190ac2daac4 (patch)
tree8dae77a31670a888d733484cb17dd4077d5444e8 /Mono.Nat
parentc32d8656382a0eacb301692e0084377fc433ae9b (diff)
Update to 3.5.2 and .net core 2.1
Diffstat (limited to 'Mono.Nat')
-rw-r--r--Mono.Nat/AsyncResults/AsyncResult.cs71
-rw-r--r--Mono.Nat/Enums/MapState.cs36
-rw-r--r--Mono.Nat/Exceptions/MappingException.cs68
-rw-r--r--Mono.Nat/ISearcher.cs6
-rw-r--r--Mono.Nat/Mono.Nat.csproj106
-rw-r--r--Mono.Nat/NatManager.cs86
-rw-r--r--Mono.Nat/NatUtility.cs233
-rw-r--r--Mono.Nat/Pmp/AsyncResults/PortMapAsyncResult.cs52
-rw-r--r--Mono.Nat/Pmp/PmpNatDevice.cs22
-rw-r--r--Mono.Nat/Pmp/PmpSearcher.cs (renamed from Mono.Nat/Pmp/Searchers/PmpSearcher.cs)49
-rw-r--r--Mono.Nat/Upnp/Messages/DiscoverDeviceMessage.cs60
-rw-r--r--Mono.Nat/Upnp/Messages/ErrorMessage.cs63
-rw-r--r--Mono.Nat/Upnp/Messages/Responses/CreatePortMappingResponseMessage.cs48
-rw-r--r--Mono.Nat/Upnp/Messages/UpnpMessage.cs6
-rw-r--r--Mono.Nat/Upnp/Searchers/UpnpSearcher.cs9
-rw-r--r--Mono.Nat/Upnp/UpnpNatDevice.cs48
16 files changed, 175 insertions, 788 deletions
diff --git a/Mono.Nat/AsyncResults/AsyncResult.cs b/Mono.Nat/AsyncResults/AsyncResult.cs
deleted file mode 100644
index e98e7d7ca..000000000
--- a/Mono.Nat/AsyncResults/AsyncResult.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-
-namespace Mono.Nat
-{
- internal class AsyncResult : IAsyncResult
- {
- private object asyncState;
- private AsyncCallback callback;
- private bool completedSynchronously;
- private bool isCompleted;
- private Exception storedException;
- private ManualResetEvent waitHandle;
-
- public AsyncResult(AsyncCallback callback, object asyncState)
- {
- this.callback = callback;
- this.asyncState = asyncState;
- waitHandle = new ManualResetEvent(false);
- }
-
- public object AsyncState
- {
- get { return asyncState; }
- }
-
- public ManualResetEvent AsyncWaitHandle
- {
- get { return waitHandle; }
- }
-
- WaitHandle IAsyncResult.AsyncWaitHandle
- {
- get { return waitHandle; }
- }
-
- public bool CompletedSynchronously
- {
- get { return completedSynchronously; }
- protected internal set { completedSynchronously = value; }
- }
-
- public bool IsCompleted
- {
- get { return isCompleted; }
- protected internal set { isCompleted = value; }
- }
-
- public Exception StoredException
- {
- get { return storedException; }
- }
-
- public void Complete()
- {
- Complete(storedException);
- }
-
- public void Complete(Exception ex)
- {
- storedException = ex;
- isCompleted = true;
- waitHandle.Set();
-
- if (callback != null)
- callback(this);
- }
- }
-}
diff --git a/Mono.Nat/Enums/MapState.cs b/Mono.Nat/Enums/MapState.cs
deleted file mode 100644
index 5ed2abd8f..000000000
--- a/Mono.Nat/Enums/MapState.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-//
-// Copyright (C) 2006 Alan McGovern
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-
-namespace Mono.Nat
-{
- public enum MapState
- {
- AlreadyMapped,
- Available
- }
-} \ No newline at end of file
diff --git a/Mono.Nat/Exceptions/MappingException.cs b/Mono.Nat/Exceptions/MappingException.cs
deleted file mode 100644
index 9c0c4f122..000000000
--- a/Mono.Nat/Exceptions/MappingException.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-//
-// Copyright (C) 2006 Alan McGovern
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-
-namespace Mono.Nat
-{
- public class MappingException : Exception
- {
- private int errorCode;
- private string errorText;
-
- public int ErrorCode
- {
- get { return this.errorCode; }
- }
-
- public string ErrorText
- {
- get { return this.errorText; }
- }
-
- public MappingException()
- : base()
- {
- }
-
- public MappingException(string message)
- : base(message)
- {
- }
-
- public MappingException(int errorCode, string errorText)
- : base (string.Format ("Error {0}: {1}", errorCode, errorText))
- {
- this.errorCode = errorCode;
- this.errorText = errorText;
- }
-
- public MappingException(string message, Exception innerException)
- : base(message, innerException)
- {
- }
- }
-}
diff --git a/Mono.Nat/ISearcher.cs b/Mono.Nat/ISearcher.cs
index 51042bf27..fff7e8d75 100644
--- a/Mono.Nat/ISearcher.cs
+++ b/Mono.Nat/ISearcher.cs
@@ -33,20 +33,14 @@ using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
-using System.Threading.Tasks;
namespace Mono.Nat
{
- public delegate void NatDeviceCallback(INatDevice device);
-
internal interface ISearcher
{
event EventHandler<DeviceEventArgs> DeviceFound;
- event EventHandler<DeviceEventArgs> DeviceLost;
void Search();
void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint);
- DateTime NextSearch { get; }
- NatProtocol Protocol { get; }
}
}
diff --git a/Mono.Nat/Mono.Nat.csproj b/Mono.Nat/Mono.Nat.csproj
index 426824f0d..4de89290e 100644
--- a/Mono.Nat/Mono.Nat.csproj
+++ b/Mono.Nat/Mono.Nat.csproj
@@ -1,97 +1,17 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{CB7F2326-6497-4A3D-BA03-48513B17A7BE}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Mono.Nat</RootNamespace>
- <AssemblyName>Mono.Nat</AssemblyName>
- <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <TargetFrameworkProfile />
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Net.Http" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="..\SharedVersion.cs">
- <Link>Properties\SharedVersion.cs</Link>
- </Compile>
- <Compile Include="AbstractNatDevice.cs" />
- <Compile Include="AsyncResults\AsyncResult.cs" />
- <Compile Include="Enums\MapState.cs" />
- <Compile Include="Enums\ProtocolType.cs" />
- <Compile Include="EventArgs\DeviceEventArgs.cs" />
- <Compile Include="Exceptions\MappingException.cs" />
- <Compile Include="INatDevice.cs" />
- <Compile Include="ISearcher.cs" />
- <Compile Include="Mapping.cs" />
- <Compile Include="NatProtocol.cs" />
- <Compile Include="NatUtility.cs" />
- <Compile Include="Pmp\AsyncResults\PortMapAsyncResult.cs" />
- <Compile Include="Pmp\PmpConstants.cs" />
- <Compile Include="Pmp\PmpNatDevice.cs" />
- <Compile Include="Pmp\Searchers\PmpSearcher.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Upnp\Messages\DiscoverDeviceMessage.cs" />
- <Compile Include="Upnp\Messages\ErrorMessage.cs" />
- <Compile Include="Upnp\Messages\GetServicesMessage.cs" />
- <Compile Include="Upnp\Messages\Requests\CreatePortMappingMessage.cs" />
- <Compile Include="Upnp\Messages\Responses\CreatePortMappingResponseMessage.cs" />
- <Compile Include="Upnp\Messages\UpnpMessage.cs" />
- <Compile Include="Upnp\Searchers\UpnpSearcher.cs" />
- <Compile Include="Upnp\UpnpNatDevice.cs" />
- </ItemGroup>
+<Project Sdk="Microsoft.NET.Sdk">
+
<ItemGroup>
- <Folder Include="Upnp\AsyncResults\" />
+ <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
</ItemGroup>
+
<ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
- <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
- <Name>MediaBrowser.Common</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
- <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
- <Name>MediaBrowser.Controller</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
- <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
- <Name>MediaBrowser.Model</Name>
- </ProjectReference>
+ <Compile Include="..\SharedVersion.cs"/>
</ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
+ <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+ </PropertyGroup>
+
+</Project>
diff --git a/Mono.Nat/NatManager.cs b/Mono.Nat/NatManager.cs
new file mode 100644
index 000000000..752fd0416
--- /dev/null
+++ b/Mono.Nat/NatManager.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Net;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Dlna;
+using MediaBrowser.Model.Logging;
+using System.Linq;
+
+namespace Mono.Nat
+{
+ public class NatManager : IDisposable
+ {
+ public event EventHandler<DeviceEventArgs> DeviceFound;
+
+ private List<ISearcher> controllers = new List<ISearcher>();
+
+ private ILogger Logger;
+ private IHttpClient HttpClient;
+
+ public NatManager(ILogger logger, IHttpClient httpClient)
+ {
+ Logger = logger;
+ HttpClient = httpClient;
+ }
+
+ private object _runSyncLock = new object();
+ public void StartDiscovery()
+ {
+ lock (_runSyncLock)
+ {
+ if (controllers.Count > 0)
+ {
+ return;
+ }
+
+ controllers.Add(new PmpSearcher(Logger));
+
+ foreach (var searcher in controllers)
+ {
+ searcher.DeviceFound += Searcher_DeviceFound;
+ }
+ }
+ }
+
+ public void StopDiscovery()
+ {
+ lock (_runSyncLock)
+ {
+ var disposables = controllers.OfType<IDisposable>().ToList();
+ controllers.Clear();
+
+ foreach (var disposable in disposables)
+ {
+ disposable.Dispose();
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ StopDiscovery();
+ }
+
+ public Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)
+ {
+ switch (protocol)
+ {
+ case NatProtocol.Upnp:
+ var searcher = new UpnpSearcher(Logger, HttpClient);
+ searcher.DeviceFound += Searcher_DeviceFound;
+ return searcher.Handle(localAddress, deviceInfo, endpoint);
+ default:
+ throw new ArgumentException("Unexpected protocol: " + protocol);
+ }
+ }
+
+ private void Searcher_DeviceFound(object sender, DeviceEventArgs e)
+ {
+ if (DeviceFound != null)
+ {
+ DeviceFound(sender, e);
+ }
+ }
+ }
+}
diff --git a/Mono.Nat/NatUtility.cs b/Mono.Nat/NatUtility.cs
deleted file mode 100644
index bf703e399..000000000
--- a/Mono.Nat/NatUtility.cs
+++ /dev/null
@@ -1,233 +0,0 @@
-//
-// Authors:
-// Ben Motmans <ben.motmans@gmail.com>
-// Nicholas Terry <nick.i.terry@gmail.com>
-//
-// Copyright (C) 2007 Ben Motmans
-// Copyright (C) 2014 Nicholas Terry
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Collections.Generic;
-using System.IO;
-using System.Net.NetworkInformation;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.Logging;
-
-namespace Mono.Nat
-{
- public static class NatUtility
- {
- public static event EventHandler<DeviceEventArgs> DeviceFound;
- public static event EventHandler<DeviceEventArgs> DeviceLost;
-
- private static List<ISearcher> controllers;
- private static bool verbose;
-
- public static List<NatProtocol> EnabledProtocols { get; set; }
-
- public static ILogger Logger { get; set; }
- public static IHttpClient HttpClient { get; set; }
-
- public static bool Verbose
- {
- get { return verbose; }
- set { verbose = value; }
- }
-
- static NatUtility()
- {
- EnabledProtocols = new List<NatProtocol>
- {
- NatProtocol.Pmp
- };
-
- controllers = new List<ISearcher>();
- controllers.Add(PmpSearcher.Instance);
-
- controllers.ForEach(searcher =>
- {
- searcher.DeviceFound += (sender, args) =>
- {
- if (DeviceFound != null)
- DeviceFound(sender, args);
- };
- searcher.DeviceLost += (sender, args) =>
- {
- if (DeviceLost != null)
- DeviceLost(sender, args);
- };
- });
- }
-
- internal static void Log(string format, params object[] args)
- {
- var logger = Logger;
- if (logger != null)
- logger.Debug(format, args);
- }
-
- private static async Task SearchAndListen(CancellationToken cancellationToken)
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- try
- {
- if (EnabledProtocols.Contains(PmpSearcher.Instance.Protocol))
- {
- await Receive(PmpSearcher.Instance, PmpSearcher.sockets).ConfigureAwait(false);
- }
-
- foreach (ISearcher s in controllers)
- {
- if (s.NextSearch < DateTime.Now && EnabledProtocols.Contains(s.Protocol))
- {
- Log("Searching for: {0}", s.GetType().Name);
- s.Search();
- }
- }
- }
- catch (Exception e)
- {
-
- }
- await Task.Delay(100).ConfigureAwait(false);
- }
- }
-
- static async Task Receive(ISearcher searcher, List<UdpClient> clients)
- {
- foreach (UdpClient client in clients)
- {
- if (client.Available > 0)
- {
- IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
- var result = await client.ReceiveAsync().ConfigureAwait(false);
- var data = result.Buffer;
- var received = result.RemoteEndPoint;
- searcher.Handle(localAddress, data, received);
- }
- }
- }
-
- private static CancellationTokenSource _currentCancellationTokenSource;
- private static object _runSyncLock = new object();
- public static void StartDiscovery()
- {
- lock (_runSyncLock)
- {
- if (_currentCancellationTokenSource == null)
- {
- return;
- }
-
- var tokenSource = new CancellationTokenSource();
-
- _currentCancellationTokenSource = tokenSource;
- //Task.Factory.StartNew(() => SearchAndListen(tokenSource.Token), tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
- }
- }
-
- public static void StopDiscovery()
- {
- lock (_runSyncLock)
- {
- var tokenSource = _currentCancellationTokenSource;
-
- if (tokenSource != null)
- {
- try
- {
- tokenSource.Cancel();
- tokenSource.Dispose();
- }
- catch
- {
-
- }
-
- _currentCancellationTokenSource = null;
- }
- }
- }
-
- //checks if an IP address is a private address space as defined by RFC 1918
- public static bool IsPrivateAddressSpace(IPAddress address)
- {
- byte[] ba = address.GetAddressBytes();
-
- switch ((int)ba[0])
- {
- case 10:
- return true; //10.x.x.x
- case 172:
- return ((int)ba[1] & 16) != 0; //172.16-31.x.x
- case 192:
- return (int)ba[1] == 168; //192.168.x.x
- default:
- return false;
- }
- }
-
- public static void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint, NatProtocol protocol)
- {
- switch (protocol)
- {
- case NatProtocol.Upnp:
- //UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
- break;
- case NatProtocol.Pmp:
- PmpSearcher.Instance.Handle(localAddress, response, endpoint);
- break;
- default:
- throw new ArgumentException("Unexpected protocol: " + protocol);
- }
- }
-
- public static async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)
- {
- switch (protocol)
- {
- case NatProtocol.Upnp:
- var searcher = new UpnpSearcher(Logger, HttpClient);
- searcher.DeviceFound += Searcher_DeviceFound;
- await searcher.Handle(localAddress, deviceInfo, endpoint).ConfigureAwait(false);
- break;
- default:
- throw new ArgumentException("Unexpected protocol: " + protocol);
- }
- }
-
- private static void Searcher_DeviceFound(object sender, DeviceEventArgs e)
- {
- if (DeviceFound != null)
- {
- DeviceFound(sender, e);
- }
- }
- }
-}
diff --git a/Mono.Nat/Pmp/AsyncResults/PortMapAsyncResult.cs b/Mono.Nat/Pmp/AsyncResults/PortMapAsyncResult.cs
deleted file mode 100644
index c8ccf5435..000000000
--- a/Mono.Nat/Pmp/AsyncResults/PortMapAsyncResult.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Authors:
-// Ben Motmans <ben.motmans@gmail.com>
-//
-// Copyright (C) 2007 Ben Motmans
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-
-namespace Mono.Nat.Pmp
-{
- internal class PortMapAsyncResult : AsyncResult
- {
- private Mapping mapping;
-
- internal PortMapAsyncResult (Mapping mapping, AsyncCallback callback, object asyncState)
- : base (callback, asyncState)
- {
- this.mapping = mapping;
- }
-
- internal PortMapAsyncResult (Protocol protocol, int port, int lifetime, AsyncCallback callback, object asyncState)
- : base (callback, asyncState)
- {
- this.mapping = new Mapping (protocol, port, port, lifetime);
- }
-
- internal Mapping Mapping
- {
- get { return mapping; }
- }
- }
-}
diff --git a/Mono.Nat/Pmp/PmpNatDevice.cs b/Mono.Nat/Pmp/PmpNatDevice.cs
index fb45b365b..2ef66fdbb 100644
--- a/Mono.Nat/Pmp/PmpNatDevice.cs
+++ b/Mono.Nat/Pmp/PmpNatDevice.cs
@@ -32,6 +32,7 @@ using System.Threading;
using System.Collections.Generic;
using System.Threading.Tasks;
using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Logging;
namespace Mono.Nat.Pmp
{
@@ -39,11 +40,18 @@ namespace Mono.Nat.Pmp
{
private IPAddress localAddress;
private IPAddress publicAddress;
+ private ILogger _logger;
- internal PmpNatDevice(IPAddress localAddress, IPAddress publicAddress)
+ internal PmpNatDevice(IPAddress localAddress, IPAddress publicAddress, ILogger logger)
{
+ if (localAddress == null)
+ {
+ throw new ArgumentNullException("localAddress");
+ }
+
this.localAddress = localAddress;
this.publicAddress = publicAddress;
+ _logger = logger;
}
public override IPAddress LocalAddress
@@ -97,8 +105,7 @@ namespace Mono.Nat.Pmp
while (attempt < PmpConstants.RetryAttempts)
{
- await udpClient.SendAsync(buffer, buffer.Length,
- new IPEndPoint(LocalAddress, PmpConstants.ServerPort));
+ await udpClient.SendAsync(buffer, buffer.Length, new IPEndPoint(LocalAddress, PmpConstants.ServerPort));
if (attempt == 0)
{
@@ -125,9 +132,8 @@ namespace Mono.Nat.Pmp
mapping.Protocol,
mapping.PrivatePort,
e.Message);
- NatUtility.Log(message);
- var pmpException = e as MappingException;
- throw new MappingException(message, pmpException);
+ _logger.Debug(message);
+ throw e;
}
return mapping;
@@ -177,7 +183,7 @@ namespace Mono.Nat.Pmp
};
var errorMsg = errors[resultCode];
- NatUtility.Log("Error in CreatePortMapListen: " + errorMsg);
+ _logger.Debug("Error in CreatePortMapListen: " + errorMsg);
return;
}
@@ -192,7 +198,7 @@ namespace Mono.Nat.Pmp
}
catch (Exception ex)
{
- NatUtility.Logger.ErrorException("Error in CreatePortMapListen", ex);
+ _logger.ErrorException("Error in CreatePortMapListen", ex);
return;
}
}
diff --git a/Mono.Nat/Pmp/Searchers/PmpSearcher.cs b/Mono.Nat/Pmp/PmpSearcher.cs
index 2836071d0..180fb48d7 100644
--- a/Mono.Nat/Pmp/Searchers/PmpSearcher.cs
+++ b/Mono.Nat/Pmp/PmpSearcher.cs
@@ -37,33 +37,44 @@ using Mono.Nat.Pmp;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
+using MediaBrowser.Model.Logging;
+using System.Linq;
namespace Mono.Nat
{
- internal class PmpSearcher : ISearcher
+ internal class PmpSearcher : ISearcher, IDisposable
{
- static PmpSearcher instance = new PmpSearcher();
+ private ILogger _logger;
-
- public static PmpSearcher Instance
- {
- get { return instance; }
- }
-
- private int timeout;
+ private int timeout = 250;
private DateTime nextSearch;
public event EventHandler<DeviceEventArgs> DeviceFound;
- public event EventHandler<DeviceEventArgs> DeviceLost;
- static PmpSearcher()
+ public PmpSearcher(ILogger logger)
{
+ _logger = logger;
+
CreateSocketsAndAddGateways();
}
- public static List<UdpClient> sockets;
- protected static Dictionary<UdpClient, List<IPEndPoint>> gatewayLists;
+ public void Dispose()
+ {
+ var list = sockets.ToList();
+ sockets.Clear();
+
+ foreach (var s in list)
+ {
+ using (s)
+ {
+ s.Close();
+ }
+ }
+ }
+
+ private List<UdpClient> sockets;
+ private Dictionary<UdpClient, List<IPEndPoint>> gatewayLists;
- internal static void CreateSocketsAndAddGateways()
+ private void CreateSocketsAndAddGateways()
{
sockets = new List<UdpClient>();
gatewayLists = new Dictionary<UdpClient, List<IPEndPoint>>();
@@ -137,11 +148,6 @@ namespace Mono.Nat
}
}
- PmpSearcher()
- {
- timeout = 250;
- }
-
public async void Search()
{
foreach (UdpClient s in sockets)
@@ -202,12 +208,13 @@ namespace Mono.Nat
return;
int errorcode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(response, 2));
if (errorcode != 0)
- NatUtility.Log("Non zero error: {0}", errorcode);
+ _logger.Debug("Non zero error: {0}", errorcode);
IPAddress publicIp = new IPAddress(new byte[] { response[8], response[9], response[10], response[11] });
nextSearch = DateTime.Now.AddMinutes(5);
timeout = 250;
- OnDeviceFound(new DeviceEventArgs(new PmpNatDevice(endpoint.Address, publicIp)));
+
+ OnDeviceFound(new DeviceEventArgs(new PmpNatDevice(endpoint.Address, publicIp, _logger)));
}
public DateTime NextSearch
diff --git a/Mono.Nat/Upnp/Messages/DiscoverDeviceMessage.cs b/Mono.Nat/Upnp/Messages/DiscoverDeviceMessage.cs
deleted file mode 100644
index 87f5835a6..000000000
--- a/Mono.Nat/Upnp/Messages/DiscoverDeviceMessage.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-//
-// Copyright (C) 2006 Alan McGovern
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Net;
-using System.Text;
-
-namespace Mono.Nat.Upnp
-{
- internal static class DiscoverDeviceMessage
- {
- /// <summary>
- /// The message sent to discover all uPnP devices on the network
- /// </summary>
- /// <returns></returns>
- public static byte[] EncodeSSDP()
- {
- string s = "M-SEARCH * HTTP/1.1\r\n"
- + "HOST: 239.255.255.250:1900\r\n"
- + "MAN: \"ssdp:discover\"\r\n"
- + "MX: 3\r\n"
- + "ST: ssdp:all\r\n\r\n";
- return UTF8Encoding.ASCII.GetBytes(s);
- }
-
- public static byte[] EncodeUnicast(IPAddress gatewayAddress)
- {
- //Format obtained from http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf pg 31
- //This method only works with upnp 1.1 routers... unfortunately
- string s = "M-SEARCH * HTTP/1.1\r\n"
- + "HOST: " + gatewayAddress + ":1900\r\n"
- + "MAN: \"ssdp:discover\"\r\n"
- + "ST: ssdp:all\r\n\r\n";
- //+ "USER-AGENT: unix/5.1 UPnP/1.1 MyProduct/1.0\r\n\r\n";
- return UTF8Encoding.ASCII.GetBytes(s);
- }
- }
-}
diff --git a/Mono.Nat/Upnp/Messages/ErrorMessage.cs b/Mono.Nat/Upnp/Messages/ErrorMessage.cs
deleted file mode 100644
index 7c0c44d8e..000000000
--- a/Mono.Nat/Upnp/Messages/ErrorMessage.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-//
-// Copyright (C) 2006 Alan McGovern
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
- internal class ErrorMessage : MessageBase
- {
- #region Member Variables
- public string Description
- {
- get { return this.description; }
- }
- private string description;
-
- public int ErrorCode
- {
- get { return this.errorCode; }
- }
- private int errorCode;
- #endregion
-
-
- #region Constructors
- public ErrorMessage(int errorCode, string description)
- :base(null)
- {
- this.description = description;
- this.errorCode = errorCode;
- }
- #endregion
-
- public override HttpRequestOptions Encode()
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Mono.Nat/Upnp/Messages/Responses/CreatePortMappingResponseMessage.cs b/Mono.Nat/Upnp/Messages/Responses/CreatePortMappingResponseMessage.cs
deleted file mode 100644
index 48776dd6f..000000000
--- a/Mono.Nat/Upnp/Messages/Responses/CreatePortMappingResponseMessage.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-//
-// Copyright (C) 2006 Alan McGovern
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-
-
-using System;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
- internal class CreatePortMappingResponseMessage : MessageBase
- {
- #region Constructors
- public CreatePortMappingResponseMessage()
- :base(null)
- {
- }
- #endregion
-
- public override HttpRequestOptions Encode()
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Mono.Nat/Upnp/Messages/UpnpMessage.cs b/Mono.Nat/Upnp/Messages/UpnpMessage.cs
index b0264fc4a..37a46e47d 100644
--- a/Mono.Nat/Upnp/Messages/UpnpMessage.cs
+++ b/Mono.Nat/Upnp/Messages/UpnpMessage.cs
@@ -37,7 +37,6 @@ namespace Mono.Nat.Upnp
{
internal abstract class MessageBase
{
- internal static readonly CultureInfo Culture = CultureInfo.InvariantCulture;
protected UpnpNatDevice device;
protected MessageBase(UpnpNatDevice device)
@@ -48,7 +47,6 @@ namespace Mono.Nat.Upnp
protected HttpRequestOptions CreateRequest(string upnpMethod, string methodParameters)
{
string ss = "http://" + this.device.HostEndPoint.ToString() + this.device.ControlUrl;
- NatUtility.Log("Initiating request to: {0}", ss);
var req = new HttpRequestOptions();
req.LogErrors = false;
@@ -84,14 +82,14 @@ namespace Mono.Nat.Upnp
get { return "POST"; }
}
- internal static void WriteFullElement(XmlWriter writer, string element, string value)
+ protected void WriteFullElement(XmlWriter writer, string element, string value)
{
writer.WriteStartElement(element);
writer.WriteString(value);
writer.WriteEndElement();
}
- internal static XmlWriter CreateWriter(StringBuilder sb)
+ protected XmlWriter CreateWriter(StringBuilder sb)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
diff --git a/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs b/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
index d9b16dd81..7c1e89d3b 100644
--- a/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
+++ b/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
@@ -46,7 +46,6 @@ namespace Mono.Nat
internal class UpnpSearcher : ISearcher
{
public event EventHandler<DeviceEventArgs> DeviceFound;
- public event EventHandler<DeviceEventArgs> DeviceLost;
private DateTime nextSearch;
private readonly ILogger _logger;
@@ -64,8 +63,11 @@ namespace Mono.Nat
public async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
{
- // No matter what, this method should never throw an exception. If something goes wrong
- // we should still be in a position to handle the next reply correctly.
+ if (localAddress == null)
+ {
+ throw new ArgumentNullException("localAddress");
+ }
+
try
{
/* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
@@ -82,7 +84,6 @@ namespace Mono.Nat
// We have an internet gateway device now
UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger, _httpClient);
- NatUtility.Log("Fetching service list: {0}", d.HostEndPoint);
await d.GetServicesList().ConfigureAwait(false);
OnDeviceFound(new DeviceEventArgs(d));
diff --git a/Mono.Nat/Upnp/UpnpNatDevice.cs b/Mono.Nat/Upnp/UpnpNatDevice.cs
index fda990fa8..cae7f5fc8 100644
--- a/Mono.Nat/Upnp/UpnpNatDevice.cs
+++ b/Mono.Nat/Upnp/UpnpNatDevice.cs
@@ -56,6 +56,11 @@ namespace Mono.Nat.Upnp
internal UpnpNatDevice(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint hostEndPoint, string serviceType, ILogger logger, IHttpClient httpClient)
{
+ if (localAddress == null)
+ {
+ throw new ArgumentNullException("localAddress");
+ }
+
this.LastSeen = DateTime.Now;
this.localAddress = localAddress;
@@ -72,21 +77,19 @@ namespace Mono.Nat.Upnp
// Are we going to get addresses with the "http://" attached?
if (locationDetails.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
{
- NatUtility.Log("Found device at: {0}", locationDetails);
+ _logger.Debug("Found device at: {0}", locationDetails);
// This bit strings out the "http://" from the string
locationDetails = locationDetails.Substring(7);
this.hostEndPoint = hostEndPoint;
- NatUtility.Log("Parsed device as: {0}", this.hostEndPoint.ToString());
-
// The service description URL is the remainder of the "locationDetails" string. The bit that was originally after the ip
// and port information
this.serviceDescriptionUrl = locationDetails.Substring(locationDetails.IndexOf('/'));
}
else
{
- NatUtility.Log("Couldn't decode address. Please send following string to the developer: ");
+ _logger.Debug("Couldn't decode address. Please send following string to the developer: ");
}
}
@@ -113,7 +116,7 @@ namespace Mono.Nat.Upnp
{
if (response.StatusCode != HttpStatusCode.OK)
{
- NatUtility.Log("{0}: Couldn't get services list: {1}", HostEndPoint, response.StatusCode);
+ _logger.Debug("{0}: Couldn't get services list: {1}", HostEndPoint, response.StatusCode);
return; // FIXME: This the best thing to do??
}
@@ -136,12 +139,11 @@ namespace Mono.Nat.Upnp
{
return;
}
- NatUtility.Log("{0}: Couldn't parse services list", HostEndPoint);
+ _logger.Debug("{0}: Couldn't parse services list", HostEndPoint);
System.Threading.Thread.Sleep(10);
}
}
- NatUtility.Log("{0}: Parsed services list", HostEndPoint);
XmlNamespaceManager ns = new XmlNamespaceManager(xmldoc.NameTable);
ns.AddNamespace("ns", "urn:schemas-upnp-org:device-1-0");
XmlNodeList nodes = xmldoc.SelectNodes("//*/ns:serviceList", ns);
@@ -153,31 +155,35 @@ namespace Mono.Nat.Upnp
{
//If the service is a WANIPConnection, then we have what we want
string type = service["serviceType"].InnerText;
- NatUtility.Log("{0}: Found service: {1}", HostEndPoint, type);
- StringComparison c = StringComparison.OrdinalIgnoreCase;
+ _logger.Debug("{0}: Found service: {1}", HostEndPoint, type);
+
// TODO: Add support for version 2 of UPnP.
- if (type.Equals("urn:schemas-upnp-org:service:WANPPPConnection:1", c) ||
- type.Equals("urn:schemas-upnp-org:service:WANIPConnection:1", c))
+ if (string.Equals(type, "urn:schemas-upnp-org:service:WANPPPConnection:1", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(type, "urn:schemas-upnp-org:service:WANIPConnection:1", StringComparison.OrdinalIgnoreCase))
{
this.controlUrl = service["controlURL"].InnerText;
- NatUtility.Log("{0}: Found upnp service at: {1}", HostEndPoint, controlUrl);
- try
+ _logger.Debug("{0}: Found upnp service at: {1}", HostEndPoint, controlUrl);
+
+ Uri u;
+ if (Uri.TryCreate(controlUrl, UriKind.RelativeOrAbsolute, out u))
{
- Uri u = new Uri(controlUrl);
if (u.IsAbsoluteUri)
{
EndPoint old = hostEndPoint;
- this.hostEndPoint = new IPEndPoint(IPAddress.Parse(u.Host), u.Port);
- NatUtility.Log("{0}: Absolute URI detected. Host address is now: {1}", old, HostEndPoint);
- this.controlUrl = controlUrl.Substring(u.GetLeftPart(UriPartial.Authority).Length);
- NatUtility.Log("{0}: New control url: {1}", HostEndPoint, controlUrl);
+ IPAddress parsedHostIpAddress;
+ if (IPAddress.TryParse(u.Host, out parsedHostIpAddress))
+ {
+ this.hostEndPoint = new IPEndPoint(parsedHostIpAddress, u.Port);
+ //_logger.Debug("{0}: Absolute URI detected. Host address is now: {1}", old, HostEndPoint);
+ this.controlUrl = controlUrl.Substring(u.GetLeftPart(UriPartial.Authority).Length);
+ //_logger.Debug("{0}: New control url: {1}", HostEndPoint, controlUrl);
+ }
}
}
- catch
+ else
{
- NatUtility.Log("{0}: Assuming control Uri is relative: {1}", HostEndPoint, controlUrl);
+ _logger.Debug("{0}: Assuming control Uri is relative: {1}", HostEndPoint, controlUrl);
}
- NatUtility.Log("{0}: Handshake Complete", HostEndPoint);
return;
}
}