mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-25 06:40:58 -04:00
add compilation swtich : libupnp for linux and miniupnp for windows
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1786 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
e0d7178089
commit
49b24c2b14
8 changed files with 1063 additions and 16 deletions
|
@ -21,34 +21,32 @@ debug {
|
||||||
QMAKE_CXXFLAGS *= -g
|
QMAKE_CXXFLAGS *= -g
|
||||||
}
|
}
|
||||||
|
|
||||||
linux-g++ {
|
unix {
|
||||||
OBJECTS_DIR = temp/linux-g++/obj
|
|
||||||
DESTDIR = lib
|
DESTDIR = lib
|
||||||
QMAKE_CXXFLAGS *= -Wall
|
QMAKE_CXXFLAGS *= -Wall
|
||||||
QMAKE_CC = g++
|
QMAKE_CC = g++
|
||||||
|
|
||||||
SSL_DIR = /usr/include/openssl
|
SSL_DIR = /usr/include/openssl
|
||||||
UPNP_DIR = /usr/include/upnp
|
UPNP_DIR = /usr/include/upnp
|
||||||
|
INCLUDEPATH += . $${SSL_DIR} $${UPNP_DIR}
|
||||||
|
|
||||||
|
#gpg files
|
||||||
HEADERS += /usr/include/gpg-error.h
|
HEADERS += /usr/include/gpg-error.h
|
||||||
HEADERS += /usr/include/gpgme.h
|
HEADERS += /usr/include/gpgme.h
|
||||||
INCLUDEPATH += . $${SSL_DIR} $${UPNP_DIR}
|
|
||||||
|
#libupnp implementation files
|
||||||
|
HEADERS += upnp/UPnPBase.h
|
||||||
|
SOURCES += upnp/UPnPBase.cpp
|
||||||
|
|
||||||
CONFIG += version_detail_bash_script
|
CONFIG += version_detail_bash_script
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linux-g++ {
|
||||||
|
OBJECTS_DIR = temp/linux-g++/obj
|
||||||
|
}
|
||||||
|
|
||||||
linux-g++-64 {
|
linux-g++-64 {
|
||||||
OBJECTS_DIR = temp/linux-g++-64/obj
|
OBJECTS_DIR = temp/linux-g++-64/obj
|
||||||
DESTDIR = lib
|
|
||||||
QMAKE_CXXFLAGS *= -Wall
|
|
||||||
QMAKE_CC = g++
|
|
||||||
|
|
||||||
SSL_DIR = /usr/include/openssl
|
|
||||||
UPNP_DIR = /usr/include/upnp
|
|
||||||
HEADERS += /usr/include/gpg-error.h
|
|
||||||
HEADERS += /usr/include/gpgme.h
|
|
||||||
INCLUDEPATH += . $${SSL_DIR} $${UPNP_DIR}
|
|
||||||
|
|
||||||
CONFIG += version_detail_bash_script
|
|
||||||
}
|
}
|
||||||
|
|
||||||
version_detail_bash_script {
|
version_detail_bash_script {
|
||||||
|
@ -83,8 +81,10 @@ win32 {
|
||||||
OBJECTS_DIR = temp/obj
|
OBJECTS_DIR = temp/obj
|
||||||
MOC_DIR = temp/moc
|
MOC_DIR = temp/moc
|
||||||
DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW
|
DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW
|
||||||
|
DEFINES *= MINIUPNPC_VERSION=13
|
||||||
DESTDIR = lib
|
DESTDIR = lib
|
||||||
|
|
||||||
|
|
||||||
UPNPC_DIR = ../../../../miniupnpc-1.3
|
UPNPC_DIR = ../../../../miniupnpc-1.3
|
||||||
GPG_ERROR_DIR = ../../../../libgpg-error-1.7
|
GPG_ERROR_DIR = ../../../../libgpg-error-1.7
|
||||||
GPGME_DIR = ../../../../gpgme-1.1.8
|
GPGME_DIR = ../../../../gpgme-1.1.8
|
||||||
|
@ -93,7 +93,7 @@ win32 {
|
||||||
ZLIB_DIR = ../../../../zlib-1.2.3
|
ZLIB_DIR = ../../../../zlib-1.2.3
|
||||||
SSL_DIR = ../../../../OpenSSL
|
SSL_DIR = ../../../../OpenSSL
|
||||||
|
|
||||||
INCLUDEPATH += . $${SSL_DIR}/include $${UPNPC_DIR} $${PTHREADS_DIR} $${ZLIB_DIR}
|
INCLUDEPATH += . $${SSL_DIR}/include $${UPNPC_DIR} $${PTHREADS_DIR} $${ZLIB_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src
|
||||||
}
|
}
|
||||||
################################### COMMON stuff ##################################
|
################################### COMMON stuff ##################################
|
||||||
|
|
||||||
|
@ -286,7 +286,6 @@ SOURCES = \
|
||||||
ft/ftdwlqueue.cc \
|
ft/ftdwlqueue.cc \
|
||||||
dht/opendhtmgr.cc \
|
dht/opendhtmgr.cc \
|
||||||
upnp/upnphandler.cc \
|
upnp/upnphandler.cc \
|
||||||
upnp/UPnPBase.cpp \
|
|
||||||
dht/opendht.cc \
|
dht/opendht.cc \
|
||||||
dht/opendhtstr.cc \
|
dht/opendhtstr.cc \
|
||||||
dht/b64.c \
|
dht/b64.c \
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//This file uses libupnp
|
||||||
|
|
||||||
#define UPNP_C
|
#define UPNP_C
|
||||||
|
|
||||||
#include "UPnPBase.h"
|
#include "UPnPBase.h"
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//this file uses libupnp
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//Linux and macos implementation
|
||||||
|
#ifndef WINDOWS_SYS
|
||||||
|
|
||||||
/* This stuff is actually C */
|
/* This stuff is actually C */
|
||||||
|
|
||||||
|
@ -410,3 +412,578 @@ bool upnphandler::getExternalAddress(struct sockaddr_in &addr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WINDOWS_SYS
|
||||||
|
|
||||||
|
/* 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 "upnp/upnputil.h"
|
||||||
|
|
||||||
|
class uPnPConfigData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct UPNPDev * devlist;
|
||||||
|
struct UPNPUrls urls;
|
||||||
|
struct IGDdatas data;
|
||||||
|
char lanaddr[16]; /* my ip address on the LAN */
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "util/rsnet.h"
|
||||||
|
|
||||||
|
bool upnphandler::initUPnPState()
|
||||||
|
{
|
||||||
|
/* allocate memory */
|
||||||
|
uPnPConfigData *upcd = new uPnPConfigData;
|
||||||
|
|
||||||
|
#if MINIUPNPC_VERSION >= 11
|
||||||
|
/* Starting from version 1.1, miniupnpc api has a new parameter (int sameport) */
|
||||||
|
upcd->devlist = upnpDiscover(2000, NULL, NULL, 0);
|
||||||
|
#else
|
||||||
|
upcd->devlist = upnpDiscover(2000, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(upcd->devlist)
|
||||||
|
{
|
||||||
|
struct UPNPDev * device;
|
||||||
|
printf("List of UPNP devices found on the network :\n");
|
||||||
|
for(device=upcd->devlist;device;device=device->pNext)
|
||||||
|
{
|
||||||
|
printf("\n desc: %s\n st: %s\n",
|
||||||
|
device->descURL, device->st);
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
if(UPNP_GetValidIGD(upcd->devlist, &(upcd->urls),
|
||||||
|
&(upcd->data), upcd->lanaddr,
|
||||||
|
sizeof(upcd->lanaddr)))
|
||||||
|
{
|
||||||
|
printf("Found valid IGD : %s\n",
|
||||||
|
upcd->urls.controlURL);
|
||||||
|
printf("Local LAN ip address : %s\n",
|
||||||
|
upcd->lanaddr);
|
||||||
|
|
||||||
|
/* MODIFY STATE */
|
||||||
|
dataMtx.lock(); /* LOCK MUTEX */
|
||||||
|
|
||||||
|
/* convert to ipaddress. */
|
||||||
|
inet_aton(upcd->lanaddr, &(upnp_iaddr.sin_addr));
|
||||||
|
upnp_iaddr.sin_port = htons(iport);
|
||||||
|
|
||||||
|
upnpState = RS_UPNP_S_READY;
|
||||||
|
if (upnpConfig)
|
||||||
|
{
|
||||||
|
delete upnpConfig;
|
||||||
|
}
|
||||||
|
upnpConfig = upcd; /* */
|
||||||
|
|
||||||
|
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
|
|
||||||
|
|
||||||
|
/* done -> READY */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
freeUPNPDevlist(upcd->devlist);
|
||||||
|
upcd->devlist = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No IGD UPnP Device found on the network !\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MODIFY STATE */
|
||||||
|
dataMtx.lock(); /* LOCK MUTEX */
|
||||||
|
|
||||||
|
upnpState = RS_UPNP_S_UNAVAILABLE;
|
||||||
|
delete upcd;
|
||||||
|
upnpConfig = NULL;
|
||||||
|
|
||||||
|
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
|
|
||||||
|
/* done, FAILED -> NOT AVAILABLE */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::printUPnPState()
|
||||||
|
{
|
||||||
|
std::cerr << "upnphandler::printUPnPState() ... locking";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
||||||
|
|
||||||
|
std::cerr << "upnphandler::printUPnPState() ... locked";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
uPnPConfigData *config = upnpConfig;
|
||||||
|
if ((upnpState >= RS_UPNP_S_READY) && (config))
|
||||||
|
{
|
||||||
|
DisplayInfos(&(config -> urls), &(config->data));
|
||||||
|
GetConnectionStatus(&(config -> urls), &(config->data));
|
||||||
|
ListRedirections(&(config -> urls), &(config->data));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "UPNP not Ready" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool upnphandler::checkUPnPActive()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
||||||
|
|
||||||
|
uPnPConfigData *config = upnpConfig;
|
||||||
|
if ((upnpState > RS_UPNP_S_READY) && (config))
|
||||||
|
{
|
||||||
|
char eprot1[] = "TCP";
|
||||||
|
char eprot2[] = "UDP";
|
||||||
|
|
||||||
|
char in_addr[256];
|
||||||
|
char in_port1[256];
|
||||||
|
char in_port2[256];
|
||||||
|
char eport1[256];
|
||||||
|
char eport2[256];
|
||||||
|
|
||||||
|
struct sockaddr_in localAddr = upnp_iaddr;
|
||||||
|
uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr);
|
||||||
|
|
||||||
|
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
||||||
|
snprintf(in_port2, 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));
|
||||||
|
|
||||||
|
snprintf(eport1, 256, "%d", eport_curr);
|
||||||
|
snprintf(eport2, 256, "%d", eport_curr);
|
||||||
|
|
||||||
|
std::cerr << "upnphandler::checkUPnPState()";
|
||||||
|
std::cerr << " Checking Redirection: InAddr: " << in_addr;
|
||||||
|
std::cerr << " InPort: " << in_port1;
|
||||||
|
std::cerr << " ePort: " << eport1;
|
||||||
|
std::cerr << " eProt: " << eprot1;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
bool tcpOk = TestRedirect(&(config -> urls), &(config->data),
|
||||||
|
in_addr, in_port1, eport1, eprot1);
|
||||||
|
bool udpOk = TestRedirect(&(config -> urls), &(config->data),
|
||||||
|
in_addr, in_port2, eport2, eprot2);
|
||||||
|
|
||||||
|
if ((!tcpOk) || (!udpOk))
|
||||||
|
{
|
||||||
|
std::cerr << "upnphandler::checkUPnPState() ... Redirect Expired, restarting";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
toStop = true;
|
||||||
|
toStart = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class upnpThreadData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
upnphandler *handler;
|
||||||
|
bool start;
|
||||||
|
bool stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thread routines */
|
||||||
|
extern "C" void* doSetupUPnP(void* p)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
data->handler->printUPnPState();
|
||||||
|
|
||||||
|
delete data;
|
||||||
|
pthread_exit(NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::background_setup_upnp(bool start, bool stop)
|
||||||
|
{
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
|
/* launch thread */
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
||||||
|
|
||||||
|
uPnPConfigData *config = upnpConfig;
|
||||||
|
if (!((upnpState >= RS_UPNP_S_READY) && (config)))
|
||||||
|
{
|
||||||
|
std::cerr << "upnphandler::start_upnp() Not Ready";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char eprot1[] = "TCP";
|
||||||
|
char eprot2[] = "UDP";
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
std::cerr << "Using LocalPort for extPort!";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eport_curr)
|
||||||
|
{
|
||||||
|
std::cerr << "Invalid eport ... ";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* our port */
|
||||||
|
char in_addr[256];
|
||||||
|
char in_port1[256];
|
||||||
|
char in_port2[256];
|
||||||
|
char eport1[256];
|
||||||
|
char eport2[256];
|
||||||
|
|
||||||
|
upnp_iaddr.sin_port = htons(iport);
|
||||||
|
struct sockaddr_in localAddr = upnp_iaddr;
|
||||||
|
uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr);
|
||||||
|
|
||||||
|
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
||||||
|
snprintf(in_port2, 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));
|
||||||
|
|
||||||
|
snprintf(eport1, 256, "%d", eport_curr);
|
||||||
|
snprintf(eport2, 256, "%d", eport_curr);
|
||||||
|
|
||||||
|
std::cerr << "Attempting Redirection: InAddr: " << in_addr;
|
||||||
|
std::cerr << " InPort: " << in_port1;
|
||||||
|
std::cerr << " ePort: " << eport1;
|
||||||
|
std::cerr << " eProt: " << eprot1;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
if (!SetRedirectAndTest(&(config -> urls), &(config->data),
|
||||||
|
in_addr, in_port1, eport1, eprot1))
|
||||||
|
{
|
||||||
|
upnpState = RS_UPNP_S_TCP_FAILED;
|
||||||
|
}
|
||||||
|
else if (!SetRedirectAndTest(&(config -> urls), &(config->data),
|
||||||
|
in_addr, in_port2, eport2, eprot2))
|
||||||
|
{
|
||||||
|
upnpState = RS_UPNP_S_UDP_FAILED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
upnpState = RS_UPNP_S_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* now store the external address */
|
||||||
|
char externalIPAddress[32];
|
||||||
|
UPNP_GetExternalIPAddress(config -> urls.controlURL,
|
||||||
|
config->data.servicetype,
|
||||||
|
externalIPAddress);
|
||||||
|
|
||||||
|
sockaddr_clear(&upnp_eaddr);
|
||||||
|
|
||||||
|
if(externalIPAddress[0])
|
||||||
|
{
|
||||||
|
std::cerr << "Stored External address: " << externalIPAddress;
|
||||||
|
std::cerr << ":" << eport_curr;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr));
|
||||||
|
upnp_eaddr.sin_family = AF_INET;
|
||||||
|
upnp_eaddr.sin_port = htons(eport_curr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "FAILED To get external Address";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
toStart = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::shutdown_upnp()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */
|
||||||
|
|
||||||
|
uPnPConfigData *config = upnpConfig;
|
||||||
|
if (!((upnpState >= RS_UPNP_S_READY) && (config)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char eprot1[] = "TCP";
|
||||||
|
char eprot2[] = "UDP";
|
||||||
|
|
||||||
|
/* always attempt this (unless no port number) */
|
||||||
|
if (eport_curr > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
char eport1[256];
|
||||||
|
char eport2[256];
|
||||||
|
|
||||||
|
snprintf(eport1, 256, "%d", eport_curr);
|
||||||
|
snprintf(eport2, 256, "%d", eport_curr);
|
||||||
|
|
||||||
|
std::cerr << "Attempting To Remove Redirection: port: " << eport1;
|
||||||
|
std::cerr << " Prot: " << eprot1;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
RemoveRedirect(&(config -> urls), &(config->data),
|
||||||
|
eport1, eprot1);
|
||||||
|
|
||||||
|
|
||||||
|
std::cerr << "Attempting To Remove Redirection: port: " << eport2;
|
||||||
|
std::cerr << " Prot: " << eprot2;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
RemoveRedirect(&(config -> urls), &(config->data),
|
||||||
|
eport2, eprot2);
|
||||||
|
|
||||||
|
upnpState = RS_UPNP_S_READY;
|
||||||
|
toStop = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ External Interface *****************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
upnphandler::upnphandler()
|
||||||
|
:toEnable(false), toStart(false), toStop(false),
|
||||||
|
eport(0), eport_curr(0),
|
||||||
|
upnpState(RS_UPNP_S_UNINITIALISED),
|
||||||
|
upnpConfig(NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
upnphandler::~upnphandler()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RsIface */
|
||||||
|
void upnphandler::enable(bool active)
|
||||||
|
{
|
||||||
|
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 */
|
||||||
|
|
||||||
|
shutdown_upnp();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void upnphandler::restart()
|
||||||
|
{
|
||||||
|
/* non-blocking call to shutdown upnp, and startup again. */
|
||||||
|
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 ***/
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// std::cerr << "UPnPHandler::setInternalAddress() pre Lock!" << std::endl;
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
// std::cerr << "UPnPHandler::setInternalAddress() postLock!" << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "UPnPHandler::setInternalPort(" << iport_in << ") current port: ";
|
||||||
|
std::cerr << iport << std::endl;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// std::cerr << "UPnPHandler::getExternalPort() pre Lock!" << std::endl;
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
// std::cerr << "UPnPHandler::getExternalPort() postLock!" << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "UPnPHandler::setExternalPort(" << eport_in << ") current port: ";
|
||||||
|
std::cerr << eport << std::endl;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
// std::cerr << "UPnPHandler::getInternalAddress() pre Lock!" << std::endl;
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
// std::cerr << "UPnPHandler::getInternalAddress() postLock!" << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "UPnPHandler::getInternalAddress()" << std::endl;
|
||||||
|
|
||||||
|
addr = upnp_iaddr;
|
||||||
|
bool valid = (upnpState >= RS_UPNP_S_ACTIVE);
|
||||||
|
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::getExternalAddress(struct sockaddr_in &addr)
|
||||||
|
{
|
||||||
|
// std::cerr << "UPnPHandler::getExternalAddress() pre Lock!" << std::endl;
|
||||||
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
// std::cerr << "UPnPHandler::getExternalAddress() postLock!" << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "UPnPHandler::getExternalAddress()" << std::endl;
|
||||||
|
addr = upnp_eaddr;
|
||||||
|
bool valid = (upnpState == RS_UPNP_S_ACTIVE);
|
||||||
|
|
||||||
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
//Linux and macos implementation
|
||||||
|
#ifndef WINDOWS_SYS
|
||||||
|
|
||||||
#ifndef _RS_UPNP_IFACE_H
|
#ifndef _RS_UPNP_IFACE_H
|
||||||
#define _RS_UPNP_IFACE_H
|
#define _RS_UPNP_IFACE_H
|
||||||
|
|
||||||
|
@ -76,3 +79,119 @@ class upnphandler: public pqiNetAssistFirewall
|
||||||
int CtrlPointCallbackEventHandler(Upnp_EventType ,void* , void*);
|
int CtrlPointCallbackEventHandler(Upnp_EventType ,void* , void*);
|
||||||
|
|
||||||
#endif /* _RS_UPNP_IFACE_H */
|
#endif /* _RS_UPNP_IFACE_H */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WINDOWS_SYS
|
||||||
|
//windows implementation
|
||||||
|
#ifndef _RS_UPNP_IFACE_H
|
||||||
|
#define _RS_UPNP_IFACE_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
/* platform independent networking... */
|
||||||
|
#include "pqi/pqinetwork.h"
|
||||||
|
#include "pqi/pqiassist.h"
|
||||||
|
|
||||||
|
#include "util/rsthreads.h"
|
||||||
|
|
||||||
|
class upnpentry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
std::string id;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
unsigned int flags;
|
||||||
|
int status;
|
||||||
|
int lastTs;
|
||||||
|
};
|
||||||
|
|
||||||
|
class upnpforward
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
unsigned int flags;
|
||||||
|
struct sockaddr_in iaddr;
|
||||||
|
struct sockaddr_in eaddr;
|
||||||
|
int status;
|
||||||
|
int lastTs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define RS_UPNP_S_UNINITIALISED 0
|
||||||
|
#define RS_UPNP_S_UNAVAILABLE 1
|
||||||
|
#define RS_UPNP_S_READY 2
|
||||||
|
#define RS_UPNP_S_TCP_FAILED 3
|
||||||
|
#define RS_UPNP_S_UDP_FAILED 4
|
||||||
|
#define RS_UPNP_S_ACTIVE 5
|
||||||
|
|
||||||
|
class uPnPConfigData;
|
||||||
|
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool start_upnp();
|
||||||
|
bool shutdown_upnp();
|
||||||
|
|
||||||
|
bool initUPnPState();
|
||||||
|
bool printUPnPState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool background_setup_upnp(bool, bool);
|
||||||
|
bool checkUPnPActive();
|
||||||
|
|
||||||
|
/* Mutex for data below */
|
||||||
|
RsMutex dataMtx;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
unsigned int upnpState;
|
||||||
|
uPnPConfigData *upnpConfig;
|
||||||
|
|
||||||
|
struct sockaddr_in upnp_iaddr;
|
||||||
|
struct sockaddr_in upnp_eaddr;
|
||||||
|
|
||||||
|
/* active port forwarding */
|
||||||
|
std::list<upnpforward> activeForwards;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _RS_UPNP_IFACE_H */
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//this file use miniupnp
|
||||||
|
|
||||||
#include "upnp/upnphandler.h"
|
#include "upnp/upnphandler.h"
|
||||||
|
|
||||||
|
|
291
libretroshare/src/upnp/upnputil.c
Normal file
291
libretroshare/src/upnp/upnputil.c
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
//this file uses miniupnp
|
||||||
|
|
||||||
|
#include "upnp/upnputil.h"
|
||||||
|
|
||||||
|
/* protofix() checks if protocol is "UDP" or "TCP"
|
||||||
|
* returns NULL if not */
|
||||||
|
const char * protofix(const char * proto)
|
||||||
|
{
|
||||||
|
static const char proto_tcp[4] = { 'T', 'C', 'P', 0};
|
||||||
|
static const char proto_udp[4] = { 'U', 'D', 'P', 0};
|
||||||
|
int i, b;
|
||||||
|
for(i=0, b=1; i<4; i++)
|
||||||
|
b = b && ( (proto[i] == proto_tcp[i])
|
||||||
|
|| (proto[i] == (proto_tcp[i] | 32)) );
|
||||||
|
if(b)
|
||||||
|
return proto_tcp;
|
||||||
|
for(i=0, b=1; i<4; i++)
|
||||||
|
b = b && ( (proto[i] == proto_udp[i])
|
||||||
|
|| (proto[i] == (proto_udp[i] | 32)) );
|
||||||
|
if(b)
|
||||||
|
return proto_udp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayInfos(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
char externalIPAddress[16];
|
||||||
|
char connectionType[64];
|
||||||
|
char status[64];
|
||||||
|
char lastconnerror[64];
|
||||||
|
unsigned int uptime;
|
||||||
|
unsigned int brUp, brDown;
|
||||||
|
UPNP_GetConnectionTypeInfo(urls->controlURL,
|
||||||
|
data->servicetype,
|
||||||
|
connectionType);
|
||||||
|
if(connectionType[0])
|
||||||
|
printf("Connection Type : %s\n", connectionType);
|
||||||
|
else
|
||||||
|
printf("GetConnectionTypeInfo failed.\n");
|
||||||
|
UPNP_GetStatusInfo(urls->controlURL, data->servicetype, status, &uptime, lastconnerror);
|
||||||
|
printf("Status : %s, uptime=%u LastConnError %s\n", status, uptime, lastconnerror);
|
||||||
|
UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->servicetype_CIF,
|
||||||
|
&brDown, &brUp);
|
||||||
|
printf("MaxBitRateDown : %u bps MaxBitRateUp %u bps\n", brDown, brUp);
|
||||||
|
UPNP_GetExternalIPAddress(urls->controlURL,
|
||||||
|
data->servicetype,
|
||||||
|
externalIPAddress);
|
||||||
|
if(externalIPAddress[0])
|
||||||
|
printf("ExternalIPAddress = %s\n", externalIPAddress);
|
||||||
|
else
|
||||||
|
printf("GetExternalIPAddress failed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetConnectionStatus(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
|
||||||
|
DisplayInfos(urls, data);
|
||||||
|
bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->servicetype_CIF);
|
||||||
|
bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->servicetype_CIF);
|
||||||
|
packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->servicetype_CIF);
|
||||||
|
packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->servicetype_CIF);
|
||||||
|
printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
|
||||||
|
printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListRedirections(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
int i = 0;
|
||||||
|
char index[6];
|
||||||
|
char intClient[16];
|
||||||
|
char intPort[6];
|
||||||
|
char extPort[6];
|
||||||
|
char protocol[4];
|
||||||
|
char desc[80];
|
||||||
|
char enabled[6];
|
||||||
|
char rHost[64];
|
||||||
|
char duration[16];
|
||||||
|
/*unsigned int num=0;
|
||||||
|
UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
|
||||||
|
printf("PortMappingNumberOfEntries : %u\n", num);*/
|
||||||
|
do {
|
||||||
|
snprintf(index, 6, "%d", i);
|
||||||
|
rHost[0] = '\0'; enabled[0] = '\0';
|
||||||
|
duration[0] = '\0'; desc[0] = '\0';
|
||||||
|
extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
|
||||||
|
r = UPNP_GetGenericPortMappingEntry(urls->controlURL, data->servicetype,
|
||||||
|
index,
|
||||||
|
extPort, intClient, intPort,
|
||||||
|
protocol, desc, enabled,
|
||||||
|
rHost, duration);
|
||||||
|
if(r==0)
|
||||||
|
printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n"
|
||||||
|
" desc='%s' rHost='%s'\n",
|
||||||
|
i, protocol, extPort, intClient, intPort,
|
||||||
|
enabled, duration,
|
||||||
|
desc, rHost);
|
||||||
|
i++;
|
||||||
|
} while(r==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test function
|
||||||
|
* 1 - get connection type
|
||||||
|
* 2 - get extenal ip address
|
||||||
|
* 3 - Add port mapping
|
||||||
|
* 4 - get this port mapping from the IGD */
|
||||||
|
bool SetRedirectAndTest(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * iaddr,
|
||||||
|
const char * iport,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto)
|
||||||
|
{
|
||||||
|
char externalIPAddress[16];
|
||||||
|
char intClient[16];
|
||||||
|
char intPort[6];
|
||||||
|
char leaseDuration[] = "3600"; /* 60 mins */
|
||||||
|
int r;
|
||||||
|
int ok = 1;
|
||||||
|
|
||||||
|
if(!iaddr || !iport || !eport || !proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong arguments\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
proto = protofix(proto);
|
||||||
|
if(!proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid protocol\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPNP_GetExternalIPAddress(urls->controlURL,
|
||||||
|
data->servicetype,
|
||||||
|
externalIPAddress);
|
||||||
|
if(externalIPAddress[0])
|
||||||
|
printf("ExternalIPAddress = %s\n", externalIPAddress);
|
||||||
|
else
|
||||||
|
printf("GetExternalIPAddress failed.\n");
|
||||||
|
|
||||||
|
// Unix at the moment!
|
||||||
|
#if MINIUPNPC_VERSION >= 13
|
||||||
|
/* Starting from miniupnpc version 1.2, lease duration parameter is gone */
|
||||||
|
r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
|
eport, iport, iaddr, 0, proto, NULL);
|
||||||
|
#else
|
||||||
|
#if MINIUPNPC_VERSION >= 12
|
||||||
|
/* Starting from miniupnpc version 1.2, lease duration parameter is gone */
|
||||||
|
r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
|
eport, iport, iaddr, 0, proto);
|
||||||
|
#else
|
||||||
|
/* The lease parameter is also gone in minupnpc 1.0 */
|
||||||
|
r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
|
eport, iport, iaddr,0, 0, proto);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
|
// eport, iport, iaddr, 0, leaseDuration, proto);
|
||||||
|
|
||||||
|
// r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
|
// eport, iport, iaddr, 0, proto);
|
||||||
|
if(r==0)
|
||||||
|
{
|
||||||
|
printf("AddPortMapping(%s, %s, %s) failed\n", eport, iport, iaddr);
|
||||||
|
//this seems to trigger for unknown reasons sometimes.
|
||||||
|
//rely on Checking it afterwards...
|
||||||
|
//should check IP address then!
|
||||||
|
//ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPNP_GetSpecificPortMappingEntry(urls->controlURL,
|
||||||
|
data->servicetype,
|
||||||
|
eport, proto,
|
||||||
|
intClient, intPort);
|
||||||
|
if(intClient[0])
|
||||||
|
printf("InternalIP:Port = %s:%s\n", intClient, intPort);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("GetSpecificPortMappingEntry failed.\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((strcmp(iaddr, intClient) != 0) || (strcmp(iport, intPort) != 0))
|
||||||
|
{
|
||||||
|
printf("PortMappingEntry to wrong location! FAILED\n");
|
||||||
|
printf("IP1:\"%s\"\n", iaddr);
|
||||||
|
printf("IP2:\"%s\"\n", intClient);
|
||||||
|
printf("PORT1:\"%s\"\n", iport);
|
||||||
|
printf("PORT2:\"%s\"\n", intPort);
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("external %s:%s is redirected to internal %s:%s\n",
|
||||||
|
externalIPAddress, eport, intClient, intPort);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
printf("uPnP Forward/Mapping Succeeded\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("uPnP Forward/Mapping Failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestRedirect(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * iaddr,
|
||||||
|
const char * iport,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto)
|
||||||
|
{
|
||||||
|
char intClient[16];
|
||||||
|
char intPort[6];
|
||||||
|
int ok = 1;
|
||||||
|
|
||||||
|
if(!iaddr || !iport || !eport || !proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong arguments\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
proto = protofix(proto);
|
||||||
|
if(!proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid protocol\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPNP_GetSpecificPortMappingEntry(urls->controlURL,
|
||||||
|
data->servicetype,
|
||||||
|
eport, proto,
|
||||||
|
intClient, intPort);
|
||||||
|
if(intClient[0])
|
||||||
|
printf("uPnP Check: InternalIP:Port = %s:%s\n", intClient, intPort);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("GetSpecificPortMappingEntry failed.\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("uPnP Check: External port %s is redirected to internal %s:%s\n",
|
||||||
|
eport, intClient, intPort);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
printf("uPnP Check: uPnP Forward/Mapping still Active\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("uPnP Check: Forward/Mapping has been Dropped\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
RemoveRedirect(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto)
|
||||||
|
{
|
||||||
|
if(!proto || !eport)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid arguments\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
proto = protofix(proto);
|
||||||
|
if(!proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "protocol invalid\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#if MINIUPNPC_VERSION >= 13
|
||||||
|
UPNP_DeletePortMapping(urls->controlURL, data->servicetype, eport, proto, NULL);
|
||||||
|
#else
|
||||||
|
UPNP_DeletePortMapping(urls->controlURL, data->servicetype, eport, proto);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* EOF */
|
56
libretroshare/src/upnp/upnputil.h
Normal file
56
libretroshare/src/upnp/upnputil.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
//this file uses miniupnp
|
||||||
|
|
||||||
|
#ifndef MINIUPNP_UTIL_H_
|
||||||
|
#define MINIUPNP_UTIL_H_
|
||||||
|
|
||||||
|
/* $Id: upnpc.c,v 1.50 2007/04/26 19:00:10 nanard Exp $ */
|
||||||
|
/* Project : miniupnp
|
||||||
|
* Author : Thomas Bernard
|
||||||
|
* Copyright (c) 2005 Thomas Bernard
|
||||||
|
* This software is subject to the conditions detailed in the
|
||||||
|
* LICENCE file provided in this distribution.
|
||||||
|
* */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
#include <miniwget.h>
|
||||||
|
#include <miniupnpc.h>
|
||||||
|
#include <upnpcommands.h>
|
||||||
|
|
||||||
|
/* protofix() checks if protocol is "UDP" or "TCP"
|
||||||
|
* returns NULL if not */
|
||||||
|
const char * protofix(const char * proto);
|
||||||
|
void DisplayInfos(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data);
|
||||||
|
|
||||||
|
void GetConnectionStatus(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data);
|
||||||
|
|
||||||
|
void ListRedirections(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data);
|
||||||
|
|
||||||
|
bool SetRedirectAndTest(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * iaddr,
|
||||||
|
const char * iport,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto);
|
||||||
|
|
||||||
|
bool TestRedirect(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * iaddr,
|
||||||
|
const char * iport,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto);
|
||||||
|
|
||||||
|
bool RemoveRedirect(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto);
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue