From db319f8f0b07d6087508c2c2a338eea32f400f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 16 Jun 2014 16:33:16 +0200 Subject: [PATCH 1/5] this will never happen --- OpenRA.Game/Network/UPnP.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/OpenRA.Game/Network/UPnP.cs b/OpenRA.Game/Network/UPnP.cs index 1e883d8e3c..0b8e38a857 100644 --- a/OpenRA.Game/Network/UPnP.cs +++ b/OpenRA.Game/Network/UPnP.cs @@ -63,14 +63,11 @@ namespace OpenRA.Network public static void DeviceFound(object sender, DeviceEventArgs args) { - if (args.Device == null) - return; - Log.Write("server", "NAT device discovered."); - + Game.Settings.Server.NatDeviceAvailable = true; Game.Settings.Server.AllowPortForward = true; - + try { NatDevice = args.Device; From d25fd654bc4a3736ab5b01915d87959707c40426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 16 Jun 2014 16:33:57 +0200 Subject: [PATCH 2/5] NatUtility.DeviceLost is never fired --- OpenRA.Game/Network/UPnP.cs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/OpenRA.Game/Network/UPnP.cs b/OpenRA.Game/Network/UPnP.cs index 0b8e38a857..dcca301d6f 100644 --- a/OpenRA.Game/Network/UPnP.cs +++ b/OpenRA.Game/Network/UPnP.cs @@ -25,7 +25,6 @@ namespace OpenRA.Network NatUtility.Logger = Log.Channels["server"].Writer; NatUtility.Verbose = Game.Settings.Server.VerboseNatDiscovery; NatUtility.DeviceFound += DeviceFound; - NatUtility.DeviceLost += DeviceLost; Game.Settings.Server.NatDeviceAvailable = false; NatUtility.StartDiscovery(); Log.Write("server", "NAT discovery started."); @@ -86,27 +85,6 @@ namespace OpenRA.Network Game.Settings.Server.AllowPortForward = false; } } - - public static void DeviceLost(object sender, DeviceEventArgs args) - { - Log.Write("server", "NAT device lost."); - - if (args.Device == null) - return; - - try - { - NatDevice = args.Device; - Log.Write("server", "Type: {0}", NatDevice.GetType()); - } - catch (Exception e) - { - Log.Write("server", "Can't fetch type from lost NAT device: {0}", e); - } - - Game.Settings.Server.NatDeviceAvailable = false; - Game.Settings.Server.AllowPortForward = false; - } public static void ForwardPort() { From 4d2412f4b81399ec88fd243196900c059a014de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 16 Jun 2014 16:34:44 +0200 Subject: [PATCH 3/5] this can't throw --- OpenRA.Game/Game.cs | 2 +- OpenRA.Game/Network/UPnP.cs | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 804939411b..df0c10f46a 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -362,7 +362,7 @@ namespace OpenRA InitializeWithMod(Settings.Game.Mod, args.GetValue("Launch.Replay", null)); if (Settings.Server.DiscoverNatDevices) - RunAfterDelay(Settings.Server.NatDiscoveryTimeout, UPnP.TryStoppingNatDiscovery); + RunAfterDelay(Settings.Server.NatDiscoveryTimeout, UPnP.StoppingNatDiscovery); } public static void InitializeWithMod(string mod, string replay) diff --git a/OpenRA.Game/Network/UPnP.cs b/OpenRA.Game/Network/UPnP.cs index dcca301d6f..e05c4f26a5 100644 --- a/OpenRA.Game/Network/UPnP.cs +++ b/OpenRA.Game/Network/UPnP.cs @@ -37,21 +37,11 @@ namespace OpenRA.Network } } - public static void TryStoppingNatDiscovery() + public static void StoppingNatDiscovery() { Log.Write("server", "Stopping NAT discovery."); + NatUtility.StopDiscovery(); - try - { - NatUtility.StopDiscovery(); - } - catch (Exception e) - { - Log.Write("server", "Failed to stop NAT device discovery: {0}", e); - Game.Settings.Server.NatDeviceAvailable = false; - Game.Settings.Server.AllowPortForward = false; - } - if (NatDevice == null) { Log.Write("server", "No NAT devices with UPnP enabled found within {0} ms deadline. Disabling automatic port forwarding.".F(Game.Settings.Server.NatDiscoveryTimeout)); From a8c029f13070ef7c003527a04457810253ab75ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 16 Jun 2014 16:35:33 +0200 Subject: [PATCH 4/5] check if we really found a UPnP compatible NAT device --- OpenRA.Game/Network/UPnP.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Game/Network/UPnP.cs b/OpenRA.Game/Network/UPnP.cs index e05c4f26a5..97e61fe5d3 100644 --- a/OpenRA.Game/Network/UPnP.cs +++ b/OpenRA.Game/Network/UPnP.cs @@ -42,7 +42,7 @@ namespace OpenRA.Network Log.Write("server", "Stopping NAT discovery."); NatUtility.StopDiscovery(); - if (NatDevice == null) + if (NatDevice == null || NatDevice.GetType() != typeof(Mono.Nat.Upnp.UpnpNatDevice)) { Log.Write("server", "No NAT devices with UPnP enabled found within {0} ms deadline. Disabling automatic port forwarding.".F(Game.Settings.Server.NatDiscoveryTimeout)); Game.Settings.Server.NatDeviceAvailable = false; From 1f7b0ad5d49fa99e7cfbb0c9330642e7f3ef2a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 16 Jun 2014 16:42:06 +0200 Subject: [PATCH 5/5] time limit the port forwarding if possible --- OpenRA.Game/Network/UPnP.cs | 28 +++++++++++++++++++--------- OpenRA.Game/Server/Server.cs | 2 +- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/OpenRA.Game/Network/UPnP.cs b/OpenRA.Game/Network/UPnP.cs index 97e61fe5d3..da3f36df18 100644 --- a/OpenRA.Game/Network/UPnP.cs +++ b/OpenRA.Game/Network/UPnP.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -76,28 +76,38 @@ namespace OpenRA.Network } } - public static void ForwardPort() + public static void ForwardPort(int lifetime) { try { - var mapping = new Mapping(Protocol.Tcp, Game.Settings.Server.ExternalPort, Game.Settings.Server.ListenPort); + var mapping = new Mapping(Protocol.Tcp, Game.Settings.Server.ExternalPort, Game.Settings.Server.ListenPort, lifetime); NatDevice.CreatePortMap(mapping); - Log.Write("server", "Create port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort); + Log.Write("server", "Create port mapping: protocol = {0}, public = {1}, private = {2}, lifetime = {3} s", + mapping.Protocol, mapping.PublicPort, mapping.PrivatePort, mapping.Lifetime); } - catch (Exception e) + catch (MappingException e) { - Log.Write("server", "Can not forward ports via UPnP: {0}", e); - Game.Settings.Server.AllowPortForward = false; + if (e.ErrorCode == 725 && lifetime != 0) + { + Log.Write("server", "NAT device answered with OnlyPermanentLeasesSupported. Retrying..."); + ForwardPort(0); + } + else + { + Log.Write("server", "Can not forward ports via UPnP: {0}", e); + Game.Settings.Server.AllowPortForward = false; + } } } - + public static void RemovePortforward() { try { var mapping = new Mapping(Protocol.Tcp, Game.Settings.Server.ExternalPort, Game.Settings.Server.ListenPort); NatDevice.DeletePortMap(mapping); - Log.Write("server", "Remove port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort); + Log.Write("server", "Remove port mapping: protocol = {0}, public = {1}, private = {2}, expiration = {3}", + mapping.Protocol, mapping.PublicPort, mapping.PrivatePort, mapping.Expiration); } catch (Exception e) { diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index 92fa9f31a2..9a6105907b 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -110,7 +110,7 @@ namespace OpenRA.Server randomSeed = (int)DateTime.Now.ToBinary(); if (Settings.AllowPortForward) - UPnP.ForwardPort(); + UPnP.ForwardPort(3600); foreach (var trait in modData.Manifest.ServerTraits) serverTraits.Add(modData.ObjectCreator.CreateObject(trait));