add a timeout to ext addr finder

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1778 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
joss17 2009-10-30 00:44:04 +00:00
parent c517e42f25
commit 95888fed59
3 changed files with 91 additions and 61 deletions

View file

@ -43,10 +43,9 @@ const uint32_t RS_NET_NEED_RESET = 0x0000;
const uint32_t RS_NET_UNKNOWN = 0x0001; const uint32_t RS_NET_UNKNOWN = 0x0001;
const uint32_t RS_NET_UPNP_INIT = 0x0002; const uint32_t RS_NET_UPNP_INIT = 0x0002;
const uint32_t RS_NET_UPNP_SETUP = 0x0003; const uint32_t RS_NET_UPNP_SETUP = 0x0003;
const uint32_t RS_NET_EXT_ADDR_FINDER = 0x0004; const uint32_t RS_NET_DONE = 0x0004;
const uint32_t RS_NET_DONE = 0x0005; const uint32_t RS_NET_LOOPBACK = 0x0005;
const uint32_t RS_NET_LOOPBACK = 0x0006; const uint32_t RS_NET_MODE_DOWN = 0x0006;
const uint32_t RS_NET_MODE_DOWN = 0x0007;
/* Stun modes (TODO) */ /* Stun modes (TODO) */
const uint32_t RS_STUN_DHT = 0x0001; const uint32_t RS_STUN_DHT = 0x0001;
@ -54,7 +53,7 @@ const uint32_t RS_STUN_DONE = 0x0002;
const uint32_t RS_STUN_LIST_MIN = 100; const uint32_t RS_STUN_LIST_MIN = 100;
const uint32_t RS_STUN_FOUND_MIN = 10; const uint32_t RS_STUN_FOUND_MIN = 10;
const uint32_t MAX_UPNP_INIT = 70; /* seconds UPnP timeout */ const uint32_t MAX_UPNP_INIT = 20; /* seconds UPnP timeout */
const uint32_t MAX_NETWORK_INIT = 75; /* seconds Udp timeout */ const uint32_t MAX_NETWORK_INIT = 75; /* seconds Udp timeout */
const uint32_t MIN_TIME_BETWEEN_NET_RESET = 5; const uint32_t MIN_TIME_BETWEEN_NET_RESET = 5;
@ -384,10 +383,10 @@ void p3ConnectMgr::netStartup()
switch(ownState.netMode & RS_NET_MODE_TRYMODE) switch(ownState.netMode & RS_NET_MODE_TRYMODE)
{ {
case RS_NET_MODE_TRY_EXT: /* v similar to UDP */ // case RS_NET_MODE_TRY_EXT: /* v similar to UDP */
ownState.netMode |= RS_NET_MODE_EXT; // ownState.netMode |= RS_NET_MODE_EXT;
mNetStatus = RS_NET_EXT_ADDR_FINDER; // mNetStatus = RS_NET_EXT_ADDR_FINDER;
break; // break;
case RS_NET_MODE_TRY_UDP: case RS_NET_MODE_TRY_UDP:
ownState.netMode |= RS_NET_MODE_UDP; ownState.netMode |= RS_NET_MODE_UDP;
@ -513,6 +512,11 @@ void p3ConnectMgr::netTick()
connMtx.unlock(); /* UNLOCK MUTEX */ connMtx.unlock(); /* UNLOCK MUTEX */
//tick the extra adress finder
if ((netStatus > RS_NET_UNKNOWN) && use_extr_addr_finder && !netFlagExtraAddressCheckOk) {
netExtraAddressCheck();
}
switch(netStatus) switch(netStatus)
{ {
case RS_NET_NEED_RESET: case RS_NET_NEED_RESET:
@ -534,6 +538,7 @@ void p3ConnectMgr::netTick()
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::netTick() STATUS: UPNP_INIT" << std::endl; std::cerr << "p3ConnectMgr::netTick() STATUS: UPNP_INIT" << std::endl;
#endif #endif
netExtraAddressCheck();
netUpnpInit(); netUpnpInit();
break; break;
@ -544,19 +549,11 @@ void p3ConnectMgr::netTick()
netUpnpCheck(); netUpnpCheck();
break; break;
case RS_NET_EXT_ADDR_FINDER:
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::netTick() STATUS: RS_NET_EXT_ADDR_FINDER" << std::endl;
#endif
netExtraAddressCheck();
break;
case RS_NET_DONE: case RS_NET_DONE:
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
//std::cerr << "p3ConnectMgr::netTick() STATUS: DONE" << std::endl; //std::cerr << "p3ConnectMgr::netTick() STATUS: DONE" << std::endl;
#endif #endif
stunCheck(); /* Keep on stunning */ stunCheck(); /* Keep on stunning */
netExtraAddressCheck();
break; break;
@ -698,6 +695,7 @@ void p3ConnectMgr::networkConsistencyCheck()
delta = time(NULL) - mNetInitTS; delta = time(NULL) - mNetInitTS;
std::cerr << "p3ConnectMgr::networkConsistencyCheck() time since last rest : " << delta << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() time since last rest : " << delta << std::endl;
#endif #endif
bool doNetReset = false; bool doNetReset = false;
//if one of the flag is degrated from true to false during last tick, let's do a reset //if one of the flag is degrated from true to false during last tick, let's do a reset
//storing old flags //storing old flags
@ -741,7 +739,9 @@ void p3ConnectMgr::networkConsistencyCheck()
std::cerr << "p3ConnectMgr::networkConsistencyCheck() using STUN for ownState.serveraddr." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() using STUN for ownState.serveraddr." << std::endl;
#endif #endif
ownState.serveraddr = extAddr; ownState.serveraddr = extAddr;
} else if (getExtFinderExtAddress(extAddr)) { } else {
//call the extrafinder address
if (getExtFinderExtAddress(extAddr)) {
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::networkConsistencyCheck() using External address finder for ownState.serveraddr." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() using External address finder for ownState.serveraddr." << std::endl;
#endif #endif
@ -757,6 +757,8 @@ void p3ConnectMgr::networkConsistencyCheck()
#endif #endif
doNetReset = true; doNetReset = true;
} }
}
connMtx.unlock(); /* UNLOCK MUTEX */ connMtx.unlock(); /* UNLOCK MUTEX */
@ -781,9 +783,15 @@ void p3ConnectMgr::networkConsistencyCheck()
void p3ConnectMgr::netExtraAddressCheck() void p3ConnectMgr::netExtraAddressCheck()
{ struct sockaddr_in tmpip; { struct sockaddr_in tmpip;
if (use_extr_addr_finder && mExtAddrFinder->hasValidIP(&tmpip)) { if (use_extr_addr_finder && mExtAddrFinder->hasValidIP(&tmpip)) {
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::netExtraAddressCheck() return true" << std::endl;
#endif
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
netFlagExtraAddressCheckOk = true; netFlagExtraAddressCheckOk = true;
} else { } else {
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::netExtraAddressCheck() return false" << std::endl;
#endif
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
netFlagExtraAddressCheckOk = false; netFlagExtraAddressCheckOk = false;
} }

View file

@ -15,6 +15,8 @@
#include <algorithm> #include <algorithm>
#include <stdio.h> #include <stdio.h>
const uint32_t MAX_IP_STORE = 20; /* seconds ip address timeout */
static const std::string ADDR_AGENT = "Mozilla/5.0"; static const std::string ADDR_AGENT = "Mozilla/5.0";
static std::string scan_ip(const std::string& text) static std::string scan_ip(const std::string& text)
@ -139,27 +141,40 @@ void* doExtAddrSearch(void *p)
std::cout << "ip found through " << *it << ": \"" << ip << "\"" << std::endl ; std::cout << "ip found through " << *it << ": \"" << ip << "\"" << std::endl ;
#endif #endif
} }
if(res.empty()) if(res.empty())
{ {
// thread safe copy results.
//
af->_addrMtx.lock();
*(af->_found) = false ;
*(af->mFoundTS) = time(NULL) ;
*(af->_searching) = false ;
pthread_exit(NULL); pthread_exit(NULL);
af->_addrMtx.unlock();
return NULL ; return NULL ;
} }
sort(res.begin(),res.end()) ; // eliminates outliers. sort(res.begin(),res.end()) ; // eliminates outliers.
// thread safe copy results.
//
RsStackMutex mut(af->_addrMtx) ;
if(!inet_aton(res[res.size()/2].c_str(),&(af->_addr->sin_addr))) if(!inet_aton(res[res.size()/2].c_str(),&(af->_addr->sin_addr)))
{ {
std::cerr << "ExtAddrFinder: Could not convert " << res[res.size()/2] << " into an address." << std::endl ; std::cerr << "ExtAddrFinder: Could not convert " << res[res.size()/2] << " into an address." << std::endl ;
af->_addrMtx.lock();
*(af->_found) = false ;
*(af->mFoundTS) = time(NULL) ;
*(af->_searching) = false ;
af->_addrMtx.unlock();
pthread_exit(NULL); pthread_exit(NULL);
return NULL ; return NULL ;
} }
af->_addrMtx.lock();
*(af->_found) = true ; *(af->_found) = true ;
*(af->mFoundTS) = time(NULL) ;
*(af->_searching) = false ; *(af->_searching) = false ;
af->_addrMtx.unlock();
pthread_exit(NULL); pthread_exit(NULL);
return NULL ; return NULL ;
@ -179,37 +194,41 @@ bool ExtAddrFinder::hasValidIP(struct sockaddr_in *addr)
#ifdef EXTADDRSEARCH_DEBUG #ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: Getting ip." << std::endl ; std::cerr << "ExtAddrFinder: Getting ip." << std::endl ;
#endif #endif
if(*_found) if(*_found)
{ {
#ifdef EXTADDRSEARCH_DEBUG #ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: Has stored ip: responding with this ip." << std::endl ; std::cerr << "ExtAddrFinder: Has stored ip: responding with this ip." << std::endl ;
#endif #endif
*addr = *_addr ; *addr = *_addr;
return true ;
} }
if(_addrMtx.trylock()) //timeout the current ip
time_t delta = time(NULL) - *mFoundTS;
if(delta > MAX_IP_STORE) {//launch a research
if( _addrMtx.trylock())
{ {
if(!*_searching) if(!*_searching)
{ {
#ifdef EXTADDRSEARCH_DEBUG #ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: No stored ip: Initiating new search." << std::endl ; std::cerr << "ExtAddrFinder: No stored ip: Initiating new search." << std::endl ;
#endif #endif
*_searching = true ; *_searching = true ;
start_request() ; start_request() ;
} }
#ifdef EXTADDRSEARCH_DEBUG #ifdef EXTADDRSEARCH_DEBUG
else else
std::cerr << "ExtAddrFinder: Already searching." << std::endl ; std::cerr << "ExtAddrFinder: Already searching." << std::endl ;
#endif #endif
_addrMtx.unlock(); _addrMtx.unlock();
} }
#ifdef EXTADDRSEARCH_DEBUG #ifdef EXTADDRSEARCH_DEBUG
else else
std::cerr << "ExtAddrFinder: (Note) Could not acquire lock. Busy." << std::endl ; std::cerr << "ExtAddrFinder: (Note) Could not acquire lock. Busy." << std::endl ;
#endif #endif
}
return false ; return *_found ;
} }
ExtAddrFinder::~ExtAddrFinder() ExtAddrFinder::~ExtAddrFinder()
@ -244,6 +263,8 @@ ExtAddrFinder::ExtAddrFinder()
_searching = new bool ; _searching = new bool ;
*_searching = false ; *_searching = false ;
*mFoundTS = time(NULL);
_addr = (sockaddr_in*)malloc(sizeof(sockaddr_in)) ; _addr = (sockaddr_in*)malloc(sizeof(sockaddr_in)) ;
_ip_servers.push_back(std::string( "checkip.dyndns.org" )) ; _ip_servers.push_back(std::string( "checkip.dyndns.org" )) ;

View file

@ -20,6 +20,7 @@ class ExtAddrFinder
private: private:
friend void* doExtAddrSearch(void *p) ; friend void* doExtAddrSearch(void *p) ;
time_t *mFoundTS;
RsMutex _addrMtx ; RsMutex _addrMtx ;
struct sockaddr_in *_addr ; struct sockaddr_in *_addr ;
bool *_found ; bool *_found ;