Fixed up some Upnp issues:

* Enabled a lease duration (requires mods to miniupnpc library)
 * this is set at 10 mins for the moment.
 * Added Check functions to see if UPnP forwarding is still up.
 * improved error checking in Forward() function.
 * added #define for UDP local address testing.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@359 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2008-02-27 15:43:02 +00:00
parent 8b230a55cf
commit 31454138b7
6 changed files with 160 additions and 9 deletions

View File

@ -32,7 +32,9 @@
#include "util/rsprint.h" #include "util/rsprint.h"
#define DHT_DEBUG 1 #define DHT_DEBUG 1
/*****
* #define P3DHTMGR_USE_LOCAL_UDP_CONN 1 // For Testing only
****/
/**** DHT State Variables **** /**** DHT State Variables ****
* TODO: * TODO:
@ -743,7 +745,11 @@ int p3DhtMgr::checkNotifyDHT()
if (dhtNotify(peer.hash1, own.hash2, "")) if (dhtNotify(peer.hash1, own.hash2, ""))
{ {
/* feedback to say we started it! */ /* feedback to say we started it! */
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
connCb->peerConnectRequest(peer.id, peer.laddr, RS_CB_DHT);
#else
connCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT); connCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT);
#endif
} }
@ -1247,7 +1253,7 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
/* update data */ /* update data */
std::string peerid; std::string peerid;
struct sockaddr_in raddr; struct sockaddr_in raddr, laddr;
if (it != peers.end()) if (it != peers.end())
{ {
@ -1270,6 +1276,7 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
it->second.notifyPending = 0; it->second.notifyPending = 0;
peerid = (it->second).id; peerid = (it->second).id;
raddr = (it->second).raddr; raddr = (it->second).raddr;
laddr = (it->second).laddr;
} }
} }
else else
@ -1284,7 +1291,13 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
/* do callback */ /* do callback */
if (doNotify) if (doNotify)
{
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
connCb->peerConnectRequest(peerid, laddr, RS_CB_DHT);
#else
connCb->peerConnectRequest(peerid, raddr, RS_CB_DHT); connCb->peerConnectRequest(peerid, raddr, RS_CB_DHT);
#endif
}
return true; return true;
} }
@ -1376,7 +1389,11 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
//ent.type, RS_CB_LOCAL_ADDR | RS_CB_REMOTE_ADDR, RS_CB_DHT); //ent.type, RS_CB_LOCAL_ADDR | RS_CB_REMOTE_ADDR, RS_CB_DHT);
if (doNotify) if (doNotify)
{ {
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
connCb->peerConnectRequest(ent.id, ent.laddr, RS_CB_DHT);
#else
connCb->peerConnectRequest(ent.id, ent.raddr, RS_CB_DHT); connCb->peerConnectRequest(ent.id, ent.raddr, RS_CB_DHT);
#endif
} }
} }

View File

@ -297,7 +297,8 @@ int pqipersongrp::removePeer(std::string id)
if (it != mods.end()) if (it != mods.end())
{ {
SearchModule *mod = it->second; SearchModule *mod = it->second;
RemoveSearchModule(mod); // Don't duplicate remove!!!
//RemoveSearchModule(mod);
secpolicy_delete(mod -> sp); secpolicy_delete(mod -> sp);
pqiperson *p = (pqiperson *) mod -> pqi; pqiperson *p = (pqiperson *) mod -> pqi;
p -> reset(); p -> reset();

View File

@ -117,6 +117,7 @@ void upnphandler::checkUPnPState()
case RS_UPNP_S_UDP_FAILED: case RS_UPNP_S_UDP_FAILED:
case RS_UPNP_S_ACTIVE: case RS_UPNP_S_ACTIVE:
printUPnPState(); printUPnPState();
checkUPnPActive();
updateUPnP(); updateUPnP();
break; break;
@ -221,6 +222,65 @@ bool upnphandler::printUPnPState()
} }
bool upnphandler::checkUPnPActive()
{
dataMtx.lock(); /* LOCK 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;
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",
((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);
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;
}
}
dataMtx.unlock(); /* UNLOCK MUTEX */
return true;
}
bool upnphandler::updateUPnP() bool upnphandler::updateUPnP()
{ {

View File

@ -69,6 +69,8 @@ virtual void run();
bool initUPnPState(); bool initUPnPState();
void checkUPnPState(); void checkUPnPState();
bool printUPnPState(); bool printUPnPState();
bool checkUPnPActive();
bool updateUPnP(); bool updateUPnP();

View File

@ -115,6 +115,7 @@ bool SetRedirectAndTest(struct UPNPUrls * urls,
char externalIPAddress[16]; char externalIPAddress[16];
char intClient[16]; char intClient[16];
char intPort[6]; char intPort[6];
char leaseDuration[] = "600";
int r; int r;
int ok = 1; int ok = 1;
@ -139,11 +140,14 @@ bool SetRedirectAndTest(struct UPNPUrls * urls,
printf("GetExternalIPAddress failed.\n"); printf("GetExternalIPAddress failed.\n");
r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
eport, iport, iaddr, 0, proto); eport, iport, iaddr, 0, leaseDuration, proto);
if(r==0) if(r==0)
{ {
printf("AddPortMapping(%s, %s, %s) failed\n", eport, iport, iaddr); printf("AddPortMapping(%s, %s, %s) failed\n", eport, iport, iaddr);
ok = 0; //this seems to trigger for unknown reasons sometimes.
//rely on Checking it afterwards...
//should check IP address then!
//ok = 0;
} }
UPNP_GetSpecificPortMappingEntry(urls->controlURL, UPNP_GetSpecificPortMappingEntry(urls->controlURL,
@ -158,6 +162,16 @@ bool SetRedirectAndTest(struct UPNPUrls * urls,
ok = 0; 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", printf("external %s:%s is redirected to internal %s:%s\n",
externalIPAddress, eport, intClient, intPort); externalIPAddress, eport, intClient, intPort);
@ -173,6 +187,56 @@ bool SetRedirectAndTest(struct UPNPUrls * urls,
return ok; 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 bool

View File

@ -34,10 +34,17 @@ void ListRedirections(struct UPNPUrls * urls,
bool SetRedirectAndTest(struct UPNPUrls * urls, bool SetRedirectAndTest(struct UPNPUrls * urls,
struct IGDdatas * data, struct IGDdatas * data,
const char * iaddr, const char * iaddr,
const char * iport, const char * iport,
const char * eport, const char * eport,
const char * proto); 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, bool RemoveRedirect(struct UPNPUrls * urls,
struct IGDdatas * data, struct IGDdatas * data,