diff --git a/libretroshare/src/pqi/p3dhtmgr.cc b/libretroshare/src/pqi/p3dhtmgr.cc index 58c1ff41d..63dc4842e 100644 --- a/libretroshare/src/pqi/p3dhtmgr.cc +++ b/libretroshare/src/pqi/p3dhtmgr.cc @@ -32,7 +32,9 @@ #include "util/rsprint.h" #define DHT_DEBUG 1 - +/***** + * #define P3DHTMGR_USE_LOCAL_UDP_CONN 1 // For Testing only + ****/ /**** DHT State Variables **** * TODO: @@ -743,7 +745,11 @@ int p3DhtMgr::checkNotifyDHT() if (dhtNotify(peer.hash1, own.hash2, "")) { /* 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); +#endif } @@ -1247,7 +1253,7 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash) /* update data */ std::string peerid; - struct sockaddr_in raddr; + struct sockaddr_in raddr, laddr; if (it != peers.end()) { @@ -1270,6 +1276,7 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash) it->second.notifyPending = 0; peerid = (it->second).id; raddr = (it->second).raddr; + laddr = (it->second).laddr; } } else @@ -1284,7 +1291,13 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash) /* do callback */ if (doNotify) + { +#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN + connCb->peerConnectRequest(peerid, laddr, RS_CB_DHT); +#else connCb->peerConnectRequest(peerid, raddr, RS_CB_DHT); +#endif + } 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); 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); +#endif } } diff --git a/libretroshare/src/pqi/pqipersongrp.cc b/libretroshare/src/pqi/pqipersongrp.cc index 3f7d9133a..8120fb5fd 100644 --- a/libretroshare/src/pqi/pqipersongrp.cc +++ b/libretroshare/src/pqi/pqipersongrp.cc @@ -297,7 +297,8 @@ int pqipersongrp::removePeer(std::string id) if (it != mods.end()) { SearchModule *mod = it->second; - RemoveSearchModule(mod); + // Don't duplicate remove!!! + //RemoveSearchModule(mod); secpolicy_delete(mod -> sp); pqiperson *p = (pqiperson *) mod -> pqi; p -> reset(); diff --git a/libretroshare/src/upnp/upnphandler.cc b/libretroshare/src/upnp/upnphandler.cc index 588fa510f..0a628c292 100644 --- a/libretroshare/src/upnp/upnphandler.cc +++ b/libretroshare/src/upnp/upnphandler.cc @@ -117,6 +117,7 @@ void upnphandler::checkUPnPState() case RS_UPNP_S_UDP_FAILED: case RS_UPNP_S_ACTIVE: printUPnPState(); + checkUPnPActive(); updateUPnP(); 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() { diff --git a/libretroshare/src/upnp/upnphandler.h b/libretroshare/src/upnp/upnphandler.h index 4fdeb7ea6..fac6eb900 100644 --- a/libretroshare/src/upnp/upnphandler.h +++ b/libretroshare/src/upnp/upnphandler.h @@ -69,6 +69,8 @@ virtual void run(); bool initUPnPState(); void checkUPnPState(); bool printUPnPState(); + +bool checkUPnPActive(); bool updateUPnP(); diff --git a/libretroshare/src/upnp/upnputil.c b/libretroshare/src/upnp/upnputil.c index 915f5dc12..befd19b0e 100644 --- a/libretroshare/src/upnp/upnputil.c +++ b/libretroshare/src/upnp/upnputil.c @@ -115,6 +115,7 @@ bool SetRedirectAndTest(struct UPNPUrls * urls, char externalIPAddress[16]; char intClient[16]; char intPort[6]; + char leaseDuration[] = "600"; int r; int ok = 1; @@ -139,11 +140,14 @@ bool SetRedirectAndTest(struct UPNPUrls * urls, printf("GetExternalIPAddress failed.\n"); r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, - eport, iport, iaddr, 0, proto); + eport, iport, iaddr, 0, leaseDuration, proto); if(r==0) { 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, @@ -158,6 +162,16 @@ bool SetRedirectAndTest(struct UPNPUrls * urls, 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); @@ -173,6 +187,56 @@ bool SetRedirectAndTest(struct UPNPUrls * urls, 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 diff --git a/libretroshare/src/upnp/upnputil.h b/libretroshare/src/upnp/upnputil.h index 3c8e74b18..61d6332e2 100644 --- a/libretroshare/src/upnp/upnputil.h +++ b/libretroshare/src/upnp/upnputil.h @@ -34,10 +34,17 @@ void ListRedirections(struct UPNPUrls * urls, bool SetRedirectAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto); + 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,