diff --git a/Server/Core/Helper/UPnP.cs b/Server/Core/Helper/UPnP.cs index 42358abb..b91c4b92 100644 --- a/Server/Core/Helper/UPnP.cs +++ b/Server/Core/Helper/UPnP.cs @@ -1,8 +1,6 @@ -using System; -using System.Net; -using System.Net.Sockets; +using System.Collections.Generic; using System.Threading; -using NATUPNPLib; +using Mono.Nat; namespace xServer.Core.Helper { @@ -10,85 +8,58 @@ internal static class UPnP { public static bool IsPortForwarded { get; private set; } public static ushort Port { get; private set; } + private static readonly HashSet Devices = new HashSet(); public static void ForwardPort(ushort port) { Port = port; + NatUtility.DeviceFound += DeviceFound; + NatUtility.DeviceLost += DeviceLost; + NatUtility.StartDiscovery(); new Thread(() => { - string ipAddr = string.Empty; - int retry = 0; - - do + while (Devices.Count == 0) // wait until first device found { - try - { - TcpClient c = null; - EndPoint endPoint; - try - { - c = new TcpClient(); - c.Connect("www.google.com", 80); - endPoint = c.Client.LocalEndPoint; - } - finally - { - // Placed in here to make sure that a failed TcpClient will never linger! - if (c != null) - { - c.Close(); - } - } - - if (endPoint != null) - { - ipAddr = endPoint.ToString(); - int index = ipAddr.IndexOf(":", StringComparison.Ordinal); - ipAddr = ipAddr.Remove(index); - - // We got through successfully and with an endpoint and a parsed IP address. We may exit the loop. - break; - } - else - { - retry++; - } - } - catch - { - retry++; - } - } while (retry < 5); - - if (string.IsNullOrEmpty(ipAddr)) // If we can't successfully connect - return; + Thread.Sleep(1000); + } try { - IStaticPortMappingCollection portMap = new UPnPNAT().StaticPortMappingCollection; - if (portMap != null) - portMap.Add(port, "TCP", port, ipAddr, true, "xRAT 2.0 UPnP"); + foreach (var device in Devices) + { + device.CreatePortMap(new Mapping(Protocol.Tcp, Port, Port)); + } IsPortForwarded = true; } - catch + catch (MappingException) { + IsPortForwarded = false; } }).Start(); } + private static void DeviceFound(object sender, DeviceEventArgs args) + { + Devices.Add(args.Device); + } + + private static void DeviceLost(object sender, DeviceEventArgs args) + { + Devices.Remove(args.Device); + } + public static void RemovePort() { - try - { - IStaticPortMappingCollection portMap = new UPnPNAT().StaticPortMappingCollection; - if (portMap != null) - portMap.Remove(Port, "TCP"); - IsPortForwarded = false; - } - catch + foreach (var device in Devices) { + if (device.GetSpecificMapping(Protocol.Tcp, Port).PublicPort > 0) // if port map exists + { + device.DeletePortMap(new Mapping(Protocol.Tcp, Port, Port)); + } } + IsPortForwarded = false; + NatUtility.StopDiscovery(); } } } \ No newline at end of file diff --git a/Server/Forms/FrmSettings.cs b/Server/Forms/FrmSettings.cs index 272271b1..c1878c2f 100644 --- a/Server/Forms/FrmSettings.cs +++ b/Server/Forms/FrmSettings.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Windows.Forms; +using xServer.Core.Helper; using xServer.Core.Misc; using xServer.Core.Networking; using xServer.Settings; @@ -47,8 +48,8 @@ private void btnListen_Click(object sender, EventArgs e) { try { - if (chkUseUpnp.Checked && !Core.Helper.UPnP.IsPortForwarded) - Core.Helper.UPnP.ForwardPort(ushort.Parse(ncPort.Value.ToString(CultureInfo.InvariantCulture))); + if (chkUseUpnp.Checked && !UPnP.IsPortForwarded) + UPnP.ForwardPort(ushort.Parse(ncPort.Value.ToString(CultureInfo.InvariantCulture))); if(chkNoIPIntegration.Checked) NoIpUpdater.Start(); _listenServer.Listen(ushort.Parse(ncPort.Value.ToString(CultureInfo.InvariantCulture))); @@ -65,8 +66,8 @@ private void btnListen_Click(object sender, EventArgs e) try { _listenServer.Disconnect(); - if (Core.Helper.UPnP.IsPortForwarded) - Core.Helper.UPnP.RemovePort(); + if (UPnP.IsPortForwarded) + UPnP.RemovePort(); } finally { diff --git a/Server/Server.csproj b/Server/Server.csproj index 04dd5a4e..958e2518 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -51,6 +51,9 @@ False lib\Mono.Cecil.dll + + lib\Mono.Nat.dll + @@ -436,17 +439,6 @@ - - - {1C565858-F302-471E-B409-F180AA4ABEC6} - 1 - 0 - 0 - tlbimp - False - True - -