Răsfoiți Sursa

trim nat project

Luke Pulverenti 8 ani în urmă
părinte
comite
bdcaf5dd02

+ 1 - 3
MediaBrowser.Common.Implementations/Archiving/ZipClient.cs

@@ -6,8 +6,6 @@ using SharpCompress.Common;
 using SharpCompress.Reader;
 using SharpCompress.Reader;
 using SharpCompress.Reader.Zip;
 using SharpCompress.Reader.Zip;
 using System.IO;
 using System.IO;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.IO;
 
 
 namespace MediaBrowser.Common.Implementations.Archiving
 namespace MediaBrowser.Common.Implementations.Archiving
 {
 {
@@ -16,7 +14,7 @@ namespace MediaBrowser.Common.Implementations.Archiving
     /// </summary>
     /// </summary>
     public class ZipClient : IZipClient
     public class ZipClient : IZipClient
     {
     {
-		private IFileSystem _fileSystem;
+		private readonly IFileSystem _fileSystem;
 
 
 		public ZipClient(IFileSystem fileSystem) 
 		public ZipClient(IFileSystem fileSystem) 
 		{
 		{

+ 0 - 19
MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs

@@ -91,9 +91,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             NatUtility.DeviceLost += NatUtility_DeviceLost;
             NatUtility.DeviceLost += NatUtility_DeviceLost;
 
 
 
 
-            // it is hard to say what one should do when an unhandled exception is raised
-            // because there isn't anything one can do about it. Probably save a log or ignored it.
-            NatUtility.UnhandledException += NatUtility_UnhandledException;
             NatUtility.StartDiscovery();
             NatUtility.StartDiscovery();
 
 
             _timer = new PeriodicTimer(ClearCreatedRules, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
             _timer = new PeriodicTimer(ClearCreatedRules, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
@@ -184,21 +181,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             }
             }
         }
         }
 
 
-        void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e)
-        {
-            var ex = e.ExceptionObject as Exception;
-
-            if (ex == null)
-            {
-                //_logger.Error("Unidentified error reported by Mono.Nat");
-            }
-            else
-            {
-                // Seeing some blank exceptions coming through here
-                //_logger.ErrorException("Error reported by Mono.Nat: ", ex);
-            }
-        }
-
         void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
         void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
         {
         {
             try
             try
@@ -287,7 +269,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
                 NatUtility.StopDiscovery();
                 NatUtility.StopDiscovery();
                 NatUtility.DeviceFound -= NatUtility_DeviceFound;
                 NatUtility.DeviceFound -= NatUtility_DeviceFound;
                 NatUtility.DeviceLost -= NatUtility_DeviceLost;
                 NatUtility.DeviceLost -= NatUtility_DeviceLost;
-                NatUtility.UnhandledException -= NatUtility_UnhandledException;
             }
             }
             // Statements in try-block will no fail because StopDiscovery is a one-line 
             // Statements in try-block will no fail because StopDiscovery is a one-line 
             // method that was no chances to fail.
             // method that was no chances to fail.

+ 0 - 38
Mono.Nat/AbstractNatDevice.cs

@@ -52,43 +52,5 @@ namespace Mono.Nat
 		}
 		}
 
 
 	    public abstract Task CreatePortMap(Mapping mapping);
 	    public abstract Task CreatePortMap(Mapping mapping);
-
-		public virtual void DeletePortMap (Mapping mapping)
-		{
-			IAsyncResult result = BeginDeletePortMap (mapping, null, mapping);
-			EndDeletePortMap(result);
-		}
-
-		public virtual Mapping[] GetAllMappings ()
-		{
-			IAsyncResult result = BeginGetAllMappings (null, null);
-			return EndGetAllMappings (result);
-		}
-
-		public virtual IPAddress GetExternalIP ()
-		{
-			IAsyncResult result = BeginGetExternalIP(null, null);
-			return EndGetExternalIP(result);
-		}
-
-		public virtual Mapping GetSpecificMapping (Protocol protocol, int port)
-		{
-			IAsyncResult result = this.BeginGetSpecificMapping (protocol, port, null, null);
-			return this.EndGetSpecificMapping(result);
-		}
-
-        public abstract IAsyncResult BeginCreatePortMap(Mapping mapping, AsyncCallback callback, object asyncState);
-		public abstract IAsyncResult BeginDeletePortMap (Mapping mapping, AsyncCallback callback, object asyncState);
-		
-		public abstract IAsyncResult BeginGetAllMappings (AsyncCallback callback, object asyncState);
-		public abstract IAsyncResult BeginGetExternalIP (AsyncCallback callback, object asyncState);
-        public abstract IAsyncResult BeginGetSpecificMapping(Protocol protocol, int externalPort, AsyncCallback callback, object asyncState);
-
-		public abstract void EndCreatePortMap (IAsyncResult result);
-		public abstract void EndDeletePortMap (IAsyncResult result);
-		
-		public abstract Mapping[] EndGetAllMappings (IAsyncResult result);
-		public abstract IPAddress EndGetExternalIP (IAsyncResult result);
-		public abstract Mapping EndGetSpecificMapping (IAsyncResult result);
 	}
 	}
 }
 }

+ 0 - 18
Mono.Nat/INatDevice.cs

@@ -37,26 +37,8 @@ namespace Mono.Nat
 	public interface INatDevice
 	public interface INatDevice
 	{
 	{
 		Task CreatePortMap (Mapping mapping);
 		Task CreatePortMap (Mapping mapping);
-		void DeletePortMap (Mapping mapping);
 		
 		
 		IPAddress LocalAddress { get; }
 		IPAddress LocalAddress { get; }
-		Mapping[] GetAllMappings ();
-		IPAddress GetExternalIP ();
-		Mapping GetSpecificMapping (Protocol protocol, int port);
-
-		IAsyncResult BeginCreatePortMap (Mapping mapping, AsyncCallback callback, object asyncState);
-		IAsyncResult BeginDeletePortMap (Mapping mapping, AsyncCallback callback, object asyncState);
-
-		IAsyncResult BeginGetAllMappings (AsyncCallback callback, object asyncState);
-		IAsyncResult BeginGetExternalIP (AsyncCallback callback, object asyncState);
-		IAsyncResult BeginGetSpecificMapping (Protocol protocol, int externalPort, AsyncCallback callback, object asyncState);
-
-		void EndCreatePortMap (IAsyncResult result);
-		void EndDeletePortMap (IAsyncResult result);
-
-		Mapping[] EndGetAllMappings (IAsyncResult result);
-		IPAddress EndGetExternalIP (IAsyncResult result);
-		Mapping EndGetSpecificMapping (IAsyncResult result);
 
 
 		DateTime LastSeen { get; set; }
 		DateTime LastSeen { get; set; }
 	}
 	}

+ 3 - 9
Mono.Nat/Mono.Nat.csproj

@@ -56,20 +56,11 @@
     <Compile Include="Pmp\PmpNatDevice.cs" />
     <Compile Include="Pmp\PmpNatDevice.cs" />
     <Compile Include="Pmp\Searchers\PmpSearcher.cs" />
     <Compile Include="Pmp\Searchers\PmpSearcher.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Upnp\AsyncResults\GetAllMappingsAsyncResult.cs" />
