mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 22:25:04 -04:00
Created V0.3.x branch and moved the head into the trunk directory.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@246 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
commit
935745a08e
1318 changed files with 348809 additions and 0 deletions
26
libretroshare/src/upnp/Makefile
Normal file
26
libretroshare/src/upnp/Makefile
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
RS_TOP_DIR = ..
|
||||
include ../make.opt
|
||||
|
||||
OBJ = upnphandler.o upnputil.o
|
||||
|
||||
CFLAGS += -I$(UPNPC_DIR) -DMINIUPNP_EXPORTS
|
||||
|
||||
all : $(OBJ) librs upnptest
|
||||
|
||||
upnptest: $(OBJ) upnptest.o
|
||||
$(CC) $(CFLAGS) -o upnptest $(OBJ) upnptest.o $(RSLIBS)
|
||||
|
||||
librs: $(OBJ)
|
||||
$(AR) r $(LIBRS) $(OBJ)
|
||||
$(RANLIB) $(LIBRS)
|
||||
|
||||
.cc.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
clean:
|
||||
-/bin/rm $(OBJ) upnptest.o
|
||||
|
||||
clobber: clean
|
||||
-/bin/rm upnptest
|
||||
|
356
libretroshare/src/upnp/upnphandler.cc
Normal file
356
libretroshare/src/upnp/upnphandler.cc
Normal file
|
@ -0,0 +1,356 @@
|
|||
|
||||
#include "dht/dhthandler.h"
|
||||
|
||||
|
||||
/* This stuff is actually C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
#endif
|
||||
/* This stuff is actually C */
|
||||
|
||||
|
||||
|
||||
|
||||
/* HACK TO SWITCH THIS OFF during testing */
|
||||
/*define NO_UPNP_RUNNING 1*/
|
||||
|
||||
#include "upnp/upnputil.h"
|
||||
#include "upnp/upnphandler.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>
|
||||
|
||||
|
||||
void upnphandler::run()
|
||||
{
|
||||
|
||||
/* infinite loop */
|
||||
while(1)
|
||||
{
|
||||
std::cerr << "UPnPHandler::Run()" << std::endl;
|
||||
int allowedSleep = 30; /* check every 30 seconds */
|
||||
|
||||
/* lock it up */
|
||||
dataMtx.lock(); /* LOCK MUTEX */
|
||||
|
||||
bool shutdown = toShutdown;
|
||||
int state = upnpState;
|
||||
|
||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
if (shutdown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* do the work! */
|
||||
checkUPnPState();
|
||||
|
||||
/* check new state for sleep period */
|
||||
|
||||
dataMtx.lock(); /* LOCK MUTEX */
|
||||
|
||||
state = upnpState;
|
||||
|
||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
|
||||
/* state machine */
|
||||
switch(state)
|
||||
{
|
||||
case RS_UPNP_S_UNINITIALISED:
|
||||
case RS_UPNP_S_UNAVAILABLE:
|
||||
/* failed ... try again in 30 min. */
|
||||
allowedSleep = 1800;
|
||||
break;
|
||||
|
||||
case RS_UPNP_S_READY:
|
||||
case RS_UPNP_S_TCP_FAILED:
|
||||
case RS_UPNP_S_UDP_FAILED:
|
||||
case RS_UPNP_S_ACTIVE:
|
||||
/* working ... normal 15 seconds */
|
||||
allowedSleep = 15;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* default??? how did it get here? */
|
||||
break;
|
||||
}
|
||||
|
||||
std::cerr << "UPnPHandler::Run() sleeping for:" << allowedSleep << std::endl;
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
sleep(allowedSleep);
|
||||
#else
|
||||
Sleep(1000 * allowedSleep);
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void upnphandler::checkUPnPState()
|
||||
{
|
||||
dataMtx.lock(); /* LOCK MUTEX */
|
||||
|
||||
int state = upnpState;
|
||||
|
||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
/* state machine */
|
||||
switch(state)
|
||||
{
|
||||
case RS_UPNP_S_UNINITIALISED:
|
||||
case RS_UPNP_S_UNAVAILABLE:
|
||||
initUPnPState();
|
||||
break;
|
||||
|
||||
case RS_UPNP_S_READY:
|
||||
case RS_UPNP_S_TCP_FAILED:
|
||||
case RS_UPNP_S_UDP_FAILED:
|
||||
case RS_UPNP_S_ACTIVE:
|
||||
printUPnPState();
|
||||
updateUPnP();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool upnphandler::initUPnPState()
|
||||
{
|
||||
/* allocate memory */
|
||||
uPnPConfigData *upcd = new uPnPConfigData;
|
||||
|
||||
upcd->devlist = upnpDiscover(2000);
|
||||
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 = iaddr.sin_port;
|
||||
|
||||
upnpState = RS_UPNP_S_READY;
|
||||
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");
|
||||
}
|
||||
|
||||
upnpState = RS_UPNP_S_UNAVAILABLE;
|
||||
delete upcd;
|
||||
upnpConfig = NULL;
|
||||
|
||||
/* done, FAILED -> NOT AVAILABLE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool upnphandler::printUPnPState()
|
||||
{
|
||||
std::cerr << "upnphandler::printUPnPState() ... locking";
|
||||
std::cerr << std::endl;
|
||||
|
||||
dataMtx.lock(); /* LOCK 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;
|
||||
}
|
||||
|
||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool upnphandler::updateUPnP()
|
||||
{
|
||||
dataMtx.lock(); /* LOCK MUTEX */
|
||||
|
||||
|
||||
uPnPConfigData *config = upnpConfig;
|
||||
if (!((upnpState >= RS_UPNP_S_READY) && (config)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char eprot1[] = "TCP";
|
||||
char eprot2[] = "UDP";
|
||||
|
||||
/* if we're to unload -> unload */
|
||||
if ((toStop) && (eport_curr > 0))
|
||||
{
|
||||
toStop = false;
|
||||
|
||||
char eport1[256];
|
||||
char eport2[256];
|
||||
|
||||
snprintf(eport1, 256, "%d", eport_curr);
|
||||
snprintf(eport2, 256, "%d", eport_curr + 1);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* if we're to load -> load */
|
||||
if (toStart)
|
||||
{
|
||||
/* select external ports */
|
||||
eport_curr = eport;
|
||||
if (!eport_curr)
|
||||
{
|
||||
/* use local port if eport is zero */
|
||||
eport_curr = ntohs(iaddr.sin_port);
|
||||
std::cerr << "Using LocalPort for extPort!";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
if (!eport_curr)
|
||||
{
|
||||
std::cerr << "Invalid eport ... ";
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
toStart = false;
|
||||
|
||||
/* our port */
|
||||
char in_addr[256];
|
||||
char in_port1[256];
|
||||
char in_port2[256];
|
||||
char eport1[256];
|
||||
char eport2[256];
|
||||
|
||||
//struct sockaddr_in localAddr = iaddr;
|
||||
if (iaddr.sin_addr.s_addr != upnp_iaddr.sin_addr.s_addr)
|
||||
{
|
||||
std::cerr << "Warning ... Address Mismatch!";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
upnp_iaddr.sin_port = iaddr.sin_port;
|
||||
struct sockaddr_in localAddr = upnp_iaddr;
|
||||
|
||||
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
||||
snprintf(in_port2, 256, "%d", ntohs(localAddr.sin_port) + 1);
|
||||
snprintf(in_addr, 256, "%d.%d.%d.%d",
|
||||
((localAddr.sin_addr.s_addr >> 0) & 0xff),
|
||||
((localAddr.sin_addr.s_addr >> 8) & 0xff),
|
||||
((localAddr.sin_addr.s_addr >> 16) & 0xff),
|
||||
((localAddr.sin_addr.s_addr >> 24) & 0xff));
|
||||
|
||||
snprintf(eport1, 256, "%d", eport_curr);
|
||||
snprintf(eport2, 256, "%d", eport_curr + 1);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
230
libretroshare/src/upnp/upnphandler.h
Normal file
230
libretroshare/src/upnp/upnphandler.h
Normal file
|
@ -0,0 +1,230 @@
|
|||
#ifndef _RS_UPNP_IFACE_H
|
||||
#define _RS_UPNP_IFACE_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "util/rsthreads.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
/* platform independent networking... */
|
||||
#include "pqi/pqinetwork.h"
|
||||
#include "pqi/pqiaddrstore.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 RsThread
|
||||
{
|
||||
public:
|
||||
|
||||
upnphandler()
|
||||
:toShutdown(false), toEnable(false),
|
||||
toStart(false), toStop(false),
|
||||
eport(0), eport_curr(0),
|
||||
upnpState(RS_UPNP_S_UNINITIALISED),
|
||||
upnpConfig(NULL)
|
||||
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
~upnphandler()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* RsIface */
|
||||
void enableUPnP(bool active)
|
||||
{
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
|
||||
toEnable = active;
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
}
|
||||
|
||||
/* RsIface */
|
||||
void shutdownUPnP()
|
||||
{
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
|
||||
toShutdown = true;
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
}
|
||||
|
||||
void setupUPnPForwarding()
|
||||
{
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
|
||||
toStart = true;
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
}
|
||||
|
||||
void shutdownUPnPForwarding()
|
||||
{
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
|
||||
toStop = true;
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
}
|
||||
|
||||
|
||||
/* the address that the listening port is on */
|
||||
void setInternalAddress(struct sockaddr_in iaddr_in)
|
||||
{
|
||||
// std::cerr << "UPnPHandler::setInternalAddress() pre Lock!" << std::endl;
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
// std::cerr << "UPnPHandler::setInternalAddress() postLock!" << std::endl;
|
||||
|
||||
if ((iaddr.sin_addr.s_addr != iaddr_in.sin_addr.s_addr) ||
|
||||
(iaddr.sin_port != iaddr_in.sin_port))
|
||||
{
|
||||
iaddr = iaddr_in;
|
||||
if (toEnable)
|
||||
{
|
||||
toStop = true;
|
||||
toStart = true;
|
||||
}
|
||||
}
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
}
|
||||
|
||||
void setExternalPort(unsigned short eport_in)
|
||||
{
|
||||
// std::cerr << "UPnPHandler::getExternalPort() pre Lock!" << std::endl;
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
// std::cerr << "UPnPHandler::getExternalPort() postLock!" << std::endl;
|
||||
|
||||
/* flag both shutdown/start -> for restart */
|
||||
if (eport != eport_in)
|
||||
{
|
||||
eport = eport_in;
|
||||
if (toEnable)
|
||||
{
|
||||
toStop = true;
|
||||
toStart = true;
|
||||
}
|
||||
}
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
}
|
||||
|
||||
/* as determined by uPnP */
|
||||
bool getInternalAddress(struct sockaddr_in &addr)
|
||||
{
|
||||
// std::cerr << "UPnPHandler::getInternalAddress() pre Lock!" << std::endl;
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
// std::cerr << "UPnPHandler::getInternalAddress() postLock!" << std::endl;
|
||||
|
||||
addr = upnp_iaddr;
|
||||
bool valid = (upnpState >= RS_UPNP_S_READY);
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool getExternalAddress(struct sockaddr_in &addr)
|
||||
{
|
||||
// std::cerr << "UPnPHandler::getExternalAddress() pre Lock!" << std::endl;
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
// std::cerr << "UPnPHandler::getExternalAddress() postLock!" << std::endl;
|
||||
|
||||
addr = upnp_eaddr;
|
||||
bool valid = (upnpState >= RS_UPNP_S_READY);
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
int getUPnPStatus(upnpentry &ent)
|
||||
{
|
||||
// std::cerr << "UPnPHandler::getUPnPStatus() pre Lock!" << std::endl;
|
||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||
// std::cerr << "UPnPHandler::getUPnPStatus() postLock!" << std::endl;
|
||||
|
||||
/* TODO - define data structure first */
|
||||
int state = upnpState;
|
||||
|
||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
int init();
|
||||
int shutdown();
|
||||
int print();
|
||||
|
||||
/* must run thread */
|
||||
virtual void run();
|
||||
|
||||
private:
|
||||
|
||||
bool initUPnPState();
|
||||
void checkUPnPState();
|
||||
bool printUPnPState();
|
||||
bool updateUPnP();
|
||||
|
||||
|
||||
/* Mutex for data below */
|
||||
RsMutex dataMtx;
|
||||
|
||||
/* requested from rs */
|
||||
bool toShutdown; /* if set shuts down the thread. */
|
||||
|
||||
bool toEnable; /* overall on/off switch */
|
||||
bool toStart; /* if set start forwarding */
|
||||
bool toStop; /* if set stop forwarding */
|
||||
|
||||
struct sockaddr_in iaddr;
|
||||
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 */
|
110
libretroshare/src/upnp/upnptest.cc
Normal file
110
libretroshare/src/upnp/upnptest.cc
Normal file
|
@ -0,0 +1,110 @@
|
|||
|
||||
#include "upnp/upnphandler.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
int id = argc % 3;
|
||||
|
||||
/*********
|
||||
char *fhash1 = "3509426505463458576487";
|
||||
char *hash2 = "1549879882341985914515";
|
||||
char *hash3 = "8743598543269526505434";
|
||||
|
||||
int port1 = 8754;
|
||||
int port2 = 2355;
|
||||
int port3 = 6621;
|
||||
**********/
|
||||
|
||||
std::cerr << "Starting dhttest Id: " << id << std::endl;
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#else
|
||||
// Windows Networking Init.
|
||||
WORD wVerReq = MAKEWORD(2,2);
|
||||
WSADATA wsaData;
|
||||
|
||||
if (0 != WSAStartup(wVerReq, &wsaData))
|
||||
{
|
||||
std::cerr << "Failed to Startup Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Started Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_process_attach_np();
|
||||
#endif
|
||||
|
||||
|
||||
upnphandler upnp;
|
||||
|
||||
upnp.start();
|
||||
|
||||
#ifdef NOTEVER
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
dht.setOwnPort(port1);
|
||||
dht.setOwnHash(hash1);
|
||||
|
||||
dht.addFriend(hash2);
|
||||
dht.addFriend(hash3);
|
||||
}
|
||||
else if (id == 1)
|
||||
{
|
||||
dht.setOwnPort(port2);
|
||||
dht.setOwnHash(hash2);
|
||||
|
||||
dht.addFriend(hash1);
|
||||
dht.addFriend(hash3);
|
||||
}
|
||||
else
|
||||
{
|
||||
dht.setOwnPort(port3);
|
||||
dht.setOwnHash(hash3);
|
||||
|
||||
dht.addFriend(hash1);
|
||||
dht.addFriend(hash2);
|
||||
}
|
||||
#endif /* NOTEVER */
|
||||
|
||||
for(int i = 0; 1; i++)
|
||||
{
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
sleep(1);
|
||||
#else
|
||||
|
||||
Sleep(1000);
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
||||
if (i % 300 == 10)
|
||||
{
|
||||
/* start up a forward */
|
||||
upnp.setupUPnPForwarding();
|
||||
|
||||
}
|
||||
|
||||
if (i % 300 == 20)
|
||||
{
|
||||
/* shutdown a forward */
|
||||
upnp.shutdownUPnPForwarding();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
201
libretroshare/src/upnp/upnputil.c
Normal file
201
libretroshare/src/upnp/upnputil.c
Normal file
|
@ -0,0 +1,201 @@
|
|||
|
||||
#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];
|
||||
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);
|
||||
printf("Status : %s, uptime=%u\n", status, uptime);
|
||||
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];
|
||||
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");
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
UPNP_DeletePortMapping(urls->controlURL, data->servicetype, eport, proto);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
48
libretroshare/src/upnp/upnputil.h
Normal file
48
libretroshare/src/upnp/upnputil.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
|
||||
#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 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