Bugfixes for ExclusiveProxy Mode.

* changed PeerConnectStateBox::getNetState() to calcNetState() to provide up-to-date info (internal mNetState can be stale!)
 * Added "bool addrChangeLikely" parameter to ReleaseProxyExclusiveLock() - this parameter is determined by whether we actually started a UDP connection.
 * disabled ForceRestun in UdpStunner if addrChange is unlikely.
 * Reduced Stunner Period Slow from 3 minutes to 2 minutes - exact value will only be known after real-world testing.
 * More debugging.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-netupgrade@4458 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2011-07-17 16:24:45 +00:00
parent 181ad06e33
commit c33b415ef4
7 changed files with 73 additions and 26 deletions

View File

@ -85,11 +85,6 @@ PeerConnectStateBox::PeerConnectStateBox()
} }
uint32_t PeerConnectStateBox::getNetState()
{
return mNetState;
}
std::string NetStateAsString(uint32_t netstate) std::string NetStateAsString(uint32_t netstate)
{ {
@ -301,6 +296,13 @@ bool PeerConnectStateBox::shouldUseProxyPort(uint32_t netmode, uint32_t nathole,
return shouldUseProxyPortInternal(netstate); return shouldUseProxyPortInternal(netstate);
} }
uint32_t PeerConnectStateBox::calcNetState(uint32_t netmode, uint32_t nathole, uint32_t nattype)
{
uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype);
return netstate;
}
uint32_t PeerConnectStateBox::connectCb(uint32_t cbtype, uint32_t netmode, uint32_t nathole, uint32_t nattype) uint32_t PeerConnectStateBox::connectCb(uint32_t cbtype, uint32_t netmode, uint32_t nathole, uint32_t nattype)
{ {
uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype); uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype);

View File

@ -89,7 +89,7 @@ class PeerConnectStateBox
bool shouldUseProxyPort(uint32_t netmode, uint32_t nathole, uint32_t nattype); bool shouldUseProxyPort(uint32_t netmode, uint32_t nathole, uint32_t nattype);
uint32_t getNetState(); uint32_t calcNetState(uint32_t netmode, uint32_t nathole, uint32_t nattype);
std::string connectState() const; std::string connectState() const;
std::string mPeerId; std::string mPeerId;

View File