-    <Compile Include="Upnp\AsyncResults\PortMapAsyncResult.cs" />
     <Compile Include="Upnp\Messages\DiscoverDeviceMessage.cs" />
     <Compile Include="Upnp\Messages\DiscoverDeviceMessage.cs" />
     <Compile Include="Upnp\Messages\ErrorMessage.cs" />
     <Compile Include="Upnp\Messages\ErrorMessage.cs" />
     <Compile Include="Upnp\Messages\GetServicesMessage.cs" />
     <Compile Include="Upnp\Messages\GetServicesMessage.cs" />
     <Compile Include="Upnp\Messages\Requests\CreatePortMappingMessage.cs" />
     <Compile Include="Upnp\Messages\Requests\CreatePortMappingMessage.cs" />
-    <Compile Include="Upnp\Messages\Requests\DeletePortMappingMessage.cs" />
-    <Compile Include="Upnp\Messages\Requests\GetExternalIPAddressMessage.cs" />
-    <Compile Include="Upnp\Messages\Requests\GetGenericPortMappingEntry.cs" />
-    <Compile Include="Upnp\Messages\Requests\GetSpecificPortMappingEntryMessage.cs" />
     <Compile Include="Upnp\Messages\Responses\CreatePortMappingResponseMessage.cs" />
     <Compile Include="Upnp\Messages\Responses\CreatePortMappingResponseMessage.cs" />
-    <Compile Include="Upnp\Messages\Responses\DeletePortMappingResponseMessage.cs" />
-    <Compile Include="Upnp\Messages\Responses\GetExternalIPAddressResponseMessage.cs" />
-    <Compile Include="Upnp\Messages\Responses\GetGenericPortMappingEntryResponseMessage.cs" />
     <Compile Include="Upnp\Messages\UpnpMessage.cs" />
     <Compile Include="Upnp\Messages\UpnpMessage.cs" />
     <Compile Include="Upnp\Searchers\UpnpSearcher.cs" />
     <Compile Include="Upnp\Searchers\UpnpSearcher.cs" />
     <Compile Include="Upnp\Upnp.cs" />
     <Compile Include="Upnp\Upnp.cs" />
@@ -89,6 +80,9 @@
       <Name>MediaBrowser.Model</Name>
       <Name>MediaBrowser.Model</Name>
     </ProjectReference>
     </ProjectReference>
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Upnp\AsyncResults\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   <!-- 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.
        Other similar extension points exist, see Microsoft.Common.targets.

+ 9 - 10
Mono.Nat/NatUtility.cs

@@ -34,6 +34,7 @@ using System.Linq;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;
 using System.Net.NetworkInformation;
 using System.Net.NetworkInformation;
+using System.Threading.Tasks;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
@@ -46,8 +47,6 @@ namespace Mono.Nat
 		public static event EventHandler<DeviceEventArgs> DeviceFound;
 		public static event EventHandler<DeviceEventArgs> DeviceFound;
 		public static event EventHandler<DeviceEventArgs> DeviceLost;
 		public static event EventHandler<DeviceEventArgs> DeviceLost;
         
         
-        public static event EventHandler<UnhandledExceptionEventArgs> UnhandledException;
-
 		private static List<ISearcher> controllers;
 		private static List<ISearcher> controllers;
 		private static bool verbose;
 		private static bool verbose;
 
 
@@ -87,9 +86,8 @@ namespace Mono.Nat
                             DeviceLost(sender, args);
                             DeviceLost(sender, args);
                     };
                     };
                 });
                 });
-            Thread t = new Thread(SearchAndListen);
-            t.IsBackground = true;
-            t.Start();
+
+            Task.Factory.StartNew(SearchAndListen, TaskCreationOptions.LongRunning);
         }
         }
 
 
 		internal static void Log(string format, params object[] args)
 		internal static void Log(string format, params object[] args)
@@ -99,7 +97,7 @@ namespace Mono.Nat
 		        logger.Debug(format, args);
 		        logger.Debug(format, args);
 		}
 		}
 
 
-        private static void SearchAndListen()
+        private static async Task SearchAndListen()
         {
         {
             while (true)
             while (true)
             {
             {
@@ -115,18 +113,19 @@ namespace Mono.Nat
                     }
                     }
 
 
                     foreach (ISearcher s in controllers)
                     foreach (ISearcher s in controllers)
+                    {
                         if (s.NextSearch < DateTime.Now && enabledProtocols.Contains(s.Protocol))
                         if (s.NextSearch < DateTime.Now && enabledProtocols.Contains(s.Protocol))
                         {
                         {
                             Log("Searching for: {0}", s.GetType().Name);
                             Log("Searching for: {0}", s.GetType().Name);
-							s.Search();
+                            s.Search();
                         }
                         }
+                    }
                 }
                 }
                 catch (Exception e)
                 catch (Exception e)
                 {
                 {
-                    if (UnhandledException != null)
-                        UnhandledException(typeof(NatUtility), new UnhandledExceptionEventArgs(e, false));
+                    
                 }
                 }
-				Thread.Sleep(10);
+                await Task.Delay(100).ConfigureAwait(false);
             }
             }
 		}
 		}
 
 

+ 127 - 195
Mono.Nat/Pmp/PmpNatDevice.cs

