mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Split the upnp files into libupnp and miniupnp implementations.
modified libretroshare.pro to allow either to be used. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5733 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
1a1e453c7e
commit
d208b59d33
@ -155,13 +155,9 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
MOC_DIR = temp/moc
|
MOC_DIR = temp/moc
|
||||||
DESTDIR = lib
|
DESTDIR = lib
|
||||||
|
|
||||||
# miniupnp implementation files
|
# linux/bsd can use either - libupnp is more complete and packaged.
|
||||||
#HEADERS += upnp/upnputil.h
|
#CONFIG += upnp_miniupnpc
|
||||||
#SOURCES += upnp/upnputil.c
|
CONFIG += upnp_libupnp
|
||||||
|
|
||||||
# libupnp implementation files
|
|
||||||
HEADERS += upnp/UPnPBase.h
|
|
||||||
SOURCES += upnp/UPnPBase.cpp
|
|
||||||
|
|
||||||
# zeroconf disabled at the end of libretroshare.pro (but need the code)
|
# zeroconf disabled at the end of libretroshare.pro (but need the code)
|
||||||
#CONFIG += zeroconf
|
#CONFIG += zeroconf
|
||||||
@ -192,9 +188,8 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
DEFINES *= STATICLIB \
|
DEFINES *= STATICLIB \
|
||||||
WIN32
|
WIN32
|
||||||
|
|
||||||
# miniupnp implementation files
|
CONFIG += upnp_miniupnpc
|
||||||
HEADERS += upnp/upnputil.h
|
|
||||||
SOURCES += upnp/upnputil.c
|
|
||||||
SSL_DIR = ../../../../openssl
|
SSL_DIR = ../../../../openssl
|
||||||
UPNPC_DIR = ../../../../miniupnpc-1.3
|
UPNPC_DIR = ../../../../miniupnpc-1.3
|
||||||
GPG_ERROR_DIR = ../../../../libgpg-error-1.7
|
GPG_ERROR_DIR = ../../../../libgpg-error-1.7
|
||||||
@ -230,9 +225,8 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
# QMAKE_CFLAGS_DEBUG += -O2
|
# QMAKE_CFLAGS_DEBUG += -O2
|
||||||
DEFINES += USE_CMD_ARGS
|
DEFINES += USE_CMD_ARGS
|
||||||
|
|
||||||
# miniupnp implementation files
|
CONFIG += upnp_libupnp
|
||||||
HEADERS += upnp/upnputil.h
|
|
||||||
SOURCES += upnp/upnputil.c
|
|
||||||
UPNPC_DIR = ../../../lib/miniupnpc-1.3
|
UPNPC_DIR = ../../../lib/miniupnpc-1.3
|
||||||
PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release
|
PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release
|
||||||
ZLIB_DIR = ../../../lib/zlib-1.2.3
|
ZLIB_DIR = ../../../lib/zlib-1.2.3
|
||||||
@ -261,9 +255,7 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
# DEFINES *= MINIUPNPC_VERSION=13
|
# DEFINES *= MINIUPNPC_VERSION=13
|
||||||
DESTDIR = lib
|
DESTDIR = lib
|
||||||
|
|
||||||
# miniupnp implementation files
|
CONFIG += upnp_miniupnpc
|
||||||
HEADERS += upnp/upnputil.h
|
|
||||||
SOURCES += upnp/upnputil.c
|
|
||||||
|
|
||||||
# zeroconf disabled at the end of libretroshare.pro (but need the code)
|
# zeroconf disabled at the end of libretroshare.pro (but need the code)
|
||||||
CONFIG += zeroconf
|
CONFIG += zeroconf
|
||||||
@ -296,9 +288,13 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
-Dstatvfs64=statvfs \
|
-Dstatvfs64=statvfs \
|
||||||
-Dfopen64=fopen
|
-Dfopen64=fopen
|
||||||
|
|
||||||
|
# linux/bsd can use either - libupnp is more complete and packaged.
|
||||||
|
#CONFIG += upnp_miniupnpc
|
||||||
|
CONFIG += upnp_libupnp
|
||||||
|
|
||||||
# libupnp implementation files
|
# libupnp implementation files
|
||||||
HEADERS += upnp/UPnPBase.h
|
HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h
|
||||||
SOURCES += upnp/UPnPBase.cpp
|
SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc
|
||||||
DESTDIR = lib
|
DESTDIR = lib
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +413,7 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
HEADERS += turtle/p3turtle.h \
|
HEADERS += turtle/p3turtle.h \
|
||||||
turtle/rsturtleitem.h \
|
turtle/rsturtleitem.h \
|
||||||
turtle/turtletypes.h
|
turtle/turtletypes.h
|
||||||
HEADERS += upnp/upnphandler.h
|
|
||||||
HEADERS += util/folderiterator.h \
|
HEADERS += util/folderiterator.h \
|
||||||
util/rsdebug.h \
|
util/rsdebug.h \
|
||||||
util/smallobject.h \
|
util/smallobject.h \
|
||||||
@ -434,6 +430,7 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
util/rsrandom.h \
|
util/rsrandom.h \
|
||||||
util/radix64.h \
|
util/radix64.h \
|
||||||
util/pugiconfig.h
|
util/pugiconfig.h
|
||||||
|
|
||||||
SOURCES += dbase/cachestrapper.cc \
|
SOURCES += dbase/cachestrapper.cc \
|
||||||
dbase/fimonitor.cc \
|
dbase/fimonitor.cc \
|
||||||
dbase/findex.cc \
|
dbase/findex.cc \
|
||||||
@ -549,7 +546,7 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
# turtle/turtlerouting.cc \
|
# turtle/turtlerouting.cc \
|
||||||
# turtle/turtlesearch.cc \
|
# turtle/turtlesearch.cc \
|
||||||
# turtle/turtletunnels.cc
|
# turtle/turtletunnels.cc
|
||||||
SOURCES += upnp/upnphandler.cc
|
|
||||||
SOURCES += util/folderiterator.cc \
|
SOURCES += util/folderiterator.cc \
|
||||||
util/rsdebug.cc \
|
util/rsdebug.cc \
|
||||||
util/smallobject.cc \
|
util/smallobject.cc \
|
||||||
@ -564,6 +561,18 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
util/rsversion.cc \
|
util/rsversion.cc \
|
||||||
util/rswin.cc \
|
util/rswin.cc \
|
||||||
util/rsrandom.cc
|
util/rsrandom.cc
|
||||||
|
|
||||||
|
upnp_miniupnpc {
|
||||||
|
HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h
|
||||||
|
SOURCES += upnp/upnputil.c upnp/upnphandler_miniupnp.cc
|
||||||
|
}
|
||||||
|
|
||||||
|
upnp_libupnp {
|
||||||
|
HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h
|
||||||
|
SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc
|
||||||
|
DEFINES *= RS_USE_LIBUPNP
|
||||||
|
}
|
||||||
|
|
||||||
zeroconf {
|
zeroconf {
|
||||||
HEADERS += zeroconf/p3zeroconf.h
|
HEADERS += zeroconf/p3zeroconf.h
|
||||||
SOURCES += zeroconf/p3zeroconf.cc
|
SOURCES += zeroconf/p3zeroconf.cc
|
||||||
@ -600,7 +609,6 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
util/contentvalue.h \
|
util/contentvalue.h \
|
||||||
gxs/gxscoreserver.h \
|
gxs/gxscoreserver.h \
|
||||||
gxs/gxssecurity.h \
|
gxs/gxssecurity.h \
|
||||||
gxs/gxssecurity.h \
|
|
||||||
gxs/rsgxsifaceimpl.h \
|
gxs/rsgxsifaceimpl.h \
|
||||||
services/p3posted.h \
|
services/p3posted.h \
|
||||||
retroshare/rsposted.h \
|
retroshare/rsposted.h \
|
||||||
@ -620,7 +628,6 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
util/contentvalue.cc \
|
util/contentvalue.cc \
|
||||||
gxs/gxscoreserver.cc \
|
gxs/gxscoreserver.cc \
|
||||||
gxs/gxssecurity.cc \
|
gxs/gxssecurity.cc \
|
||||||
gxs/gxssecurity.cc \
|
|
||||||
gxs/rsgxsifaceimpl.cc \
|
gxs/rsgxsifaceimpl.cc \
|
||||||
services/p3posted.cc \
|
services/p3posted.cc \
|
||||||
serialiser/rsposteditems.cc
|
serialiser/rsposteditems.cc
|
||||||
@ -631,7 +638,7 @@ HEADERS += retroshare/rsgame.h \
|
|||||||
services/p3idservice.h \
|
services/p3idservice.h \
|
||||||
serialiser/rsgxsiditems.h
|
serialiser/rsgxsiditems.h
|
||||||
|
|
||||||
SOURCES += services/p3idservice.cc
|
#SOURCES += services/p3idservice.cc
|
||||||
# serialiser/rsgxsiditems.cc \
|
# serialiser/rsgxsiditems.cc \
|
||||||
|
|
||||||
# Wiki Service
|
# Wiki Service
|
||||||
|
@ -1795,7 +1795,11 @@ RsTurtle *rsTurtle = NULL ;
|
|||||||
#ifdef RS_ENABLE_ZCNATASSIST
|
#ifdef RS_ENABLE_ZCNATASSIST
|
||||||
#include "zeroconf/p3zcnatassist.h"
|
#include "zeroconf/p3zcnatassist.h"
|
||||||
#else
|
#else
|
||||||
#include "upnp/upnphandler.h"
|
#ifdef RS_USE_LIBUPNP
|
||||||
|
#include "upnp/upnphandler_linux.h"
|
||||||
|
#else
|
||||||
|
#include "upnp/upnphandler_miniupnp.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "services/p3disc.h"
|
#include "services/p3disc.h"
|
||||||
|
431
libretroshare/src/upnp/upnphandler_linux.cc
Normal file
431
libretroshare/src/upnp/upnphandler_linux.cc
Normal file
@ -0,0 +1,431 @@
|
|||||||
|
//Linux only
|
||||||
|
/* This stuff is actually C */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern C */
|
||||||
|
#endif
|
||||||
|
/* This stuff is actually C */
|
||||||
|
|
||||||
|
#include "upnp/upnphandler_linux.h"
|
||||||
|
|
||||||
|
#include "util/rsnet.h"
|
||||||
|
|
||||||
|
bool upnphandler::initUPnPState()
|
||||||
|
{
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::initUPnPState" << std::endl;
|
||||||
|
#endif
|
||||||
|
cUPnPControlPoint = new CUPnPControlPoint(2000);
|
||||||
|
|
||||||
|
bool IGWDetected = cUPnPControlPoint->GetIGWDeviceDetected();
|
||||||
|
|
||||||
|
if (IGWDetected) {
|
||||||
|
/* MODIFY STATE */
|
||||||
|
dataMtx.lock(); /* LOCK MUTEX */
|
||||||
|
upnpState = RS_UPNP_S_READY;
|
||||||
|
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::initUPnPState cUPnPControlPoint internal ip adress : ";
|
||||||
|
std::cerr << cUPnPControlPoint->getInternalIpAddress() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//const char ipaddr = cUPnPControlPoint->getInternalIpAddress().c_str();
|
||||||
|
inet_aton(cUPnPControlPoint->getInternalIpAddress(), &(upnp_iaddr.sin_addr));
|
||||||
|
upnp_iaddr.sin_port = htons(iport);
|
||||||
|
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::initUPnPState READY" << std::endl;
|
||||||
|
#endif
|
||||||
|
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
|
|
||||||
|
} else {
|
||||||
|
upnpState = RS_UPNP_S_UNAVAILABLE;
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::initUPnPState UNAVAILABLE" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
class upnpThreadData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
upnphandler *handler;
|
||||||
|
bool start;
|
||||||
|
bool stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thread routines */
|
||||||
|
extern "C" void* doSetupUPnP(void* p)
|
||||||
|
{
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "doSetupUPnP Creating upnp thread." << std::endl;
|
||||||
|
#endif
|
||||||
|
upnpThreadData *data = (upnpThreadData *) p;
|
||||||
|
if ((!data) || (!data->handler))
|
||||||
|
{
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* publish it! */
|
||||||
|
if (data -> stop)
|
||||||
|
{
|
||||||
|
data->handler->shutdown_upnp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data -> start)
|
||||||
|
{
|
||||||
|
data->handler->initUPnPState();
|
||||||
|
data->handler->start_upnp();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete data;
|
||||||
|
pthread_exit(NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::background_setup_upnp(bool start, bool stop)
|
||||||
|
{
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
|
/* launch thread */
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "background_setup_upnp Creating upnp thread." << std::endl;
|
||||||
|
#endif
|
||||||
|
upnpThreadData *data = new upnpThreadData();
|
||||||
|
data->handler = this;
|
||||||
|
data->start = start;
|
||||||
|
data->stop = stop;
|
||||||
|
|
||||||
|
pthread_create(&tid, 0, &doSetupUPnP, (void *) data);
|
||||||
|
pthread_detach(tid); /* so memory is reclaimed in linux */
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::start_upnp()
|
||||||
|
{
|
||||||
|
if (!(upnpState >= RS_UPNP_S_READY))
|
||||||
|
{
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::start_upnp() Not Ready" << std::endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in localAddr;
|
||||||
|
{
|
||||||
|
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
||||||
|
|
||||||
|
/* if we're to load -> load */
|
||||||
|
/* select external ports */
|
||||||
|
eport_curr = eport;
|
||||||
|
if (!eport_curr)
|
||||||
|
{
|
||||||
|
/* use local port if eport is zero */
|
||||||
|
eport_curr = iport;
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::start_upnp() Using LocalPort for extPort." << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eport_curr)
|
||||||
|
{
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::start_upnp() Invalid eport ... " << std::endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* our port */
|
||||||
|
char in_addr[256];
|
||||||
|
char in_port1[256];
|
||||||
|
|
||||||
|
upnp_iaddr.sin_port = htons(iport);
|
||||||
|
localAddr = upnp_iaddr;
|
||||||
|
uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr);
|
||||||
|
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
||||||
|
snprintf(in_addr, 256, "%d.%d.%d.%d",
|
||||||
|
((linaddr >> 24) & 0xff),
|
||||||
|
((linaddr >> 16) & 0xff),
|
||||||
|
((linaddr >> 8) & 0xff),
|
||||||
|
((linaddr >> 0) & 0xff));
|
||||||
|
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "Attempting Redirection: InAddr: " << in_addr;
|
||||||
|
std::cerr << " InPort: " << in_port1;
|
||||||
|
std::cerr << " ePort: " << eport_curr;
|
||||||
|
std::cerr << " eProt: " << "TCP and UDP";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//first of all, build the mappings
|
||||||
|
std::vector<CUPnPPortMapping> upnpPortMapping1;
|
||||||
|
CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "TCP", true, "tcp retroshare redirection");
|
||||||
|
upnpPortMapping1.push_back(cUPnPPortMapping1);
|
||||||
|
std::vector<CUPnPPortMapping> upnpPortMapping2;
|
||||||
|
CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "UDP", true, "udp retroshare redirection");
|
||||||
|
upnpPortMapping2.push_back(cUPnPPortMapping2);
|
||||||
|
|
||||||
|
//attempt to remove formal port redirection rules
|
||||||
|
cUPnPControlPoint->DeletePortMappings(upnpPortMapping1);
|
||||||
|
cUPnPControlPoint->DeletePortMappings(upnpPortMapping2);
|
||||||
|
|
||||||
|
//add new rules
|
||||||
|
bool res = cUPnPControlPoint->AddPortMappings(upnpPortMapping1);
|
||||||
|
bool res2 = cUPnPControlPoint->AddPortMappings(upnpPortMapping2);
|
||||||
|
|
||||||
|
struct sockaddr_in extAddr;
|
||||||
|
bool extAddrResult = getExternalAddress(extAddr);
|
||||||
|
|
||||||
|
{
|
||||||
|
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
||||||
|
|
||||||
|
if (extAddrResult && (res || res2)) {
|
||||||
|
upnpState = RS_UPNP_S_ACTIVE;
|
||||||
|
} else {
|
||||||
|
upnpState = RS_UPNP_S_TCP_AND_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
toStart = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (upnpState == RS_UPNP_S_ACTIVE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::shutdown_upnp()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
||||||
|
|
||||||
|
/* always attempt this (unless no port number) */
|
||||||
|
if (eport_curr > 0 && eport > 0 && (upnpState >= RS_UPNP_S_ACTIVE))
|
||||||
|
{
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr;
|
||||||
|
std::cerr << " Prot: TCP";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<CUPnPPortMapping> upnpPortMapping1;
|
||||||
|
CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, 0, "TCP", true, "tcp redirection");
|
||||||
|
upnpPortMapping1.push_back(cUPnPPortMapping1);
|
||||||
|
cUPnPControlPoint->DeletePortMappings(upnpPortMapping1);
|
||||||
|
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr;
|
||||||
|
std::cerr << " Prot: UDP";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<CUPnPPortMapping> upnpPortMapping2;
|
||||||
|
CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, 0, "UDP", true, "udp redirection");
|
||||||
|
upnpPortMapping2.push_back(cUPnPPortMapping2);
|
||||||
|
cUPnPControlPoint->DeletePortMappings(upnpPortMapping2);
|
||||||
|
|
||||||
|
//destroy the upnp object
|
||||||
|
cUPnPControlPoint->~CUPnPControlPoint();
|
||||||
|
} else {
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::shutdown_upnp() : avoid upnp connection for shutdonws because probably a net flag went down." << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//stopping os ok, set starting to true for next net reset
|
||||||
|
toStop = false;
|
||||||
|
toStart = true;
|
||||||
|
upnpState = RS_UPNP_S_UNINITIALISED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ External Interface *****************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
upnphandler::upnphandler()
|
||||||
|
:
|
||||||
|
upnpState(RS_UPNP_S_UNINITIALISED), dataMtx("upupState"),
|
||||||
|
cUPnPControlPoint(NULL),
|
||||||
|
toEnable(false), toStart(false), toStop(false),
|
||||||
|
iport(0),eport(0), eport_curr(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
upnphandler::~upnphandler()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RsIface */
|
||||||
|
void upnphandler::enable(bool active)
|
||||||
|
{
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::enable called with argument active : " << active << std::endl;
|
||||||
|
std::cerr << "toEnable : " << toEnable << std::endl;
|
||||||
|
std::cerr << "toStart : " << toStart << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
if (active != toEnable)
|
||||||
|
{
|
||||||
|
if (active)
|
||||||
|
{
|
||||||
|
toStart = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toStop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toEnable = active;
|
||||||
|
|
||||||
|
bool start = toStart;
|
||||||
|
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
/* make background thread to startup UPnP */
|
||||||
|
background_setup_upnp(true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void upnphandler::shutdown()
|
||||||
|
{
|
||||||
|
/* blocking call to shutdown upnp */
|
||||||
|
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::shutdown() called." << std::endl;
|
||||||
|
#endif
|
||||||
|
shutdown_upnp();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void upnphandler::restart()
|
||||||
|
{
|
||||||
|
/* non-blocking call to shutdown upnp, and startup again. */
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << "upnphandler::restart() called." << std::endl;
|
||||||
|
#endif
|
||||||
|
background_setup_upnp(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool upnphandler::getEnabled()
|
||||||
|
{
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
|
||||||
|
bool on = toEnable;
|
||||||
|
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::getActive()
|
||||||
|
{
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr <<"upnphandler::getActive() result : " << (upnpState == RS_UPNP_S_ACTIVE) << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool on = (upnpState == RS_UPNP_S_ACTIVE);
|
||||||
|
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the address that the listening port is on */
|
||||||
|
void upnphandler::setInternalPort(unsigned short iport_in)
|
||||||
|
{
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
if (iport != iport_in)
|
||||||
|
{
|
||||||
|
iport = iport_in;
|
||||||
|
if ((toEnable) &&
|
||||||
|
(upnpState == RS_UPNP_S_ACTIVE))
|
||||||
|
{
|
||||||
|
toStop = true;
|
||||||
|
toStart = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
}
|
||||||
|
|
||||||
|
void upnphandler::setExternalPort(unsigned short eport_in)
|
||||||
|
{
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
/* flag both shutdown/start -> for restart */
|
||||||
|
if (eport != eport_in)
|
||||||
|
{
|
||||||
|
eport = eport_in;
|
||||||
|
if ((toEnable) &&
|
||||||
|
(upnpState == RS_UPNP_S_ACTIVE))
|
||||||
|
{
|
||||||
|
toStop = true;
|
||||||
|
toStart = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* as determined by uPnP */
|
||||||
|
bool upnphandler::getInternalAddress(struct sockaddr_in &addr)
|
||||||
|
{
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
addr = upnp_iaddr;
|
||||||
|
bool valid = (upnpState >= RS_UPNP_S_ACTIVE);
|
||||||
|
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::getExternalAddress(struct sockaddr_in &addr)
|
||||||
|
{
|
||||||
|
std::string externalAdress = cUPnPControlPoint->getExternalAddress();
|
||||||
|
|
||||||
|
if(!externalAdress.empty() && externalAdress != "")
|
||||||
|
{
|
||||||
|
const char* externalIPAddress = externalAdress.c_str();
|
||||||
|
|
||||||
|
#ifdef UPNP_DEBUG
|
||||||
|
std::cerr << " upnphandler::getExternalAddress() : " << externalIPAddress;
|
||||||
|
std::cerr << ":" << eport_curr;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
sockaddr_clear(&upnp_eaddr);
|
||||||
|
inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr));
|
||||||
|
upnp_eaddr.sin_family = AF_INET;
|
||||||
|
upnp_eaddr.sin_port = htons(eport_curr);
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
addr = upnp_eaddr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
78
libretroshare/src/upnp/upnphandler_linux.h
Normal file
78
libretroshare/src/upnp/upnphandler_linux.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#ifndef _RS_UPNP_IFACE_H
|
||||||
|
#define _RS_UPNP_IFACE_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* platform independent networking... */
|
||||||
|
#include "pqi/pqinetwork.h"
|
||||||
|
#include "pqi/pqiassist.h"
|
||||||
|
|
||||||
|
#include "util/rsthreads.h"
|
||||||
|
|
||||||
|
#include <upnp/upnp.h>
|
||||||
|
#include "upnp/UPnPBase.h"
|
||||||
|
|
||||||
|
#define RS_UPNP_S_UNINITIALISED 0
|
||||||
|
#define RS_UPNP_S_UNAVAILABLE 1
|
||||||
|
#define RS_UPNP_S_READY 2
|
||||||
|
#define RS_UPNP_S_TCP_AND_FAILED 3
|
||||||
|
//#define RS_UPNP_S_UDP_FAILED 4
|
||||||
|
#define RS_UPNP_S_ACTIVE 5
|
||||||
|
|
||||||
|
class upnphandler: public pqiNetAssistFirewall
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
upnphandler();
|
||||||
|
virtual ~upnphandler();
|
||||||
|
|
||||||
|
/* External Interface (pqiNetAssistFirewall) */
|
||||||
|
virtual void enable(bool active);
|
||||||
|
virtual void shutdown();
|
||||||
|
virtual void restart();
|
||||||
|
|
||||||
|
virtual bool getEnabled();
|
||||||
|
virtual bool getActive();
|
||||||
|
|
||||||
|
virtual void setInternalPort(unsigned short iport_in);
|
||||||
|
virtual void setExternalPort(unsigned short eport_in);
|
||||||
|
virtual bool getInternalAddress(struct sockaddr_in &addr);
|
||||||
|
virtual bool getExternalAddress(struct sockaddr_in &addr);
|
||||||
|
|
||||||
|
/* Public functions - for background thread operation,
|
||||||
|
* but effectively private from rest of RS, as in derived class
|
||||||
|
*/
|
||||||
|
unsigned int upnpState;
|
||||||
|
|
||||||
|
bool start_upnp();
|
||||||
|
bool shutdown_upnp();
|
||||||
|
|
||||||
|
bool initUPnPState();
|
||||||
|
|
||||||
|
/* Mutex for data below */
|
||||||
|
RsMutex dataMtx;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CUPnPControlPoint *cUPnPControlPoint;
|
||||||
|
|
||||||
|
bool background_setup_upnp(bool, bool);
|
||||||
|
|
||||||
|
|
||||||
|
bool toEnable; /* overall on/off switch */
|
||||||
|
bool toStart; /* if set start forwarding */
|
||||||
|
bool toStop; /* if set stop forwarding */
|
||||||
|
|
||||||
|
unsigned short iport;
|
||||||
|
unsigned short eport; /* config */
|
||||||
|
unsigned short eport_curr; /* current forwarded */
|
||||||
|
|
||||||
|
/* info from upnp */
|
||||||
|
struct sockaddr_in upnp_iaddr;
|
||||||
|
struct sockaddr_in upnp_eaddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* info from upnp */
|
||||||
|
int CtrlPointCallbackEventHandler(Upnp_EventType ,void* , void*);
|
||||||
|
|
||||||
|
#endif /* _RS_UPNP_IFACE_H */
|
@ -1,440 +1,4 @@
|
|||||||
//Linux only
|
|
||||||
#if !defined(WINDOWS_SYS) && !defined(__APPLE__)
|
|
||||||
|
|
||||||
/* This stuff is actually C */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern C */
|
|
||||||
#endif
|
|
||||||
/* This stuff is actually C */
|
|
||||||
|
|
||||||
#include "upnp/upnphandler.h"
|
|
||||||
|
|
||||||
#include "util/rsnet.h"
|
|
||||||
|
|
||||||
bool upnphandler::initUPnPState()
|
|
||||||
{
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::initUPnPState" << std::endl;
|
|
||||||
#endif
|
|
||||||
cUPnPControlPoint = new CUPnPControlPoint(2000);
|
|
||||||
|
|
||||||
bool IGWDetected = cUPnPControlPoint->GetIGWDeviceDetected();
|
|
||||||
|
|
||||||
if (IGWDetected) {
|
|
||||||
/* MODIFY STATE */
|
|
||||||
dataMtx.lock(); /* LOCK MUTEX */
|
|
||||||
upnpState = RS_UPNP_S_READY;
|
|
||||||
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::initUPnPState cUPnPControlPoint internal ip adress : ";
|
|
||||||
std::cerr << cUPnPControlPoint->getInternalIpAddress() << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//const char ipaddr = cUPnPControlPoint->getInternalIpAddress().c_str();
|
|
||||||
inet_aton(cUPnPControlPoint->getInternalIpAddress(), &(upnp_iaddr.sin_addr));
|
|
||||||
upnp_iaddr.sin_port = htons(iport);
|
|
||||||
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::initUPnPState READY" << std::endl;
|
|
||||||
#endif
|
|
||||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
|
||||||
|
|
||||||
} else {
|
|
||||||
upnpState = RS_UPNP_S_UNAVAILABLE;
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::initUPnPState UNAVAILABLE" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class upnpThreadData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
upnphandler *handler;
|
|
||||||
bool start;
|
|
||||||
bool stop;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Thread routines */
|
|
||||||
extern "C" void* doSetupUPnP(void* p)
|
|
||||||
{
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "doSetupUPnP Creating upnp thread." << std::endl;
|
|
||||||
#endif
|
|
||||||
upnpThreadData *data = (upnpThreadData *) p;
|
|
||||||
if ((!data) || (!data->handler))
|
|
||||||
{
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* publish it! */
|
|
||||||
if (data -> stop)
|
|
||||||
{
|
|
||||||
data->handler->shutdown_upnp();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data -> start)
|
|
||||||
{
|
|
||||||
data->handler->initUPnPState();
|
|
||||||
data->handler->start_upnp();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
pthread_exit(NULL);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool upnphandler::background_setup_upnp(bool start, bool stop)
|
|
||||||
{
|
|
||||||
pthread_t tid;
|
|
||||||
|
|
||||||
/* launch thread */
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "background_setup_upnp Creating upnp thread." << std::endl;
|
|
||||||
#endif
|
|
||||||
upnpThreadData *data = new upnpThreadData();
|
|
||||||
data->handler = this;
|
|
||||||
data->start = start;
|
|
||||||
data->stop = stop;
|
|
||||||
|
|
||||||
pthread_create(&tid, 0, &doSetupUPnP, (void *) data);
|
|
||||||
pthread_detach(tid); /* so memory is reclaimed in linux */
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool upnphandler::start_upnp()
|
|
||||||
{
|
|
||||||
if (!(upnpState >= RS_UPNP_S_READY))
|
|
||||||
{
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::start_upnp() Not Ready" << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sockaddr_in localAddr;
|
|
||||||
{
|
|
||||||
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
|
||||||
|
|
||||||
/* if we're to load -> load */
|
|
||||||
/* select external ports */
|
|
||||||
eport_curr = eport;
|
|
||||||
if (!eport_curr)
|
|
||||||
{
|
|
||||||
/* use local port if eport is zero */
|
|
||||||
eport_curr = iport;
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::start_upnp() Using LocalPort for extPort." << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!eport_curr)
|
|
||||||
{
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::start_upnp() Invalid eport ... " << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* our port */
|
|
||||||
char in_addr[256];
|
|
||||||
char in_port1[256];
|
|
||||||
|
|
||||||
upnp_iaddr.sin_port = htons(iport);
|
|
||||||
localAddr = upnp_iaddr;
|
|
||||||
uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr);
|
|
||||||
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
|
||||||
snprintf(in_addr, 256, "%d.%d.%d.%d",
|
|
||||||
((linaddr >> 24) & 0xff),
|
|
||||||
((linaddr >> 16) & 0xff),
|
|
||||||
((linaddr >> 8) & 0xff),
|
|
||||||
((linaddr >> 0) & 0xff));
|
|
||||||
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "Attempting Redirection: InAddr: " << in_addr;
|
|
||||||
std::cerr << " InPort: " << in_port1;
|
|
||||||
std::cerr << " ePort: " << eport_curr;
|
|
||||||
std::cerr << " eProt: " << "TCP and UDP";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//first of all, build the mappings
|
|
||||||
std::vector<CUPnPPortMapping> upnpPortMapping1;
|
|
||||||
CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "TCP", true, "tcp retroshare redirection");
|
|
||||||
upnpPortMapping1.push_back(cUPnPPortMapping1);
|
|
||||||
std::vector<CUPnPPortMapping> upnpPortMapping2;
|
|
||||||
CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "UDP", true, "udp retroshare redirection");
|
|
||||||
upnpPortMapping2.push_back(cUPnPPortMapping2);
|
|
||||||
|
|
||||||
//attempt to remove formal port redirection rules
|
|
||||||
cUPnPControlPoint->DeletePortMappings(upnpPortMapping1);
|
|
||||||
cUPnPControlPoint->DeletePortMappings(upnpPortMapping2);
|
|
||||||
|
|
||||||
//add new rules
|
|
||||||
bool res = cUPnPControlPoint->AddPortMappings(upnpPortMapping1);
|
|
||||||
bool res2 = cUPnPControlPoint->AddPortMappings(upnpPortMapping2);
|
|
||||||
|
|
||||||
struct sockaddr_in extAddr;
|
|
||||||
bool extAddrResult = getExternalAddress(extAddr);
|
|
||||||
|
|
||||||
{
|
|
||||||
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
|
||||||
|
|
||||||
if (extAddrResult && (res || res2)) {
|
|
||||||
upnpState = RS_UPNP_S_ACTIVE;
|
|
||||||
} else {
|
|
||||||
upnpState = RS_UPNP_S_TCP_AND_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
toStart = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (upnpState == RS_UPNP_S_ACTIVE);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool upnphandler::shutdown_upnp()
|
|
||||||
{
|
|
||||||
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
|
||||||
|
|
||||||
/* always attempt this (unless no port number) */
|
|
||||||
if (eport_curr > 0 && eport > 0 && (upnpState >= RS_UPNP_S_ACTIVE))
|
|
||||||
{
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr;
|
|
||||||
std::cerr << " Prot: TCP";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::vector<CUPnPPortMapping> upnpPortMapping1;
|
|
||||||
CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, 0, "TCP", true, "tcp redirection");
|
|
||||||
upnpPortMapping1.push_back(cUPnPPortMapping1);
|
|
||||||
cUPnPControlPoint->DeletePortMappings(upnpPortMapping1);
|
|
||||||
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr;
|
|
||||||
std::cerr << " Prot: UDP";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::vector<CUPnPPortMapping> upnpPortMapping2;
|
|
||||||
CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, 0, "UDP", true, "udp redirection");
|
|
||||||
upnpPortMapping2.push_back(cUPnPPortMapping2);
|
|
||||||
cUPnPControlPoint->DeletePortMappings(upnpPortMapping2);
|
|
||||||
|
|
||||||
//destroy the upnp object
|
|
||||||
cUPnPControlPoint->~CUPnPControlPoint();
|
|
||||||
} else {
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::shutdown_upnp() : avoid upnp connection for shutdonws because probably a net flag went down." << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//stopping os ok, set starting to true for next net reset
|
|
||||||
toStop = false;
|
|
||||||
toStart = true;
|
|
||||||
upnpState = RS_UPNP_S_UNINITIALISED;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************ External Interface *****************************
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
upnphandler::upnphandler()
|
|
||||||
:
|
|
||||||
upnpState(RS_UPNP_S_UNINITIALISED), dataMtx("upupState"),
|
|
||||||
cUPnPControlPoint(NULL),
|
|
||||||
toEnable(false), toStart(false), toStop(false),
|
|
||||||
iport(0),eport(0), eport_curr(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
upnphandler::~upnphandler()
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RsIface */
|
|
||||||
void upnphandler::enable(bool active)
|
|
||||||
{
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::enable called with argument active : " << active << std::endl;
|
|
||||||
std::cerr << "toEnable : " << toEnable << std::endl;
|
|
||||||
std::cerr << "toStart : " << toStart << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
|
||||||
if (active != toEnable)
|
|
||||||
{
|
|
||||||
if (active)
|
|
||||||
{
|
|
||||||
toStart = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toStop = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
toEnable = active;
|
|
||||||
|
|
||||||
bool start = toStart;
|
|
||||||
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
|
|
||||||
if (start)
|
|
||||||
{
|
|
||||||
/* make background thread to startup UPnP */
|
|
||||||
background_setup_upnp(true, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void upnphandler::shutdown()
|
|
||||||
{
|
|
||||||
/* blocking call to shutdown upnp */
|
|
||||||
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::shutdown() called." << std::endl;
|
|
||||||
#endif
|
|
||||||
shutdown_upnp();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void upnphandler::restart()
|
|
||||||
{
|
|
||||||
/* non-blocking call to shutdown upnp, and startup again. */
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << "upnphandler::restart() called." << std::endl;
|
|
||||||
#endif
|
|
||||||
background_setup_upnp(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool upnphandler::getEnabled()
|
|
||||||
{
|
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
|
||||||
|
|
||||||
bool on = toEnable;
|
|
||||||
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
|
|
||||||
return on;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool upnphandler::getActive()
|
|
||||||
{
|
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
|
||||||
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr <<"upnphandler::getActive() result : " << (upnpState == RS_UPNP_S_ACTIVE) << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool on = (upnpState == RS_UPNP_S_ACTIVE);
|
|
||||||
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
|
|
||||||
return on;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the address that the listening port is on */
|
|
||||||
void upnphandler::setInternalPort(unsigned short iport_in)
|
|
||||||
{
|
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
|
||||||
if (iport != iport_in)
|
|
||||||
{
|
|
||||||
iport = iport_in;
|
|
||||||
if ((toEnable) &&
|
|
||||||
(upnpState == RS_UPNP_S_ACTIVE))
|
|
||||||
{
|
|
||||||
toStop = true;
|
|
||||||
toStart = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
}
|
|
||||||
|
|
||||||
void upnphandler::setExternalPort(unsigned short eport_in)
|
|
||||||
{
|
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
|
||||||
/* flag both shutdown/start -> for restart */
|
|
||||||
if (eport != eport_in)
|
|
||||||
{
|
|
||||||
eport = eport_in;
|
|
||||||
if ((toEnable) &&
|
|
||||||
(upnpState == RS_UPNP_S_ACTIVE))
|
|
||||||
{
|
|
||||||
toStop = true;
|
|
||||||
toStart = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* as determined by uPnP */
|
|
||||||
bool upnphandler::getInternalAddress(struct sockaddr_in &addr)
|
|
||||||
{
|
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
|
||||||
addr = upnp_iaddr;
|
|
||||||
bool valid = (upnpState >= RS_UPNP_S_ACTIVE);
|
|
||||||
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool upnphandler::getExternalAddress(struct sockaddr_in &addr)
|
|
||||||
{
|
|
||||||
std::string externalAdress = cUPnPControlPoint->getExternalAddress();
|
|
||||||
|
|
||||||
if(!externalAdress.empty() && externalAdress != "")
|
|
||||||
{
|
|
||||||
const char* externalIPAddress = externalAdress.c_str();
|
|
||||||
|
|
||||||
#ifdef UPNP_DEBUG
|
|
||||||
std::cerr << " upnphandler::getExternalAddress() : " << externalIPAddress;
|
|
||||||
std::cerr << ":" << eport_curr;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
|
||||||
sockaddr_clear(&upnp_eaddr);
|
|
||||||
inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr));
|
|
||||||
upnp_eaddr.sin_family = AF_INET;
|
|
||||||
upnp_eaddr.sin_port = htons(eport_curr);
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
|
|
||||||
addr = upnp_eaddr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Windows / Mac version.
|
// Windows / Mac version.
|
||||||
#if defined(WINDOWS_SYS) || defined(__APPLE__)
|
|
||||||
|
|
||||||
/* This stuff is actually C */
|
/* This stuff is actually C */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -1001,4 +565,3 @@ bool upnphandler::getExternalAddress(struct sockaddr_in &addr)
|
|||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
@ -1,94 +1,4 @@
|
|||||||
//Linux only...
|
//windows/osx (miniupnpc) implementation
|
||||||
#if !defined(WINDOWS_SYS) && !defined(__APPLE__)
|
|
||||||
|
|
||||||
#ifndef _RS_UPNP_IFACE_H
|
|
||||||
#define _RS_UPNP_IFACE_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* platform independent networking... */
|
|
||||||
#include "pqi/pqinetwork.h"
|
|
||||||
#include "pqi/pqiassist.h"
|
|
||||||
|
|
||||||
#include "util/rsthreads.h"
|
|
||||||
|
|
||||||
#include <upnp/upnp.h>
|
|
||||||
#include "upnp/UPnPBase.h"
|
|
||||||
|
|
||||||
#define RS_UPNP_S_UNINITIALISED 0
|
|
||||||
#define RS_UPNP_S_UNAVAILABLE 1
|
|
||||||
#define RS_UPNP_S_READY 2
|
|
||||||
#define RS_UPNP_S_TCP_AND_FAILED 3
|
|
||||||
//#define RS_UPNP_S_UDP_FAILED 4
|
|
||||||
#define RS_UPNP_S_ACTIVE 5
|
|
||||||
|
|
||||||
class upnphandler: public pqiNetAssistFirewall
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
upnphandler();
|
|
||||||
virtual ~upnphandler();
|
|
||||||
|
|
||||||
/* External Interface (pqiNetAssistFirewall) */
|
|
||||||
virtual void enable(bool active);
|
|
||||||
virtual void shutdown();
|
|
||||||
virtual void restart();
|
|
||||||
|
|
||||||
virtual bool getEnabled();
|
|
||||||
virtual bool getActive();
|
|
||||||
|
|
||||||
virtual void setInternalPort(unsigned short iport_in);
|
|
||||||
virtual void setExternalPort(unsigned short eport_in);
|
|
||||||
virtual bool getInternalAddress(struct sockaddr_in &addr);
|
|
||||||
virtual bool getExternalAddress(struct sockaddr_in &addr);
|
|
||||||
|
|
||||||
/* Public functions - for background thread operation,
|
|
||||||
* but effectively private from rest of RS, as in derived class
|
|
||||||
*/
|
|
||||||
unsigned int upnpState;
|
|
||||||
|
|
||||||
bool start_upnp();
|
|
||||||
bool shutdown_upnp();
|
|
||||||
|
|
||||||
bool initUPnPState();
|
|
||||||
|
|
||||||
/* Mutex for data below */
|
|
||||||
RsMutex dataMtx;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
CUPnPControlPoint *cUPnPControlPoint;
|
|
||||||
|
|
||||||
bool background_setup_upnp(bool, bool);
|
|
||||||
|
|
||||||
|
|
||||||
bool toEnable; /* overall on/off switch */
|
|
||||||
bool toStart; /* if set start forwarding */
|
|
||||||
bool toStop; /* if set stop forwarding */
|
|
||||||
|
|
||||||
unsigned short iport;
|
|
||||||
unsigned short eport; /* config */
|
|
||||||
unsigned short eport_curr; /* current forwarded */
|
|
||||||
|
|
||||||
/* info from upnp */
|
|
||||||
struct sockaddr_in upnp_iaddr;
|
|
||||||
struct sockaddr_in upnp_eaddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* info from upnp */
|
|
||||||
int CtrlPointCallbackEventHandler(Upnp_EventType ,void* , void*);
|
|
||||||
|
|
||||||
#endif /* _RS_UPNP_IFACE_H */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(WINDOWS_SYS) || defined(__APPLE__)
|
|
||||||
|
|
||||||
//windows implementation
|
|
||||||
#ifndef _RS_UPNP_IFACE_H
|
#ifndef _RS_UPNP_IFACE_H
|
||||||
#define _RS_UPNP_IFACE_H
|
#define _RS_UPNP_IFACE_H
|
||||||
|
|
||||||
@ -194,4 +104,3 @@ bool checkUPnPActive();
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _RS_UPNP_IFACE_H */
|
#endif /* _RS_UPNP_IFACE_H */
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user