UPnP-based automatic port-forwarding using miniupnpc. Breaks windows build at the moment. Refs #2305

This was SVN commit r14332.
This commit is contained in:
JoshuaJB 2013-12-13 02:23:02 +00:00
parent b508fe848a
commit 667537ee49
3 changed files with 78 additions and 0 deletions

View File

@ -264,6 +264,18 @@ extern_lib_defs = {
add_source_lib_paths("cxxtest") add_source_lib_paths("cxxtest")
end, end,
}, },
miniupnpc = {
compile_settings = function()
add_source_include_paths("miniupnpc")
end,
link_settings = function()
add_source_lib_paths("miniupnpc")
add_default_links({
win_names = { "miniupnpc" },
unix_names = { "miniupnpc" },
})
end,
},
comsuppw = { comsuppw = {
link_settings = function() link_settings = function()
add_default_links({ add_default_links({

View File

@ -573,6 +573,7 @@ function setup_all_libs ()
"spidermonkey", "spidermonkey",
"enet", "enet",
"boost", -- dragged in via server->simulation.h->random "boost", -- dragged in via server->simulation.h->random
"miniupnpc"
} }
setup_static_lib_project("network", source_dirs, extern_libs, {}) setup_static_lib_project("network", source_dirs, extern_libs, {})
@ -846,6 +847,7 @@ used_extern_libs = {
"libcurl", "libcurl",
"valgrind", "valgrind",
"miniupnpc",
} }
if not os.is("windows") and not _OPTIONS["android"] and not os.is("macosx") then if not os.is("windows") and not _OPTIONS["android"] and not os.is("macosx") then

View File

@ -30,6 +30,12 @@
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "simulation2/Simulation2.h" #include "simulation2/Simulation2.h"
// Next four files are for UPnP port forwarding.
#include <miniupnpc/miniwget.h>
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
#define DEFAULT_SERVER_NAME L"Unnamed Server" #define DEFAULT_SERVER_NAME L"Unnamed Server"
#define DEFAULT_WELCOME_MESSAGE L"Welcome" #define DEFAULT_WELCOME_MESSAGE L"Welcome"
#define MAX_CLIENTS 8 #define MAX_CLIENTS 8
@ -182,6 +188,64 @@ bool CNetServerWorker::SetupConnection()
int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this); int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this);
ENSURE(ret == 0); ENSURE(ret == 0);
// Start UPnP Setup.
// Values we want to set.
const char * internalPort = "20595";
const char * externalPort = "20595";
const char * leaseDuration = "86400"; // 24 Hours.
const char * description = "0AD Multiplayer";
const char * protocall = "UDP";
char internalIPAddress[64];
char externalIPAddress[40];
// Variables to hold the values that actually get set.
char intClient[40];
char intPort[6];
char duration[16];
int r;
// Intermediate variables.
struct UPNPUrls urls;
struct IGDdatas data;
struct UPNPDev * devlist = 0;
// Try getting the UPnP device for 7 seconds. TODO: Make this asynchronous?
devlist = upnpDiscover(7000, 0, 0, 0, 0, 0);
// Get our internal IP address.
UPNP_GetValidIGD(devlist, &urls, &data, internalIPAddress, sizeof(internalIPAddress));
// Try getting our external/internet facing IP. TODO: Display this on the game-setup page for conviniance.
UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
// See if we actually got our address.
if(externalIPAddress[0])
LOGMESSAGE(L"Net server: ExternalIPAddress = %s\n", externalIPAddress);
else
LOGMESSAGE(L"Net server: GetExternalIPAddress failed.\n");
// Try to setup port forwarding.
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
externalPort, internalPort, internalIPAddress, description,
protocall, 0, leaseDuration);
// Check the port actually got forwarded.
if (r != UPNPCOMMAND_SUCCESS)
LOGMESSAGE(L"Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
externalPort, internalPort, internalIPAddress, r, strupnperror(r));
r = UPNP_GetSpecificPortMappingEntry(urls.controlURL,
data.first.servicetype,
externalPort, protocall,
intClient, intPort, NULL/*desc*/,
NULL/*enabled*/, duration);
if(r!=UPNPCOMMAND_SUCCESS)
LOGMESSAGE(L"Net server: GetSpecificPortMappingEntry() failed with code %d (%s)\n", r, strupnperror(r));
// If we succeed, log it.
if(intClient[0])
LOGMESSAGE(L"Net server: External %s:%s %s is redirected to internal %s:%s (duration=%s)\n",
externalIPAddress, externalPort, protocall, intClient, intPort, duration);
// End UPnP setup.
return true; return true;
} }