@@ -34,234 +34,166 @@ using System.Threading.Tasks;
 
 
 namespace Mono.Nat.Pmp
 namespace Mono.Nat.Pmp
 {
 {
-	internal sealed class PmpNatDevice : AbstractNatDevice, IEquatable<PmpNatDevice> 
-	{
-        private AsyncResult externalIpResult;
-        private bool pendingOp;
-		private IPAddress localAddress;
-		private IPAddress publicAddress;
-		
-		internal PmpNatDevice (IPAddress localAddress, IPAddress publicAddress)
-		{
-			this.localAddress = localAddress;
-			this.publicAddress = publicAddress;
-		}
-		
-		public override IPAddress LocalAddress
-		{
-			get { return localAddress; }
-		}
+    internal sealed class PmpNatDevice : AbstractNatDevice, IEquatable<PmpNatDevice>
+    {
+        private IPAddress localAddress;
+        private IPAddress publicAddress;
 
 
-	    public override Task CreatePortMap(Mapping mapping)
-	    {
-            CreatePortMap(mapping, true);
-	        return Task.FromResult(true);
-	    }
-
-        private void StartOp(ref AsyncResult result, AsyncCallback callback, object asyncState)
+        internal PmpNatDevice(IPAddress localAddress, IPAddress publicAddress)
         {
         {
-            if (pendingOp == true)
-                throw new InvalidOperationException("Can only have one simultaenous async operation");
-
-            pendingOp = true;
-            result = new AsyncResult(callback, asyncState);
+            this.localAddress = localAddress;
+            this.publicAddress = publicAddress;
         }
         }
 
 
-        private void EndOp(IAsyncResult supplied, ref AsyncResult actual)
+        public override IPAddress LocalAddress
         {
         {
-            if (supplied == null)
-                throw new ArgumentNullException("result");
+            get { return localAddress; }
+        }
 
 
-            if (supplied != actual)
-                throw new ArgumentException("Supplied IAsyncResult does not match the stored result");
+        public override Task CreatePortMap(Mapping mapping)
+        {
+            return InternalCreatePortMapAsync(mapping, true);
+        }
 
 
-            if (!supplied.IsCompleted)
-                supplied.AsyncWaitHandle.WaitOne();
+        public override bool Equals(object obj)
+        {
+            PmpNatDevice device = obj as PmpNatDevice;
+            return (device == null) ? false : this.Equals(device);
+        }
 
 
-            if (actual.StoredException != null)
-                throw actual.StoredException;
+        public override int GetHashCode()
+        {
+            return this.publicAddress.GetHashCode();
+        }
 
 
-            pendingOp = false;
-            actual = null;
+        public bool Equals(PmpNatDevice other)
+        {
+            return (other == null) ? false : this.publicAddress.Equals(other.publicAddress);
         }
         }
-		
-		public override bool Equals(object obj)
-		{
-			PmpNatDevice 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;
 
 
-		private Mapping CreatePortMap (Mapping mapping, bool create)
-		{
-			List<byte> package = new List<byte> ();
-			
-			package.Add (PmpConstants.Version);
-			package.Add (mapping.Protocol == Protocol.Tcp ? PmpConstants.OperationCodeTcp : PmpConstants.OperationCodeUdp);
-			package.Add ((byte)0); //reserved
-			package.Add ((byte)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)));
+                using (var udpClient = new UdpClient())
+                {
+                    var cancellationTokenSource = new CancellationTokenSource();
 
 
-			CreatePortMapAsyncState state = new CreatePortMapAsyncState ();
-			state.Buffer = package.ToArray ();
-			state.Mapping = mapping;
+                    while (attempt < PmpConstants.RetryAttempts)
+                    {
+                        await udpClient.SendAsync(buffer, buffer.Length,
+                                new IPEndPoint(LocalAddress, PmpConstants.ServerPort));
 
 
-			ThreadPool.QueueUserWorkItem (new WaitCallback (CreatePortMapAsync), state);
-			WaitHandle.WaitAll (new WaitHandle[] {state.ResetEvent});
-			
-			if (!state.Success) {
-				string type = create ? "create" : "delete";
-				throw new MappingException (String.Format ("Failed to {0} portmap (protocol={1}, private port={2}", type, mapping.Protocol, mapping.PrivatePort));
-			}
-			
-			return state.Mapping;
-		}
-		
-		private void CreatePortMapAsync (object obj)
-		{
-			CreatePortMapAsyncState state = obj as CreatePortMapAsyncState;
-			
-			UdpClient udpClient = new UdpClient ();
-			CreatePortMapListenState listenState = new CreatePortMapListenState (state, udpClient);
+                        if (attempt == 0)
+                        {
+                            Task.Run(() => CreatePortMapListen(udpClient, mapping, cancellationTokenSource.Token));
+                        }
 
 
-			int attempt = 0;
-			int delay = PmpConstants.RetryDelay;
-			
-			ThreadPool.QueueUserWorkItem (new WaitCallback (CreatePortMapListen), listenState);
+                        attempt++;
+                        delay *= 2;
+                        await Task.Delay(delay).ConfigureAwait(false);
+                    }
 
 
-			while (attempt < PmpConstants.RetryAttempts && !listenState.Success) {
-				udpClient.Send (state.Buffer, state.Buffer.Length, new IPEndPoint (localAddress, PmpConstants.ServerPort));
-                listenState.UdpClientReady.Set();
+                    cancellationTokenSource.Cancel();
+                }
+            }
+            catch (OperationCanceledException)
+            {
 
 
-				attempt++;
-				delay *= 2;
-				Thread.Sleep (delay);
-			}
-			
-			state.Success = listenState.Success;
-			
-			udpClient.Close ();
-			state.ResetEvent.Set ();
-		}
-		
-		private void CreatePortMapListen (object obj)
-		{
-			CreatePortMapListenState state = obj as CreatePortMapListenState;
+            }
+            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);
+                NatUtility.Log(message);
+                var pmpException = e as MappingException;
+                throw new MappingException(message, pmpException);
+            }
+
+            return mapping;
+        }
 
 
-            UdpClient udpClient = state.UdpClient;
-            state.UdpClientReady.WaitOne(); // Evidently UdpClient has some lazy-init Send/Receive race?
-			IPEndPoint endPoint = new IPEndPoint (localAddress, PmpConstants.ServerPort);
-			
-			while (!state.Success) 
+        private async void CreatePortMapListen(UdpClient udpClient, Mapping mapping, CancellationToken cancellationToken)
+        {
+            while (!cancellationToken.IsCancellationRequested)
             {
             {
-                byte[] data;
-                try
-                {
-                    data = udpClient.Receive(ref endPoint);
-                }
-                catch (SocketException)
-                {
-                    state.Success = false;
-                    return;
-                }
+                var result = await udpClient.ReceiveAsync().ConfigureAwait(false);
+                var endPoint = result.RemoteEndPoint;
+                byte[] data = data = result.Buffer;
 
 
-                catch (ObjectDisposedException)
-                {
-                    state.Success = false;
-                    return;
-                }
-			
-				if (data.Length < 16)
-					continue;
+                if (data.Length < 16)
+                    continue;
 
 
-				if (data[0] != PmpConstants.Version)
-					continue;
-			
-				byte opCode = (byte)(data[1] & (byte)127);
-				
-				Protocol protocol = Protocol.Tcp;
-				if (opCode == PmpConstants.OperationCodeUdp)
-					protocol = Protocol.Udp;
+                if (data[0] != PmpConstants.Version)
+                    continue;
 
 
-				short resultCode = IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, 2));
-				uint epoch = (uint)IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (data, 4));
+                var opCode = (byte)(data[1] & 127);
 
 
-				int privatePort = IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, 8));
-				int publicPort = IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, 10));
+                var protocol = Protocol.Tcp;
+                if (opCode == PmpConstants.OperationCodeUdp)
+                    protocol = Protocol.Udp;
 
 
-				uint lifetime = (uint)IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (data, 12));
+                short resultCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 2));
+                int epoch = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));
 
 
-				if (publicPort < 0 || privatePort < 0 || resultCode != PmpConstants.ResultCodeSuccess)
-                {
-					state.Success = false;
-					return;
-				}
-				
-				if (lifetime == 0) 
-                {
-					//mapping was deleted
-					state.Success = true;
-					state.Mapping = null;
-					return;
-				} 
-                else 
+                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)
                 {
                 {
-					//mapping was created
-					//TODO: verify that the private port+protocol are a match
-					Mapping mapping = state.Mapping;
-					mapping.PublicPort = publicPort;
-                    mapping.Protocol = protocol;
-					mapping.Expiration = DateTime.Now.AddSeconds (lifetime);
+                    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"
+                                     };
+                    throw new MappingException(resultCode, errors[resultCode]);
+                }
 
 
-					state.Success = true;
-				}
-			}
-		}
+                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;
+            }
+        }
 
 
         /// <summary>
         /// <summary>
         /// Overridden.
         /// Overridden.
         /// </summary>
         /// </summary>
         /// <returns></returns>
         /// <returns></returns>
