mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-27 10:21:40 -05:00
* added DETERMINISTIC_SYMMETRIC NAT type to Connect Logic. (CBS_NETSTATE_EXCLUSIVENAT)
* added DETERMINISTIC_SYMMETRIC NAT to retroshare/rsconfig and NetStateBox. * added ExclusiveMode to udpStunner. * Tweaked UdpStunner ping logic. * added TCP_WAIT to Connect Logic. NB: This stuff is still to be tested! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-netupgrade@4440 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
d6938721b0
commit
85d232ff4f
@ -30,6 +30,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#define FAILED_WAIT_TIME (300) //(1800) // 30 minutes.
|
||||
#define TCP_WAIT_TIME (60) // 1 minutes.
|
||||
#define DIRECT_WAIT_TIME (60) // 1 minutes.
|
||||
#define PROXY_WAIT_TIME (60) // 1 minutes.
|
||||
#define RELAY_WAIT_TIME (60) // 1 minutes.
|
||||
@ -64,6 +65,10 @@ std::string NetStateAsString(uint32_t netstate)
|
||||
str = "StableNat";
|
||||
break;
|
||||
|
||||
case CSB_NETSTATE_EXCLUSIVENAT:
|
||||
str = "ExclusiveNat";
|
||||
break;
|
||||
|
||||
case CSB_NETSTATE_FIREWALLED:
|
||||
str = "Firewalled";
|
||||
break;
|
||||
@ -83,6 +88,10 @@ std::string StateAsString(uint32_t state)
|
||||
str = "Start";
|
||||
break;
|
||||
|
||||
case CSB_TCP_WAIT:
|
||||
str = "TCP Wait";
|
||||
break;
|
||||
|
||||
case CSB_DIRECT_ATTEMPT:
|
||||
str = "Direct Attempt";
|
||||
break;
|
||||
@ -210,6 +219,10 @@ uint32_t convertNetStateToInternal(uint32_t netmode, uint32_t nattype)
|
||||
{
|
||||
connNet = CSB_NETSTATE_STABLENAT;
|
||||
}
|
||||
else if (nattype == RSNET_NATTYPE_DETERM_SYM)
|
||||
{
|
||||
connNet = CSB_NETSTATE_EXCLUSIVENAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
connNet = CSB_NETSTATE_FIREWALLED;
|
||||
@ -278,6 +291,7 @@ uint32_t PeerConnectStateBox::connectCb_direct()
|
||||
|
||||
switch(mState)
|
||||
{
|
||||
|
||||
case CSB_DIRECT_ATTEMPT:
|
||||
{
|
||||
errorMsg(std::cerr, "mState == DIRECT_ATTEMPT", 0);
|
||||
@ -325,13 +339,32 @@ uint32_t PeerConnectStateBox::connectCb_direct()
|
||||
case CSB_START:
|
||||
{
|
||||
/* starting up the connection */
|
||||
mState = CSB_DIRECT_ATTEMPT;
|
||||
retval = CSB_ACTION_DIRECT_CONN | CSB_ACTION_DHT_PORT;
|
||||
mState = CSB_TCP_WAIT;
|
||||
retval = CSB_ACTION_TCP_CONN;
|
||||
mStateTS = now;
|
||||
mNoAttempts = 0;
|
||||
|
||||
}
|
||||
break;
|
||||
case CSB_TCP_WAIT:
|
||||
{
|
||||
/* if too soon */
|
||||
if (now - mStateTS < TCP_WAIT_TIME)
|
||||
{
|
||||
/* same state */
|
||||
retval = CSB_ACTION_WAIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* try again */
|
||||
mState = CSB_DIRECT_ATTEMPT;
|
||||
retval = CSB_ACTION_DIRECT_CONN | CSB_ACTION_DHT_PORT;
|
||||
mStateTS = now;
|
||||
mNoAttempts = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSB_DIRECT_WAIT:
|
||||
{
|
||||
/* if too soon */
|
||||
@ -430,7 +463,24 @@ uint32_t PeerConnectStateBox::connectCb_unreachable()
|
||||
} /* FALLTHROUGH TO START CASE */
|
||||
case CSB_START:
|
||||
{
|
||||
/* starting up the connection */
|
||||
mState = CSB_TCP_WAIT;
|
||||
retval = CSB_ACTION_WAIT; /* NO POINT TRYING A TCP_CONN */
|
||||
mStateTS = now;
|
||||
mNoAttempts = 0;
|
||||
|
||||
}
|
||||
break;
|
||||
case CSB_TCP_WAIT:
|
||||
{
|
||||
/* if too soon */
|
||||
if (now - mStateTS < TCP_WAIT_TIME)
|
||||
{
|
||||
/* same state */
|
||||
retval = CSB_ACTION_WAIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* starting up the connection */
|
||||
if (mState != CSB_NETSTATE_FIREWALLED)
|
||||
{
|
||||
@ -443,10 +493,12 @@ uint32_t PeerConnectStateBox::connectCb_unreachable()
|
||||
stateMsg(std::cerr, "Firewalled => RELAY_ATTEMPT", 0);
|
||||
mState = CSB_RELAY_ATTEMPT;
|
||||
retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT;
|
||||
|
||||
}
|
||||
|
||||
mStateTS = now;
|
||||
mNoAttempts = 0;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
@ -29,21 +29,23 @@
|
||||
/* a connect state box */
|
||||
|
||||
#define CSB_START 1
|
||||
#define CSB_DIRECT_ATTEMPT 2
|
||||
#define CSB_DIRECT_WAIT 3
|
||||
#define CSB_PROXY_ATTEMPT 4
|
||||
#define CSB_PROXY_WAIT 5
|
||||
#define CSB_RELAY_ATTEMPT 6
|
||||
#define CSB_RELAY_WAIT 7
|
||||
#define CSB_REVERSE_WAIT 8
|
||||
#define CSB_FAILED_WAIT 9
|
||||
#define CSB_CONNECTED 10
|
||||
#define CSB_TCP_WAIT 2
|
||||
#define CSB_DIRECT_ATTEMPT 3
|
||||
#define CSB_DIRECT_WAIT 4
|
||||
#define CSB_PROXY_ATTEMPT 5
|
||||
#define CSB_PROXY_WAIT 6
|
||||
#define CSB_RELAY_ATTEMPT 7
|
||||
#define CSB_RELAY_WAIT 8
|
||||
#define CSB_REVERSE_WAIT 9
|
||||
#define CSB_FAILED_WAIT 10
|
||||
#define CSB_CONNECTED 11
|
||||
|
||||
|
||||
#define CSB_NETSTATE_UNKNOWN 0
|
||||
#define CSB_NETSTATE_FORWARD 1
|
||||
#define CSB_NETSTATE_STABLENAT 2
|
||||
#define CSB_NETSTATE_FIREWALLED 3
|
||||
#define CSB_NETSTATE_EXCLUSIVENAT 3
|
||||
#define CSB_NETSTATE_FIREWALLED 4
|
||||
|
||||
#define CSB_CONNECT_DIRECT 1
|
||||
#define CSB_CONNECT_UNREACHABLE 2
|
||||
@ -53,9 +55,10 @@
|
||||
#define CSB_ACTION_MASK_PORT 0xff00
|
||||
|
||||
#define CSB_ACTION_WAIT 0x0001
|
||||
#define CSB_ACTION_DIRECT_CONN 0x0002
|
||||
#define CSB_ACTION_PROXY_CONN 0x0004
|
||||
#define CSB_ACTION_RELAY_CONN 0x0008
|
||||
#define CSB_ACTION_TCP_CONN 0x0002
|
||||
#define CSB_ACTION_DIRECT_CONN 0x0004
|
||||
#define CSB_ACTION_PROXY_CONN 0x0008
|
||||
#define CSB_ACTION_RELAY_CONN 0x0010
|
||||
|
||||
#define CSB_ACTION_DHT_PORT 0x0100
|
||||
#define CSB_ACTION_PROXY_PORT 0x0200
|
||||
|
@ -1546,8 +1546,8 @@ void p3NetMgr::updateNetStateBox_temporal()
|
||||
|
||||
}
|
||||
|
||||
#define NET_STUNNER_PERIOD_FAST (300) // default of Stunner.
|
||||
#define NET_STUNNER_PERIOD_SLOW (300) // 5 minutes.
|
||||
#define NET_STUNNER_PERIOD_FAST (-1) // default of Stunner.
|
||||
#define NET_STUNNER_PERIOD_SLOW (180) // 3 minutes.
|
||||
|
||||
void p3NetMgr::updateNatSetting()
|
||||
{
|
||||
|
@ -31,10 +31,22 @@ void pqiNetStateBox::setAddressStunProxy(struct sockaddr_in *addr, bool stable)
|
||||
(addr->sin_port != mStunProxyAddr.sin_port))
|
||||
|
||||
{
|
||||
|
||||
if (addr->sin_addr.s_addr == mStunProxyAddr.sin_addr.s_addr)
|
||||
{
|
||||
if (mStunProxyStable != stable)
|
||||
{
|
||||
mStunProxySemiStable = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mStunProxySemiStable = false; // change of address - must trigger this again!
|
||||
}
|
||||
|
||||
mStunProxySet = true;
|
||||
mStunProxyStable = stable;
|
||||
mStunProxyAddr = *addr;
|
||||
|
||||
mStatusOkay = false;
|
||||
}
|
||||
mStunProxyTS = time(NULL);
|
||||
@ -168,6 +180,7 @@ void pqiNetStateBox::reset()
|
||||
//struct sockaddr_in mStunDhtAddr;
|
||||
|
||||
mStunProxySet = false;
|
||||
mStunProxySemiStable = false;
|
||||
time_t mStunProxyTS = 0;
|
||||
bool mStunProxyStable = false;
|
||||
//struct sockaddr_in mStunProxyAddr;
|
||||
@ -268,7 +281,30 @@ void pqiNetStateBox::determineNetworkState()
|
||||
//mExtAddress = mStunDhtExtAddress;
|
||||
//mExtAddrStable = false;
|
||||
|
||||
if (!mStunProxyStable)
|
||||
if (mStunProxySemiStable)
|
||||
{
|
||||
/* I'm guessing this will be a common mode for modern NAT/Firewalls.
|
||||
* a DETERMINISTIC SYMMETRIC NAT.... This is likely to be the
|
||||
* next iteration on the RESTRICTED CONE firewall described below.
|
||||
* If you Stun fast, it looks like a SYMMETRIC NAT, but if you let
|
||||
* the NAT timeout, you get back your original port so it looks like
|
||||
* a RESTRICTED CONE nat...
|
||||
*
|
||||
* This kind of NAT is passable, if you only attempt one connection at
|
||||
* a time, and are careful about it!
|
||||
*
|
||||
* NB: The StunDht port will never get this mode.
|
||||
* It has unsolicited traffic which triggers SYM mode
|
||||
*
|
||||
*/
|
||||
|
||||
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
||||
mNatTypeMode = RSNET_NATTYPE_DETERM_SYM;
|
||||
mNatHoleMode = RSNET_NATHOLE_NONE;
|
||||
mNetStateMode = RSNET_NETSTATE_WARNING_NATTED;
|
||||
|
||||
}
|
||||
else if (!mStunProxyStable)
|
||||
{
|
||||
/* both unstable, Symmetric NAT, Firewalled, No UDP Hole */
|
||||
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
||||
@ -316,7 +352,15 @@ void pqiNetStateBox::determineNetworkState()
|
||||
//mExtAddrStable = true;
|
||||
|
||||
// Initial Fallback Guess at firewall state.
|
||||
if (!mStunProxyStable)
|
||||
if (mStunProxySemiStable)
|
||||
{
|
||||
/* must be a forwarded port/ext or something similar */
|
||||
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
||||
mNatTypeMode = RSNET_NATTYPE_DETERM_SYM;
|
||||
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
|
||||
mNetStateMode = RSNET_NETSTATE_GOOD;
|
||||
}
|
||||
else if (!mStunProxyStable)
|
||||
{
|
||||
/* must be a forwarded port/ext or something similar */
|
||||
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
||||
@ -523,7 +567,8 @@ void pqiNetStateBox::workoutNetworkMode()
|
||||
mConnectModes |= RSNET_CONNECT_RELAY_UDP;
|
||||
|
||||
if ((mNatTypeMode == RSNET_NATTYPE_RESTRICTED_CONE) ||
|
||||
(mNatTypeMode == RSNET_NATTYPE_FULL_CONE))
|
||||
(mNatTypeMode == RSNET_NATTYPE_FULL_CONE) ||
|
||||
(mNatTypeMode == RSNET_NATTYPE_DETERM_SYM))
|
||||
{
|
||||
mConnectModes |= RSNET_CONNECT_PROXY_UDP;
|
||||
}
|
||||
@ -573,6 +618,9 @@ std::string NetStateNatTypeString(uint32_t natType)
|
||||
case RSNET_NATTYPE_SYMMETRIC:
|
||||
str = "SYMMETRIC NAT";
|
||||
break;
|
||||
case RSNET_NATTYPE_DETERM_SYM:
|
||||
str = "DETERMINISTIC SYM NAT";
|
||||
break;
|
||||
case RSNET_NATTYPE_RESTRICTED_CONE:
|
||||
str = "RESTRICTED CONE NAT";
|
||||
break;
|
||||
|
@ -66,6 +66,7 @@ class pqiNetStateBox
|
||||
bool mStunProxySet;
|
||||
time_t mStunProxyTS;
|
||||
bool mStunProxyStable;
|
||||
bool mStunProxySemiStable;
|
||||
struct sockaddr_in mStunProxyAddr;
|
||||
|
||||
bool mDhtSet;
|
||||
|
@ -49,9 +49,10 @@ extern RsServerConfig *rsConfig;
|
||||
#define RSNET_NATTYPE_NONE 1
|
||||
#define RSNET_NATTYPE_UNKNOWN 2
|
||||
#define RSNET_NATTYPE_SYMMETRIC 3
|
||||
#define RSNET_NATTYPE_RESTRICTED_CONE 4
|
||||
#define RSNET_NATTYPE_FULL_CONE 5
|
||||
#define RSNET_NATTYPE_OTHER 6
|
||||
#define RSNET_NATTYPE_DETERM_SYM 4
|
||||
#define RSNET_NATTYPE_RESTRICTED_CONE 5
|
||||
#define RSNET_NATTYPE_FULL_CONE 6
|
||||
#define RSNET_NATTYPE_OTHER 7
|
||||
|
||||
// WHAT TYPE OF HOLE?
|
||||
#define RSNET_NATHOLE_UNKNOWN 0
|
||||
|
@ -65,6 +65,9 @@ UdpStunner::UdpStunner(UdpPublisher *pub)
|
||||
mSuccessRate = 0.0;
|
||||
mTargetStunPeriod = TOU_STUN_DEFAULT_TARGET_RATE;
|
||||
|
||||
mExclusiveMode = false;
|
||||
mExclusiveModeTS = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,6 +83,76 @@ void UdpStunner::SetAcceptLocalNet()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int UdpStunner::setExclusiveMode() /* returns seconds since last send/recv */
|
||||
{
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
#ifdef DEBUG_UDP_STUNNER_FILTER
|
||||
std::cerr << "UdpStunner::setExclusiveMode();
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
if (mExclusiveMode)
|
||||
{
|
||||
#ifdef DEBUG_UDP_STUNNER_FILTER
|
||||
std::cerr << "UdpStunner::setExclusiveMode() FAILED;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t now = time(NULL);
|
||||
mExclusiveMode = true;
|
||||
mExclusiveModeTS = now;
|
||||
|
||||
int lastcomms = mStunLastRecvAny;
|
||||
if (mStunLastSendAny > lastcomms)
|
||||
{
|
||||
lastcomms = mStunLastSendAny;
|
||||
}
|
||||
|
||||
int commsage = now - lastcomms;
|
||||
|
||||
/* cannot return 0, as this indicates error */
|
||||
if (commsage == 0)
|
||||
{
|
||||
commsage = 1;
|
||||
}
|
||||
#ifdef DEBUG_UDP_STUNNER_FILTER
|
||||
std::cerr << "UdpStunner::setExclusiveMode() SUCCESS. last comms: " << commsage;
|
||||
std::cerr << " ago";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return commsage;
|
||||
}
|
||||
|
||||
int UdpStunner::cancelExclusiveMode()
|
||||
{
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
if (!mExclusiveMode)
|
||||
{
|
||||
#ifdef DEBUG_UDP_STUNNER_FILTER
|
||||
std::cerr << "UdpStunner::cancelExclusiveMode() ERROR, not in exclusive Mode";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t now = time(NULL);
|
||||
mExclusiveMode = false;
|
||||
|
||||
#ifdef DEBUG_UDP_STUNNER_FILTER
|
||||
std::cerr << "UdpStunner::cancelExclusiveMode() Canceled. Was in ExclusiveMode for: " << now - mExclusiveModeTS;
|
||||
std::cerr << " secs";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void UdpStunner::setTargetStunPeriod(int32_t sec_per_stun)
|
||||
{
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
@ -238,12 +311,15 @@ bool UdpStunner::externalAddr(struct sockaddr_in &external, uint8_t &stable)
|
||||
|
||||
if (eaddrKnown)
|
||||
{
|
||||
/* address timeout */
|
||||
if (time(NULL) - eaddrTime > (mTargetStunPeriod * 2))
|
||||
/* address timeout
|
||||
* no timeout if in exclusive mode
|
||||
*/
|
||||
if ((time(NULL) - eaddrTime > (mTargetStunPeriod * 2)) && (!mExclusiveMode))
|
||||
{
|
||||
std::cerr << "UdpStunner::externalAddr() eaddr expired";
|
||||
std::cerr << std::endl;
|
||||
|
||||
eaddrKnown = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -550,14 +626,23 @@ bool UdpStunner::checkStunDesired()
|
||||
return false; /* all good */
|
||||
}
|
||||
|
||||
if (mExclusiveMode)
|
||||
{
|
||||
return false; /* no pings in exclusive mode */
|
||||
}
|
||||
|
||||
if (!eaddrKnown)
|
||||
{
|
||||
/* check properly! (this will limit it to two successful stuns) */
|
||||
if (!locked_checkExternalAddress())
|
||||
{
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::checkStunDesired() YES, we don't have extAddr Yet";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return true; /* want our external address */
|
||||
}
|
||||
}
|
||||
|
||||
/* check if we need to send one now */
|
||||
now = time(NULL);
|
||||
@ -567,8 +652,11 @@ bool UdpStunner::checkStunDesired()
|
||||
* if we have 100% success rate, then we can delay until exactly TARGET RATE.
|
||||
* if we have 0% success rate, then try at double TARGET RATE.
|
||||
*
|
||||
* generalised to a rate_scale parameter below...
|
||||
*/
|
||||
double stunPeriod = (mTargetStunPeriod / 2.0) * (1.0 + mSuccessRate);
|
||||
|
||||
#define RATE_SCALE (3.0)
|
||||
double stunPeriod = (mTargetStunPeriod / (RATE_SCALE)) * (1.0 + mSuccessRate * (RATE_SCALE - 1.0));
|
||||
time_t nextStun = mStunLastRecvResp + (int) stunPeriod;
|
||||
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
@ -735,7 +823,10 @@ bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const str
|
||||
locked_printStunList();
|
||||
#endif
|
||||
|
||||
if (!mExclusiveMode)
|
||||
{
|
||||
locked_checkExternalAddress();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
@ -83,6 +83,10 @@ virtual ~UdpStunner() { return; }
|
||||
void SetAcceptLocalNet();
|
||||
#endif
|
||||
|
||||
int setExclusiveMode(); /* returns seconds since last send/recv */
|
||||
int cancelExclusiveMode();
|
||||
|
||||
|
||||
void setTargetStunPeriod(int32_t sec_per_stun);
|
||||
bool addStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
||||
bool getStunPeer(int idx, std::string &id,
|
||||
@ -141,6 +145,8 @@ bool locked_checkExternalAddress();
|
||||
uint32_t mTargetStunPeriod;
|
||||
double mSuccessRate;
|
||||
|
||||
bool mExclusiveMode; /* when this is switched on, the stunner stays silent (and extAddr is maintained) */
|
||||
time_t mExclusiveModeTS;
|
||||
};
|
||||
|
||||
/* generic stun functions */
|
||||
|
Loading…
x
Reference in New Issue
Block a user