2011-07-09 20:41:39 -04:00
|
|
|
|
2011-07-12 10:16:46 -04:00
|
|
|
#include "retroshare/rsconfig.h"
|
2011-07-09 20:41:39 -04:00
|
|
|
#include "util/rsnet.h"
|
|
|
|
#include "pqi/pqinetstatebox.h"
|
|
|
|
#include "time.h"
|
|
|
|
|
2011-07-12 10:16:46 -04:00
|
|
|
#include <sstream>
|
|
|
|
|
2011-07-09 20:41:39 -04:00
|
|
|
// External Interface.
|
|
|
|
|
|
|
|
void pqiNetStateBox::setAddressStunDht(struct sockaddr_in *addr, bool stable)
|
|
|
|
{
|
|
|
|
if ((!mStunDhtSet) || (mStunDhtStable != stable) ||
|
|
|
|
(addr->sin_addr.s_addr != mStunDhtAddr.sin_addr.s_addr) ||
|
|
|
|
(addr->sin_port != mStunDhtAddr.sin_port))
|
|
|
|
{
|
|
|
|
mStunDhtSet = true;
|
|
|
|
mStunDhtStable = stable;
|
|
|
|
mStunDhtAddr = *addr;
|
|
|
|
|
|
|
|
mStatusOkay = false;
|
|
|
|
}
|
|
|
|
mStunDhtTS = time(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::setAddressStunProxy(struct sockaddr_in *addr, bool stable)
|
|
|
|
{
|
|
|
|
if ((!mStunProxySet) || (mStunProxyStable != stable) ||
|
|
|
|
(addr->sin_addr.s_addr != mStunProxyAddr.sin_addr.s_addr) ||
|
|
|
|
(addr->sin_port != mStunProxyAddr.sin_port))
|
|
|
|
|
|
|
|
{
|
2011-07-13 07:41:25 -04:00
|
|
|
|
|
|
|
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!
|
|
|
|
}
|
|
|
|
|
2011-07-09 20:41:39 -04:00
|
|
|
mStunProxySet = true;
|
|
|
|
mStunProxyStable = stable;
|
|
|
|
mStunProxyAddr = *addr;
|
|
|
|
mStatusOkay = false;
|
|
|
|
}
|
|
|
|
mStunProxyTS = time(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::setAddressUPnP(bool active, struct sockaddr_in *addr)
|
|
|
|
{
|
|
|
|
if ((!mUPnPSet) || (mUPnPActive != active) ||
|
|
|
|
(addr->sin_addr.s_addr != mUPnPAddr.sin_addr.s_addr) ||
|
|
|
|
(addr->sin_port != mUPnPAddr.sin_port))
|
|
|
|
|
|
|
|
{
|
|
|
|
mUPnPSet = true;
|
|
|
|
mUPnPAddr = *addr;
|
|
|
|
mUPnPActive = active;
|
|
|
|
|
|
|
|
mStatusOkay = false;
|
|
|
|
}
|
|
|
|
mUPnPTS = time(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::setAddressNatPMP(bool active, struct sockaddr_in *addr)
|
|
|
|
{
|
|
|
|
if ((!mNatPMPSet) || (mNatPMPActive != active) ||
|
|
|
|
(addr->sin_addr.s_addr != mNatPMPAddr.sin_addr.s_addr) ||
|
|
|
|
(addr->sin_port != mNatPMPAddr.sin_port))
|
|
|
|
|
|
|
|
{
|
|
|
|
mNatPMPSet = true;
|
|
|
|
mNatPMPAddr = *addr;
|
|
|
|
mNatPMPActive = active;
|
|
|
|
|
|
|
|
mStatusOkay = false;
|
|
|
|
}
|
|
|
|
mNatPMPTS = time(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::setAddressWebIP(bool active, struct sockaddr_in *addr)
|
|
|
|
{
|
|
|
|
if ((!mWebIPSet) || (mWebIPActive != active) ||
|
|
|
|
(addr->sin_addr.s_addr != mWebIPAddr.sin_addr.s_addr) ||
|
|
|
|
(addr->sin_port != mWebIPAddr.sin_port))
|
|
|
|
|
|
|
|
{
|
|
|
|
mWebIPSet = true;
|
|
|
|
mWebIPAddr = *addr;
|
|
|
|
mWebIPActive = active;
|
|
|
|
|
|
|
|
mStatusOkay = false;
|
|
|
|
}
|
|
|
|
mWebIPTS = time(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::setDhtState(bool on, bool active)
|
|
|
|
{
|
|
|
|
if ((!mDhtSet) || (mDhtActive != active) || (mDhtOn != on))
|
|
|
|
{
|
|
|
|
mDhtSet = true;
|
|
|
|
mDhtActive = active;
|
|
|
|
mDhtOn = on;
|
|
|
|
|
|
|
|
mStatusOkay = false;
|
|
|
|
}
|
|
|
|
mDhtTS = time(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Extract Net State */
|
|
|
|
uint32_t pqiNetStateBox::getNetworkMode()
|
|
|
|
{
|
|
|
|
updateNetState();
|
|
|
|
return mNetworkMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t pqiNetStateBox::getNatTypeMode()
|
|
|
|
{
|
|
|
|
updateNetState();
|
|
|
|
return mNatTypeMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t pqiNetStateBox::getNatHoleMode()
|
|
|
|
{
|
|
|
|
updateNetState();
|
|
|
|
return mNatHoleMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t pqiNetStateBox::getConnectModes()
|
|
|
|
{
|
|
|
|
updateNetState();
|
|
|
|
return mConnectModes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t pqiNetStateBox::getNetStateMode()
|
|
|
|
{
|
|
|
|
updateNetState();
|
|
|
|
return mNetStateMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************** Internal Workings *******************************/
|
|
|
|
pqiNetStateBox::pqiNetStateBox()
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::reset()
|
|
|
|
{
|
|
|
|
|
2011-07-09 20:41:39 -04:00
|
|
|
mStatusOkay = false;
|
|
|
|
//time_t mStatusTS;
|
|
|
|
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_UNKNOWN;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_UNKNOWN;
|
|
|
|
mConnectModes = RSNET_CONNECT_NONE;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_BAD_UNKNOWN;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
/* Parameters set externally */
|
|
|
|
|
|
|
|
mStunDhtSet = false;
|
2011-07-27 13:02:05 -04:00
|
|
|
mStunDhtTS = 0;
|
|
|
|
mStunDhtStable = false;
|
2011-07-09 20:41:39 -04:00
|
|
|
//struct sockaddr_in mStunDhtAddr;
|
|
|
|
|
|
|
|
mStunProxySet = false;
|
2011-07-13 07:41:25 -04:00
|
|
|
mStunProxySemiStable = false;
|
2011-07-27 13:02:05 -04:00
|
|
|
mStunProxyTS = 0;
|
|
|
|
mStunProxyStable = false;
|
2011-07-09 20:41:39 -04:00
|
|
|
//struct sockaddr_in mStunProxyAddr;
|
|
|
|
|
|
|
|
mUPnPSet = false;
|
|
|
|
mUPnPActive = false;
|
|
|
|
//struct sockaddr_in mUPnPAddr;
|
|
|
|
|
|
|
|
mNatPMPSet = false;
|
|
|
|
mNatPMPActive = false;
|
|
|
|
//struct sockaddr_in mNatPMPAddr;
|
|
|
|
|
|
|
|
mWebIPSet = false;
|
|
|
|
mWebIPActive = false;
|
|
|
|
//struct sockaddr_in mWebIPAddr;
|
|
|
|
|
|
|
|
mPortForwardedSet = false;
|
|
|
|
mPortForwarded = 0;
|
|
|
|
|
|
|
|
mDhtSet = false;
|
|
|
|
mDhtActive = false;
|
|
|
|
mDhtOn = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NETSTATE_PARAM_TIMEOUT 600
|
|
|
|
#define NETSTATE_TIMEOUT 60
|
|
|
|
|
|
|
|
/* check/update Net State */
|
|
|
|
int pqiNetStateBox::statusOkay()
|
|
|
|
{
|
|
|
|
if (!mStatusOkay)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
time_t now = time(NULL);
|
|
|
|
if (now - mStatusTS > NETSTATE_TIMEOUT)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pqiNetStateBox::updateNetState()
|
|
|
|
{
|
|
|
|
if (!statusOkay())
|
|
|
|
{
|
|
|
|
determineNetworkState();
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::clearOldNetworkData()
|
|
|
|
{
|
|
|
|
/* check if any measurements are too old to consider */
|
|
|
|
time_t now = time(NULL);
|
|
|
|
if (now - mStunProxyTS > NETSTATE_PARAM_TIMEOUT)
|
|
|
|
{
|
|
|
|
mStunProxySet = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (now - mStunDhtTS > NETSTATE_PARAM_TIMEOUT)
|
|
|
|
{
|
|
|
|
mStunDhtSet = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pqiNetStateBox::determineNetworkState()
|
|
|
|
{
|
|
|
|
clearOldNetworkData();
|
|
|
|
time_t now = time(NULL);
|
|
|
|
|
|
|
|
/* now we use the remaining valid input to determine network state */
|
|
|
|
|
|
|
|
/* Most important Factor is whether we have DHT(STUN) info to ID connection */
|
|
|
|
if (mDhtActive)
|
|
|
|
{
|
|
|
|
/* firstly lets try to identify OFFLINE / UNKNOWN */
|
|
|
|
if ((!mStunProxySet) || (!mStunDhtSet))
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_UNKNOWN;
|
2011-07-09 20:41:39 -04:00
|
|
|
// Assume these.
|
2011-07-12 10:16:46 -04:00
|
|
|
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NONE;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_BAD_UNKNOWN;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
//mExtAddress = .... unknown;
|
|
|
|
//mExtAddrStable = false;
|
|
|
|
}
|
|
|
|
else // Both Are Set!
|
|
|
|
{
|
|
|
|
if (!mStunDhtStable)
|
|
|
|
{
|
|
|
|
//mExtAddress = mStunDhtExtAddress;
|
|
|
|
//mExtAddrStable = false;
|
|
|
|
|
2011-07-13 07:41:25 -04:00
|
|
|
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)
|
2011-07-09 20:41:39 -04:00
|
|
|
{
|
|
|
|
/* both unstable, Symmetric NAT, Firewalled, No UDP Hole */
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_SYMMETRIC;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NONE;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_BAD_NATSYM;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* if DhtStun Unstable, but ProxyStable, then we have
|
|
|
|
* an interesting case. This is close to a Debian Firewall
|
|
|
|
* I tested in the past....
|
|
|
|
*
|
|
|
|
* The big difference between DhtStun and ProxyStun is
|
|
|
|
* that Dht Port receives unsolicated packets,
|
|
|
|
* while Proxy Port always sends an outgoing one first.
|
|
|
|
*
|
|
|
|
* In the case of the debian firewall, the unsolicated pkts
|
|
|
|
* caused the outgoing port to change.
|
|
|
|
*
|
|
|
|
* We will label this difference RESTRICTED vs FULL CONE,
|
|
|
|
* but that label is really fully accurate. (gray area).
|
|
|
|
*/
|
|
|
|
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_RESTRICTED_CONE;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NONE;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_WARNING_NATTED;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else // Dht Stable.
|
|
|
|
{
|
|
|
|
/* DHT Stable port can be caused by:
|
|
|
|
* 1) Forwarded Port (UPNP, NATPMP, FORWARDED)
|
|
|
|
* 2) FULL CONE NAT.
|
|
|
|
* 3) EXT Port.
|
|
|
|
* Must look at Proxy Stability.
|
|
|
|
* - if Proxy Unstable, then must be forwarded port.
|
|
|
|
* - if Proxy Stable, then we cannot tell.
|
|
|
|
* -> Must use User Info (Upnp, PMP, Forwarded Flag).
|
|
|
|
* -> Also possible to be EXT Port (Check against iface)
|
|
|
|
*/
|
|
|
|
|
|
|
|
//mExtAddress = mStunDhtExtAddress;
|
|
|
|
//mExtAddrStable = true;
|
|
|
|
|
|
|
|
// Initial Fallback Guess at firewall state.
|
2011-07-13 07:41:25 -04:00
|
|
|
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)
|
2011-07-09 20:41:39 -04:00
|
|
|
{
|
|
|
|
/* must be a forwarded port/ext or something similar */
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_SYMMETRIC;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_GOOD;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* fallback is FULL CONE NAT */
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_FULL_CONE;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NONE;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_WARNING_NATTED;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mUPnPActive)
|
|
|
|
{
|
|
|
|
// This Mode is OKAY.
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
2011-07-09 20:41:39 -04:00
|
|
|
// Use Fallback Guess.
|
2011-07-12 10:16:46 -04:00
|
|
|
//mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_UPNP;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_GOOD;
|
2011-07-09 20:41:39 -04:00
|
|
|
//mExtAddress = ... from UPnP, should match StunDht.
|
|
|
|
//mExtAddrStable = true;
|
|
|
|
}
|
|
|
|
else if (mNatPMPActive)
|
|
|
|
{
|
|
|
|
// This Mode is OKAY.
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
2011-07-09 20:41:39 -04:00
|
|
|
// Use Fallback Guess.
|
2011-07-12 10:16:46 -04:00
|
|
|
//mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NATPMP;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_GOOD;
|
2011-07-09 20:41:39 -04:00
|
|
|
//mExtAddress = ... from NatPMP, should match NatPMP
|
|
|
|
//mExtAddrStable = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bool isExtAddress = false;
|
|
|
|
|
|
|
|
if (isExtAddress)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_EXTERNALIP;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_NONE;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NONE;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_GOOD;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
//mExtAddrStable = true;
|
|
|
|
}
|
|
|
|
else if (mPortForwardedSet)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
2011-07-09 20:41:39 -04:00
|
|
|
// Use Fallback Guess.
|
2011-07-12 10:16:46 -04:00
|
|
|
//mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_ADV_FORWARD;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
//mExtAddrStable = true; // Probably, makin assumption.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* At this point, we go with the fallback guesses */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // DHT Inactive, must use other means...
|
|
|
|
{
|
|
|
|
/* If we get here we are dealing with a silly peer in "DarkMode".
|
|
|
|
* We have to primarily rely on the feedback from UPnP, PMP or WebSite "WhatsMyIp".
|
|
|
|
* This is in the "Advanced" Settings and liable to be set wrong.
|
|
|
|
* but thats the users fault!
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (mUPnPActive)
|
|
|
|
{
|
|
|
|
// This Mode is OKAY.
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_UPNP;
|
2011-07-09 20:41:39 -04:00
|
|
|
//mExtAddress = ... from UPnP.
|
|
|
|
//mExtAddrStable = true;
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
else if (mNatPMPActive)
|
|
|
|
{
|
|
|
|
// This Mode is OKAY.
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NATPMP;
|
2011-07-09 20:41:39 -04:00
|
|
|
//mExtAddress = ... from NatPMP.
|
|
|
|
//mExtAddrStable = true;
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* if we reach this point, we really need a Web "WhatsMyIp" Check of our Ext Ip Address. */
|
|
|
|
/* Check for the possibility of an EXT address ... */
|
|
|
|
bool isExtAddress = false;
|
|
|
|
|
|
|
|
//mExtAddress = ... from WhatsMyIp.
|
|
|
|
|
|
|
|
if (isExtAddress)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_EXTERNALIP;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_NONE;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NONE;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
//mExtAddrStable = true;
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
else if (mPortForwardedSet)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
//mExtAddrStable = true; // Probably, makin assumption.
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* At this point we must assume firewalled.
|
|
|
|
* These people have destroyed the possibility of making connections ;(
|
|
|
|
* Should WARN about this.
|
|
|
|
*/
|
2011-07-12 10:16:46 -04:00
|
|
|
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
|
|
|
|
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
|
|
|
|
mNatHoleMode = RSNET_NATHOLE_NONE;
|
|
|
|
mNetStateMode = RSNET_NETSTATE_BAD_NODHT_NAT;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
//mExtAddrStable = false; // Unlikely to be stable.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
workoutNetworkMode();
|
|
|
|
|
|
|
|
/* say that things are okay */
|
|
|
|
mStatusOkay = true;
|
|
|
|
mStatusTS = now;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* based on calculated settings, what is the network mode
|
|
|
|
*/
|
|
|
|
|
|
|
|
void pqiNetStateBox::workoutNetworkMode()
|
|
|
|
{
|
|
|
|
/* connectModes are dependent on the other modes */
|
2011-07-12 10:16:46 -04:00
|
|
|
mConnectModes = RSNET_CONNECT_NONE;
|
2011-07-09 20:41:39 -04:00
|
|
|
switch(mNetworkMode)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
case RSNET_NETWORK_UNKNOWN:
|
|
|
|
case RSNET_NETWORK_OFFLINE:
|
|
|
|
case RSNET_NETWORK_LOCALNET:
|
2011-07-09 20:41:39 -04:00
|
|
|
/* nothing here */
|
|
|
|
break;
|
2011-07-12 10:16:46 -04:00
|
|
|
case RSNET_NETWORK_EXTERNALIP:
|
|
|
|
mConnectModes = RSNET_CONNECT_OUTGOING_TCP;
|
|
|
|
mConnectModes |= RSNET_CONNECT_ACCEPT_TCP;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
if (mDhtActive)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mConnectModes |= RSNET_CONNECT_DIRECT_UDP;
|
2011-07-09 20:41:39 -04:00
|
|
|
/* if open port. don't want PROXY or RELAY connect
|
|
|
|
* because we should be able to do direct with EVERYONE.
|
|
|
|
* Ability to do Proxy is dependent on FIREWALL status.
|
|
|
|
* Technically could do RELAY, but disable both.
|
|
|
|
*/
|
2011-07-12 10:16:46 -04:00
|
|
|
//mConnectModes |= RSNET_CONNECT_PROXY_UDP;
|
|
|
|
//mConnectModes |= RSNET_CONNECT_RELAY_UDP;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
break;
|
2011-07-12 10:16:46 -04:00
|
|
|
case RSNET_NETWORK_BEHINDNAT:
|
|
|
|
mConnectModes = RSNET_CONNECT_OUTGOING_TCP;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
|
|
|
/* we're okay if there's a NAT HOLE */
|
2011-07-12 10:16:46 -04:00
|
|
|
if ((mNatHoleMode == RSNET_NATHOLE_UPNP) ||
|
|
|
|
(mNatHoleMode == RSNET_NATHOLE_NATPMP) ||
|
|
|
|
(mNatHoleMode == RSNET_NATHOLE_FORWARDED))
|
2011-07-09 20:41:39 -04:00
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mConnectModes |= RSNET_CONNECT_ACCEPT_TCP;
|
2011-07-09 20:41:39 -04:00
|
|
|
if (mDhtActive)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mConnectModes |= RSNET_CONNECT_DIRECT_UDP;
|
2011-07-09 20:41:39 -04:00
|
|
|
/* dont want PROXY | RELAY with open ports */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* If behind NAT without NATHOLE, this is where RELAY | PROXY
|
|
|
|
* are useful. We Flag DIRECT connections, cos we can do these
|
|
|
|
* with peers with Open Ports. (but not with other NATted peers).
|
|
|
|
*/
|
|
|
|
if (mDhtActive)
|
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mConnectModes |= RSNET_CONNECT_DIRECT_UDP;
|
|
|
|
mConnectModes |= RSNET_CONNECT_RELAY_UDP;
|
2011-07-09 20:41:39 -04:00
|
|
|
|
2011-07-12 10:16:46 -04:00
|
|
|
if ((mNatTypeMode == RSNET_NATTYPE_RESTRICTED_CONE) ||
|
2011-07-13 07:41:25 -04:00
|
|
|
(mNatTypeMode == RSNET_NATTYPE_FULL_CONE) ||
|
|
|
|
(mNatTypeMode == RSNET_NATTYPE_DETERM_SYM))
|
2011-07-09 20:41:39 -04:00
|
|
|
{
|
2011-07-12 10:16:46 -04:00
|
|
|
mConnectModes |= RSNET_CONNECT_PROXY_UDP;
|
2011-07-09 20:41:39 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-12 10:16:46 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string NetStateNetworkModeString(uint32_t netMode)
|
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
switch(netMode)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case RSNET_NETWORK_UNKNOWN:
|
|
|
|
str = "Unknown NetState";
|
|
|
|
break;
|
|
|
|
case RSNET_NETWORK_OFFLINE:
|
|
|
|
str = "Offline";
|
|
|
|
break;
|
|
|
|
case RSNET_NETWORK_LOCALNET:
|
|
|
|
str = "Local Net";
|
|
|
|
break;
|
|
|
|
case RSNET_NETWORK_BEHINDNAT:
|
|
|
|
str = "Behind NAT";
|
|
|
|
break;
|
|
|
|
case RSNET_NETWORK_EXTERNALIP:
|
|
|
|
str = "External IP";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string NetStateNatTypeString(uint32_t natType)
|
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
switch(natType)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case RSNET_NATTYPE_UNKNOWN:
|
|
|
|
str = "UNKNOWN NAT STATE";
|
|
|
|
break;
|
|
|
|
case RSNET_NATTYPE_SYMMETRIC:
|
|
|
|
str = "SYMMETRIC NAT";
|
|
|
|
break;
|
2011-07-13 07:41:25 -04:00
|
|
|
case RSNET_NATTYPE_DETERM_SYM:
|
|
|
|
str = "DETERMINISTIC SYM NAT";
|
|
|
|
break;
|
2011-07-12 10:16:46 -04:00
|
|
|
case RSNET_NATTYPE_RESTRICTED_CONE:
|
|
|
|
str = "RESTRICTED CONE NAT";
|
|
|
|
break;
|
|
|
|
case RSNET_NATTYPE_FULL_CONE:
|
|
|
|
str = "FULL CONE NAT";
|
|
|
|
break;
|
|
|
|
case RSNET_NATTYPE_OTHER:
|
|
|
|
str = "OTHER NAT";
|
|
|
|
break;
|
|
|
|
case RSNET_NATTYPE_NONE:
|
|
|
|
str = "NO NAT";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string NetStateNatHoleString(uint32_t natHole)
|
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
switch(natHole)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case RSNET_NATHOLE_UNKNOWN:
|
|
|
|
str = "UNKNOWN NAT HOLE STATUS";
|
|
|
|
break;
|
|
|
|
case RSNET_NATHOLE_NONE:
|
|
|
|
str = "NO NAT HOLE";
|
|
|
|
break;
|
|
|
|
case RSNET_NATHOLE_UPNP:
|
|
|
|
str = "UPNP FORWARD";
|
|
|
|
break;
|
|
|
|
case RSNET_NATHOLE_NATPMP:
|
|
|
|
str = "NATPMP FORWARD";
|
|
|
|
break;
|
|
|
|
case RSNET_NATHOLE_FORWARDED:
|
|
|
|
str = "MANUAL FORWARD";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string NetStateConnectModesString(uint32_t connect)
|
|
|
|
{
|
|
|
|
std::ostringstream connOut;
|
|
|
|
if (connect & RSNET_CONNECT_OUTGOING_TCP)
|
|
|
|
{
|
|
|
|
connOut << "TCP_OUT ";
|
|
|
|
}
|
|
|
|
if (connect & RSNET_CONNECT_ACCEPT_TCP)
|
|
|
|
{
|
|
|
|
connOut << "TCP_IN ";
|
|
|
|
}
|
|
|
|
if (connect & RSNET_CONNECT_DIRECT_UDP)
|
|
|
|
{
|
|
|
|
connOut << "DIRECT_UDP ";
|
|
|
|
}
|
|
|
|
if (connect & RSNET_CONNECT_PROXY_UDP)
|
|
|
|
{
|
|
|
|
connOut << "PROXY_UDP ";
|
|
|
|
}
|
|
|
|
if (connect & RSNET_CONNECT_RELAY_UDP)
|
|
|
|
{
|
|
|
|
connOut << "RELAY_UDP ";
|
|
|
|
}
|
|
|
|
return connOut.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string NetStateNetStateString(uint32_t netstate)
|
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
switch(netstate)
|
|
|
|
{
|
|
|
|
case RSNET_NETSTATE_BAD_UNKNOWN:
|
|
|
|
str = "NET BAD: Unknown State";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_BAD_OFFLINE:
|
|
|
|
str = "NET BAD: Offline";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_BAD_NATSYM:
|
|
|
|
str = "NET BAD: Behind Symmetric NAT";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_BAD_NODHT_NAT:
|
|
|
|
str = "NET BAD: Behind NAT & No DHT";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_WARNING_RESTART:
|
|
|
|
str = "NET WARNING: NET Restart";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_WARNING_NATTED:
|
|
|
|
str = "NET WARNING: Behind NAT";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_WARNING_NODHT:
|
|
|
|
str = "NET WARNING: No DHT";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_GOOD:
|
|
|
|
str = "NET STATE GOOD!";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_ADV_FORWARD:
|
|
|
|
str = "CAUTION: UNVERIFABLE FORWARD!";
|
|
|
|
break;
|
|
|
|
case RSNET_NETSTATE_ADV_DARK_FORWARD:
|
|
|
|
str = "CAUTION: UNVERIFABLE FORWARD & NO DHT";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|