-        public override string ToString( )
+        public override string ToString()
         {
         {
-            return String.Format( "PmpNatDevice - Local Address: {0}, Public IP: {1}, Last Seen: {2}",
-                this.localAddress, this.publicAddress, this.LastSeen );
+            return String.Format("PmpNatDevice - Local Address: {0}, Public IP: {1}, Last Seen: {2}",
+                this.localAddress, this.publicAddress, this.LastSeen);
         }
         }
-
-
-		private class CreatePortMapAsyncState
-		{
-			internal byte[] Buffer;
-			internal ManualResetEvent ResetEvent = new ManualResetEvent (false);
-			internal Mapping Mapping;
-			
-			internal bool Success;
-		}
-		
-		private class CreatePortMapListenState
-		{
-			internal volatile bool Success;
-			internal Mapping Mapping;
-            internal UdpClient UdpClient;
-            internal ManualResetEvent UdpClientReady;
-			
-			internal CreatePortMapListenState (CreatePortMapAsyncState state, UdpClient client)
-			{
-                Mapping = state.Mapping;
-                UdpClient = client; UdpClientReady = new ManualResetEvent(false);
-			}
-		}
-	}
+    }
 }
 }

+ 0 - 56
Mono.Nat/Upnp/AsyncResults/GetAllMappingsAsyncResult.cs

@@ -1,56 +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.Collections.Generic;
-using System.Text;
-using System.Net;
-
-namespace Mono.Nat.Upnp
-{
-	internal class GetAllMappingsAsyncResult : PortMapAsyncResult
-	{
-		private List<Mapping> mappings;
-		private Mapping specificMapping;
-		
-		public GetAllMappingsAsyncResult(WebRequest request, AsyncCallback callback, object asyncState)
-			: base(request, callback, asyncState)
-		{
-			mappings = new List<Mapping>();
-		}
-
-		public List<Mapping> Mappings
-		{
-			get { return this.mappings; }
-		}
-
-		public Mapping SpecificMapping
-		{
-			get { return this.specificMapping; }
-			set { this.specificMapping = value; }
-		}
-	}
-}

+ 0 - 75
Mono.Nat/Upnp/AsyncResults/PortMapAsyncResult.cs

@@ -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;
-using System.Net;
-using System.Threading;
-
-namespace Mono.Nat.Upnp
-{
-	internal class PortMapAsyncResult : AsyncResult
-	{
-		private WebRequest request;
-		private MessageBase savedMessage;
-		
-		protected PortMapAsyncResult(WebRequest request, AsyncCallback callback, object asyncState)
-			: base (callback, asyncState)
-		{
-			this.request = request;
-		}
-		
-		internal WebRequest Request
-		{
-			get { return this.request; }
-			set { this.request = value; }
-		}
-
-		internal MessageBase SavedMessage
-		{
-			get { return this.savedMessage; }
-			set { this.savedMessage = value; }
-		}
-
-		internal static PortMapAsyncResult Create (MessageBase message, WebRequest request, AsyncCallback storedCallback, object asyncState)
-		{
-			if (message is GetGenericPortMappingEntry)
-				return new GetAllMappingsAsyncResult(request, storedCallback, asyncState);
-
-			if (message is GetSpecificPortMappingEntryMessage)
-			{
-				GetSpecificPortMappingEntryMessage mapMessage = (GetSpecificPortMappingEntryMessage)message;
-				GetAllMappingsAsyncResult result = new GetAllMappingsAsyncResult(request, storedCallback, asyncState);
-				
-				result.SpecificMapping = new Mapping(mapMessage.protocol, 0, mapMessage.externalPort, 0);
-				return result;
-			}
-
-			return new PortMapAsyncResult(request, storedCallback, asyncState);
-		}
-	}
-}

+ 0 - 5
Mono.Nat/Upnp/Messages/ErrorMessage.cs

@@ -59,10 +59,5 @@ namespace Mono.Nat.Upnp
         {
         {
             throw new NotImplementedException();
             throw new NotImplementedException();
         }
         }
-
-        public override System.Net.WebRequest Encode(out byte[] body)
-        {
-            throw new NotImplementedException();
-        }
     }
     }
 }
 }

+ 0 - 11
Mono.Nat/Upnp/Messages/GetServicesMessage.cs

@@ -60,17 +60,6 @@ namespace Mono.Nat.Upnp
             }
             }
         }
         }
 
 
-        public override WebRequest Encode(out byte[] body)
-        {
-            HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://" + this.hostAddress.ToString() + this.servicesDescriptionUrl);
-            req.Headers.Add("ACCEPT-LANGUAGE", "en");
-            req.Method = "GET";
-
-            body = new byte[0];
-            return req;
-        }
-
-
         public override HttpRequestOptions Encode()
         public override HttpRequestOptions Encode()
         {
         {
             var req = new HttpRequestOptions();
             var req = new HttpRequestOptions();

+ 0 - 20
Mono.Nat/Upnp/Messages/Requests/CreatePortMappingMessage.cs

@@ -71,25 +71,5 @@ namespace Mono.Nat.Upnp
             writer.Flush();
             writer.Flush();
             return CreateRequest("AddPortMapping", builder.ToString());
             return CreateRequest("AddPortMapping", builder.ToString());
         }
         }
-
-        public override WebRequest Encode(out byte[] body)
-        {
-            CultureInfo culture = CultureInfo.InvariantCulture;
-
-            StringBuilder 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(), out body);
-        }
     }
     }
 }
 }

+ 0 - 71
Mono.Nat/Upnp/Messages/Requests/DeletePortMappingMessage.cs

@@ -1,71 +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.Text;
-using System.Xml;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
-	internal class DeletePortMappingMessage : MessageBase
-	{
-		private Mapping mapping;
-
-		public DeletePortMappingMessage(Mapping mapping, UpnpNatDevice device)
-			: base(device)
-		{
-			this.mapping = mapping;
-		}
-
-	    public override HttpRequestOptions Encode()
-	    {
-            StringBuilder builder = new StringBuilder(256);
-            XmlWriter writer = CreateWriter(builder);
-
-            WriteFullElement(writer, "NewRemoteHost", string.Empty);
-            WriteFullElement(writer, "NewExternalPort", mapping.PublicPort.ToString(MessageBase.Culture));
-            WriteFullElement(writer, "NewProtocol", mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP");
-
-            writer.Flush();
-            return CreateRequest("DeletePortMapping", builder.ToString());
-        }
-
-        public override WebRequest Encode(out byte[] body)
-		{
-			StringBuilder builder = new StringBuilder(256);
-			XmlWriter writer = CreateWriter(builder);
-
-			WriteFullElement(writer, "NewRemoteHost", string.Empty);
-			WriteFullElement(writer, "NewExternalPort", mapping.PublicPort.ToString(MessageBase.Culture));
-			WriteFullElement(writer, "NewProtocol", mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP");
-
-			writer.Flush();
-			return CreateRequest("DeletePortMapping", builder.ToString(), out body);
-		}
-	}
-}

+ 0 - 56
Mono.Nat/Upnp/Messages/Requests/GetExternalIPAddressMessage.cs

@@ -1,56 +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.Collections.Generic;
-using System.Text;
-using System.Net;
-using System.IO;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
-    internal class GetExternalIPAddressMessage : MessageBase
-    {
-
-        #region Constructors
-        public GetExternalIPAddressMessage(UpnpNatDevice device)
-            :base(device)
-        {
-        }
-        #endregion
-
-        public override HttpRequestOptions Encode()
-        {
-            return CreateRequest("GetExternalIPAddress", string.Empty);
-        }
-
-        public override WebRequest Encode(out byte[] body)
-        {
-            return CreateRequest("GetExternalIPAddress", string.Empty, out body);
-        }
-    }
-}

