aboutsummaryrefslogtreecommitdiff
path: root/Mono.Nat
diff options
context:
space:
mode:
Diffstat (limited to 'Mono.Nat')
-rw-r--r--Mono.Nat/AbstractNatDevice.cs55
-rw-r--r--Mono.Nat/Enums/ProtocolType.cs36
-rw-r--r--Mono.Nat/EventArgs/DeviceEventArgs.cs45
-rw-r--r--Mono.Nat/INatDevice.cs45
-rw-r--r--Mono.Nat/ISearcher.cs46
-rw-r--r--Mono.Nat/Mapping.cs121
-rw-r--r--Mono.Nat/Mono.Nat.csproj17
-rw-r--r--Mono.Nat/NatManager.cs86
-rw-r--r--Mono.Nat/NatProtocol.cs8
-rw-r--r--Mono.Nat/Pmp/PmpConstants.cs56
-rw-r--r--Mono.Nat/Pmp/PmpNatDevice.cs217
-rw-r--r--Mono.Nat/Pmp/PmpSearcher.cs235
-rw-r--r--Mono.Nat/Properties/AssemblyInfo.cs21
-rw-r--r--Mono.Nat/Upnp/Messages/GetServicesMessage.cs77
-rw-r--r--Mono.Nat/Upnp/Messages/Requests/CreatePortMappingMessage.cs75
-rw-r--r--Mono.Nat/Upnp/Messages/UpnpMessage.cs99
-rw-r--r--Mono.Nat/Upnp/Searchers/UpnpSearcher.cs111
-rw-r--r--Mono.Nat/Upnp/UpnpNatDevice.cs269
18 files changed, 0 insertions, 1619 deletions
diff --git a/Mono.Nat/AbstractNatDevice.cs b/Mono.Nat/AbstractNatDevice.cs
deleted file mode 100644
index 1241170c1..000000000
--- a/Mono.Nat/AbstractNatDevice.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-// Ben Motmans <ben.motmans@gmail.com>
-//
-// Copyright (C) 2006 Alan McGovern
-// 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Net;
-using System.Threading.Tasks;
-
-namespace Mono.Nat
-{
- public abstract class AbstractNatDevice : INatDevice
- {
- private DateTime lastSeen;
-
- protected AbstractNatDevice()
- {
- }
-
- public abstract IPAddress LocalAddress { get; }
-
- public DateTime LastSeen
- {
- get { return lastSeen; }
- set { lastSeen = value; }
- }
-
- public abstract Task CreatePortMap(Mapping mapping);
- }
-}
diff --git a/Mono.Nat/Enums/ProtocolType.cs b/Mono.Nat/Enums/ProtocolType.cs
deleted file mode 100644
index 54480598d..000000000
--- a/Mono.Nat/Enums/ProtocolType.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 Protocol
- {
- Tcp,
- Udp
- }
-}
diff --git a/Mono.Nat/EventArgs/DeviceEventArgs.cs b/Mono.Nat/EventArgs/DeviceEventArgs.cs
deleted file mode 100644
index 6358a0c29..000000000
--- a/Mono.Nat/EventArgs/DeviceEventArgs.cs
+++ /dev/null
@@ -1,45 +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 DeviceEventArgs : EventArgs
- {
- private INatDevice device;
-
- public DeviceEventArgs(INatDevice device)
- {
- this.device = device;
- }
-
- public INatDevice Device
- {
- get { return this.device; }
- }
- }
-}
diff --git a/Mono.Nat/INatDevice.cs b/Mono.Nat/INatDevice.cs
deleted file mode 100644
index 6a1509071..000000000
--- a/Mono.Nat/INatDevice.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-// Ben Motmans <ben.motmans@gmail.com>
-//
-// Copyright (C) 2006 Alan McGovern
-// 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Net;
-using System.Threading.Tasks;
-
-namespace Mono.Nat
-{
- public interface INatDevice
- {
- Task CreatePortMap (Mapping mapping);
-
- IPAddress LocalAddress { get; }
-
- DateTime LastSeen { get; set; }
- }
-}
diff --git a/Mono.Nat/ISearcher.cs b/Mono.Nat/ISearcher.cs
deleted file mode 100644
index 95c2f2aa9..000000000
--- a/Mono.Nat/ISearcher.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-// Ben Motmans <ben.motmans@gmail.com>
-// Nicholas Terry <nick.i.terry@gmail.com>
-//
-// Copyright (C) 2006 Alan McGovern
-// 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.Collections.Generic;
-using System.Text;
-using System.Net.Sockets;
-using System.Net;
-
-namespace Mono.Nat
-{
- internal interface ISearcher
- {
- event EventHandler<DeviceEventArgs> DeviceFound;
-
- void Search();
- void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint);
- }
-}
diff --git a/Mono.Nat/Mapping.cs b/Mono.Nat/Mapping.cs
deleted file mode 100644
index 5b15d4e14..000000000
--- a/Mono.Nat/Mapping.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-// Ben Motmans <ben.motmans@gmail.com>
-//
-// Copyright (C) 2006 Alan McGovern
-// 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
-{
- public class Mapping
- {
- private string description;
- private DateTime expiration;
- private int lifetime;
- private int privatePort;
- private Protocol protocol;
- private int publicPort;
-
- public Mapping(Protocol protocol, int privatePort, int publicPort)
- : this (protocol, privatePort, publicPort, 0)
- {
- }
-
- public Mapping(Protocol protocol, int privatePort, int publicPort, int lifetime)
- {
- this.protocol = protocol;
- this.privatePort = privatePort;
- this.publicPort = publicPort;
- this.lifetime = lifetime;
-
- if (lifetime == int.MaxValue)
- this.expiration = DateTime.MaxValue;
- else if (lifetime == 0)
- this.expiration = DateTime.Now;
- else
- this.expiration = DateTime.Now.AddSeconds (lifetime);
- }
-
- public string Description
- {
- get { return description; }
- set { description = value; }
- }
-
- public Protocol Protocol
- {
- get { return protocol; }
- internal set { protocol = value; }
- }
-
- public int PrivatePort
- {
- get { return privatePort; }
- internal set { privatePort = value; }
- }
-
- public int PublicPort
- {
- get { return publicPort; }
- internal set { publicPort = value; }
- }
-
- public int Lifetime
- {
- get { return lifetime; }
- internal set { lifetime = value; }
- }
-
- public DateTime Expiration
- {
- get { return expiration; }
- internal set { expiration = value; }
- }
-
- public bool IsExpired()
- {
- return expiration < DateTime.Now;
- }
-
- public override bool Equals(object obj)
- {
- var other = obj as Mapping;
- return other == null ? false : this.protocol == other.protocol &&
- this.privatePort == other.privatePort && this.publicPort == other.publicPort;
- }
-
- public override int GetHashCode()
- {
- return this.protocol.GetHashCode() ^ this.privatePort.GetHashCode() ^ this.publicPort.GetHashCode();
- }
-
- public override string ToString()
- {
- return String.Format( "Protocol: {0}, Public Port: {1}, Private Port: {2}, Description: {3}, Expiration: {4}, Lifetime: {5}",
- this.protocol, this.publicPort, this.privatePort, this.description, this.expiration, this.lifetime );
- }
- }
-}
diff --git a/Mono.Nat/Mono.Nat.csproj b/Mono.Nat/Mono.Nat.csproj
deleted file mode 100644
index edfd5c9bb..000000000
--- a/Mono.Nat/Mono.Nat.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
- <ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
- <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
- </ItemGroup>
-
- <ItemGroup>
- <Compile Include="..\SharedVersion.cs" />
- </ItemGroup>
-
- <PropertyGroup>
- <TargetFramework>netstandard2.0</TargetFramework>
- <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
- </PropertyGroup>
-
-</Project>
diff --git a/Mono.Nat/NatManager.cs b/Mono.Nat/NatManager.cs
deleted file mode 100644
index 3ed01a6b3..000000000
--- a/Mono.Nat/NatManager.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System;
-using System.Net;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.Dlna;
-using Microsoft.Extensions.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/NatProtocol.cs b/Mono.Nat/NatProtocol.cs
deleted file mode 100644
index 2768f133c..000000000
--- a/Mono.Nat/NatProtocol.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Mono.Nat
-{
- public enum NatProtocol
- {
- Upnp = 0,
- Pmp = 1
- }
-}
diff --git a/Mono.Nat/Pmp/PmpConstants.cs b/Mono.Nat/Pmp/PmpConstants.cs
deleted file mode 100644
index 83fa8e07c..000000000
--- a/Mono.Nat/Pmp/PmpConstants.cs
+++ /dev/null
@@ -1,56 +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 static class PmpConstants
- {
- public const byte Version = (byte)0;
-
- public const byte OperationCode = (byte)0;
- public const byte OperationCodeUdp = (byte)1;
- public const byte OperationCodeTcp = (byte)2;
- public const byte ServerNoop = (byte)128;
-
- public const int ClientPort = 5350;
- public const int ServerPort = 5351;
-
- public const int RetryDelay = 250;
- public const int RetryAttempts = 9;
-
- public const int RecommendedLeaseTime = 60 * 60;
- public const int DefaultLeaseTime = RecommendedLeaseTime;
-
- public const short ResultCodeSuccess = 0;
- public const short ResultCodeUnsupportedVersion = 1;
- public const short ResultCodeNotAuthorized = 2;
- public const short ResultCodeNetworkFailure = 3;
- public const short ResultCodeOutOfResources = 4;
- public const short ResultCodeUnsupportedOperationCode = 5;
- }
-}
diff --git a/Mono.Nat/Pmp/PmpNatDevice.cs b/Mono.Nat/Pmp/PmpNatDevice.cs
deleted file mode 100644
index 95bd72a6c..000000000
--- a/Mono.Nat/Pmp/PmpNatDevice.cs
+++ /dev/null
@@ -1,217 +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;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Extensions;
-using Microsoft.Extensions.Logging;
-
-namespace Mono.Nat.Pmp
-{
- internal sealed class PmpNatDevice : AbstractNatDevice, IEquatable<PmpNatDevice>
- {
- private IPAddress localAddress;
- private IPAddress publicAddress;
- private ILogger _logger;
-
- internal PmpNatDevice(IPAddress localAddress, IPAddress publicAddress, ILogger logger)
- {
- if (localAddress == null)
- {
- throw new ArgumentNullException(nameof(localAddress));
- }
-
- this.localAddress = localAddress;
- this.publicAddress = publicAddress;
- _logger = logger;
- }
-
- public override IPAddress LocalAddress
- {
- get { return localAddress; }
- }
-
- public override Task CreatePortMap(Mapping mapping)
- {
- return InternalCreatePortMapAsync(mapping, true);
- }
-
- public override bool Equals(object obj)
- {
- var device = obj as PmpNatDevice;
- return (device == null) ? false : this.Equals(device);
- }
-
- public override int GetHashCode()
- {
- return this.publicAddress.GetHashCode();
- }
-
- public bool Equals(PmpNatDevice other)
- {
- return (other == null) ? false : this.publicAddress.Equals(other.publicAddress);
- }
-
- private async Task<Mapping> InternalCreatePortMapAsync(Mapping mapping, bool create)
- {
- var package = new List<byte>();
-
- package.Add(PmpConstants.Version);
- package.Add(mapping.Protocol == Protocol.Tcp ? PmpConstants.OperationCodeTcp : PmpConstants.OperationCodeUdp);
- package.Add(0); //reserved
- package.Add(0); //reserved
- package.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)mapping.PrivatePort)));
- package.AddRange(
- BitConverter.GetBytes(create ? IPAddress.HostToNetworkOrder((short)mapping.PublicPort) : (short)0));
- package.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(mapping.Lifetime)));
-
- try
- {
- byte[] buffer = package.ToArray();
- int attempt = 0;
- int delay = PmpConstants.RetryDelay;
-
- using (var udpClient = new UdpClient())
- {
- var cancellationTokenSource = new CancellationTokenSource();
-
- while (attempt < PmpConstants.RetryAttempts)
- {
- await udpClient.SendAsync(buffer, buffer.Length, new IPEndPoint(LocalAddress, PmpConstants.ServerPort));
-
- if (attempt == 0)
- {
- await Task.Run(() => CreatePortMapListen(udpClient, mapping, cancellationTokenSource.Token));
- }
-
- attempt++;
- delay *= 2;
- await Task.Delay(delay).ConfigureAwait(false);
- }
-
- cancellationTokenSource.Cancel();
- }
- }
- catch (OperationCanceledException)
- {
-
- }
- catch (Exception e)
- {
- string type = create ? "create" : "delete";
- string message = String.Format("Failed to {0} portmap (protocol={1}, private port={2}) {3}",
- type,
- mapping.Protocol,
- mapping.PrivatePort,
- e.Message);
- _logger.LogDebug(message);
- throw e;
- }
-
- return mapping;
- }
-
- private async void CreatePortMapListen(UdpClient udpClient, Mapping mapping, CancellationToken cancellationToken)
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- try
- {
- var result = await udpClient.ReceiveAsync().ConfigureAwait(false);
- var endPoint = result.RemoteEndPoint;
- byte[] data = data = result.Buffer;
-
- if (data.Length < 16)
- continue;
-
- if (data[0] != PmpConstants.Version)
- continue;
-
- var opCode = (byte)(data[1] & 127);
-
- var protocol = Protocol.Tcp;
- if (opCode == PmpConstants.OperationCodeUdp)
- protocol = Protocol.Udp;
-
- short resultCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 2));
- int epoch = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));
-
- short privatePort = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 8));
- short publicPort = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 10));
-
- var lifetime = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 12));
-
- if (privatePort < 0 || publicPort < 0 || resultCode != PmpConstants.ResultCodeSuccess)
- {
- var errors = new[]
- {
- "Success",
- "Unsupported Version",
- "Not Authorized/Refused (e.g. box supports mapping, but user has turned feature off)"
- ,
- "Network Failure (e.g. NAT box itself has not obtained a DHCP lease)",
- "Out of resources (NAT box cannot create any more mappings at this time)",
- "Unsupported opcode"
- };
-
- var errorMsg = errors[resultCode];
- _logger.LogDebug("Error in CreatePortMapListen: " + errorMsg);
- return;
- }
-
- if (lifetime == 0) return; //mapping was deleted
-
- //mapping was created
- //TODO: verify that the private port+protocol are a match
- mapping.PublicPort = publicPort;
- mapping.Protocol = protocol;
- mapping.Expiration = DateTime.Now.AddSeconds(lifetime);
- return;
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error in CreatePortMapListen");
- return;
- }
- }
- }
-
- /// <summary>
- /// Overridden.
- /// </summary>
- /// <returns></returns>
- public override string ToString()
- {
- return String.Format("PmpNatDevice - Local Address: {0}, Public IP: {1}, Last Seen: {2}",
- this.localAddress, this.publicAddress, this.LastSeen);
- }
- }
-}
diff --git a/Mono.Nat/Pmp/PmpSearcher.cs b/Mono.Nat/Pmp/PmpSearcher.cs
deleted file mode 100644
index 46c2e9d80..000000000
--- a/Mono.Nat/Pmp/PmpSearcher.cs
+++ /dev/null
@@ -1,235 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-// Ben Motmans <ben.motmans@gmail.com>
-// Nicholas Terry <nick.i.terry@gmail.com>
-//
-// Copyright (C) 2006 Alan McGovern
-// 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.Collections.Generic;
-using System.Text;
-using System.Net;
-using Mono.Nat.Pmp;
-using System.Net.NetworkInformation;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using System.Linq;
-
-namespace Mono.Nat
-{
- internal class PmpSearcher : ISearcher, IDisposable
- {
- private ILogger _logger;
-
- private int timeout = 250;
- private DateTime nextSearch;
- public event EventHandler<DeviceEventArgs> DeviceFound;
-
- public PmpSearcher(ILogger logger)
- {
- _logger = logger;
-
- CreateSocketsAndAddGateways();
- }
-
- 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;
-
- private void CreateSocketsAndAddGateways()
- {
- sockets = new List<UdpClient>();
- gatewayLists = new Dictionary<UdpClient, List<IPEndPoint>>();
-
- try
- {
- foreach (var n in NetworkInterface.GetAllNetworkInterfaces())
- {
- if (n.OperationalStatus != OperationalStatus.Up && n.OperationalStatus != OperationalStatus.Unknown)
- continue;
- IPInterfaceProperties properties = n.GetIPProperties();
- var gatewayList = new List<IPEndPoint>();
-
- foreach (GatewayIPAddressInformation gateway in properties.GatewayAddresses)
- {
- if (gateway.Address.AddressFamily == AddressFamily.InterNetwork)
- {
- gatewayList.Add(new IPEndPoint(gateway.Address, PmpConstants.ServerPort));
- }
- }
- if (gatewayList.Count == 0)
- {
- /* Mono on OSX doesn't give any gateway addresses, so check DNS entries */
- foreach (var gw2 in properties.DnsAddresses)
- {
- if (gw2.AddressFamily == AddressFamily.InterNetwork)
- {
- gatewayList.Add(new IPEndPoint(gw2, PmpConstants.ServerPort));
- }
- }
- foreach (UnicastIPAddressInformation unicast in properties.UnicastAddresses)
- {
- if (/*unicast.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
- && unicast.AddressPreferredLifetime != UInt32.MaxValue
- && */unicast.Address.AddressFamily == AddressFamily.InterNetwork)
- {
- var bytes = unicast.Address.GetAddressBytes();
- bytes[3] = 1;
- gatewayList.Add(new IPEndPoint(new IPAddress(bytes), PmpConstants.ServerPort));
- }
- }
- }
-
- if (gatewayList.Count > 0)
- {
- foreach (var address in properties.UnicastAddresses)
- {
- if (address.Address.AddressFamily == AddressFamily.InterNetwork)
- {
- UdpClient client;
-
- try
- {
- client = new UdpClient(new IPEndPoint(address.Address, 0));
- }
- catch (SocketException)
- {
- continue; // Move on to the next address.
- }
-
- gatewayLists.Add(client, gatewayList);
- sockets.Add(client);
- }
- }
- }
- }
- }
- catch (Exception)
- {
- // NAT-PMP does not use multicast, so there isn't really a good fallback.
- }
- }
-
- public async void Search()
- {
- foreach (UdpClient s in sockets)
- {
- try
- {
- await Search(s).ConfigureAwait(false);
- }
- catch
- {
- // Ignore any search errors
- }
- }
- }
-
- async Task Search(UdpClient client)
- {
- // Sort out the time for the next search first. The spec says the
- // timeout should double after each attempt. Once it reaches 64 seconds
- // (and that attempt fails), assume no devices available
- nextSearch = DateTime.Now.AddMilliseconds(timeout);
- timeout *= 2;
-
- // We've tried 9 times as per spec, try searching again in 5 minutes
- if (timeout == 128 * 1000)
- {
- timeout = 250;
- nextSearch = DateTime.Now.AddMinutes(10);
- return;
- }
-
- // The nat-pmp search message. Must be sent to GatewayIP:53531
- byte[] buffer = new byte[] { PmpConstants.Version, PmpConstants.OperationCode };
- foreach (IPEndPoint gatewayEndpoint in gatewayLists[client])
- {
- await client.SendAsync(buffer, buffer.Length, gatewayEndpoint).ConfigureAwait(false);
- }
- }
-
- bool IsSearchAddress(IPAddress address)
- {
- foreach (var gatewayList in gatewayLists.Values)
- foreach (var gatewayEndpoint in gatewayList)
- if (gatewayEndpoint.Address.Equals(address))
- return true;
- return false;
- }
-
- public void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint)
- {
- if (!IsSearchAddress(endpoint.Address))
- return;
- if (response.Length != 12)
- return;
- if (response[0] != PmpConstants.Version)
- return;
- if (response[1] != PmpConstants.ServerNoop)
- return;
- int errorcode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(response, 2));
- if (errorcode != 0)
- _logger.LogDebug("Non zero error: {0}", errorcode);
-
- var 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, _logger)));
- }
-
- public DateTime NextSearch
- {
- get { return nextSearch; }
- }
- private void OnDeviceFound(DeviceEventArgs args)
- {
- if (DeviceFound != null)
- DeviceFound(this, args);
- }
-
- public NatProtocol Protocol
- {
- get { return NatProtocol.Pmp; }
- }
- }
-}
diff --git a/Mono.Nat/Properties/AssemblyInfo.cs b/Mono.Nat/Properties/AssemblyInfo.cs
deleted file mode 100644
index ea1c9dee6..000000000
--- a/Mono.Nat/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Reflection;
-using System.Resources;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Mono.Nat")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Jellyfin Project")]
-[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
-[assembly: AssemblyCopyright("Copyright © 2006 Alan McGovern. Copyright © 2007 Ben Motmans. Code releases unde the MIT license. Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: NeutralResourcesLanguage("en")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
diff --git a/Mono.Nat/Upnp/Messages/GetServicesMessage.cs b/Mono.Nat/Upnp/Messages/GetServicesMessage.cs
deleted file mode 100644
index 72b4c2b25..000000000
--- a/Mono.Nat/Upnp/Messages/GetServicesMessage.cs
+++ /dev/null
@@ -1,77 +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 System.Diagnostics;
-using System.Net;
-using MediaBrowser.Common.Net;
-using Microsoft.Extensions.Logging;
-
-namespace Mono.Nat.Upnp
-{
- internal class GetServicesMessage : MessageBase
- {
- private string servicesDescriptionUrl;
- private EndPoint hostAddress;
- private readonly ILogger _logger;
-
- public GetServicesMessage(string description, EndPoint hostAddress, ILogger logger)
- : base(null)
- {
- if (string.IsNullOrEmpty(description))
- _logger.LogWarning("Description is null");
-
- if (hostAddress == null)
- _logger.LogWarning("hostaddress is null");
-
- this.servicesDescriptionUrl = description;
- this.hostAddress = hostAddress;
- _logger = logger;
- }
-
- public override string Method
- {
- get
- {
- return "GET";
- }
- }
-
- public override HttpRequestOptions Encode()
- {
- var req = new HttpRequestOptions();
-
- // The periodic request logging may keep some devices awake
- req.LogRequestAsDebug = true;
- req.LogErrors = false;
-
- req.Url = "http://" + this.hostAddress.ToString() + this.servicesDescriptionUrl;
- req.RequestHeaders.Add("ACCEPT-LANGUAGE", "en");
-
- return req;
- }
- }
-}
diff --git a/Mono.Nat/Upnp/Messages/Requests/CreatePortMappingMessage.cs b/Mono.Nat/Upnp/Messages/Requests/CreatePortMappingMessage.cs
deleted file mode 100644
index 7d6844e32..000000000
--- a/Mono.Nat/Upnp/Messages/Requests/CreatePortMappingMessage.cs
+++ /dev/null
@@ -1,75 +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.IO;
-using System.Globalization;
-using System.Text;
-using System.Xml;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
- internal class CreatePortMappingMessage : MessageBase
- {
- #region Private Fields
-
- private IPAddress localIpAddress;
- private Mapping mapping;
-
- #endregion
-
-
- #region Constructors
- public CreatePortMappingMessage(Mapping mapping, IPAddress localIpAddress, UpnpNatDevice device)
- : base(device)
- {
- this.mapping = mapping;
- this.localIpAddress = localIpAddress;
- }
- #endregion
-
- public override HttpRequestOptions Encode()
- {
- var culture = CultureInfo.InvariantCulture;
-
- var builder = new StringBuilder(256);
- XmlWriter writer = CreateWriter(builder);
-
- WriteFullElement(writer, "NewRemoteHost", string.Empty);
- WriteFullElement(writer, "NewExternalPort", this.mapping.PublicPort.ToString(culture));
- WriteFullElement(writer, "NewProtocol", this.mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP");
- WriteFullElement(writer, "NewInternalPort", this.mapping.PrivatePort.ToString(culture));
- WriteFullElement(writer, "NewInternalClient", this.localIpAddress.ToString());
- WriteFullElement(writer, "NewEnabled", "1");
- WriteFullElement(writer, "NewPortMappingDescription", string.IsNullOrEmpty(mapping.Description) ? "Mono.Nat" : mapping.Description);
- WriteFullElement(writer, "NewLeaseDuration", mapping.Lifetime.ToString());
-
- writer.Flush();
- return CreateRequest("AddPortMapping", builder.ToString());
- }
- }
-}
diff --git a/Mono.Nat/Upnp/Messages/UpnpMessage.cs b/Mono.Nat/Upnp/Messages/UpnpMessage.cs
deleted file mode 100644
index 1151dd997..000000000
--- a/Mono.Nat/Upnp/Messages/UpnpMessage.cs
+++ /dev/null
@@ -1,99 +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 System.Diagnostics;
-using System.Xml;
-using System.Net;
-using System.IO;
-using System.Text;
-using System.Globalization;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
- internal abstract class MessageBase
- {
- protected UpnpNatDevice device;
-
- protected MessageBase(UpnpNatDevice device)
- {
- this.device = device;
- }
-
- protected HttpRequestOptions CreateRequest(string upnpMethod, string methodParameters)
- {
- string ss = "http://" + this.device.HostEndPoint.ToString() + this.device.ControlUrl;
-
- var req = new HttpRequestOptions();
- req.LogErrors = false;
-
- // The periodic request logging may keep some devices awake
- req.LogRequestAsDebug = true;
-
- req.Url = ss;
- req.EnableKeepAlive = false;
- req.RequestContentType = "text/xml";
- req.AppendCharsetToMimeType = true;
- req.RequestHeaders.Add("SOAPACTION", "\"" + device.ServiceType + "#" + upnpMethod + "\"");
-
- string bodyString = "<s:Envelope "
- + "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
- + "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
- + "<s:Body>"
- + "<u:" + upnpMethod + " "
- + "xmlns:u=\"" + device.ServiceType + "\">"
- + methodParameters
- + "</u:" + upnpMethod + ">"
- + "</s:Body>"
- + "</s:Envelope>\r\n\r\n";
-
- req.RequestContentBytes = System.Text.Encoding.UTF8.GetBytes(bodyString);
- return req;
- }
-
- public abstract HttpRequestOptions Encode();
-
- public virtual string Method
- {
- get { return "POST"; }
- }
-
- protected void WriteFullElement(XmlWriter writer, string element, string value)
- {
- writer.WriteStartElement(element);
- writer.WriteString(value);
- writer.WriteEndElement();
- }
-
- protected XmlWriter CreateWriter(StringBuilder sb)
- {
- var settings = new XmlWriterSettings();
- settings.ConformanceLevel = ConformanceLevel.Fragment;
- return XmlWriter.Create(sb, settings);
- }
- }
-}
diff --git a/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs b/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
deleted file mode 100644
index 3b54c4680..000000000
--- a/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-// Ben Motmans <ben.motmans@gmail.com>
-// Nicholas Terry <nick.i.terry@gmail.com>
-//
-// Copyright (C) 2006 Alan McGovern
-// 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.Collections.Generic;
-using System.Text;
-using System.Net;
-using Mono.Nat.Upnp;
-using System.Diagnostics;
-using System.Net.Sockets;
-using System.Net.NetworkInformation;
-using MediaBrowser.Common.Net;
-using Microsoft.Extensions.Logging;
-using MediaBrowser.Model.Dlna;
-using System.Threading.Tasks;
-
-namespace Mono.Nat
-{
- internal class UpnpSearcher : ISearcher
- {
- public event EventHandler<DeviceEventArgs> DeviceFound;
-
- private readonly ILogger _logger;
- private readonly IHttpClient _httpClient;
-
- public UpnpSearcher(ILogger logger, IHttpClient httpClient)
- {
- _logger = logger;
- _httpClient = httpClient;
- }
-
- public void Search()
- {
- }
-
- public async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
- {
- if (localAddress == null)
- {
- throw new ArgumentNullException(nameof(localAddress));
- }
-
- try
- {
- /* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
- * Any other device type is no good to us for this purpose. See the IGP overview paper
- * page 5 for an overview of device types and their hierarchy.
- * http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */
-
- /* TODO: Currently we are assuming version 1 of the protocol. We should figure out which
- * version it is and apply the correct URN. */
-
- /* Some routers don't correctly implement the version ID on the URN, so we only search for the type
- * prefix. */
-
- // We have an internet gateway device now
- var d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger, _httpClient);
-
- await d.GetServicesList().ConfigureAwait(false);
-
- OnDeviceFound(new DeviceEventArgs(d));
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error decoding device response");
- }
- }
-
- public void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint)
- {
- }
-
- private void OnDeviceFound(DeviceEventArgs args)
- {
- if (DeviceFound != null)
- DeviceFound(this, args);
- }
-
- public NatProtocol Protocol
- {
- get { return NatProtocol.Upnp; }
- }
- }
-}
diff --git a/Mono.Nat/Upnp/UpnpNatDevice.cs b/Mono.Nat/Upnp/UpnpNatDevice.cs
deleted file mode 100644
index fd408ee63..000000000
--- a/Mono.Nat/Upnp/UpnpNatDevice.cs
+++ /dev/null
@@ -1,269 +0,0 @@
-//
-// Authors:
-// Alan McGovern alan.mcgovern@gmail.com
-// Ben Motmans <ben.motmans@gmail.com>
-//
-// Copyright (C) 2006 Alan McGovern
-// 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;
-using System.IO;
-using System.Net;
-using System.Xml;
-using System.Text;
-using System.Diagnostics;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Net;
-using Microsoft.Extensions.Logging;
-using MediaBrowser.Model.Dlna;
-
-namespace Mono.Nat.Upnp
-{
- public sealed class UpnpNatDevice : AbstractNatDevice, IEquatable<UpnpNatDevice>
- {
- private EndPoint hostEndPoint;
- private IPAddress localAddress;
- private string serviceDescriptionUrl;
- private string controlUrl;
- private string serviceType;
- private readonly ILogger _logger;
- private readonly IHttpClient _httpClient;
-
- public override IPAddress LocalAddress
- {
- get { return localAddress; }
- }
-
- internal UpnpNatDevice(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint hostEndPoint, string serviceType, ILogger logger, IHttpClient httpClient)
- {
- if (localAddress == null)
- {
- throw new ArgumentNullException(nameof(localAddress));
- }
-
- this.LastSeen = DateTime.Now;
- this.localAddress = localAddress;
-
- // Split the string at the "location" section so i can extract the ipaddress and service description url
- string locationDetails = deviceInfo.Location.ToString();
- this.serviceType = serviceType;
- _logger = logger;
- _httpClient = httpClient;
-
- // Make sure we have no excess whitespace
- locationDetails = locationDetails.Trim();
-
- // FIXME: Is this reliable enough. What if we get a hostname as opposed to a proper http address
- // Are we going to get addresses with the "http://" attached?
- if (locationDetails.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
- {
- _logger.LogDebug("Found device at: {0}", locationDetails);
- // This bit strings out the "http://" from the string
- locationDetails = locationDetails.Substring(7);
-
- this.hostEndPoint = hostEndPoint;
-
- // 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
- {
- _logger.LogDebug("Couldn't decode address. Please send following string to the developer: ");
- }
- }
-
- public async Task GetServicesList()
- {
- // Create a HTTPWebRequest to download the list of services the device offers
- var message = new GetServicesMessage(this.serviceDescriptionUrl, this.hostEndPoint, _logger);
-
- using (var response = await _httpClient.SendAsync(message.Encode(), message.Method).ConfigureAwait(false))
- {
- OnServicesReceived(response);
- }
- }
-
- private void OnServicesReceived(HttpResponseInfo response)
- {
- int abortCount = 0;
- int bytesRead = 0;
- byte[] buffer = new byte[10240];
- var servicesXml = new StringBuilder();
- var xmldoc = new XmlDocument();
-
- using (var s = response.Content)
- {
- if (response.StatusCode != HttpStatusCode.OK)
- {
- _logger.LogDebug("{0}: Couldn't get services list: {1}", HostEndPoint, response.StatusCode);
- return; // FIXME: This the best thing to do??
- }
-
- while (true)
- {
- bytesRead = s.Read(buffer, 0, buffer.Length);
- servicesXml.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead));
- try
- {
- xmldoc.LoadXml(servicesXml.ToString());
- break;
- }
- catch (XmlException)
- {
- // If we can't receive the entire XML within 500ms, then drop the connection
- // Unfortunately not all routers supply a valid ContentLength (mine doesn't)
- // so this hack is needed to keep testing our recieved data until it gets successfully
- // parsed by the xmldoc. Without this, the code will never pick up my router.
- if (abortCount++ > 50)
- {
- return;
- }
- _logger.LogDebug("{0}: Couldn't parse services list", HostEndPoint);
- System.Threading.Thread.Sleep(10);
- }
- }
-
- var ns = new XmlNamespaceManager(xmldoc.NameTable);
- ns.AddNamespace("ns", "urn:schemas-upnp-org:device-1-0");
- XmlNodeList nodes = xmldoc.SelectNodes("//*/ns:serviceList", ns);
-
- foreach (XmlNode node in nodes)
- {
- //Go through each service there
- foreach (XmlNode service in node.ChildNodes)
- {
- //If the service is a WANIPConnection, then we have what we want
- string type = service["serviceType"].InnerText;
- _logger.LogDebug("{0}: Found service: {1}", HostEndPoint, type);
-
- // TODO: Add support for version 2 of UPnP.
- 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;
- _logger.LogDebug("{0}: Found upnp service at: {1}", HostEndPoint, controlUrl);
-
- Uri u;
- if (Uri.TryCreate(controlUrl, UriKind.RelativeOrAbsolute, out u))
- {
- if (u.IsAbsoluteUri)
- {
- var old = hostEndPoint;
- IPAddress parsedHostIpAddress;
- if (IPAddress.TryParse(u.Host, out parsedHostIpAddress))
- {
- this.hostEndPoint = new IPEndPoint(parsedHostIpAddress, u.Port);
- //_logger.LogDebug("{0}: Absolute URI detected. Host address is now: {1}", old, HostEndPoint);
- this.controlUrl = controlUrl.Substring(u.GetLeftPart(UriPartial.Authority).Length);
- //_logger.LogDebug("{0}: New control url: {1}", HostEndPoint, controlUrl);
- }
- }
- }
- else
- {
- _logger.LogDebug("{0}: Assuming control Uri is relative: {1}", HostEndPoint, controlUrl);
- }
- return;
- }
- }
- }
-
- //If we get here, it means that we didn't get WANIPConnection service, which means no uPnP forwarding
- //So we don't invoke the callback, so this device is never added to our lists
- }
- }
-
- /// <summary>
- /// The EndPoint that the device is at
- /// </summary>
- internal EndPoint HostEndPoint
- {
- get { return this.hostEndPoint; }
- }
-
- /// <summary>
- /// The relative url of the xml file that describes the list of services is at
- /// </summary>
- internal string ServiceDescriptionUrl
- {
- get { return this.serviceDescriptionUrl; }
- }
-
- /// <summary>
- /// The relative url that we can use to control the port forwarding
- /// </summary>
- internal string ControlUrl
- {
- get { return this.controlUrl; }
- }
-
- /// <summary>
- /// The service type we're using on the device
- /// </summary>
- public string ServiceType
- {
- get { return serviceType; }
- }
-
- public override async Task CreatePortMap(Mapping mapping)
- {
- var message = new CreatePortMappingMessage(mapping, localAddress, this);
- using (await _httpClient.SendAsync(message.Encode(), message.Method).ConfigureAwait(false))
- {
-
- }
- }
-
- public override bool Equals(object obj)
- {
- var device = obj as UpnpNatDevice;
- return (device == null) ? false : this.Equals((device));
- }
-
-
- public bool Equals(UpnpNatDevice other)
- {
- return (other == null) ? false : (this.hostEndPoint.Equals(other.hostEndPoint)
- //&& this.controlUrl == other.controlUrl
- && this.serviceDescriptionUrl == other.serviceDescriptionUrl);
- }
-
- public override int GetHashCode()
- {
- return (this.hostEndPoint.GetHashCode() ^ this.controlUrl.GetHashCode() ^ this.serviceDescriptionUrl.GetHashCode());
- }
-
- /// <summary>
- /// Overridden.
- /// </summary>
- /// <returns></returns>
- public override string ToString()
- {
- //GetExternalIP is blocking and can throw exceptions, can't use it here.
- return String.Format(
- "UpnpNatDevice - EndPoint: {0}, External IP: {1}, Control Url: {2}, Service Description Url: {3}, Service Type: {4}, Last Seen: {5}",
- this.hostEndPoint, "Manually Check" /*this.GetExternalIP()*/, this.controlUrl, this.serviceDescriptionUrl, this.serviceType, this.LastSeen);
- }
- }
-}