#region Copyright & License Information /* * Copyright 2007-2020 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, either version 3 of * the License, or (at your option) any later version. For more * information, see COPYING. */ #endregion using System; using System.Diagnostics; using System.Net; using System.Threading; using System.Threading.Tasks; using Open.Nat; namespace OpenRA.Network { public enum UPnPStatus { Enabled, Disabled, NotSupported } public class UPnP { static NatDevice natDevice; static Mapping mapping; static bool initialized; public static IPAddress ExternalIP { get; private set; } public static UPnPStatus Status { get { return initialized ? natDevice != null ? UPnPStatus.Enabled : UPnPStatus.NotSupported : UPnPStatus.Disabled; } } public static async Task DiscoverNatDevices(int timeout) { initialized = true; NatDiscoverer.TraceSource.Switch.Level = SourceLevels.Verbose; var logChannel = Log.Channel("nat"); NatDiscoverer.TraceSource.Listeners.Add(new TextWriterTraceListener(logChannel.Writer)); var natDiscoverer = new NatDiscoverer(); var token = new CancellationTokenSource(timeout); natDevice = await natDiscoverer.DiscoverDeviceAsync(PortMapper.Upnp, token); try { ExternalIP = await natDevice.GetExternalIPAsync(); } catch (Exception e) { Console.WriteLine("Getting the external IP from NAT device failed: {0}", e.Message); Log.Write("nat", e.StackTrace); } } public static async Task ForwardPort(int listen, int external) { mapping = new Mapping(Protocol.Tcp, listen, external, "OpenRA"); try { await natDevice.CreatePortMapAsync(mapping); } catch (Exception e) { Console.WriteLine("Port forwarding failed: {0}", e.Message); Log.Write("nat", e.StackTrace); } } public static async Task RemovePortForward() { try { await natDevice.DeletePortMapAsync(mapping); } catch (Exception e) { Console.WriteLine("Port removal failed: {0}", e.Message); Log.Write("nat", e.StackTrace); } } } }