+ 0 - 67
Mono.Nat/Upnp/Messages/Requests/GetGenericPortMappingEntry.cs

@@ -1,67 +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.Collections.Generic;
-using System.Text;
-using System.Xml;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
-    internal class GetGenericPortMappingEntry : MessageBase
-    {
-        private int index;
-
-        public GetGenericPortMappingEntry(int index, UpnpNatDevice device)
-            :base(device)
-        {
-            this.index = index;
-        }
-
-        public override HttpRequestOptions Encode()
-        {
-            StringBuilder sb = new StringBuilder(128);
-            XmlWriter writer = CreateWriter(sb);
-
-            WriteFullElement(writer, "NewPortMappingIndex", index.ToString());
-
-            writer.Flush();
-            return CreateRequest("GetGenericPortMappingEntry", sb.ToString());
-        }
-
-        public override System.Net.WebRequest Encode(out byte[] body)
-        {
-            StringBuilder sb = new StringBuilder(128);
-            XmlWriter writer = CreateWriter(sb);
-
-            WriteFullElement(writer, "NewPortMappingIndex", index.ToString());
-
-            writer.Flush();
-            return CreateRequest("GetGenericPortMappingEntry", sb.ToString(), out body);
-        }
-    }
-}

+ 0 - 74
Mono.Nat/Upnp/Messages/Requests/GetSpecificPortMappingEntryMessage.cs

@@ -1,74 +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.Collections.Generic;
-using System.Text;
-using System.Xml;
-using System.Net;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
-	internal class GetSpecificPortMappingEntryMessage : MessageBase
-	{
-		internal Protocol protocol;
-		internal int externalPort;
-
-		public GetSpecificPortMappingEntryMessage(Protocol protocol, int externalPort, UpnpNatDevice device)
-			: base(device)
-		{
-			this.protocol = protocol;
-			this.externalPort = externalPort;
-		}
-
-		public override WebRequest Encode(out byte[] body)
-		{
-			StringBuilder sb = new StringBuilder(64);
-			XmlWriter writer = CreateWriter(sb);
-
-			WriteFullElement(writer, "NewRemoteHost", string.Empty);
-			WriteFullElement(writer, "NewExternalPort", externalPort.ToString());
-			WriteFullElement(writer, "NewProtocol", protocol == Protocol.Tcp ? "TCP" : "UDP");
-			writer.Flush();
-
-			return CreateRequest("GetSpecificPortMappingEntry", sb.ToString(), out body);
-        }
-
-        public override HttpRequestOptions Encode()
-        {
-            StringBuilder sb = new StringBuilder(64);
-            XmlWriter writer = CreateWriter(sb);
-
-            WriteFullElement(writer, "NewRemoteHost", string.Empty);
-            WriteFullElement(writer, "NewExternalPort", externalPort.ToString());
-            WriteFullElement(writer, "NewProtocol", protocol == Protocol.Tcp ? "TCP" : "UDP");
-            writer.Flush();
-
-            return CreateRequest("GetSpecificPortMappingEntry", sb.ToString());
-        }
-    }
-}

+ 0 - 5
Mono.Nat/Upnp/Messages/Responses/CreatePortMappingResponseMessage.cs

@@ -44,10 +44,5 @@ namespace Mono.Nat.Upnp
         {
         {
             throw new NotImplementedException();
             throw new NotImplementedException();
         }
         }
-
-        public override System.Net.WebRequest Encode(out byte[] body)
-        {
-            throw new NotImplementedException();
-        }
     }
     }
 }
 }

+ 0 - 51
Mono.Nat/Upnp/Messages/Responses/DeletePortMappingResponseMessage.cs

@@ -1,51 +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 DeletePortMapResponseMessage : MessageBase
-    {
-        public DeletePortMapResponseMessage()
-            :base(null)
-        {
-        }
-
-        public override HttpRequestOptions Encode()
-        {
-            throw new NotSupportedException();
-        }
-
-        public override System.Net.WebRequest Encode(out byte[] body)
-        {
-            throw new NotSupportedException();
-        }
-    }
-}

+ 0 - 59
Mono.Nat/Upnp/Messages/Responses/GetExternalIPAddressResponseMessage.cs

@@ -1,59 +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.Collections.Generic;
-using System.Text;
-using System.Net;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
-    internal class GetExternalIPAddressResponseMessage : MessageBase
-    {
-        public IPAddress ExternalIPAddress
-        {
-            get { return this.externalIPAddress; }
-        }
-        private IPAddress externalIPAddress;
-
-        public GetExternalIPAddressResponseMessage(string ip)
-            :base(null)
-        {
-            this.externalIPAddress = IPAddress.Parse(ip);
-        }
-
-        public override HttpRequestOptions Encode()
-        {
-            throw new NotImplementedException();
-        }
-
-        public override WebRequest Encode(out byte[] body)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}

+ 0 - 114
Mono.Nat/Upnp/Messages/Responses/GetGenericPortMappingEntryResponseMessage.cs

@@ -1,114 +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.Collections.Generic;
-using System.Text;
-using System.Xml;
-using MediaBrowser.Common.Net;
-
-namespace Mono.Nat.Upnp
-{
-    internal class GetGenericPortMappingEntryResponseMessage : MessageBase
-    {
-        private string remoteHost;
-        private int externalPort;
-        private Protocol protocol;
-        private int internalPort;
-        private string internalClient;
-        private bool enabled;
-        private string portMappingDescription;
-        private int leaseDuration;
-
-        public string RemoteHost
-        {
-            get { return this.remoteHost; }
-        }
-
-        public int ExternalPort
-        {
-            get { return this.externalPort; }
-        }
-
-        public Protocol Protocol
-        {
-            get { return this.protocol; }
-        }
-
-        public int InternalPort
-        {
-            get { return this.internalPort; }
-        }
-
-        public string InternalClient
-        {
-            get { return this.internalClient; }
-        }
-
-        public bool Enabled
-        {
-            get { return this.enabled; }
-        }
-
-        public string PortMappingDescription
-        {
-            get { return this.portMappingDescription; }
-        }
-
-        public int LeaseDuration
-        {
-            get { return this.leaseDuration; }
-        }
-
-
-        public GetGenericPortMappingEntryResponseMessage(XmlNode data, bool genericMapping)
-            : base(null)
-        {
-            remoteHost = (genericMapping) ? data["NewRemoteHost"].InnerText : string.Empty;
-            externalPort = (genericMapping) ? Convert.ToInt32(data["NewExternalPort"].InnerText) : -1;
-            if (genericMapping)
-                protocol = data["NewProtocol"].InnerText.Equals("TCP", StringComparison.InvariantCultureIgnoreCase) ? Protocol.Tcp : Protocol.Udp;
-            else
-                protocol = Protocol.Udp;
-
-            internalPort = Convert.ToInt32(data["NewInternalPort"].InnerText);
-            internalClient = data["NewInternalClient"].InnerText;
-            enabled = data["NewEnabled"].InnerText == "1" ? true : false;
-            portMappingDescription = data["NewPortMappingDescription"].InnerText;
-            leaseDuration = Convert.ToInt32(data["NewLeaseDuration"].InnerText);
-        }
-
-        public override HttpRequestOptions Encode()
-        {
-            throw new NotImplementedException();
-        }
-
-        public override System.Net.WebRequest Encode(out byte[] body)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}

+ 0 - 70
Mono.Nat/Upnp/Messages/UpnpMessage.cs

@@ -45,33 +45,6 @@ namespace Mono.Nat.Upnp
             this.device = device;
             this.device = device;
         }
         }
 
 
