mirror of
https://github.com/glest/glest-source.git
synced 2025-09-26 15:39:21 +02:00
- added UPNP router auto-configure for Internet games (hurray)
This commit is contained in:
@@ -51,6 +51,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "miniwget.h"
|
||||
#include "miniupnpc.h"
|
||||
#include "upnpcommands.h"
|
||||
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -58,6 +62,23 @@ using namespace Shared::Util;
|
||||
|
||||
namespace Shared{ namespace Platform{
|
||||
|
||||
int Socket::broadcast_portno = 61357;
|
||||
BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL;
|
||||
|
||||
//
|
||||
// UPnP - Start
|
||||
//
|
||||
SDL_Thread *upnpdiscover = NULL;
|
||||
static struct UPNPUrls urls;
|
||||
static struct IGDdatas data;
|
||||
// local ip address
|
||||
static char lanaddr[16] ="";
|
||||
|
||||
bool Socket::isUPNP = true;
|
||||
int ServerSocket::externalPort = Socket::broadcast_portno;
|
||||
bool ServerSocket::enabledUPNP = false;
|
||||
// UPnP - End
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#define socklen_t int
|
||||
@@ -220,9 +241,6 @@ namespace Shared{ namespace Platform{
|
||||
|
||||
#endif
|
||||
|
||||
int Socket::broadcast_portno = 61357;
|
||||
BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL;
|
||||
|
||||
int getLastSocketError() {
|
||||
#ifndef WIN32
|
||||
return errno;
|
||||
@@ -1637,6 +1655,7 @@ ServerSocket::~ServerSocket() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
stopBroadCastThread();
|
||||
NETremRedirects(ServerSocket::externalPort);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
@@ -1803,10 +1822,141 @@ Socket *ServerSocket::accept() {
|
||||
return result;
|
||||
}
|
||||
|
||||
BroadCastSocketThread::BroadCastSocketThread() : BaseThread() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
//
|
||||
// This code below handles Universal Plug and Play Router Port Forwarding
|
||||
//
|
||||
int ServerSocket::upnp_init(void *param) {
|
||||
struct UPNPDev *devlist=NULL;
|
||||
struct UPNPDev *dev=NULL;
|
||||
char *descXML=NULL;
|
||||
int descXMLsize = 0;
|
||||
char buf[255]="";
|
||||
//int *externalPort = (int *)asdf;
|
||||
ServerSocket *srv = (ServerSocket *)param;
|
||||
|
||||
int ports[2] = { externalPort, srv->getBindPort() };
|
||||
|
||||
memset(&urls, 0, sizeof(struct UPNPUrls));
|
||||
memset(&data, 0, sizeof(struct IGDdatas));
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Socket::isUPNP = %d\n", Socket::isUPNP);
|
||||
|
||||
if(Socket::isUPNP) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Searching for UPnP devices for automatic port forwarding...\n");
|
||||
devlist = upnpDiscover(2000, NULL, NULL, 0);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device search finished.\n");
|
||||
|
||||
if (devlist) {
|
||||
dev = devlist;
|
||||
while (dev) {
|
||||
if (strstr(dev->st, "InternetGatewayDevice"))
|
||||
break;
|
||||
dev = dev->pNext;
|
||||
}
|
||||
if (!dev) {
|
||||
dev = devlist; /* defaulting to first device */
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found: %s %s\n", dev->descURL, dev->st);
|
||||
|
||||
descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, sizeof(lanaddr));
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"LAN address: %s\n", lanaddr);
|
||||
if (descXML) {
|
||||
parserootdesc (descXML, descXMLsize, &data);
|
||||
free (descXML); descXML = 0;
|
||||
GetUPNPUrls (&urls, &data, dev->descURL);
|
||||
}
|
||||
sprintf(buf, "UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr);
|
||||
//addDumpInfo(buf);
|
||||
freeUPNPDevlist(devlist);
|
||||
|
||||
if (!urls.controlURL || urls.controlURL[0] == '\0') {
|
||||
sprintf(buf, "controlURL not available, UPnP disabled");
|
||||
//addDumpInfo(buf);
|
||||
//obj->DiscoveredServers();
|
||||
return false;
|
||||
}
|
||||
|
||||
//obj->DiscoveredServers();
|
||||
srv->NETaddRedirects(ports);
|
||||
ServerSocket::enabledUPNP = true;
|
||||
return true;
|
||||
}
|
||||
sprintf(buf, "UPnP device not found.");
|
||||
//addDumpInfo(buf);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"No UPnP devices found.\n");
|
||||
|
||||
//obj->DiscoveredServers();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
sprintf(buf, "UPnP detection routine disabled by user.");
|
||||
//addDumpInfo(buf);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP detection routine disabled by user.\n");
|
||||
|
||||
//obj->DiscoveredServers();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ServerSocket::upnp_add_redirect(int ports[2]) {
|
||||
char externalIP[16]="";
|
||||
char ext_port_str[16]="";
|
||||
char int_port_str[16]="";
|
||||
int r=0;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"upnp_add_redir(%d : %d)\n", ports[0],ports[1]);
|
||||
|
||||
UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP);
|
||||
|
||||
sprintf(ext_port_str, "%d", ports[0]);
|
||||
sprintf(int_port_str, "%d", ports[1]);
|
||||
|
||||
r = UPNP_AddPortMapping(urls.controlURL, data.servicetype,
|
||||
ext_port_str, int_port_str, lanaddr, "MegaGlest - www.megaglest.org", "TCP", 0);
|
||||
|
||||
if (r != UPNPCOMMAND_SUCCESS) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"AddPortMapping(%s, %s, %s) failed\n", ext_port_str, int_port_str, lanaddr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void ServerSocket::upnp_rem_redirect(int ext_port) {
|
||||
char ext_port_str[16]="";
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"upnp_rem_redir(%d)\n", ext_port);
|
||||
sprintf(ext_port_str, "%d", ext_port);
|
||||
UPNP_DeletePortMapping(urls.controlURL, data.servicetype, ext_port_str, "TCP", 0);
|
||||
}
|
||||
|
||||
void ServerSocket::NETaddRedirects(int ports[2]) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork, "%s\n", __FUNCTION__);
|
||||
//if (!upnp_done)
|
||||
//{
|
||||
// SDL_WaitThread(upnpdiscover, &upnp);
|
||||
// upnp_done = true;
|
||||
//}
|
||||
//if (upnp) {
|
||||
upnp_add_redirect(ports);
|
||||
//}
|
||||
}
|
||||
|
||||
void ServerSocket::NETremRedirects(int ext_port) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork, "%s\n", __FUNCTION__);
|
||||
if (ServerSocket::enabledUPNP) {
|
||||
ServerSocket::enabledUPNP = false;
|
||||
upnp_rem_redirect(ext_port);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSocket::NETdiscoverUPnPDevices() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] UPNP - Start\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
upnpdiscover = SDL_CreateThread(&upnp_init, this);
|
||||
}
|
||||
// END UPNP
|
||||
|
||||
//=======================================================================
|
||||
// Function : broadcast_thread
|
||||
// in : none
|
||||
@@ -1814,6 +1964,10 @@ BroadCastSocketThread::BroadCastSocketThread() : BaseThread() {
|
||||
// Description: To be forked in its own thread to send out a broadcast to the local subnet
|
||||
// the current broadcast message is <myhostname:my.ip.address.dotted>
|
||||
//
|
||||
BroadCastSocketThread::BroadCastSocketThread() : BaseThread() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void BroadCastSocketThread::execute() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
//setRunningStatus(true);
|
||||
|
Reference in New Issue
Block a user