@ -232,8 +232,7 @@ void Feedback_ConnectionFailed(std::string pid);
void Feedback_ConnectionClosed(std::string pid); void Feedback_ConnectionClosed(std::string pid);
void UdpConnectionFailed_locked(DhtPeerDetails *dpd); void UdpConnectionFailed_locked(DhtPeerDetails *dpd);
void ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd); void ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd, bool addrChgLikely);
/*********************************************************************************************** /***********************************************************************************************

View File

@ -708,9 +708,14 @@ int p3BitDht::ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId
std::cerr << " UseProxyPort? " << proxyPort; std::cerr << " UseProxyPort? " << proxyPort;
std::cerr << std::endl; std::cerr << std::endl;
std::cerr << "dhtConnectionCallback: Checking ConnectLogic.NetState: ";
std::cerr << dpd->mConnectLogic.calcNetState(mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode());
std::cerr << std::endl;
if (proxyPort) if (proxyPort)
{ {
exclusivePort = (CSB_NETSTATE_EXCLUSIVENAT == dpd->mConnectLogic.getNetState()); exclusivePort = (CSB_NETSTATE_EXCLUSIVENAT == dpd->mConnectLogic.calcNetState(
mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode()));
} }
if (exclusivePort) if (exclusivePort)
@ -718,6 +723,11 @@ int p3BitDht::ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId
std::cerr << "dhtConnectionCallback: we Require Exclusive Proxy Port for connection"; std::cerr << "dhtConnectionCallback: we Require Exclusive Proxy Port for connection";
std::cerr << std::endl; std::cerr << std::endl;
} }
else
{
std::cerr << "dhtConnectionCallback: Dont need Exclusive Proxy Port for connection";
std::cerr << std::endl;
}
connectOk = true; connectOk = true;
} }
@ -777,7 +787,7 @@ int p3BitDht::ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId
std::cerr << "PeerAction: Connect Proxy: ERROR Cannot find PeerStatus"; std::cerr << "PeerAction: Connect Proxy: ERROR Cannot find PeerStatus";
std::cerr << std::endl; std::cerr << std::endl;
connectionAllowed = BITDHT_CONNECT_ERROR_TEMPUNAVAIL; connectionAllowed = BITDHT_CONNECT_ERROR_TEMPUNAVAIL;
mProxyStunner->releaseExclusiveMode(); mProxyStunner->releaseExclusiveMode(false);
} }
} }
else else
@ -915,7 +925,7 @@ int p3BitDht::ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId
{ {
if (errcode) if (errcode)
{ {
ReleaseProxyExclusiveMode_locked(dpd); ReleaseProxyExclusiveMode_locked(dpd, false);
dpd->mPeerReqStatusMsg = "STOPPED: "; dpd->mPeerReqStatusMsg = "STOPPED: ";
dpd->mPeerReqStatusMsg += decodeConnectionError(errcode); dpd->mPeerReqStatusMsg += decodeConnectionError(errcode);
@ -1134,9 +1144,19 @@ int p3BitDht::doActions()
proxyPort = dpd->mConnectLogic.getProxyPortChoice(); proxyPort = dpd->mConnectLogic.getProxyPortChoice();
if (proxyPort) if (proxyPort)
{ {
std::cerr << "PeerAction: Using ProxyPort. NetState indicates Exclusive Mode"; std::cerr << "PeerAction: Using ProxyPort. Checking ConnectLogic.NetState: ";
std::cerr << dpd->mConnectLogic.calcNetState(mNetMgr->getNetworkMode(),
mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode());
std::cerr << std::endl; std::cerr << std::endl;
exclusivePort = (CSB_NETSTATE_EXCLUSIVENAT == dpd->mConnectLogic.getNetState());
exclusivePort = (CSB_NETSTATE_EXCLUSIVENAT == dpd->mConnectLogic.calcNetState(
mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode()));
if (exclusivePort)
{
std::cerr << "PeerAction: NetState indicates Exclusive Mode";
std::cerr << std::endl;
}
} }
} }
else else
@ -1271,7 +1291,7 @@ int p3BitDht::doActions()
if (grabbedExclusivePort) if (grabbedExclusivePort)
{ {
mProxyStunner->releaseExclusiveMode(); mProxyStunner->releaseExclusiveMode(false);
} }
RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/
@ -2008,7 +2028,7 @@ void p3BitDht::Feedback_Connected(std::string pid)
std::cerr << std::endl; std::cerr << std::endl;
} }
ReleaseProxyExclusiveMode_locked(dpd); ReleaseProxyExclusiveMode_locked(dpd, true);
} }
void p3BitDht::Feedback_ConnectionFailed(std::string pid) void p3BitDht::Feedback_ConnectionFailed(std::string pid)
@ -2110,12 +2130,12 @@ void p3BitDht::UdpConnectionFailed_locked(DhtPeerDetails *dpd)
std::cerr << std::endl; std::cerr << std::endl;
} }
ReleaseProxyExclusiveMode_locked(dpd); ReleaseProxyExclusiveMode_locked(dpd, true);
} }
void p3BitDht::ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd) void p3BitDht::ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd, bool addrChgLikely)
{ {
#ifdef DEBUG_BITDHT_COMMON #ifdef DEBUG_BITDHT_COMMON
std::cerr << "p3BitDht::ReleaseProxyExclusiveMode_locked()"; std::cerr << "p3BitDht::ReleaseProxyExclusiveMode_locked()";
@ -2125,7 +2145,7 @@ void p3BitDht::ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd)
if (dpd->mExclusiveProxyLock) if (dpd->mExclusiveProxyLock)
{ {
if (mProxyStunner->releaseExclusiveMode()) if (mProxyStunner->releaseExclusiveMode(addrChgLikely))
{ {
dpd->mExclusiveProxyLock = false; dpd->mExclusiveProxyLock = false;

View File

@ -1565,7 +1565,9 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
} }
#define NET_STUNNER_PERIOD_FAST (-1) // default of Stunner. #define NET_STUNNER_PERIOD_FAST (-1) // default of Stunner.
#define NET_STUNNER_PERIOD_SLOW (180) // 3 minutes. #define NET_STUNNER_PERIOD_SLOW (120) // This needs to be as small Routers will allow... try 2 minutes.
// FOR TESTING ONLY.
//#define NET_STUNNER_PERIOD_SLOW (60) // 3 minutes.
void p3NetMgrIMPL::updateNatSetting() void p3NetMgrIMPL::updateNatSetting()
{ {

View File

@ -71,6 +71,7 @@ UdpStunner::UdpStunner(UdpPublisher *pub)
mExclusiveMode = false; mExclusiveMode = false;
mExclusiveModeTS = 0; mExclusiveModeTS = 0;
mForceRestun = false;
return; return;
} }
@ -150,7 +151,7 @@ int UdpStunner::grabExclusiveMode() /* returns seconds since last send/recv */
return commsage; return commsage;
} }
int UdpStunner::releaseExclusiveMode() int UdpStunner::releaseExclusiveMode(bool forceStun)
{ {
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
@ -165,16 +166,18 @@ int UdpStunner::releaseExclusiveMode()
time_t now = time(NULL); time_t now = time(NULL);
mExclusiveMode = false; mExclusiveMode = false;
if (forceStun)
{
mForceRestun = true;
}
#ifdef UDPSTUN_ALLOW_LOCALNET #ifdef UDPSTUN_ALLOW_LOCALNET
/* if we are simulating an exclusive NAT, then immediately after we release - it'll become unstable. /* if we are simulating an exclusive NAT, then immediately after we release - it'll become unstable.
* This is even harser than reality... so better test.
*
* In reality, it will only become unstable if we have tried a UDP connection. * In reality, it will only become unstable if we have tried a UDP connection.
* so we use the forceStun parameter (which is true when a UDP connection has been tried).
*/ */
if (mSimExclusiveNat) if ((mSimExclusiveNat) && (forceStun))
{ {
mSimUnstableExt = true; mSimUnstableExt = true;
} }
@ -361,6 +364,14 @@ bool UdpStunner::externalAddr(struct sockaddr_in &external, uint8_t &stable)
return false; return false;
} }
/* Force Restun is triggered after an Exclusive Mode... as Ext Address is likely to have changed
* Until the Restun has got an address - we act as if we don't have an external address
*/
if (mForceRestun)
{
return false;
}
external = eaddr; external = eaddr;
if (eaddrStable) if (eaddrStable)
@ -670,6 +681,12 @@ bool UdpStunner::checkStunDesired()
return false; /* no pings in exclusive mode */ return false; /* no pings in exclusive mode */
} }
if (mForceRestun)
{
return true;
}
if (!eaddrKnown) if (!eaddrKnown)
{ {
/* check properly! (this will limit it to two successful stuns) */ /* check properly! (this will limit it to two successful stuns) */
@ -856,6 +873,12 @@ bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const str
} }
} }
/* We've received a Stun, so the ForceStun can be cancelled */
if (found)
{
mForceRestun = false;
}
/* if not found.. should we add it back in? */ /* if not found.. should we add it back in? */
/* How do we calculate the success rate? /* How do we calculate the success rate?

View File

@ -89,7 +89,7 @@ virtual ~UdpStunner() { return; }
#endif #endif
int grabExclusiveMode(); /* returns seconds since last send/recv */ int grabExclusiveMode(); /* returns seconds since last send/recv */
int releaseExclusiveMode(); int releaseExclusiveMode(bool forceStun);
void setTargetStunPeriod(int32_t sec_per_stun); void setTargetStunPeriod(int32_t sec_per_stun);
@ -156,6 +156,7 @@ bool locked_checkExternalAddress();
bool mExclusiveMode; /* when this is switched on, the stunner stays silent (and extAddr is maintained) */ bool mExclusiveMode; /* when this is switched on, the stunner stays silent (and extAddr is maintained) */
time_t mExclusiveModeTS; time_t mExclusiveModeTS;
bool mForceRestun;
}; };