-        protected WebRequest CreateRequest(string upnpMethod, string methodParameters, out byte[] body)
-        {
-            string ss = "http://" + this.device.HostEndPoint.ToString() + this.device.ControlUrl;
-            NatUtility.Log("Initiating request to: {0}", ss);
-            Uri location = new Uri(ss);
-
-            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(location);
-            req.KeepAlive = false;
-            req.Method = "POST";
-            req.ContentType = "text/xml; charset=\"utf-8\"";
-            req.Headers.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";
-
-			body = System.Text.Encoding.UTF8.GetBytes(bodyString);
-            return req;
-        }
-
         protected HttpRequestOptions CreateRequest(string upnpMethod, string methodParameters)
         protected HttpRequestOptions CreateRequest(string upnpMethod, string methodParameters)
         {
         {
             string ss = "http://" + this.device.HostEndPoint.ToString() + this.device.ControlUrl;
             string ss = "http://" + this.device.HostEndPoint.ToString() + this.device.ControlUrl;
@@ -98,50 +71,7 @@ namespace Mono.Nat.Upnp
             return req;
             return req;
         }
         }
 
 
-        public static MessageBase Decode(UpnpNatDevice device, string message)
-        {
-            XmlNode node;
-            XmlDocument doc = new XmlDocument();
-            doc.LoadXml(message);
-
-            XmlNamespaceManager nsm = new XmlNamespaceManager(doc.NameTable);
-
-            // Error messages should be found under this namespace
-            nsm.AddNamespace("errorNs", "urn:schemas-upnp-org:control-1-0");
-            nsm.AddNamespace("responseNs", device.ServiceType);
-
-            // Check to see if we have a fault code message.
-			if ((node = doc.SelectSingleNode("//errorNs:UPnPError", nsm)) != null) {
-				string errorCode = node["errorCode"] != null ? node["errorCode"].InnerText : "";
-				string errorDescription = node["errorDescription"] != null ? node["errorDescription"].InnerText : "";
-
-				return new ErrorMessage(Convert.ToInt32(errorCode, CultureInfo.InvariantCulture), errorDescription);
-			}
-
-	        if ((doc.SelectSingleNode("//responseNs:AddPortMappingResponse", nsm)) != null)
-                return new CreatePortMappingResponseMessage();
-
-            if ((doc.SelectSingleNode("//responseNs:DeletePortMappingResponse", nsm)) != null)
-                return new DeletePortMapResponseMessage();
-
-			if ((node = doc.SelectSingleNode("//responseNs:GetExternalIPAddressResponse", nsm)) != null) {
-				string newExternalIPAddress = node["NewExternalIPAddress"] != null ? node["NewExternalIPAddress"].InnerText : "";
-				return new GetExternalIPAddressResponseMessage(newExternalIPAddress);
-			}
-
-	        if ((node = doc.SelectSingleNode("//responseNs:GetGenericPortMappingEntryResponse", nsm)) != null)
-                return new GetGenericPortMappingEntryResponseMessage(node, true);
-
-            if ((node = doc.SelectSingleNode("//responseNs:GetSpecificPortMappingEntryResponse", nsm)) != null)
-                return new GetGenericPortMappingEntryResponseMessage(node, false);
-
-            NatUtility.Log("Unknown message returned. Please send me back the following XML:");
-            NatUtility.Log(message);
-            return null;
-        }
-
         public abstract HttpRequestOptions Encode();
         public abstract HttpRequestOptions Encode();
