use Mono.Nat for UPnP port forwarding
- might support more devices - supports internal and external port mapping - discover the device only once (at startup)
This commit is contained in:
3
Makefile
3
Makefile
@@ -1,7 +1,7 @@
|
|||||||
CSC = gmcs
|
CSC = gmcs
|
||||||
CSFLAGS = -nologo -warn:4 -debug:full -optimize- -codepage:utf8 -unsafe -warnaserror
|
CSFLAGS = -nologo -warn:4 -debug:full -optimize- -codepage:utf8 -unsafe -warnaserror
|
||||||
DEFINE = DEBUG;TRACE
|
DEFINE = DEBUG;TRACE
|
||||||
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll thirdparty/FuzzyLogicLibrary.dll
|
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll thirdparty/FuzzyLogicLibrary.dll thirdparty/Mono.Nat.dll
|
||||||
PHONY = core tools package all mods clean distclean dependencies
|
PHONY = core tools package all mods clean distclean dependencies
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
@@ -258,6 +258,7 @@ install: all
|
|||||||
@$(INSTALL_PROGRAM) thirdparty/FuzzyLogicLibrary.dll $(INSTALL_DIR)
|
@$(INSTALL_PROGRAM) thirdparty/FuzzyLogicLibrary.dll $(INSTALL_DIR)
|
||||||
@$(INSTALL_PROGRAM) thirdparty/SharpFont.dll $(INSTALL_DIR)
|
@$(INSTALL_PROGRAM) thirdparty/SharpFont.dll $(INSTALL_DIR)
|
||||||
@cp thirdparty/SharpFont.dll.config $(INSTALL_DIR)
|
@cp thirdparty/SharpFont.dll.config $(INSTALL_DIR)
|
||||||
|
@$(INSTALL_PROGRAM) thirdparty/Mono.Nat.dll $(INSTALL_DIR)
|
||||||
|
|
||||||
@echo "#!/bin/sh" > openra
|
@echo "#!/bin/sh" > openra
|
||||||
@echo 'BINDIR=$$(dirname $$(readlink -f $$0))' >> openra
|
@echo 'BINDIR=$$(dirname $$(readlink -f $$0))' >> openra
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ using OpenRA.Network;
|
|||||||
using OpenRA.Support;
|
using OpenRA.Support;
|
||||||
using OpenRA.Widgets;
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
|
using Mono.Nat;
|
||||||
|
using Mono.Nat.Pmp;
|
||||||
|
using Mono.Nat.Upnp;
|
||||||
|
|
||||||
using XRandom = OpenRA.Thirdparty.Random;
|
using XRandom = OpenRA.Thirdparty.Random;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
@@ -34,6 +38,8 @@ namespace OpenRA
|
|||||||
public static ModData modData;
|
public static ModData modData;
|
||||||
static WorldRenderer worldRenderer;
|
static WorldRenderer worldRenderer;
|
||||||
|
|
||||||
|
public static INatDevice natDevice;
|
||||||
|
|
||||||
public static Viewport viewport;
|
public static Viewport viewport;
|
||||||
public static Settings Settings;
|
public static Settings Settings;
|
||||||
|
|
||||||
@@ -256,6 +262,18 @@ namespace OpenRA
|
|||||||
Log.AddChannel("perf", "perf.log");
|
Log.AddChannel("perf", "perf.log");
|
||||||
Log.AddChannel("debug", "debug.log");
|
Log.AddChannel("debug", "debug.log");
|
||||||
Log.AddChannel("sync", "syncreport.log");
|
Log.AddChannel("sync", "syncreport.log");
|
||||||
|
Log.AddChannel("server", "server.log");
|
||||||
|
|
||||||
|
try {
|
||||||
|
NatUtility.DeviceFound += DeviceFound;
|
||||||
|
NatUtility.DeviceLost += DeviceLost;
|
||||||
|
|
||||||
|
NatUtility.StartDiscovery();
|
||||||
|
OpenRA.Log.Write("server", "NAT discovery started.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
OpenRA.Log.Write("server", "Can't discover UPnP-enabled device: {0}", e);
|
||||||
|
Settings.Server.AllowUPnP = false;
|
||||||
|
}
|
||||||
|
|
||||||
FileSystem.Mount("."); // Needed to access shaders
|
FileSystem.Mount("."); // Needed to access shaders
|
||||||
Renderer.Initialize( Game.Settings.Graphics.Mode );
|
Renderer.Initialize( Game.Settings.Graphics.Mode );
|
||||||
@@ -269,6 +287,31 @@ namespace OpenRA
|
|||||||
InitializeWithMods(Settings.Game.Mods);
|
InitializeWithMods(Settings.Game.Mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void DeviceFound (object sender, DeviceEventArgs args)
|
||||||
|
{
|
||||||
|
natDevice = args.Device;
|
||||||
|
|
||||||
|
Log.Write ("server", "NAT device discovered.");
|
||||||
|
Log.Write ("server", "Type: {0}", natDevice.GetType ().Name);
|
||||||
|
Log.Write ("server", "Your external IP is: {0}", natDevice.GetExternalIP ());
|
||||||
|
|
||||||
|
foreach (Mapping mp in natDevice.GetAllMappings()) {
|
||||||
|
Log.Write ("server", "Existing port mapping: protocol={0}, public={1}, private={2}", mp.Protocol, mp.PublicPort, mp.PrivatePort);
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings.Server.AllowUPnP = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeviceLost (object sender, DeviceEventArgs args)
|
||||||
|
{
|
||||||
|
natDevice = args.Device;
|
||||||
|
|
||||||
|
Log.Write("server", "NAT device Lost");
|
||||||
|
Log.Write("server", "Type: {0}", natDevice.GetType().Name);
|
||||||
|
|
||||||
|
Settings.Server.AllowUPnP = false;
|
||||||
|
}
|
||||||
|
|
||||||
public static void InitializeWithMods(string[] mods)
|
public static void InitializeWithMods(string[] mods)
|
||||||
{
|
{
|
||||||
// Clear static state if we have switched mods
|
// Clear static state if we have switched mods
|
||||||
@@ -415,7 +458,7 @@ namespace OpenRA
|
|||||||
public static void CreateServer(ServerSettings settings)
|
public static void CreateServer(ServerSettings settings)
|
||||||
{
|
{
|
||||||
server = new Server.Server(new IPEndPoint(IPAddress.Any, settings.ListenPort),
|
server = new Server.Server(new IPEndPoint(IPAddress.Any, settings.ListenPort),
|
||||||
Game.Settings.Game.Mods, settings, modData);
|
Game.Settings.Game.Mods, settings, modData, natDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int CreateLocalServer(string map)
|
public static int CreateLocalServer(string map)
|
||||||
@@ -432,7 +475,7 @@ namespace OpenRA
|
|||||||
settings.AllowUPnP = false;
|
settings.AllowUPnP = false;
|
||||||
|
|
||||||
server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0),
|
server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0),
|
||||||
Game.Settings.Game.Mods, settings, modData);
|
Game.Settings.Game.Mods, settings, modData, natDevice);
|
||||||
|
|
||||||
return server.Port;
|
return server.Port;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace OpenRA.GameRules
|
|||||||
public int ExternalPort = 1234;
|
public int ExternalPort = 1234;
|
||||||
public bool AdvertiseOnline = true;
|
public bool AdvertiseOnline = true;
|
||||||
public string MasterServer = "http://master.open-ra.org/";
|
public string MasterServer = "http://master.open-ra.org/";
|
||||||
public bool AllowUPnP = false;
|
public bool AllowUPnP = true;
|
||||||
public bool AllowCheats = false;
|
public bool AllowCheats = false;
|
||||||
public string Map = null;
|
public string Map = null;
|
||||||
public string[] Ban = null;
|
public string[] Ban = null;
|
||||||
|
|||||||
@@ -60,8 +60,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core">
|
<Reference Include="System.Core" />
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
@@ -69,6 +68,12 @@
|
|||||||
<Reference Include="SharpFont">
|
<Reference Include="SharpFont">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\thirdparty\SharpFont.dll</HintPath>
|
<HintPath>..\thirdparty\SharpFont.dll</HintPath>
|
||||||
|
<Reference Include="Mono.Nat, Version=1.1.0.0, Culture=neutral">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<Private>False</Private>
|
||||||
|
<Package>mono.nat</Package>
|
||||||
|
<HintPath>..\thirdparty\Mono.Nat.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Tao.OpenAl, Version=1.1.0.1, Culture=neutral, PublicKeyToken=a7579dda88828311">
|
<Reference Include="Tao.OpenAl, Version=1.1.0.1, Culture=neutral, PublicKeyToken=a7579dda88828311">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
@@ -151,7 +156,6 @@
|
|||||||
<Compile Include="Server\Server.cs" />
|
<Compile Include="Server\Server.cs" />
|
||||||
<Compile Include="Server\ServerOrder.cs" />
|
<Compile Include="Server\ServerOrder.cs" />
|
||||||
<Compile Include="Server\TraitInterfaces.cs" />
|
<Compile Include="Server\TraitInterfaces.cs" />
|
||||||
<Compile Include="Server\UPnP.cs" />
|
|
||||||
<Compile Include="Sound.cs" />
|
<Compile Include="Sound.cs" />
|
||||||
<Compile Include="Support\Arguments.cs" />
|
<Compile Include="Support\Arguments.cs" />
|
||||||
<Compile Include="Support\PerfHistory.cs" />
|
<Compile Include="Support\PerfHistory.cs" />
|
||||||
|
|||||||
@@ -16,14 +16,18 @@ using System.Linq;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using UPnP;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.GameRules;
|
using OpenRA.GameRules;
|
||||||
using OpenRA.Network;
|
using OpenRA.Network;
|
||||||
|
|
||||||
using XTimer = System.Timers.Timer;
|
using XTimer = System.Timers.Timer;
|
||||||
|
|
||||||
|
using Mono.Nat;
|
||||||
|
using Mono.Nat.Pmp;
|
||||||
|
using Mono.Nat.Upnp;
|
||||||
|
|
||||||
namespace OpenRA.Server
|
namespace OpenRA.Server
|
||||||
{
|
{
|
||||||
public enum ServerState : int
|
public enum ServerState : int
|
||||||
@@ -50,6 +54,8 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
public readonly IPAddress Ip;
|
public readonly IPAddress Ip;
|
||||||
public readonly int Port;
|
public readonly int Port;
|
||||||
|
public INatDevice NatDevice;
|
||||||
|
|
||||||
int randomSeed;
|
int randomSeed;
|
||||||
public readonly Thirdparty.Random Random = new Thirdparty.Random();
|
public readonly Thirdparty.Random Random = new Thirdparty.Random();
|
||||||
|
|
||||||
@@ -78,7 +84,7 @@ namespace OpenRA.Server
|
|||||||
RemovePortforward();
|
RemovePortforward();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData)
|
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData, INatDevice natDevice)
|
||||||
{
|
{
|
||||||
Log.AddChannel("server", "server.log");
|
Log.AddChannel("server", "server.log");
|
||||||
|
|
||||||
@@ -91,46 +97,12 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
ModData = modData;
|
ModData = modData;
|
||||||
|
NatDevice = natDevice;
|
||||||
|
|
||||||
randomSeed = (int)DateTime.Now.ToBinary();
|
randomSeed = (int)DateTime.Now.ToBinary();
|
||||||
|
|
||||||
if (Settings.AllowUPnP)
|
if (Settings.AllowUPnP)
|
||||||
{
|
ForwardPort();
|
||||||
try
|
|
||||||
{
|
|
||||||
if (UPnP.NAT.Discover())
|
|
||||||
{
|
|
||||||
Log.Write("server", "UPnP-enabled router discovered.");
|
|
||||||
Log.Write("server", "Your IP is: {0}", UPnP.NAT.GetExternalIP() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.Write("server", "No UPnP-enabled router detected.");
|
|
||||||
Settings.AllowUPnP = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
OpenRA.Log.Write("server", "Can't discover UPnP-enabled routers: {0}", e);
|
|
||||||
Settings.AllowUPnP = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.AllowUPnP)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (UPnP.NAT.ForwardPort(Port, ProtocolType.Tcp, "OpenRA"))
|
|
||||||
Log.Write("server", "Port {0} (TCP) has been forwarded.", Port);
|
|
||||||
else
|
|
||||||
Settings.AllowUPnP = false;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
OpenRA.Log.Write("server", "Can not forward ports via UPnP: {0}", e);
|
|
||||||
Settings.AllowUPnP = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var trait in modData.Manifest.ServerTraits)
|
foreach (var trait in modData.Manifest.ServerTraits)
|
||||||
ServerTraits.Add( modData.ObjectCreator.CreateObject<ServerTrait>(trait) );
|
ServerTraits.Add( modData.ObjectCreator.CreateObject<ServerTrait>(trait) );
|
||||||
@@ -194,6 +166,9 @@ namespace OpenRA.Server
|
|||||||
foreach (var t in ServerTraits.WithInterface<INotifyServerShutdown>())
|
foreach (var t in ServerTraits.WithInterface<INotifyServerShutdown>())
|
||||||
t.ServerShutdown(this);
|
t.ServerShutdown(this);
|
||||||
|
|
||||||
|
if (Settings.AllowUPnP)
|
||||||
|
RemovePortforward();
|
||||||
|
|
||||||
preConns.Clear();
|
preConns.Clear();
|
||||||
conns.Clear();
|
conns.Clear();
|
||||||
try { listener.Stop(); }
|
try { listener.Stop(); }
|
||||||
@@ -202,16 +177,33 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ForwardPort()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Mapping mapping = new Mapping (Protocol.Tcp, Settings.ExternalPort, Settings.ListenPort);
|
||||||
|
NatDevice.CreatePortMap(mapping);
|
||||||
|
Log.Write("server", "Create port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
OpenRA.Log.Write("server", "Can not forward ports via UPnP: {0}", e);
|
||||||
|
Settings.AllowUPnP = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RemovePortforward()
|
void RemovePortforward()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (UPnP.NAT.DeleteForwardingRule(Port, ProtocolType.Tcp))
|
Mapping mapping = new Mapping (Protocol.Tcp, Settings.ExternalPort, Settings.ListenPort);
|
||||||
Log.Write("server", "Port {0} (TCP) forwarding rules has been removed.", Port);
|
NatDevice.DeletePortMap (mapping);
|
||||||
|
Log.Write("server", "Remove port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
OpenRA.Log.Write("server", "Can not remove UPnP portforwarding rules: {0}", e);
|
OpenRA.Log.Write("server", "Can not remove UPnP portforwarding rules: {0}", e);
|
||||||
|
Settings.AllowUPnP = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,163 +0,0 @@
|
|||||||
#region Copyright & License Information
|
|
||||||
/*
|
|
||||||
* Copyright 2008-2009 http://www.codeproject.com/Members/Harold-Aptroot
|
|
||||||
* Source: http://www.codeproject.com/Articles/27992/NAT-Traversal-with-UPnP-in-C
|
|
||||||
* This file is licensed under A Public Domain dedication.
|
|
||||||
* For more information, see http://creativecommons.org/licenses/publicdomain/
|
|
||||||
*/
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Net;
|
|
||||||
using System.Xml;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace UPnP
|
|
||||||
{
|
|
||||||
public class NAT
|
|
||||||
{
|
|
||||||
static string _serviceUrl;
|
|
||||||
|
|
||||||
public static bool Discover()
|
|
||||||
{
|
|
||||||
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
|
||||||
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
|
|
||||||
s.ReceiveTimeout = 3000; //3 seconds
|
|
||||||
string req = "M-SEARCH * HTTP/1.1\r\n" +
|
|
||||||
"HOST: 239.255.255.250:1900\r\n" +
|
|
||||||
"ST:upnp:rootdevice\r\n" +
|
|
||||||
"MAN:\"ssdp:discover\"\r\n" +
|
|
||||||
"MX:3\r\n\r\n";
|
|
||||||
byte[] data = Encoding.ASCII.GetBytes(req);
|
|
||||||
IPEndPoint ipe = new IPEndPoint(IPAddress.Broadcast, 1900);
|
|
||||||
byte[] buffer = new byte[0x1000];
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s.SendTo(data, ipe);
|
|
||||||
int length = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
length = s.Receive(buffer);
|
|
||||||
|
|
||||||
string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower();
|
|
||||||
if (resp.Contains("upnp:rootdevice"))
|
|
||||||
{
|
|
||||||
resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9);
|
|
||||||
resp = resp.Substring(0, resp.IndexOf("\r")).Trim();
|
|
||||||
if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp)))
|
|
||||||
{
|
|
||||||
s.Close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (length > 0);
|
|
||||||
s.Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
s.Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String GetServiceUrl(string resp)
|
|
||||||
{
|
|
||||||
XmlDocument desc = new XmlDocument();
|
|
||||||
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(resp);
|
|
||||||
r.KeepAlive = false;
|
|
||||||
using (WebResponse wres = r.GetResponse())
|
|
||||||
{
|
|
||||||
using (Stream ress = wres.GetResponseStream())
|
|
||||||
{
|
|
||||||
desc.Load(ress);
|
|
||||||
XmlNamespaceManager nsMgr = new XmlNamespaceManager(desc.NameTable);
|
|
||||||
nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0");
|
|
||||||
XmlNode typen = desc.SelectSingleNode("//tns:device/tns:deviceType/text()", nsMgr);
|
|
||||||
if (!typen.Value.Contains("InternetGatewayDevice"))
|
|
||||||
return null;
|
|
||||||
XmlNode node = desc.SelectSingleNode("//tns:service[tns:serviceType=\"urn:schemas-upnp-org:service:WANIPConnection:1\"]/tns:controlURL/text()", nsMgr);
|
|
||||||
if (node == null)
|
|
||||||
return null;
|
|
||||||
Uri respUri = new Uri(resp);
|
|
||||||
Uri combinedUri = new Uri(respUri, node.Value);
|
|
||||||
return combinedUri.AbsoluteUri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ForwardPort(int port, ProtocolType protocol, string description)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_serviceUrl))
|
|
||||||
throw new Exception("No UPnP service available or Discover() has not been called");
|
|
||||||
string body = String.Format("<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"+
|
|
||||||
"<NewRemoteHost></NewRemoteHost><NewExternalPort>{0}</NewExternalPort>"+
|
|
||||||
"<NewProtocol>{1}</NewProtocol><NewInternalPort>{0}</NewInternalPort>" +
|
|
||||||
"<NewInternalClient>{2}</NewInternalClient><NewEnabled>1</NewEnabled>" +
|
|
||||||
"<NewPortMappingDescription>{3}</NewPortMappingDescription>"+
|
|
||||||
"<NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping>",
|
|
||||||
port, protocol.ToString().ToUpper(),Dns.GetHostAddresses(Dns.GetHostName())[0], description);
|
|
||||||
if (SOAPRequest(_serviceUrl, body, "AddPortMapping") != null)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool DeleteForwardingRule(int port, ProtocolType protocol)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_serviceUrl))
|
|
||||||
throw new Exception("No UPnP service available or Discover() has not been called");
|
|
||||||
string body = String.Format("<u:DeletePortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
|
||||||
"<NewRemoteHost></NewRemoteHost><NewExternalPort>{0}</NewExternalPort>"+
|
|
||||||
"<NewProtocol>{1}</NewProtocol></u:DeletePortMapping>", port, protocol.ToString().ToUpper() );
|
|
||||||
if (SOAPRequest(_serviceUrl, body, "DeletePortMapping") != null)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IPAddress GetExternalIP()
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_serviceUrl))
|
|
||||||
throw new Exception("No UPnP service available or Discover() has not been called");
|
|
||||||
XmlDocument xdoc = SOAPRequest(_serviceUrl, "<u:GetExternalIPAddress xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
|
||||||
"</u:GetExternalIPAddress>", "GetExternalIPAddress");
|
|
||||||
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable);
|
|
||||||
nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0");
|
|
||||||
string IP = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr).Value;
|
|
||||||
return IPAddress.Parse(IP);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static XmlDocument SOAPRequest(string url, string soap, string function)
|
|
||||||
{
|
|
||||||
string body = "<?xml version=\"1.0\"?>" +
|
|
||||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
|
|
||||||
"<s:Body>" +
|
|
||||||
soap +
|
|
||||||
"</s:Body>" +
|
|
||||||
"</s:Envelope>";
|
|
||||||
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(url);
|
|
||||||
r.KeepAlive = false;
|
|
||||||
r.Method = "POST";
|
|
||||||
byte[] b = Encoding.UTF8.GetBytes(body);
|
|
||||||
r.Headers.Add("SOAPACTION", "\"urn:schemas-upnp-org:service:WANIPConnection:1#" + function + "\"");
|
|
||||||
r.ContentType = "text/xml; charset=\"utf-8\"";
|
|
||||||
r.ContentLength = b.Length;
|
|
||||||
Stream newStream = r.GetRequestStream();
|
|
||||||
newStream.Write(b, 0, b.Length);
|
|
||||||
XmlDocument resp = new XmlDocument();
|
|
||||||
using (WebResponse wres = r.GetResponse())
|
|
||||||
{
|
|
||||||
using (Stream ress = wres.GetResponseStream())
|
|
||||||
{
|
|
||||||
resp.Load(ress);
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -50,6 +50,9 @@ cp thirdparty/FuzzyLogicLibrary.dll packaging/built
|
|||||||
# SharpFont for FreeType support
|
# SharpFont for FreeType support
|
||||||
cp thirdparty/SharpFont* packaging/built
|
cp thirdparty/SharpFont* packaging/built
|
||||||
|
|
||||||
|
# Mono.NAT for UPnP support
|
||||||
|
cp thirdparty/Mono.Nat.dll packaging/built
|
||||||
|
|
||||||
# Copy game icon for windows package
|
# Copy game icon for windows package
|
||||||
cp OpenRA.Game/OpenRA.ico packaging/built
|
cp OpenRA.Game/OpenRA.ico packaging/built
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ Section "Client" Client
|
|||||||
File "${SRCDIR}\OpenRA.Renderer.Null.dll"
|
File "${SRCDIR}\OpenRA.Renderer.Null.dll"
|
||||||
File "${SRCDIR}\ICSharpCode.SharpZipLib.dll"
|
File "${SRCDIR}\ICSharpCode.SharpZipLib.dll"
|
||||||
File "${SRCDIR}\FuzzyLogicLibrary.dll"
|
File "${SRCDIR}\FuzzyLogicLibrary.dll"
|
||||||
|
File "${SRCDIR}\Mono.Nat.dll"
|
||||||
File "${SRCDIR}\COPYING"
|
File "${SRCDIR}\COPYING"
|
||||||
File "${SRCDIR}\HACKING"
|
File "${SRCDIR}\HACKING"
|
||||||
File "${SRCDIR}\INSTALL"
|
File "${SRCDIR}\INSTALL"
|
||||||
@@ -91,13 +92,13 @@ Section "Client" Client
|
|||||||
File "${SRCDIR}\OpenRA.ico"
|
File "${SRCDIR}\OpenRA.ico"
|
||||||
File "${SRCDIR}\Tao.*.dll"
|
File "${SRCDIR}\Tao.*.dll"
|
||||||
File "${SRCDIR}\SharpFont.*.dll"
|
File "${SRCDIR}\SharpFont.*.dll"
|
||||||
|
|
||||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||||
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
||||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\OpenRA.lnk" $OUTDIR\OpenRA.Game.exe "" \
|
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\OpenRA.lnk" $OUTDIR\OpenRA.Game.exe "" \
|
||||||
"$OUTDIR\OpenRA.Game.exe" "" "" "" ""
|
"$OUTDIR\OpenRA.Game.exe" "" "" "" ""
|
||||||
!insertmacro MUI_STARTMENU_WRITE_END
|
!insertmacro MUI_STARTMENU_WRITE_END
|
||||||
|
|
||||||
SetOutPath "$INSTDIR\cg"
|
SetOutPath "$INSTDIR\cg"
|
||||||
File "${SRCDIR}\cg\*.fx"
|
File "${SRCDIR}\cg\*.fx"
|
||||||
SetOutPath "$INSTDIR\glsl"
|
SetOutPath "$INSTDIR\glsl"
|
||||||
@@ -263,6 +264,7 @@ Function ${UN}Clean
|
|||||||
Delete $INSTDIR\OpenRA.Renderer.SdlCommon.dll
|
Delete $INSTDIR\OpenRA.Renderer.SdlCommon.dll
|
||||||
Delete $INSTDIR\ICSharpCode.SharpZipLib.dll
|
Delete $INSTDIR\ICSharpCode.SharpZipLib.dll
|
||||||
Delete $INSTDIR\FuzzyLogicLibrary.dll
|
Delete $INSTDIR\FuzzyLogicLibrary.dll
|
||||||
|
Delete $INSTDIR\Mono.Nat.dll
|
||||||
Delete $INSTDIR\Tao.*.dll
|
Delete $INSTDIR\Tao.*.dll
|
||||||
Delete $INSTDIR\SharpFont.*.dll
|
Delete $INSTDIR\SharpFont.*.dll
|
||||||
Delete $INSTDIR\COPYING
|
Delete $INSTDIR\COPYING
|
||||||
|
|||||||
BIN
thirdparty/Mono.Nat.dll
vendored
Normal file
BIN
thirdparty/Mono.Nat.dll
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user