-        public abstract WebRequest Encode(out byte[] body);
 
 
         public virtual string Method
         public virtual string Method
         {
         {

+ 3 - 430
Mono.Nat/Upnp/UpnpNatDevice.cs

@@ -70,7 +70,7 @@ namespace Mono.Nat.Upnp
 
 
             // FIXME: Is this reliable enough. What if we get a hostname as opposed to a proper http address
             // 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?
             // Are we going to get addresses with the "http://" attached?
-            if (locationDetails.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
+            if (locationDetails.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
             {
             {
                 NatUtility.Log("Found device at: {0}", locationDetails);
                 NatUtility.Log("Found device at: {0}", locationDetails);
                 // This bit strings out the "http://" from the string
                 // This bit strings out the "http://" from the string
@@ -98,7 +98,7 @@ namespace Mono.Nat.Upnp
             this.localAddress = localAddress;
             this.localAddress = localAddress;
 
 
             // Split the string at the "location" section so i can extract the ipaddress and service description url
             // Split the string at the "location" section so i can extract the ipaddress and service description url
-            string locationDetails = deviceDetails.Substring(deviceDetails.IndexOf("Location", StringComparison.InvariantCultureIgnoreCase) + 9).Split('\r')[0];
+            string locationDetails = deviceDetails.Substring(deviceDetails.IndexOf("Location", StringComparison.OrdinalIgnoreCase) + 9).Split('\r')[0];
             this.serviceType = serviceType;
             this.serviceType = serviceType;
 
 
             // Make sure we have no excess whitespace
             // Make sure we have no excess whitespace
@@ -106,7 +106,7 @@ namespace Mono.Nat.Upnp
 
 
             // FIXME: Is this reliable enough. What if we get a hostname as opposed to a proper http address
             // 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?
             // Are we going to get addresses with the "http://" attached?
-            if (locationDetails.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
+            if (locationDetails.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
             {
             {
                 NatUtility.Log("Found device at: {0}", locationDetails);
                 NatUtility.Log("Found device at: {0}", locationDetails);
                 // This bit strings out the "http://" from the string
                 // This bit strings out the "http://" from the string
@@ -171,189 +171,12 @@ namespace Mono.Nat.Upnp
             get { return serviceType; }
             get { return serviceType; }
         }
         }
 
 
-        /// <summary>
-        /// Begins an async call to get the external ip address of the router
-        /// </summary>
-        public override IAsyncResult BeginGetExternalIP(AsyncCallback callback, object asyncState)
-        {
-            // Create the port map message
-            GetExternalIPAddressMessage message = new GetExternalIPAddressMessage(this);
-            return BeginMessageInternal(message, callback, asyncState, EndGetExternalIPInternal);
-        }
-
-        /// <summary>
-        ///  Maps the specified port to this computer
-        /// </summary>
-        public override IAsyncResult BeginCreatePortMap(Mapping mapping, AsyncCallback callback, object asyncState)
-        {
-            CreatePortMappingMessage message = new CreatePortMappingMessage(mapping, localAddress, this);
-            return BeginMessageInternal(message, callback, asyncState, EndCreatePortMapInternal);
-        }
-
         public override Task CreatePortMap(Mapping mapping)
         public override Task CreatePortMap(Mapping mapping)
         {
         {
             CreatePortMappingMessage message = new CreatePortMappingMessage(mapping, localAddress, this);
             CreatePortMappingMessage message = new CreatePortMappingMessage(mapping, localAddress, this);
             return _httpClient.SendAsync(message.Encode(), message.Method);
             return _httpClient.SendAsync(message.Encode(), message.Method);
         }
         }
 
 
-        /// <summary>
-        /// Removes a port mapping from this computer  
-        /// </summary>
-        public override IAsyncResult BeginDeletePortMap(Mapping mapping, AsyncCallback callback, object asyncState)
-        {
-            DeletePortMappingMessage message = new DeletePortMappingMessage(mapping, this);
-            return BeginMessageInternal(message, callback, asyncState, EndDeletePortMapInternal);
-        }
-
-
-        public override IAsyncResult BeginGetAllMappings(AsyncCallback callback, object asyncState)
-        {
-            GetGenericPortMappingEntry message = new GetGenericPortMappingEntry(0, this);
-            return BeginMessageInternal(message, callback, asyncState, EndGetAllMappingsInternal);
-        }
-
-
-        public override IAsyncResult BeginGetSpecificMapping(Protocol protocol, int port, AsyncCallback callback, object asyncState)
-        {
-            GetSpecificPortMappingEntryMessage message = new GetSpecificPortMappingEntryMessage(protocol, port, this);
-            return this.BeginMessageInternal(message, callback, asyncState, new AsyncCallback(this.EndGetSpecificMappingInternal));
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="result"></param>
-        public override void EndCreatePortMap(IAsyncResult result)
-        {
-            if (result == null) throw new ArgumentNullException("result");
-
-            PortMapAsyncResult mappingResult = result as PortMapAsyncResult;
-            if (mappingResult == null)
-                throw new ArgumentException("Invalid AsyncResult", "result");
-
-            // Check if we need to wait for the operation to finish
-            if (!result.IsCompleted)
-                result.AsyncWaitHandle.WaitOne();
-
-            // If we have a saved exception, it means something went wrong during the mapping
-            // so we just rethrow the exception and let the user figure out what they should do.
-            if (mappingResult.SavedMessage is ErrorMessage)
-            {
-                ErrorMessage msg = mappingResult.SavedMessage as ErrorMessage;
-                throw new MappingException(msg.ErrorCode, msg.Description);
-            }
-
-            //return result.AsyncState as Mapping;
-        }
-
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="result"></param>
-        public override void EndDeletePortMap(IAsyncResult result)
-        {
-            if (result == null)
-                throw new ArgumentNullException("result");
-
-            PortMapAsyncResult mappingResult = result as PortMapAsyncResult;
-            if (mappingResult == null)
-                throw new ArgumentException("Invalid AsyncResult", "result");
-
-            // Check if we need to wait for the operation to finish
-            if (!mappingResult.IsCompleted)
-                mappingResult.AsyncWaitHandle.WaitOne();
-
-            // If we have a saved exception, it means something went wrong during the mapping
-            // so we just rethrow the exception and let the user figure out what they should do.
-            if (mappingResult.SavedMessage is ErrorMessage)
-            {
-                ErrorMessage msg = mappingResult.SavedMessage as ErrorMessage;
-                throw new MappingException(msg.ErrorCode, msg.Description);
-            }
-
-            // If all goes well, we just return
-            //return true;
-        }
-
-
-        public override Mapping[] EndGetAllMappings(IAsyncResult result)
-        {
-            if (result == null)
-                throw new ArgumentNullException("result");
-
-            GetAllMappingsAsyncResult mappingResult = result as GetAllMappingsAsyncResult;
-            if (mappingResult == null)
-                throw new ArgumentException("Invalid AsyncResult", "result");
-
-            if (!mappingResult.IsCompleted)
-                mappingResult.AsyncWaitHandle.WaitOne();
-
-            if (mappingResult.SavedMessage is ErrorMessage)
-            {
-                ErrorMessage msg = mappingResult.SavedMessage as ErrorMessage;
-                if (msg.ErrorCode != 713)
-                    throw new MappingException(msg.ErrorCode, msg.Description);
-            }
-
-            return mappingResult.Mappings.ToArray();
-        }
-
-
-        /// <summary>
-        /// Ends an async request to get the external ip address of the router
-        /// </summary>
-        public override IPAddress EndGetExternalIP(IAsyncResult result)
-        {
-            if (result == null) throw new ArgumentNullException("result");
-
-            PortMapAsyncResult mappingResult = result as PortMapAsyncResult;
-            if (mappingResult == null)
-                throw new ArgumentException("Invalid AsyncResult", "result");
-
-            if (!result.IsCompleted)
-                result.AsyncWaitHandle.WaitOne();
-
-            if (mappingResult.SavedMessage is ErrorMessage)
-            {
-                ErrorMessage msg = mappingResult.SavedMessage as ErrorMessage;
-                throw new MappingException(msg.ErrorCode, msg.Description);
-            }
-
-            if (mappingResult.SavedMessage == null)
-                return null;
-            else
-                return ((GetExternalIPAddressResponseMessage)mappingResult.SavedMessage).ExternalIPAddress;
-        }
-
-
-        public override Mapping EndGetSpecificMapping(IAsyncResult result)
-        {
-            if (result == null)
-                throw new ArgumentNullException("result");
-
-            GetAllMappingsAsyncResult mappingResult = result as GetAllMappingsAsyncResult;
-            if (mappingResult == null)
-                throw new ArgumentException("Invalid AsyncResult", "result");
-
-            if (!mappingResult.IsCompleted)
-                mappingResult.AsyncWaitHandle.WaitOne();
-
-            if (mappingResult.SavedMessage is ErrorMessage)
-            {
-                ErrorMessage message = mappingResult.SavedMessage as ErrorMessage;
-                if (message.ErrorCode != 0x2ca)
-                {
-                    throw new MappingException(message.ErrorCode, message.Description);
-                }
-            }
-            if (mappingResult.Mappings.Count == 0)
-                return new Mapping(Protocol.Tcp, -1, -1);
-
-            return mappingResult.Mappings[0];
-        }
-
-
         public override bool Equals(object obj)
         public override bool Equals(object obj)
         {
         {
             UpnpNatDevice device = obj as UpnpNatDevice;
             UpnpNatDevice device = obj as UpnpNatDevice;
@@ -373,256 +196,6 @@ namespace Mono.Nat.Upnp
             return (this.hostEndPoint.GetHashCode() ^ this.controlUrl.GetHashCode() ^ this.serviceDescriptionUrl.GetHashCode());
             return (this.hostEndPoint.GetHashCode() ^ this.controlUrl.GetHashCode() ^ this.serviceDescriptionUrl.GetHashCode());
         }
         }
 
 
-        private IAsyncResult BeginMessageInternal(MessageBase message, AsyncCallback storedCallback, object asyncState, AsyncCallback callback)
-        {
-            byte[] body;
-            WebRequest request = message.Encode(out body);
-            PortMapAsyncResult mappingResult = PortMapAsyncResult.Create(message, request, storedCallback, asyncState);
-
-            if (body.Length > 0)
-            {
-                request.ContentLength = body.Length;
-                request.BeginGetRequestStream(delegate (IAsyncResult result)
-                {
-                    try
-                    {
-                        Stream s = request.EndGetRequestStream(result);
-                        s.Write(body, 0, body.Length);
-                        request.BeginGetResponse(callback, mappingResult);
-                    }
-                    catch (Exception ex)
-                    {
-                        mappingResult.Complete(ex);
-                    }
-                }, null);
-            }
-            else
-            {
-                request.BeginGetResponse(callback, mappingResult);
-            }
-            return mappingResult;
-        }
-
-        private void CompleteMessage(IAsyncResult result)
-        {
-            PortMapAsyncResult mappingResult = result.AsyncState as PortMapAsyncResult;
-            mappingResult.CompletedSynchronously = result.CompletedSynchronously;
-            mappingResult.Complete();
-        }
-
-        private MessageBase DecodeMessageFromResponse(Stream s, long length)
-        {
-            StringBuilder data = new StringBuilder();
-            int bytesRead = 0;
-            int totalBytesRead = 0;
-            byte[] buffer = new byte[10240];
-
-            // Read out the content of the message, hopefully picking everything up in the case where we have no contentlength
-            if (length != -1)
-            {
-                while (totalBytesRead < length)
-                {
-                    bytesRead = s.Read(buffer, 0, buffer.Length);
-                    data.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead));
-                    totalBytesRead += bytesRead;
-                }
-            }
-            else
-            {
-                while ((bytesRead = s.Read(buffer, 0, buffer.Length)) != 0)
-                    data.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead));
-            }
-
-            // Once we have our content, we need to see what kind of message it is. It'll either a an error
-            // or a response based on the action we performed.
-            return MessageBase.Decode(this, data.ToString());
-        }
-
-        private void EndCreatePortMapInternal(IAsyncResult result)
-        {
-            EndMessageInternal(result);
-            CompleteMessage(result);
-        }
-
-        private void EndMessageInternal(IAsyncResult result)
-        {
-            HttpWebResponse response = null;
-            PortMapAsyncResult mappingResult = result.AsyncState as PortMapAsyncResult;
-
-            try
-            {
-                try
-                {
-                    response = (HttpWebResponse)mappingResult.Request.EndGetResponse(result);
-                }
-                catch (WebException ex)
-                {
-                    // Even if the request "failed" i want to continue on to read out the response from the router
-                    response = ex.Response as HttpWebResponse;
-                    if (response == null)
-                        mappingResult.SavedMessage = new ErrorMessage((int)ex.Status, ex.Message);
-                }
-                if (response != null)
-                    mappingResult.SavedMessage = DecodeMessageFromResponse(response.GetResponseStream(), response.ContentLength);
-            }
-
-            finally
-            {
-                if (response != null)
-                    response.Close();
-            }
-        }
-
-        private void EndDeletePortMapInternal(IAsyncResult result)
-        {
-            EndMessageInternal(result);
-            CompleteMessage(result);
-        }
-
-        private void EndGetAllMappingsInternal(IAsyncResult result)
-        {
-            EndMessageInternal(result);
-
-            GetAllMappingsAsyncResult mappingResult = result.AsyncState as GetAllMappingsAsyncResult;
-            GetGenericPortMappingEntryResponseMessage message = mappingResult.SavedMessage as GetGenericPortMappingEntryResponseMessage;
-            if (message != null)
-            {
-                Mapping mapping = new Mapping(message.Protocol, message.InternalPort, message.ExternalPort, message.LeaseDuration);
-                mapping.Description = message.PortMappingDescription;
-                mappingResult.Mappings.Add(mapping);
-                GetGenericPortMappingEntry next = new GetGenericPortMappingEntry(mappingResult.Mappings.Count, this);
-
-                // It's ok to do this synchronously because we should already be on anther thread
-                // and this won't block the user.
-                byte[] body;
-                WebRequest request = next.Encode(out body);
-                if (body.Length > 0)
-                {
-                    request.ContentLength = body.Length;
-                    request.GetRequestStream().Write(body, 0, body.Length);
-                }
-                mappingResult.Request = request;
-                request.BeginGetResponse(EndGetAllMappingsInternal, mappingResult);
-                return;
-            }
-
-            CompleteMessage(result);
-        }
-
-        private void EndGetExternalIPInternal(IAsyncResult result)
-        {
-            EndMessageInternal(result);
-            CompleteMessage(result);
-        }
-
-        private void EndGetSpecificMappingInternal(IAsyncResult result)
-        {
-            EndMessageInternal(result);
-
-            GetAllMappingsAsyncResult mappingResult = result.AsyncState as GetAllMappingsAsyncResult;
-            GetGenericPortMappingEntryResponseMessage message = mappingResult.SavedMessage as GetGenericPortMappingEntryResponseMessage;
-            if (message != null)
-            {
-                Mapping mapping = new Mapping(mappingResult.SpecificMapping.Protocol, message.InternalPort, mappingResult.SpecificMapping.PublicPort, message.LeaseDuration);
-                mapping.Description = mappingResult.SpecificMapping.Description;
-                mappingResult.Mappings.Add(mapping);
-            }
-
-            CompleteMessage(result);
-        }
-
-        internal async Task<bool> GetServicesList()
-        {
-            // Create a HTTPWebRequest to download the list of services the device offers
-            var requestOptions = new GetServicesMessage(this.serviceDescriptionUrl, this.hostEndPoint, _logger).Encode();
-
-            requestOptions.BufferContent = false;
-
-            using (var response = await _httpClient.Get(requestOptions).ConfigureAwait(false))
-            {
-                return ServicesReceived(response);
-            }
-        }
-
-        private bool ServicesReceived(Stream s)
-        {
-            int abortCount = 0;
-            int bytesRead = 0;
-            byte[] buffer = new byte[10240];
-            StringBuilder servicesXml = new StringBuilder();
-            XmlDocument xmldoc = new XmlDocument();
-
-            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 false;
-                    }
-                    NatUtility.Log("{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);
-
-            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;
-                    NatUtility.Log("{0}: Found service: {1}", HostEndPoint, type);
-                    StringComparison c = StringComparison.OrdinalIgnoreCase;
-                    // 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))
-                    {
-                        this.controlUrl = service["controlURL"].InnerText;
-                        NatUtility.Log("{0}: Found upnp service at: {1}", HostEndPoint, controlUrl);
-                        try
-                        {
-                            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);
-                            }
-                        }
-                        catch
-                        {
-                            NatUtility.Log("{0}: Assuming control Uri is relative: {1}", HostEndPoint, controlUrl);
-                        }
-                        NatUtility.Log("{0}: Handshake Complete", HostEndPoint);
-                        return true;
-                    }
-                }
-            }
-
-            //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
-            return false;
-        }
-
         /// <summary>
         /// <summary>
         /// Overridden.
         /// Overridden.
         /// </summary>
         /// </summary>