mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Merge pull request #1874 from PhenomRetroShare/Add_ExtIPFinderUsingDNS
Add ability to retrieve External IP using Specific DNS server.
This commit is contained in:
commit
bfbb2a5ae6
@ -635,6 +635,7 @@ SOURCES += util/folderiterator.cc \
|
||||
util/rsdiscspace.cc \
|
||||
util/rsnet.cc \
|
||||
util/rsnet_ss.cc \
|
||||
util/rsdnsutils.cc \
|
||||
util/extaddrfinder.cc \
|
||||
util/dnsresolver.cc \
|
||||
util/rsprint.cc \
|
||||
|
@ -47,14 +47,15 @@ struct RsLog::logInfo p3netmgrzoneInfo = {RsLog::Default, "p3netmgr"};
|
||||
|
||||
/* Network setup States */
|
||||
|
||||
const uint32_t RS_NET_NEEDS_RESET = 0x0000;
|
||||
const uint32_t RS_NET_UNKNOWN = 0x0001;
|
||||
const uint32_t RS_NET_UPNP_INIT = 0x0002;
|
||||
const uint32_t RS_NET_UPNP_SETUP = 0x0003;
|
||||
const uint32_t RS_NET_EXT_SETUP = 0x0004;
|
||||
const uint32_t RS_NET_DONE = 0x0005;
|
||||
const uint32_t RS_NET_LOOPBACK = 0x0006;
|
||||
//const uint32_t RS_NET_DOWN = 0x0007;
|
||||
constexpr uint32_t RS_NET_NEEDS_RESET = 0x0000;
|
||||
constexpr uint32_t RS_NET_UNKNOWN = 0x0001;
|
||||
constexpr uint32_t RS_NET_UPNP_INIT = 0x0002;
|
||||
constexpr uint32_t RS_NET_UPNP_SETUP = 0x0003;
|
||||
constexpr uint32_t RS_NET_EXT_SETUP = 0x0004;
|
||||
constexpr uint32_t RS_NET_DONE = 0x0005;
|
||||
constexpr uint32_t RS_NET_LOOPBACK = 0x0006;
|
||||
//constexpr uint32_t RS_NET_DOWN = 0x0007;
|
||||
constexpr uint32_t RS_NET_SHUTDOWN = 0x00FF; //Highest value to not restart UPnP nor ExtAddrFinder
|
||||
|
||||
/* Stun modes (TODO) */
|
||||
//const uint32_t RS_STUN_DHT = 0x0001;
|
||||
@ -68,6 +69,8 @@ const uint32_t MAX_UPNP_COMPLETE = 600; /* 10 min... seems to take a while */
|
||||
|
||||
//const uint32_t MIN_TIME_BETWEEN_NET_RESET = 5;
|
||||
|
||||
const uint32_t MIN_TIME_EXT_FINDER_UPDATE = 300; /* 5min to check if external IP is changed */
|
||||
|
||||
/****
|
||||
* #define NETMGR_DEBUG 1
|
||||
* #define NETMGR_DEBUG_RESET 1
|
||||
@ -107,19 +110,17 @@ void pqiNetStatus::print(std::ostream &out)
|
||||
}
|
||||
|
||||
|
||||
p3NetMgrIMPL::p3NetMgrIMPL() : mPeerMgr(nullptr), mLinkMgr(nullptr),
|
||||
mNetMtx("p3NetMgr"), mNetStatus(RS_NET_UNKNOWN), mStatusChanged(false),
|
||||
mDoNotNetCheckUntilTs(0)
|
||||
p3NetMgrIMPL::p3NetMgrIMPL()
|
||||
: mPeerMgr(nullptr), mLinkMgr(nullptr)
|
||||
, mNetMtx("p3NetMgr"), mNetMode(RS_NET_MODE_UDP), mVsDisc(RS_VS_DISC_FULL), mVsDht(RS_VS_DHT_FULL)// default to full.
|
||||
, mNetInitTS(0), mNetStatus(RS_NET_UNKNOWN), mStatusChanged(false)
|
||||
, mUseExtAddrFinder(true), mNetExtAddrFinderTs(0), mDoNotNetCheckUntilTs(0)
|
||||
{
|
||||
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
mNetMode = RS_NET_MODE_UDP;
|
||||
|
||||
mUseExtAddrFinder = true;
|
||||
mExtAddrFinder = new ExtAddrFinder();
|
||||
mNetInitTS = 0;
|
||||
|
||||
mNetFlags = pqiNetStatus();
|
||||
mOldNetFlags = pqiNetStatus();
|
||||
@ -133,10 +134,6 @@ p3NetMgrIMPL::p3NetMgrIMPL() : mPeerMgr(nullptr), mLinkMgr(nullptr),
|
||||
mLocalAddr.ss_family = AF_INET;
|
||||
mExtAddr.ss_family = AF_INET;
|
||||
|
||||
// default to full.
|
||||
mVsDisc = RS_VS_DISC_FULL;
|
||||
mVsDht = RS_VS_DHT_FULL;
|
||||
|
||||
}
|
||||
|
||||
#ifdef NETMGR_DEBUG
|
||||
@ -235,6 +232,10 @@ void p3NetMgrIMPL::netReset()
|
||||
rslog(RSL_ALERT, p3netmgrzone, "p3NetMgr::netReset() Called");
|
||||
|
||||
shutdown(); /* blocking shutdown call */
|
||||
{
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStatus = RS_NET_UNKNOWN;
|
||||
}
|
||||
|
||||
// Will initiate a new call for determining the external ip.
|
||||
if (mUseExtAddrFinder)
|
||||
@ -242,7 +243,7 @@ void p3NetMgrIMPL::netReset()
|
||||
#ifdef NETMGR_DEBUG_RESET
|
||||
std::cerr << "p3NetMgrIMPL::netReset() restarting AddrFinder" << std::endl;
|
||||
#endif
|
||||
mExtAddrFinder->reset() ;
|
||||
mExtAddrFinder->reset(true) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -265,7 +266,7 @@ void p3NetMgrIMPL::netReset()
|
||||
* as it calls back to p3ConnMgr.
|
||||
*/
|
||||
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
struct sockaddr_storage iaddr = mLocalAddr;
|
||||
|
||||
@ -283,8 +284,7 @@ void p3NetMgrIMPL::netReset()
|
||||
}
|
||||
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStatus = RS_NET_UNKNOWN;
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
netStatusReset_locked();
|
||||
}
|
||||
|
||||
@ -311,8 +311,8 @@ bool p3NetMgrIMPL::shutdown() /* blocking shutdown call */
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStatus = RS_NET_UNKNOWN;
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStatus = RS_NET_SHUTDOWN;
|
||||
mNetInitTS = time(NULL);
|
||||
netStatusReset_locked();
|
||||
}
|
||||
@ -347,7 +347,7 @@ void p3NetMgrIMPL::netStartup()
|
||||
*/
|
||||
|
||||
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
mNetInitTS = time(NULL);
|
||||
netStatusReset_locked();
|
||||
@ -460,35 +460,51 @@ void p3NetMgrIMPL::netStatusTick()
|
||||
|
||||
uint32_t netStatus = 0;
|
||||
rstime_t age = 0;
|
||||
bool needExtFinderUpdate = false;
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /************** LOCK MUTEX ***************/
|
||||
RS_STACK_MUTEX(mNetMtx); /************** LOCK MUTEX ***************/
|
||||
|
||||
netStatus = mNetStatus;
|
||||
age = time(NULL) - mNetInitTS;
|
||||
|
||||
}
|
||||
needExtFinderUpdate = netStatus == RS_NET_DONE;
|
||||
needExtFinderUpdate &= mNetExtAddrFinderTs < time(nullptr);
|
||||
if(needExtFinderUpdate)
|
||||
mNetExtAddrFinderTs = time(nullptr) + MIN_TIME_EXT_FINDER_UPDATE;
|
||||
}
|
||||
|
||||
if(netStatus <= RS_NET_UPNP_SETUP && mUseExtAddrFinder)
|
||||
{
|
||||
sockaddr_storage tmpip = mLocalAddr; // copies local port and correctly inits the IP family
|
||||
if( mUseExtAddrFinder
|
||||
&& ( netStatus <= RS_NET_UPNP_SETUP
|
||||
|| needExtFinderUpdate) )
|
||||
{
|
||||
sockaddr_storage tmpip;
|
||||
sockaddr_storage_copy( mLocalAddr, tmpip); // copies local port and correctly inits the IP family
|
||||
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
|
||||
std::cerr << "Asking ExtAddrFinder for IP. Initializing port with " << sockaddr_storage_port(tmpip) << std::endl;
|
||||
RS_DBG("Asking ExtAddrFinder for IP. Initializing port with ", sockaddr_storage_port(tmpip));
|
||||
#endif
|
||||
|
||||
if(mExtAddrFinder->hasValidIP(tmpip) && sockaddr_storage_ipv6_to_ipv4(tmpip) && !sockaddr_storage_same(tmpip,mExtAddr))
|
||||
{
|
||||
if(mExtAddrFinder->hasValidIPV4(tmpip))
|
||||
{
|
||||
if(!sockaddr_storage_same(tmpip,mExtAddr))
|
||||
{
|
||||
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
|
||||
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl;
|
||||
RS_DBG("Ext supplied by ExtAddrFinder. ExtAddr: ", tmpip);
|
||||
#endif
|
||||
|
||||
setExtAddress(tmpip);
|
||||
}
|
||||
}
|
||||
else if(mExtAddrFinder->hasValidIPV6(tmpip))
|
||||
{
|
||||
if(!sockaddr_storage_same(tmpip,mExtAddr))
|
||||
{
|
||||
//Only if no IPv4 else, reset connections on setExtAddress()
|
||||
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
|
||||
std::cerr << "p3NetMgrIMPL::netExtCheck() ";
|
||||
std::cerr << "ExtAddr: " << sockaddr_storage_tostring(tmpip);
|
||||
std::cerr << std::endl;
|
||||
RS_DBG("Ext supplied by ExtAddrFinder. ExtAddr: ", tmpip);
|
||||
#endif
|
||||
setExtAddress(tmpip);
|
||||
}
|
||||
}
|
||||
setExtAddress(tmpip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(netStatus)
|
||||
{
|
||||
@ -578,7 +594,7 @@ void p3NetMgrIMPL::netDhtInit()
|
||||
|
||||
uint32_t vs = 0;
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /*********** LOCKED MUTEX ************/
|
||||
RS_STACK_MUTEX(mNetMtx); /*********** LOCKED MUTEX ************/
|
||||
vs = mVsDht;
|
||||
}
|
||||
|
||||
@ -745,25 +761,16 @@ void p3NetMgrIMPL::netExtCheck()
|
||||
if (mUseExtAddrFinder)
|
||||
{
|
||||
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
|
||||
std::cerr << "p3NetMgrIMPL::netExtCheck() checking ExtAddrFinder" << std::endl;
|
||||
RS_DBG("checking ExtAddrFinder");
|
||||
#endif
|
||||
sockaddr_storage tmpip = mLocalAddr; // copies local port and correctly inits the IP family
|
||||
sockaddr_storage tmpip;
|
||||
sockaddr_storage_copy( mLocalAddr, tmpip); // copies local port and correctly inits the IP family
|
||||
|
||||
bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip);
|
||||
|
||||
if (extFinderOk && sockaddr_storage_ipv6_to_ipv4(tmpip))
|
||||
// Test for IPv4 first to be compatible with older versions.
|
||||
if (mExtAddrFinder->hasValidIPV4(tmpip))
|
||||
{
|
||||
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
|
||||
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl;
|
||||
#endif
|
||||
sockaddr_storage_setport(tmpip, guessNewExtPort());
|
||||
|
||||
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
|
||||
std::cerr << "p3NetMgrIMPL::netExtCheck() ";
|
||||
std::cerr << "ExtAddr: " << sockaddr_storage_tostring(tmpip);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
mNetFlags.mExtAddrOk = true;
|
||||
|
||||
address_votes[tmpip].n++ ;
|
||||
@ -773,10 +780,22 @@ void p3NetMgrIMPL::netExtCheck()
|
||||
* (which it is not normally) */
|
||||
mNetFlags.mExtAddrStableOk = true;
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " ExtAddrFinder "
|
||||
<< " reported external address "
|
||||
<< sockaddr_storage_iptostring(tmpip)
|
||||
<< std::endl;
|
||||
RS_DBG("Reported external IPv4 address ", sockaddr_storage_iptostring(tmpip));
|
||||
}
|
||||
else if (mExtAddrFinder->hasValidIPV6(tmpip))
|
||||
{
|
||||
sockaddr_storage_setport(tmpip, guessNewExtPort());
|
||||
|
||||
mNetFlags.mExtAddrOk = true;
|
||||
|
||||
address_votes[tmpip].n++ ;
|
||||
|
||||
/* XXX HACK TO FIX drbob: ALLOWING
|
||||
* ExtAddrFinder -> ExtAddrStableOk = true
|
||||
* (which it is not normally) */
|
||||
mNetFlags.mExtAddrStableOk = true;
|
||||
|
||||
RS_DBG("Reported external IPv6 address ", sockaddr_storage_iptostring(tmpip));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -967,7 +986,7 @@ void p3NetMgrIMPL::netExtCheck()
|
||||
|
||||
if (netSetupDone)
|
||||
{
|
||||
std::cerr << "p3NetMgrIMPL::netExtCheck() netSetupDone" << std::endl;
|
||||
RS_DBG("netSetupDone");
|
||||
|
||||
/* Setup NetStateBox with this info */
|
||||
updateNetStateBox_startup();
|
||||
@ -978,12 +997,14 @@ void p3NetMgrIMPL::netExtCheck()
|
||||
mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
|
||||
}
|
||||
|
||||
/* inform DHT about our external address */
|
||||
RsPeerId fakeId;
|
||||
netAssistKnownPeer(fakeId, mExtAddr, NETASSIST_KNOWN_PEER_SELF | NETASSIST_KNOWN_PEER_ONLINE);
|
||||
/* inform DHT about our external IPV4 address, it doesn't support IPv6 for now.*/
|
||||
if(sockaddr_storage_ipv6_to_ipv4(mExtAddr))
|
||||
{
|
||||
RsPeerId fakeId;
|
||||
netAssistKnownPeer(fakeId, mExtAddr, NETASSIST_KNOWN_PEER_SELF | NETASSIST_KNOWN_PEER_ONLINE);
|
||||
}
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Network Setup Complete"
|
||||
<< std::endl;
|
||||
RS_INFO("Network Setup Complete");
|
||||
}
|
||||
}
|
||||
|
||||
@ -994,7 +1015,8 @@ void p3NetMgrIMPL::netExtCheck()
|
||||
bool p3NetMgrIMPL::checkNetAddress()
|
||||
{
|
||||
bool addrChanged = false;
|
||||
bool validAddr = false;
|
||||
bool validAddr = false;
|
||||
bool needOwnAddrUpdate = false;
|
||||
|
||||
sockaddr_storage prefAddr;
|
||||
sockaddr_storage oldAddr;
|
||||
@ -1067,8 +1089,7 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
|
||||
if (!validAddr)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " no valid local network address "
|
||||
<<" found. Report to developers." << std::endl;
|
||||
RS_ERR("no valid local network address found. Report to developers.");
|
||||
print_stacktrace();
|
||||
|
||||
return false;
|
||||
@ -1109,6 +1130,7 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
sockaddr_storage_setport(mExtAddr, port); // this accounts for when the port was updated
|
||||
addrChanged = true;
|
||||
}
|
||||
|
||||
} // RS_STACK_MUTEX(mNetMtx);
|
||||
|
||||
if (addrChanged)
|
||||
@ -1123,11 +1145,24 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
|
||||
if (mPeerMgr) mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
|
||||
needOwnAddrUpdate = true;
|
||||
|
||||
netReset();
|
||||
}
|
||||
|
||||
if (mPeerMgr)
|
||||
{
|
||||
// Retrieve last known IP, if none, update own addresse to get current.
|
||||
peerState ps;
|
||||
mPeerMgr->getOwnNetStatus(ps);
|
||||
needOwnAddrUpdate |= ps.ipAddrs.mLocal.mAddrs.empty();
|
||||
needOwnAddrUpdate |= ps.ipAddrs.mExt.mAddrs.empty();
|
||||
if (needOwnAddrUpdate)
|
||||
{
|
||||
mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1139,7 +1174,7 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
/* to allow resets of network stuff */
|
||||
void p3NetMgrIMPL::addNetListener(pqiNetListener *listener)
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetListeners.push_back(listener);
|
||||
}
|
||||
|
||||
@ -1149,7 +1184,7 @@ bool p3NetMgrIMPL::setLocalAddress(const struct sockaddr_storage &addr)
|
||||
{
|
||||
bool changed = false;
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
if (!sockaddr_storage_same(mLocalAddr, addr))
|
||||
{
|
||||
changed = true;
|
||||
@ -1171,7 +1206,7 @@ bool p3NetMgrIMPL::setLocalAddress(const struct sockaddr_storage &addr)
|
||||
}
|
||||
bool p3NetMgrIMPL::getExtAddress(struct sockaddr_storage& addr)
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
if(mNetFlags.mExtAddrOk)
|
||||
{
|
||||
@ -1186,7 +1221,7 @@ bool p3NetMgrIMPL::setExtAddress(const struct sockaddr_storage &addr)
|
||||
{
|
||||
bool changed = false;
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
if (!sockaddr_storage_same(mExtAddr, addr))
|
||||
{
|
||||
changed = true;
|
||||
@ -1220,7 +1255,7 @@ bool p3NetMgrIMPL::setNetworkMode(uint32_t netMode)
|
||||
{
|
||||
uint32_t oldNetMode;
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
/* only change TRY flags */
|
||||
|
||||
oldNetMode = mNetMode;
|
||||
@ -1266,7 +1301,7 @@ bool p3NetMgrIMPL::setNetworkMode(uint32_t netMode)
|
||||
|
||||
bool p3NetMgrIMPL::setVisState(uint16_t vs_disc, uint16_t vs_dht)
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mVsDisc = vs_disc;
|
||||
mVsDht = vs_dht;
|
||||
|
||||
@ -1628,7 +1663,7 @@ void p3NetMgrIMPL::getNetStatus(pqiNetStatus &status)
|
||||
uint32_t netsize = 0, rsnetsize = 0;
|
||||
netAssistConnectStats(netsize, rsnetsize);
|
||||
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
/* quick update of the stuff that can change! */
|
||||
mNetFlags.mDhtOk = dhtOk;
|
||||
@ -1652,7 +1687,7 @@ void p3NetMgrIMPL::getNetStatus(pqiNetStatus &status)
|
||||
|
||||
bool p3NetMgrIMPL::getIPServersEnabled()
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
return mUseExtAddrFinder;
|
||||
}
|
||||
|
||||
@ -1661,15 +1696,32 @@ void p3NetMgrIMPL::getIPServersList(std::list<std::string>& ip_servers)
|
||||
mExtAddrFinder->getIPServersList(ip_servers);
|
||||
}
|
||||
|
||||
void p3NetMgrIMPL::getCurrentExtIPList(std::list<std::string>& ip_list)
|
||||
{
|
||||
ip_list.clear();
|
||||
sockaddr_storage addr;
|
||||
if(mExtAddrFinder->hasValidIPV4(addr))
|
||||
ip_list.push_back(sockaddr_storage_iptostring(addr));
|
||||
if(mExtAddrFinder->hasValidIPV6(addr))
|
||||
ip_list.push_back(sockaddr_storage_iptostring(addr));
|
||||
}
|
||||
|
||||
void p3NetMgrIMPL::setIPServersEnabled(bool b)
|
||||
{
|
||||
if (mUseExtAddrFinder != b)
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mExtAddrFinder->reset(true);
|
||||
if (b)
|
||||
mExtAddrFinder->start_request();
|
||||
}
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mUseExtAddrFinder = b;
|
||||
}
|
||||
|
||||
#ifdef NETMGR_DEBUG
|
||||
std::cerr << "p3NetMgr: setIPServers to " << b << std::endl ;
|
||||
RS_DBG("set mUseExtAddrFinder to ", b);
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -1682,31 +1734,31 @@ void p3NetMgrIMPL::setIPServersEnabled(bool b)
|
||||
|
||||
RsNetState p3NetMgrIMPL::getNetStateMode()
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
return mNetStateBox.getNetStateMode();
|
||||
}
|
||||
|
||||
RsNetworkMode p3NetMgrIMPL::getNetworkMode()
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
return mNetStateBox.getNetworkMode();
|
||||
}
|
||||
|
||||
RsNatTypeMode p3NetMgrIMPL::getNatTypeMode()
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
return mNetStateBox.getNatTypeMode();
|
||||
}
|
||||
|
||||
RsNatHoleMode p3NetMgrIMPL::getNatHoleMode()
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
return mNetStateBox.getNatHoleMode();
|
||||
}
|
||||
|
||||
RsConnectModes p3NetMgrIMPL::getConnectModes()
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
return mNetStateBox.getConnectModes();
|
||||
}
|
||||
|
||||
@ -1730,7 +1782,7 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
|
||||
/* input network bits */
|
||||
if (mDhtStunner->getExternalAddr(tmpaddr, isstable))
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStateBox.setAddressStunDht(tmpaddr, isstable);
|
||||
|
||||
#ifdef NETMGR_DEBUG_STATEBOX
|
||||
@ -1749,7 +1801,7 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
|
||||
/* input network bits */
|
||||
if (mProxyStunner->getExternalAddr(tmpaddr, isstable))
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStateBox.setAddressStunProxy(tmpaddr, isstable);
|
||||
|
||||
#ifdef NETMGR_DEBUG_STATEBOX
|
||||
@ -1768,7 +1820,7 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
|
||||
bool dhtOn = netAssistConnectEnabled();
|
||||
bool dhtActive = netAssistConnectActive();
|
||||
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStateBox.setDhtState(dhtOn, dhtActive);
|
||||
}
|
||||
|
||||
@ -1777,7 +1829,7 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
|
||||
|
||||
#ifdef NETMGR_DEBUG_STATEBOX
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
auto netstate = mNetStateBox.getNetStateMode();
|
||||
auto netMode = mNetStateBox.getNetworkMode();
|
||||
@ -1823,7 +1875,7 @@ void p3NetMgrIMPL::updateNatSetting()
|
||||
RsNatTypeMode natType = RsNatTypeMode::UNKNOWN;
|
||||
RsNatHoleMode natHole = RsNatHoleMode::UNKNOWN;
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
natType = mNetStateBox.getNatTypeMode();
|
||||
natHole = mNetStateBox.getNatHoleMode();
|
||||
@ -1925,7 +1977,7 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
/* fill in the data */
|
||||
struct sockaddr_storage tmpip;
|
||||
@ -1973,8 +2025,8 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
|
||||
/* ExtAddrFinder */
|
||||
if (mUseExtAddrFinder)
|
||||
{
|
||||
tmpip = mLocalAddr;
|
||||
bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip);
|
||||
tmpip = mLocalAddr;
|
||||
bool extFinderOk = mExtAddrFinder->hasValidIPV4(tmpip);
|
||||
|
||||
if (extFinderOk)
|
||||
{
|
||||
@ -2020,7 +2072,7 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
|
||||
void p3NetMgrIMPL::updateNetStateBox_reset()
|
||||
{
|
||||
{
|
||||
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
RS_STACK_MUTEX(mNetMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
mNetStateBox.reset();
|
||||
|
||||
|
@ -120,6 +120,7 @@ virtual bool shutdown() = 0; /* blocking shutdown call */
|
||||
virtual bool getIPServersEnabled() = 0;
|
||||
virtual void setIPServersEnabled(bool b) = 0;
|
||||
virtual void getIPServersList(std::list<std::string>& ip_servers) = 0;
|
||||
virtual void getCurrentExtIPList(std::list<std::string>& ip_list) = 0;
|
||||
|
||||
// ONLY USED by p3face-config.cc WHICH WILL BE REMOVED.
|
||||
virtual void getNetStatus(pqiNetStatus &status) = 0;
|
||||
@ -171,6 +172,7 @@ virtual bool shutdown(); /* blocking shutdown call */
|
||||
virtual bool getIPServersEnabled();
|
||||
virtual void setIPServersEnabled(bool b);
|
||||
virtual void getIPServersList(std::list<std::string>& ip_servers);
|
||||
virtual void getCurrentExtIPList(std::list<std::string>& ip_list);
|
||||
|
||||
// ONLY USED by p3face-config.cc WHICH WILL BE REMOVED.
|
||||
virtual void getNetStatus(pqiNetStatus &status);
|
||||
@ -307,12 +309,13 @@ void netStatusReset_locked();
|
||||
uint16_t mVsDisc;
|
||||
uint16_t mVsDht;
|
||||
|
||||
rstime_t mNetInitTS;
|
||||
rstime_t mNetInitTS;
|
||||
uint32_t mNetStatus;
|
||||
|
||||
bool mStatusChanged;
|
||||
|
||||
bool mUseExtAddrFinder;
|
||||
bool mUseExtAddrFinder;
|
||||
rstime_t mNetExtAddrFinderTs;
|
||||
|
||||
/* network status flags (read by rsiface) */
|
||||
pqiNetStatus mNetFlags;
|
||||
|
@ -788,6 +788,7 @@ public:
|
||||
virtual bool setProxyServer(const uint32_t type, const std::string &addr, const uint16_t port) = 0;
|
||||
|
||||
virtual void getIPServersList(std::list<std::string>& ip_servers) = 0;
|
||||
virtual void getCurrentExtIPList(std::list<std::string>& ip_list) = 0;
|
||||
virtual void allowServerIPDetermination(bool) = 0;
|
||||
virtual bool resetOwnExternalAddressList() = 0;
|
||||
virtual bool getAllowServerIPDetermination() = 0 ;
|
||||
|
@ -373,7 +373,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
|
||||
sockaddr_storage_ipv6_to_ipv4(it->mAddr);
|
||||
std::string toto;
|
||||
toto += sockaddr_storage_tostring(it->mAddr);
|
||||
rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime);
|
||||
rs_sprintf_append(toto, " %ld sec loc", time(NULL) - it->mSeenTime);
|
||||
d.ipAddressList.push_back(toto);
|
||||
}
|
||||
for(it = ps.ipAddrs.mExt.mAddrs.begin(); it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
|
||||
@ -381,7 +381,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
|
||||
sockaddr_storage_ipv6_to_ipv4(it->mAddr);
|
||||
std::string toto;
|
||||
toto += sockaddr_storage_tostring(it->mAddr);
|
||||
rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime);
|
||||
rs_sprintf_append(toto, " %ld sec ext", time(NULL) - it->mSeenTime);
|
||||
d.ipAddressList.push_back(toto);
|
||||
}
|
||||
}
|
||||
@ -859,9 +859,15 @@ void p3Peers::getIPServersList(std::list<std::string>& ip_servers)
|
||||
{
|
||||
mNetMgr->getIPServersList(ip_servers) ;
|
||||
}
|
||||
void p3Peers::getCurrentExtIPList(std::list<std::string>& ip_list)
|
||||
{
|
||||
mNetMgr->getCurrentExtIPList(ip_list) ;
|
||||
}
|
||||
bool p3Peers::resetOwnExternalAddressList()
|
||||
{
|
||||
return mPeerMgr->resetOwnExternalAddressList();
|
||||
//TODO Phenom 2021-10-30: Need to call something like mNetMgr->netReset();
|
||||
// to update this addresslist.
|
||||
return mPeerMgr->resetOwnExternalAddressList();
|
||||
}
|
||||
void p3Peers::allowServerIPDetermination(bool b)
|
||||
{
|
||||
@ -1287,7 +1293,11 @@ bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, Retros
|
||||
}
|
||||
#else
|
||||
sockaddr_storage tLocal;
|
||||
if(sockaddr_storage_inet_pton(tLocal, tDetails.localAddr) && sockaddr_storage_isValidNet(tLocal) && sockaddr_storage_ipv6_to_ipv4(tLocal) && tDetails.localPort )
|
||||
bool validLoc = sockaddr_storage_inet_pton(tLocal, tDetails.localAddr)
|
||||
&& sockaddr_storage_isValidNet(tLocal)
|
||||
&& tDetails.localPort;
|
||||
bool isLocIpv4 = sockaddr_storage_ipv6_to_ipv4(tLocal);
|
||||
if(validLoc && isLocIpv4)
|
||||
{
|
||||
uint32_t t4Addr = reinterpret_cast<sockaddr_in&>(tLocal).sin_addr.s_addr;
|
||||
|
||||
@ -1305,7 +1315,11 @@ bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, Retros
|
||||
}
|
||||
|
||||
sockaddr_storage tExt;
|
||||
if(sockaddr_storage_inet_pton(tExt, tDetails.extAddr) && sockaddr_storage_isValidNet(tExt) && sockaddr_storage_ipv6_to_ipv4(tExt) && tDetails.extPort )
|
||||
bool validExt = sockaddr_storage_inet_pton(tExt, tDetails.extAddr)
|
||||
&& sockaddr_storage_isValidNet(tExt)
|
||||
&& tDetails.extPort;
|
||||
bool isExtIpv4 = sockaddr_storage_ipv6_to_ipv4(tExt);
|
||||
if(validExt && isExtIpv4)
|
||||
{
|
||||
uint32_t t4Addr = reinterpret_cast<sockaddr_in&>(tExt).sin_addr.s_addr;
|
||||
|
||||
@ -1321,6 +1335,17 @@ bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, Retros
|
||||
|
||||
offset += 4+2;
|
||||
}
|
||||
else if(validExt && !isExtIpv4)
|
||||
{
|
||||
// External address is IPv6, save it on LOCATOR
|
||||
sockaddr_storage_setport(tExt,tDetails.extPort);
|
||||
std::string tLocator = sockaddr_storage_tostring(tExt);
|
||||
|
||||
addPacketHeader(RsShortInviteFieldType::LOCATOR, tLocator.size(),buf,offset,buf_size);
|
||||
memcpy(&buf[offset],tLocator.c_str(),tLocator.size());
|
||||
|
||||
offset += tLocator.size();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -1595,13 +1620,31 @@ std::string p3Peers::GetRetroshareInvite( const RsPeerId& sslId, RetroshareInvit
|
||||
|
||||
if (getPeerDetails(ssl_id, detail))
|
||||
{
|
||||
if(!(invite_flags & RetroshareInviteFlags::FULL_IP_HISTORY) || detail.isHiddenNode)
|
||||
detail.ipAddressList.clear();
|
||||
if( !(invite_flags & RetroshareInviteFlags::FULL_IP_HISTORY)
|
||||
|| detail.isHiddenNode)
|
||||
detail.ipAddressList.clear();
|
||||
|
||||
//Check if external address is IPv6, then move it to ipAddressList as RsCertificate only allow 4 numbers.
|
||||
sockaddr_storage tExt;
|
||||
bool validExt = sockaddr_storage_inet_pton(tExt, detail.extAddr)
|
||||
&& sockaddr_storage_isValidNet(tExt)
|
||||
&& detail.extPort;
|
||||
bool isExtIpv4 = sockaddr_storage_ipv6_to_ipv4(tExt);
|
||||
|
||||
if( !(invite_flags & RetroshareInviteFlags::FULL_IP_HISTORY)
|
||||
&& !detail.isHiddenNode
|
||||
&& validExt && !isExtIpv4)
|
||||
{
|
||||
sockaddr_storage_setport(tExt,detail.extPort);
|
||||
detail.ipAddressList.push_front(sockaddr_storage_tostring(tExt) + " "); // Space needed to later parse.
|
||||
detail.extAddr = ""; //Clear it to not trigg error.
|
||||
detail.extPort = 0;
|
||||
}
|
||||
|
||||
unsigned char *mem_block = nullptr;
|
||||
size_t mem_block_size = 0;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) ))
|
||||
if(!AuthGPG::getAuthGPG()->exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) ))
|
||||
{
|
||||
std::cerr << "Cannot output certificate for id \"" << detail.gpg_id
|
||||
<< "\". Sorry." << std::endl;
|
||||
|
@ -132,6 +132,7 @@ public:
|
||||
virtual bool isProxyAddress(const uint32_t type, const sockaddr_storage &addr);
|
||||
|
||||
virtual void getIPServersList(std::list<std::string>& ip_servers) override;
|
||||
virtual void getCurrentExtIPList(std::list<std::string>& ip_list) override;
|
||||
virtual void allowServerIPDetermination(bool) override;
|
||||
virtual bool getAllowServerIPDetermination() override;
|
||||
virtual bool resetOwnExternalAddressList() override;
|
||||
|
@ -41,8 +41,6 @@
|
||||
const rstime_t MAX_TIME_BEFORE_RETRY = 300 ; /* seconds before retrying an ip address */
|
||||
const rstime_t MAX_KEEP_DNS_ENTRY = 3600 ; /* seconds during which a DNS entry is considered valid */
|
||||
|
||||
static const std::string ADDR_AGENT = "Mozilla/5.0";
|
||||
|
||||
void *solveDNSEntries(void *p)
|
||||
{
|
||||
bool more_to_go = true ;
|
||||
|
@ -19,9 +19,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
//#define EXTADDRSEARCH_DEBUG
|
||||
|
||||
#include "extaddrfinder.h"
|
||||
|
||||
#include "pqi/pqinetwork.h"
|
||||
#include "rsdebug.h"
|
||||
#include "util/rsstring.h"
|
||||
#include "util/rsmemory.h"
|
||||
|
||||
@ -38,286 +42,237 @@
|
||||
#include <stdio.h>
|
||||
#include "util/rstime.h"
|
||||
|
||||
const uint32_t MAX_IP_STORE = 300; /* seconds ip address timeout */
|
||||
#include <map>
|
||||
|
||||
//#define EXTADDRSEARCH_DEBUG
|
||||
const uint32_t MAX_IP_STORE = 300; /* seconds ip address timeout */
|
||||
|
||||
static const std::string ADDR_AGENT = "Mozilla/5.0";
|
||||
|
||||
static std::string scan_ip(const std::string& text)
|
||||
class ZeroInt
|
||||
{
|
||||
std::set<unsigned char> digits ;
|
||||
digits.insert('0') ; digits.insert('3') ; digits.insert('6') ;
|
||||
digits.insert('1') ; digits.insert('4') ; digits.insert('7') ;
|
||||
digits.insert('2') ; digits.insert('5') ; digits.insert('8') ;
|
||||
digits.insert('9') ;
|
||||
public:
|
||||
ZeroInt() : n(0) {}
|
||||
uint32_t n ;
|
||||
};
|
||||
|
||||
for(int i=0;i<(int)text.size();++i)
|
||||
{
|
||||
while(i < (int)text.size() && digits.find(text[i])==digits.end()) ++i ;
|
||||
|
||||
if(i>=(int)text.size())
|
||||
return "" ;
|
||||
|
||||
unsigned int a,b,c,d ;
|
||||
|
||||
if(sscanf(text.c_str()+i,"%u.%u.%u.%u",&a,&b,&c,&d) != 4)
|
||||
continue ;
|
||||
|
||||
if(a < 256 && b<256 && c<256 && d<256)
|
||||
{
|
||||
std::string s ;
|
||||
rs_sprintf(s, "%u.%u.%u.%u", a, b, c, d) ;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return "" ;
|
||||
}
|
||||
|
||||
static void getPage(const std::string& server_name,std::string& page)
|
||||
{
|
||||
page = "" ;
|
||||
int sockfd,n=0; // socket descriptor
|
||||
struct sockaddr_in serveur; // server's parameters
|
||||
memset(&serveur.sin_zero, 0, sizeof(serveur.sin_zero));
|
||||
|
||||
char buf[1024];
|
||||
char request[1024];
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cout << "ExtAddrFinder: connecting to " << server_name << std::endl ;
|
||||
#endif
|
||||
// socket creation
|
||||
|
||||
sockfd = unix_socket(PF_INET,SOCK_STREAM,0);
|
||||
if (sockfd < 0)
|
||||
{
|
||||
std::cerr << "ExtAddrFinder: Failed to create socket" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
serveur.sin_family = AF_INET;
|
||||
|
||||
// get server's ipv4 adress
|
||||
|
||||
in_addr in ;
|
||||
|
||||
if(!rsGetHostByName(server_name.c_str(),in)) /* l'hôte n'existe pas */
|
||||
{
|
||||
std::cerr << "ExtAddrFinder: Unknown host " << server_name << std::endl;
|
||||
unix_close(sockfd);
|
||||
return ;
|
||||
}
|
||||
serveur.sin_addr = in ;
|
||||
serveur.sin_port = htons(80);
|
||||
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
printf("Connection attempt\n");
|
||||
#endif
|
||||
std::cerr << "ExtAddrFinder: resolved hostname " << server_name << " to " << rs_inet_ntoa(in) << std::endl;
|
||||
|
||||
sockaddr_storage server;
|
||||
sockaddr_storage_setipv4(server, &serveur);
|
||||
sockaddr_storage_setport(server, 80);
|
||||
if(unix_connect(sockfd, server) == -1)
|
||||
{
|
||||
std::cerr << "ExtAddrFinder: Connection error to " << server_name << std::endl ;
|
||||
unix_close(sockfd);
|
||||
return ;
|
||||
}
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cerr << "ExtAddrFinder: Connection established to " << server_name << std::endl ;
|
||||
#endif
|
||||
|
||||
// envoi
|
||||
if(snprintf( request,
|
||||
1024,
|
||||
"GET / HTTP/1.0\r\n"
|
||||
"Host: %s:%d\r\n"
|
||||
"Connection: Close\r\n"
|
||||
"\r\n",
|
||||
server_name.c_str(), 80) > 1020)
|
||||
{
|
||||
std::cerr << "ExtAddrFinder: buffer overrun. The server name \"" << server_name << "\" is too long. This is quite unexpected." << std::endl;
|
||||
unix_close(sockfd);
|
||||
return ;
|
||||
}
|
||||
|
||||
if(send(sockfd,request,strlen(request),0)== -1)
|
||||
{
|
||||
std::cerr << "ExtAddrFinder: Could not send request to " << server_name << std::endl ;
|
||||
unix_close(sockfd);
|
||||
return ;
|
||||
}
|
||||
// recéption
|
||||
|
||||
while((n = recv(sockfd, buf, sizeof buf - 1, 0)) > 0)
|
||||
{
|
||||
buf[n] = '\0';
|
||||
page += std::string(buf,n) ;
|
||||
}
|
||||
// fermeture de la socket
|
||||
|
||||
unix_close(sockfd);
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cerr << "ExtAddrFinder: Got full page from " << server_name << std::endl ;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void* doExtAddrSearch(void *p)
|
||||
void ExtAddrFinder::run()
|
||||
{
|
||||
|
||||
std::vector<std::string> res ;
|
||||
|
||||
ExtAddrFinder *af = (ExtAddrFinder*)p ;
|
||||
|
||||
for(std::list<std::string>::const_iterator it(af->_ip_servers.begin());it!=af->_ip_servers.end();++it)
|
||||
for(auto& it : _ip_servers)
|
||||
{
|
||||
std::string page ;
|
||||
|
||||
getPage(*it,page) ;
|
||||
std::string ip = scan_ip(page) ;
|
||||
|
||||
std::string ip = "";
|
||||
rsGetHostByNameSpecDNS(it,"myip.opendns.com",ip,2);
|
||||
if(ip != "")
|
||||
res.push_back(ip) ;
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cout << "ip found through " << *it << ": \"" << ip << "\"" << std::endl ;
|
||||
RS_DBG("ip found through DNS ", it, ": \"", ip, "\"");
|
||||
#endif
|
||||
}
|
||||
|
||||
if(res.empty())
|
||||
{
|
||||
// thread safe copy results.
|
||||
//
|
||||
{
|
||||
RsStackMutex mtx(af->mAddrMtx) ;
|
||||
|
||||
af->mFound = false ;
|
||||
af->mFoundTS = time(NULL) ;
|
||||
af->mSearching = false ;
|
||||
}
|
||||
return NULL ;
|
||||
reset();
|
||||
return ;
|
||||
}
|
||||
|
||||
sort(res.begin(),res.end()) ; // eliminates outliers.
|
||||
std::map<sockaddr_storage,ZeroInt> addrV4_votes;
|
||||
std::map<sockaddr_storage,ZeroInt> addrV6_votes;
|
||||
std::string all_addrV4_Found;
|
||||
std::string all_addrV6_Found;
|
||||
|
||||
|
||||
|
||||
if(!sockaddr_storage_ipv4_aton(af->mAddr, res[res.size()/2].c_str()))
|
||||
for(auto curRes : res)
|
||||
{
|
||||
std::cerr << "ExtAddrFinder: Could not convert " << res[res.size()/2] << " into an address." << std::endl ;
|
||||
sockaddr_storage addr;
|
||||
sockaddr_storage_clear(addr);
|
||||
bool validIP = sockaddr_storage_inet_pton(addr, curRes)
|
||||
&& sockaddr_storage_isValidNet(addr);
|
||||
bool isIPv4 = sockaddr_storage_ipv6_to_ipv4(addr);
|
||||
if( validIP && isIPv4 )
|
||||
{
|
||||
RsStackMutex mtx(af->mAddrMtx) ;
|
||||
af->mFound = false ;
|
||||
af->mFoundTS = time(NULL) ;
|
||||
af->mSearching = false ;
|
||||
addr.ss_family = AF_INET;
|
||||
addrV4_votes[addr].n++ ;
|
||||
all_addrV4_Found += sockaddr_storage_tostring(addr) + "\n";
|
||||
}
|
||||
return NULL ;
|
||||
else if( validIP && !isIPv4)
|
||||
{
|
||||
addr.ss_family = AF_INET6;
|
||||
addrV6_votes[addr].n++ ;
|
||||
all_addrV6_Found += sockaddr_storage_tostring(addr) + "\n";
|
||||
}
|
||||
else
|
||||
RS_ERR("Invalid addresse reported: ", curRes) ;
|
||||
|
||||
}
|
||||
|
||||
if( (0 == addrV4_votes.size()) && (0 == addrV6_votes.size()) )
|
||||
{
|
||||
RS_ERR("Could not find any external address.");
|
||||
reset();
|
||||
return ;
|
||||
}
|
||||
|
||||
if( 1 < addrV4_votes.size() )
|
||||
RS_ERR("Multiple external IPv4 addresses reported: "
|
||||
, all_addrV4_Found ) ;
|
||||
|
||||
if( 1 < addrV6_votes.size() )
|
||||
RS_ERR("Multiple external IPv6 addresses reported: "
|
||||
, all_addrV6_Found ) ;
|
||||
|
||||
{
|
||||
RsStackMutex mtx(af->mAddrMtx) ;
|
||||
af->mFound = true ;
|
||||
af->mFoundTS = time(NULL) ;
|
||||
af->mSearching = false ;
|
||||
RS_STACK_MUTEX(mAddrMtx);
|
||||
|
||||
mSearching = false ;
|
||||
mFoundTS = time(NULL) ;
|
||||
|
||||
// Only save more reported address if not only once.
|
||||
uint32_t admax = 0 ;
|
||||
sockaddr_storage_clear(mAddrV4);
|
||||
for (auto it : addrV4_votes)
|
||||
if (admax < it.second.n)
|
||||
{
|
||||
mAddrV4 = it.first ;
|
||||
mFoundV4 = true ;
|
||||
admax = it.second.n ;
|
||||
}
|
||||
|
||||
admax = 0 ;
|
||||
sockaddr_storage_clear(mAddrV6);
|
||||
for (auto it : addrV6_votes)
|
||||
if (admax < it.second.n)
|
||||
{
|
||||
mAddrV6 = it.first ;
|
||||
mFoundV6 = true ;
|
||||
admax = it.second.n ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
void ExtAddrFinder::start_request()
|
||||
{
|
||||
void *data = (void *)this;
|
||||
pthread_t tid ;
|
||||
|
||||
if(! pthread_create(&tid, 0, &doExtAddrSearch, data))
|
||||
pthread_detach(tid); /* so memory is reclaimed in linux */
|
||||
else
|
||||
std::cerr << "(EE) Could not start ExtAddrFinder thread." << std::endl;
|
||||
if (!isRunning())
|
||||
start("ExtAddrFinder");
|
||||
}
|
||||
|
||||
bool ExtAddrFinder::hasValidIP(struct sockaddr_storage &addr)
|
||||
bool ExtAddrFinder::hasValidIPV4(struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cerr << "ExtAddrFinder: Getting ip." << std::endl ;
|
||||
RS_DBG("Getting ip.");
|
||||
#endif
|
||||
|
||||
{
|
||||
RsStackMutex mut(mAddrMtx) ;
|
||||
if(mFound)
|
||||
RS_STACK_MUTEX(mAddrMtx) ;
|
||||
if(mFoundV4)
|
||||
{
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cerr << "ExtAddrFinder: Has stored ip: responding with this ip." << std::endl ;
|
||||
RS_DBG("Has stored ip responding with this ip:", sockaddr_storage_iptostring(mAddrV4)) ;
|
||||
#endif
|
||||
sockaddr_storage_copyip(addr,mAddr); // just copy the IP so we dont erase the port.
|
||||
sockaddr_storage_copyip(addr,mAddrV4); // just copy the IP so we dont erase the port.
|
||||
}
|
||||
}
|
||||
rstime_t delta;
|
||||
|
||||
testTimeOut();
|
||||
|
||||
RS_STACK_MUTEX(mAddrMtx) ;
|
||||
return mFoundV4;
|
||||
}
|
||||
|
||||
bool ExtAddrFinder::hasValidIPV6(struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
RS_DBG("Getting ip.");
|
||||
#endif
|
||||
|
||||
{
|
||||
RsStackMutex mut(mAddrMtx) ;
|
||||
//timeout the current ip
|
||||
delta = time(NULL) - mFoundTS;
|
||||
RS_STACK_MUTEX(mAddrMtx) ;
|
||||
if(mFoundV6)
|
||||
{
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
RS_DBG("Has stored ip responding with this ip:", sockaddr_storage_iptostring(mAddrV6)) ;
|
||||
#endif
|
||||
sockaddr_storage_copyip(addr,mAddrV6); // just copy the IP so we dont erase the port.
|
||||
}
|
||||
}
|
||||
if((uint32_t)delta > MAX_IP_STORE) {//launch a research
|
||||
|
||||
testTimeOut();
|
||||
|
||||
RS_STACK_MUTEX(mAddrMtx) ;
|
||||
return mFoundV6;
|
||||
}
|
||||
|
||||
void ExtAddrFinder::testTimeOut()
|
||||
{
|
||||
bool timeOut;
|
||||
{
|
||||
RS_STACK_MUTEX(mAddrMtx) ;
|
||||
//timeout the current ip
|
||||
timeOut = (mFoundTS + MAX_IP_STORE < time(NULL));
|
||||
}
|
||||
if(timeOut || mFirstTime) {//launch a research
|
||||
if( mAddrMtx.trylock())
|
||||
{
|
||||
if(!mSearching)
|
||||
{
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cerr << "ExtAddrFinder: No stored ip: Initiating new search." << std::endl ;
|
||||
RS_DBG("No stored ip: Initiating new search.");
|
||||
#endif
|
||||
mSearching = true ;
|
||||
start_request() ;
|
||||
}
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
else
|
||||
std::cerr << "ExtAddrFinder: Already searching." << std::endl ;
|
||||
RS_DBG("Already searching.");
|
||||
#endif
|
||||
mFirstTime = false;
|
||||
mAddrMtx.unlock();
|
||||
}
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
else
|
||||
std::cerr << "ExtAddrFinder: (Note) Could not acquire lock. Busy." << std::endl ;
|
||||
RS_DBG("(Note) Could not acquire lock. Busy.");
|
||||
#endif
|
||||
}
|
||||
|
||||
RsStackMutex mut(mAddrMtx) ;
|
||||
return mFound ;
|
||||
}
|
||||
|
||||
void ExtAddrFinder::reset()
|
||||
void ExtAddrFinder::reset(bool firstTime /*=false*/)
|
||||
{
|
||||
RsStackMutex mut(mAddrMtx) ;
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
RS_DBG("firstTime=", firstTime);
|
||||
#endif
|
||||
RS_STACK_MUTEX(mAddrMtx) ;
|
||||
|
||||
mFound = false ;
|
||||
mSearching = false ;
|
||||
mFoundTS = time(NULL) - MAX_IP_STORE;
|
||||
mFoundV4 = false ;
|
||||
mFoundV6 = false ;
|
||||
mFirstTime = firstTime;
|
||||
mFoundTS = time(nullptr);
|
||||
sockaddr_storage_clear(mAddrV4);
|
||||
sockaddr_storage_clear(mAddrV6);
|
||||
}
|
||||
|
||||
ExtAddrFinder::~ExtAddrFinder()
|
||||
{
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cerr << "ExtAddrFinder: Deleting ExtAddrFinder." << std::endl ;
|
||||
RS_DBG("Deleting ExtAddrFinder.");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ExtAddrFinder::ExtAddrFinder() : mAddrMtx("ExtAddrFinder")
|
||||
{
|
||||
#ifdef EXTADDRSEARCH_DEBUG
|
||||
std::cerr << "ExtAddrFinder: Creating new ExtAddrFinder." << std::endl ;
|
||||
RS_DBG("Creating new ExtAddrFinder.");
|
||||
#endif
|
||||
RsStackMutex mut(mAddrMtx) ;
|
||||
reset( true );
|
||||
|
||||
mFound = false;
|
||||
mSearching = false;
|
||||
mFoundTS = time(NULL) - MAX_IP_STORE;
|
||||
sockaddr_storage_clear(mAddr);
|
||||
|
||||
_ip_servers.push_back(std::string( "checkip.dyndns.org" )) ;
|
||||
_ip_servers.push_back(std::string( "www.myip.dk" )) ;
|
||||
_ip_servers.push_back(std::string( "showip.net" )) ;
|
||||
_ip_servers.push_back(std::string( "www.displaymyip.com")) ;
|
||||
//https://unix.stackexchange.com/questions/22615/how-can-i-get-my-external-ip-address-in-a-shell-script
|
||||
//Enter direct ip so local DNS cannot change it.
|
||||
//DNS servers must recognize "myip.opendns.com"
|
||||
_ip_servers.push_back(std::string( "208.67.222.222" )) ;//resolver1.opendns.com
|
||||
_ip_servers.push_back(std::string( "208.67.220.220" )) ;//resolver2.opendns.com
|
||||
_ip_servers.push_back(std::string( "208.67.222.220" )) ;//resolver3.opendns.com
|
||||
_ip_servers.push_back(std::string( "208.67.220.222" )) ;//resolver4.opendns.com
|
||||
_ip_servers.push_back(std::string( "2620:119:35::35" )) ;//resolver1.opendns.com
|
||||
_ip_servers.push_back(std::string( "2620:119:53::53" )) ;//resolver2.opendns.com
|
||||
}
|
||||
|
||||
|
@ -30,26 +30,31 @@
|
||||
|
||||
struct sockaddr ;
|
||||
|
||||
class ExtAddrFinder
|
||||
class ExtAddrFinder: public RsThread
|
||||
{
|
||||
public:
|
||||
ExtAddrFinder() ;
|
||||
~ExtAddrFinder() ;
|
||||
|
||||
bool hasValidIP(struct sockaddr_storage &addr) ;
|
||||
bool hasValidIPV4(struct sockaddr_storage &addr) ;
|
||||
bool hasValidIPV6(struct sockaddr_storage &addr) ;
|
||||
void getIPServersList(std::list<std::string>& ip_servers) { ip_servers = _ip_servers ; }
|
||||
|
||||
void start_request() ;
|
||||
|
||||
void reset() ;
|
||||
void reset(bool firstTime = false) ;
|
||||
|
||||
private:
|
||||
friend void* doExtAddrSearch(void *p) ;
|
||||
virtual void run();
|
||||
void testTimeOut();
|
||||
|
||||
RsMutex mAddrMtx ;
|
||||
rstime_t mFoundTS;
|
||||
struct sockaddr_storage mAddr;
|
||||
bool mFound ;
|
||||
bool mSearching ;
|
||||
std::list<std::string> _ip_servers ;
|
||||
RsMutex mAddrMtx;
|
||||
bool mSearching;
|
||||
bool mFoundV4;
|
||||
bool mFoundV6;
|
||||
bool mFirstTime;
|
||||
rstime_t mFoundTS;
|
||||
struct sockaddr_storage mAddrV4;
|
||||
struct sockaddr_storage mAddrV6;
|
||||
std::list<std::string> _ip_servers;
|
||||
};
|
||||
|
@ -40,6 +40,51 @@ std::error_condition rs_errno_to_condition(int errno_code)
|
||||
{ return std::make_error_condition(static_cast<std::errc>(errno_code)); }
|
||||
|
||||
|
||||
std::ostream& hex_dump(std::ostream& os, const void *buffer,
|
||||
std::size_t bufsize, bool showPrintableChars /*= true*/)
|
||||
{
|
||||
if (buffer == nullptr) {
|
||||
return os;
|
||||
}
|
||||
auto oldFormat = os.flags();
|
||||
auto oldFillChar = os.fill();
|
||||
constexpr std::size_t maxline{8};
|
||||
// create a place to store text version of string
|
||||
char renderString[maxline+1];
|
||||
char *rsptr{renderString};
|
||||
// convenience cast
|
||||
const unsigned char *buf{reinterpret_cast<const unsigned char *>(buffer)};
|
||||
|
||||
for (std::size_t linecount=maxline; bufsize; --bufsize, ++buf) {
|
||||
os << std::setw(2) << std::setfill('0') << std::hex
|
||||
<< static_cast<unsigned>(*buf) << ' ';
|
||||
*rsptr++ = std::isprint(*buf) ? *buf : '.';
|
||||
if (--linecount == 0) {
|
||||
*rsptr++ = '\0'; // terminate string
|
||||
if (showPrintableChars) {
|
||||
os << " | " << renderString;
|
||||
}
|
||||
os << '\n';
|
||||
rsptr = renderString;
|
||||
linecount = std::min(maxline, bufsize);
|
||||
}
|
||||
}
|
||||
// emit newline if we haven't already
|
||||
if (rsptr != renderString) {
|
||||
if (showPrintableChars) {
|
||||
for (*rsptr++ = '\0'; rsptr != &renderString[maxline+1]; ++rsptr) {
|
||||
os << " ";
|
||||
}
|
||||
os << " | " << renderString;
|
||||
}
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
os.fill(oldFillChar);
|
||||
os.flags(oldFormat);
|
||||
return os;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -211,3 +256,7 @@ void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg
|
||||
lineCount++;
|
||||
}
|
||||
}
|
||||
/// All the lines before are DEPRECATED!!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -210,6 +210,53 @@ struct RsNoDbg
|
||||
};
|
||||
|
||||
|
||||
//From https://codereview.stackexchange.com/a/165162
|
||||
/**
|
||||
* @brief hex_dump: Send Hexadecimal Dump to stream
|
||||
* @param os: Output Stream
|
||||
* @param buffer: Buffer to send
|
||||
* @param bufsize: Buffer's size
|
||||
* @param showPrintableChars: If must send printable Char too
|
||||
* @return
|
||||
* basic string:
|
||||
* 61 62 63 64 65 66 31 32 | abcdef12
|
||||
* 33 34 35 36 00 7a 79 78 | 3456.zyx
|
||||
* 77 76 75 39 38 37 36 35 | wvu98765
|
||||
* 34 45 64 77 61 72 64 00 | 4Edward.
|
||||
*
|
||||
* wide string:
|
||||
* 41 00 00 00 20 00 00 00 | A... ...
|
||||
* 77 00 00 00 69 00 00 00 | w...i...
|
||||
* 64 00 00 00 65 00 00 00 | d...e...
|
||||
* 20 00 00 00 73 00 00 00 | ...s...
|
||||
* 74 00 00 00 72 00 00 00 | t...r...
|
||||
* 69 00 00 00 6e 00 00 00 | i...n...
|
||||
* 67 00 00 00 2e 00 00 00 | g.......
|
||||
*
|
||||
* a double
|
||||
* 49 92 24 49 92 24 09 40 | I.$I.$.@
|
||||
*/
|
||||
std::ostream& hex_dump(std::ostream& os, const void *buffer,
|
||||
std::size_t bufsize, bool showPrintableChars = true);
|
||||
|
||||
/**
|
||||
* @brief The hexDump struct
|
||||
* Enable to print dump calling like that:
|
||||
* const char test[] = "abcdef123456\0zyxwvu987654Edward";
|
||||
* RsDbg()<<hexDump(test, sizeof(test))<<std::endl;
|
||||
*/
|
||||
struct hexDump {
|
||||
const void *buffer;
|
||||
std::size_t bufsize;
|
||||
hexDump(const void *buf, std::size_t bufsz) : buffer{buf}, bufsize{bufsz} {}
|
||||
friend std::ostream &operator<<(std::ostream &out, const hexDump &hd) {
|
||||
return hex_dump(out, hd.buffer, hd.bufsize, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -318,3 +365,8 @@ void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg
|
||||
#define PQL_DEBUG_ALERT RSL_DEBUG_ALERT
|
||||
#define PQL_DEBUG_BASIC RSL_DEBUG_BASIC
|
||||
#define PQL_DEBUG_ALL RSL_DEBUG_ALL
|
||||
|
||||
/// All the lines before are DEPRECATED!!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
354
libretroshare/src/util/rsdnsutils.cc
Normal file
354
libretroshare/src/util/rsdnsutils.cc
Normal file
@ -0,0 +1,354 @@
|
||||
/*******************************************************************************
|
||||
* libretroshare/src/util: rsdnsutils.cc *
|
||||
* *
|
||||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright 2021 Phenom <retrosharephenom@gmail.com> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public License *
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
//#define DEBUG_SPEC_DNS 1
|
||||
|
||||
#include "util/rsnet.h"
|
||||
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include "util/rsstring.h"
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
//https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2
|
||||
constexpr uint16_t DNSC_IN = 1; //Internet (IN)
|
||||
//https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
|
||||
constexpr uint16_t DNST_A = 1; //Ipv4 address
|
||||
constexpr uint16_t DNST_AAAA =28; //Ipv6 address
|
||||
|
||||
///Need to pack as we use sizeof them. (avoid padding)
|
||||
#pragma pack(1)
|
||||
//DNS header structure
|
||||
struct DNS_HEADER
|
||||
{
|
||||
unsigned short id; // identification number
|
||||
|
||||
//Header flags https://www.bind9.net/dns-header-flags
|
||||
unsigned char rd :1; //bit 07 Recursion Desired, indicates if the client means a recursive query
|
||||
unsigned char tc :1; //bit 06 TrunCation, indicates that this message was truncated due to excessive length
|
||||
unsigned char aa :1; //bit 05 Authoritative Answer, in a response, indicates if the DNS server is authoritative for the queried hostname
|
||||
unsigned char opcode :4;//bit 01-04 The type can be QUERY (standard query, 0), IQUERY (inverse query, 1), or STATUS (server status request, 2)
|
||||
unsigned char qr :1; //bit 00 Indicates if the message is a query (0) or a reply (1)
|
||||
|
||||
unsigned char rcode :4; //bit 12-15 Response Code can be NOERROR (0), FORMERR (1, Format error), SERVFAIL (2), NXDOMAIN (3, Nonexistent domain), etc.
|
||||
unsigned char cd :1; //bit 11 Checking Disabled [RFC 4035][RFC 6840][RFC Errata 4927] used by DNSSEC
|
||||
unsigned char ad :1; //bit 10 Authentic Data [RFC 4035][RFC 6840][RFC Errata 4924] used by DNSSEC
|
||||
unsigned char z :1; //bit 09 Zero, reserved for future use
|
||||
unsigned char ra :1; //bit 08 Recursion Available [RFC 1035] in a response, indicates if the replying DNS server supports recursion
|
||||
|
||||
unsigned short q_count; // number of question entries
|
||||
unsigned short ans_count; // number of answer entries
|
||||
unsigned short auth_count; // number of authority resource records entries
|
||||
unsigned short add_count; // number of additional resource record entries
|
||||
};
|
||||
//// OpCode text https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5
|
||||
//static const char *opcodetext[] = { "QUERY", "IQUERY", "STATUS",
|
||||
// "RESERVED3", "NOTIFY", "UPDATE",
|
||||
// "STATEFUL", "RESERVED7", "RESERVED8",
|
||||
// "RESERVED9", "RESERVED10", "RESERVED11",
|
||||
// "RESERVED12", "RESERVED13", "RESERVED14",
|
||||
// "RESERVED15" };
|
||||
//// RCode text https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
|
||||
//static const char *rcodetext[] = { "NOERROR", "FORMERR", "SERVFAIL",
|
||||
// "NXDOMAIN", "NOTIMP", "REFUSED",
|
||||
// "YXDOMAIN", "YXRRSET", "NXRRSET",
|
||||
// "NOTAUTH", "NOTZONE", "DSOTYPENI",
|
||||
// "RESERVED12", "RESERVED13", "RESERVED14",
|
||||
// "RESERVED15", "BADVERS", "BADKEY",
|
||||
// "BADTIME", "BADMODE", "BADNAME",
|
||||
// "BADALG", "BADTRUNC", "BADCOOKIE"};
|
||||
|
||||
//Constant sized fields of query structure
|
||||
//https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
|
||||
struct QUESTION
|
||||
{
|
||||
unsigned short qtype; //https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
|
||||
unsigned short qclass; //https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2
|
||||
};
|
||||
|
||||
//Constant sized fields of the resource record structure
|
||||
struct RR_DATA
|
||||
{
|
||||
unsigned short rtype; //https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
|
||||
unsigned short rclass; //https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2
|
||||
unsigned int rttl; //Time To Live is the number of seconds left before the information expires. (32bits integer, so maximum 140 years)
|
||||
unsigned short data_len;//Lenght of following data
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
bool rsGetHostByNameSpecDNS(const std::string& servername, const std::string& hostname, std::string& returned_addr, int timeout_s /*= -1*/)
|
||||
{
|
||||
#ifdef DEBUG_SPEC_DNS
|
||||
RS_DBG("servername=", servername, " hostname=", hostname);
|
||||
#endif
|
||||
|
||||
if (strlen(servername.c_str()) > 256)
|
||||
{
|
||||
RS_ERR("servername is too long > 256 chars: ", servername);
|
||||
return false;
|
||||
}
|
||||
if (strlen(hostname.c_str()) > 256)
|
||||
{
|
||||
RS_ERR("hostname is too long > 256 chars: ", hostname);
|
||||
return false;
|
||||
}
|
||||
|
||||
sockaddr_storage serverAddr;
|
||||
bool validServer = sockaddr_storage_inet_pton(serverAddr, servername)
|
||||
&& sockaddr_storage_isValidNet(serverAddr);
|
||||
bool isIPV4 = validServer && sockaddr_storage_ipv6_to_ipv4(serverAddr);
|
||||
|
||||
if (!validServer)
|
||||
{
|
||||
in_addr in ;
|
||||
if (!rsGetHostByName(servername, in))
|
||||
{
|
||||
RS_ERR("servername is on an unknow format: ", servername);
|
||||
return false;
|
||||
}
|
||||
|
||||
validServer = sockaddr_storage_inet_pton(serverAddr, rs_inet_ntoa(in))
|
||||
&& sockaddr_storage_isValidNet(serverAddr);
|
||||
isIPV4 = validServer && sockaddr_storage_ipv6_to_ipv4(serverAddr);
|
||||
|
||||
if (!validServer)
|
||||
{
|
||||
RS_ERR("rsGetHostByName return bad answer: ", rs_inet_ntoa(in));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sockaddr_storage_setport( serverAddr, 53);
|
||||
|
||||
//Set the DNS structure to standard queries
|
||||
unsigned char buf[65536];
|
||||
struct DNS_HEADER* dns = (struct DNS_HEADER *)&buf;
|
||||
dns->id = static_cast<unsigned short>(htons(getpid())); //Transaction Id
|
||||
//dns flags = 0x0100 Standard Query
|
||||
dns->qr = 0; //Query/Response: Message is a query
|
||||
dns->opcode = 0; //OpCode: Standard query
|
||||
dns->aa = 0; //Authoritative: Server is not an authority for domain
|
||||
dns->tc = 0; //TrunCated: Message is not truncated
|
||||
dns->rd = 1; //Recursion Desired: Do query recursively
|
||||
dns->ra = 0; //Recursion Available: Server cannot do recursive queries
|
||||
dns->z = 0; //Z: reserved
|
||||
dns->ad = 0; //Authentic Data: Answer/authority portion was not authenticated by the server
|
||||
dns->cd = 0; //Checking Disabled: Unacceptable
|
||||
dns->rcode = 0; //Response Code: No error
|
||||
|
||||
dns->q_count = htons(1); //1 Question
|
||||
dns->ans_count = 0; //0 Answer
|
||||
dns->auth_count = 0; //0 Authority RRs
|
||||
dns->add_count = 0; //0 Additional RRs
|
||||
size_t curSendSize = sizeof(struct DNS_HEADER);
|
||||
|
||||
//Point to the query server name portion
|
||||
unsigned char* qname =static_cast<unsigned char*>(&buf[curSendSize]);
|
||||
//First byte is Label Type: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-10
|
||||
qname[0] = 0x04; //One Label with Normal label lower 6 bits is the length of the label
|
||||
memcpy(&qname[1],hostname.c_str(),strlen(hostname.c_str()));
|
||||
size_t qnameSize = strlen((const char*)qname);
|
||||
// Format Hostname like www.google.com to 3www6google3com
|
||||
{
|
||||
size_t last = qnameSize;
|
||||
for(size_t i = qnameSize-1 ; i > 0 ; i--)
|
||||
if(qname[i]=='.')
|
||||
{
|
||||
qname[i]=last-i-1;
|
||||
last = i;
|
||||
}
|
||||
}
|
||||
curSendSize += qnameSize +1; //With \0 terminator
|
||||
|
||||
//Point to the query constant portion
|
||||
struct QUESTION* qinfo =(struct QUESTION*)&buf[curSendSize];
|
||||
qinfo->qtype = htons(isIPV4 ? DNST_A : DNST_AAAA); //Type: A / AAAA(Host Address)
|
||||
qinfo->qclass = htons(DNSC_IN); //Class: IN
|
||||
curSendSize += sizeof(struct QUESTION);
|
||||
|
||||
#ifdef DEBUG_SPEC_DNS
|
||||
RS_DBG("Sending Packet:\n", hexDump(buf, curSendSize));
|
||||
#endif
|
||||
int s = socket(serverAddr.ss_family , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries
|
||||
|
||||
if (timeout_s > -1)
|
||||
rs_setSockTimeout(s, true, timeout_s);
|
||||
|
||||
ssize_t send_size = sendto( s, (char*)buf, curSendSize, 0
|
||||
, (struct sockaddr*)&serverAddr
|
||||
, isIPV4 ? sizeof(sockaddr_in)
|
||||
: sizeof(sockaddr_in6)
|
||||
);
|
||||
if( send_size < 0)
|
||||
{
|
||||
RS_ERR("Send Failed with size = ", send_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SPEC_DNS
|
||||
RS_DBG("Waiting answer...");
|
||||
#endif
|
||||
//****************************************************************************************//
|
||||
//--- Receive the answer ---//
|
||||
//****************************************************************************************//
|
||||
socklen_t sa_size = static_cast<socklen_t>(isIPV4 ? sizeof(sockaddr_in)
|
||||
: sizeof(sockaddr_in6)
|
||||
);
|
||||
ssize_t rec_size=recvfrom( s,(char*)buf , 65536 , 0
|
||||
, (struct sockaddr*)&serverAddr
|
||||
, &sa_size
|
||||
);
|
||||
if(rec_size <= 0)
|
||||
{
|
||||
RS_ERR("Receive Failed");
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG_SPEC_DNS
|
||||
RS_DBG("Received:\n", hexDump(buf, rec_size));
|
||||
#endif
|
||||
|
||||
|
||||
if (rec_size< static_cast<ssize_t>(sizeof(struct DNS_HEADER)) )
|
||||
{
|
||||
RS_ERR("Request received too small to get DNSHeader.");
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG_SPEC_DNS
|
||||
//Point to the header portion
|
||||
dns = (struct DNS_HEADER*) buf;
|
||||
RS_DBG("The response contains :\n"
|
||||
,ntohs(dns->q_count) , " Questions.\n"
|
||||
,ntohs(dns->ans_count) , " Answers.\n"
|
||||
,ntohs(dns->auth_count) , " Authoritative Servers.\n"
|
||||
,ntohs(dns->add_count) , " Additional records.");
|
||||
#endif
|
||||
size_t curRecSize = sizeof(struct DNS_HEADER);
|
||||
|
||||
|
||||
if (rec_size< static_cast<ssize_t>(curRecSize + 1 + sizeof(struct QUESTION)) )
|
||||
{
|
||||
RS_ERR("Request received too small to get Question return.");
|
||||
return false;
|
||||
}
|
||||
//Point to the query portion
|
||||
unsigned char* qnameRecv =static_cast<unsigned char*>(&buf[curRecSize]);
|
||||
if (memcmp(qname,qnameRecv,qnameSize + 1 + sizeof(struct QUESTION)) )
|
||||
{
|
||||
RS_ERR("Request received different from that sent.");
|
||||
return false;
|
||||
}
|
||||
curRecSize += qnameSize + 1 + sizeof(struct QUESTION);
|
||||
|
||||
if (rec_size< static_cast<ssize_t>(curRecSize + 2) )
|
||||
{
|
||||
RS_ERR("Request received too small to get Answer return.");
|
||||
return false;
|
||||
}
|
||||
//Point to the Answer portion
|
||||
unsigned char* reader = &buf[curRecSize];
|
||||
|
||||
size_t rLabelSize=0;
|
||||
if((reader[0]&0xC0) == 0)
|
||||
{
|
||||
//Normal label lower 6 bits is the length of the label
|
||||
rLabelSize=(reader[0]&~(0xC0)*256) + reader[1];
|
||||
}
|
||||
else if ((reader[0]&0xC0) == 0xC0)
|
||||
{
|
||||
//Compressed label the lower 6 bits and the 8 bits from next octet form a pointer to the compression target.
|
||||
//Don't need to read it, maybe the same as in Query
|
||||
rLabelSize=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_ERR("Answer received with unmanaged label format.");
|
||||
return false;
|
||||
}
|
||||
curRecSize += 2 + rLabelSize;
|
||||
|
||||
if (rec_size< static_cast<ssize_t>(curRecSize + sizeof(struct RR_DATA)) )
|
||||
{
|
||||
RS_ERR("Request received too small to get Data return.");
|
||||
return false;
|
||||
}
|
||||
//Point to the query portion
|
||||
struct RR_DATA* rec_data = (struct RR_DATA *)&buf[curRecSize];
|
||||
if (rec_data->rtype!=qinfo->qtype)
|
||||
{
|
||||
RS_ERR("Answer's type received different from query sent.");
|
||||
return false;
|
||||
}
|
||||
if (rec_data->rclass!=qinfo->qclass)
|
||||
{
|
||||
RS_ERR("Answer's class received different from query sent.");
|
||||
return false;
|
||||
}
|
||||
curRecSize += sizeof(struct RR_DATA);
|
||||
|
||||
if (rec_size< static_cast<ssize_t>(curRecSize + ntohs(rec_data->data_len)) )
|
||||
{
|
||||
RS_ERR("Request received too small to get Full Data return.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Retrieve Address
|
||||
if(ntohs(rec_data->data_len)==4)
|
||||
{
|
||||
if (isIPV4)
|
||||
{
|
||||
in_addr ipv4Add;
|
||||
ipv4Add.s_addr=*(in_addr_t*)&buf[curRecSize];
|
||||
#ifdef DEBUG_SPEC_DNS
|
||||
RS_DBG("Retrieve address: ", rs_inet_ntoa(ipv4Add));
|
||||
#endif
|
||||
returned_addr = rs_inet_ntoa(ipv4Add);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(ntohs(rec_data->data_len)==16)
|
||||
{
|
||||
if (!isIPV4)
|
||||
{
|
||||
in6_addr ipv6Add;
|
||||
ipv6Add =*(in6_addr*)&buf[curRecSize];
|
||||
|
||||
struct sockaddr_storage ss;
|
||||
sockaddr_storage_clear(ss);
|
||||
sockaddr_in6 addr_ipv6;
|
||||
addr_ipv6.sin6_addr = ipv6Add;
|
||||
sockaddr_storage_setipv6(ss,&addr_ipv6);
|
||||
|
||||
#ifdef DEBUG_SPEC_DNS
|
||||
RS_DBG("Retrieve address: ", sockaddr_storage_iptostring(ss).c_str());
|
||||
#endif
|
||||
returned_addr = sockaddr_storage_iptostring(ss);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
RS_ERR("Retrieve unmanaged data size=", ntohs(rec_data->data_len));
|
||||
return false;
|
||||
}
|
@ -174,3 +174,17 @@ std::string rs_inet_ntoa(struct in_addr in)
|
||||
rs_sprintf(str, "%u.%u.%u.%u", (int) bytes[0], (int) bytes[1], (int) bytes[2], (int) bytes[3]);
|
||||
return str;
|
||||
}
|
||||
|
||||
int rs_setSockTimeout( int sockfd, bool forReceive /*= true*/
|
||||
, int timeout_Sec /*= 0*/, int timeout_uSec /*= 0*/)
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
DWORD timeout = timeout_Sec * 1000 + timeout_uSec;
|
||||
#else
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = timeout_Sec;
|
||||
timeout.tv_usec = timeout_uSec;
|
||||
#endif
|
||||
return setsockopt( sockfd, SOL_SOCKET, forReceive ? SO_RCVTIMEO : SO_SNDTIMEO
|
||||
, (const char*)&timeout, sizeof timeout);
|
||||
}
|
||||
|
@ -84,6 +84,18 @@ bool isExternalNet(const struct in_addr *addr);
|
||||
// uses a re-entrant version of gethostbyname
|
||||
bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) ;
|
||||
|
||||
/**
|
||||
* @brief Get hostName address using specific DNS server.
|
||||
* Using it allow to direct ask our Address to IP, so no need to have a DNS (IPv4 or IPv6).
|
||||
* If we ask to a IPv6 DNS Server, it respond for our IPv6 address.
|
||||
* @param servername: Address or name of DNS Server.
|
||||
* @param hostname: HosteName to get IP ("myip.opendns.com" to get own).
|
||||
* @param returned_addr: returned IP of hostname.
|
||||
* @param timeout_s: Timeout in sec to wait server response.
|
||||
* @return True in success.
|
||||
*/
|
||||
bool rsGetHostByNameSpecDNS(const std::string& servername, const std::string& hostname, std::string& returned_addr, int timeout_s = -1);
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const sockaddr_in&);
|
||||
std::ostream& operator<<(std::ostream& o, const sockaddr_storage&);
|
||||
|
||||
@ -159,4 +171,14 @@ bool sockaddr_storage_inet_ntop(const sockaddr_storage &addr, std::string &dst);
|
||||
int rs_setsockopt( int sockfd, int level, int optname,
|
||||
const uint8_t *optval, uint32_t optlen );
|
||||
|
||||
/**
|
||||
* @brief Set socket Timeout.
|
||||
* @param sockfd: The socket to manage.
|
||||
* @param forReceive: True for Receive, False for Send.
|
||||
* @param timeout_Sec: Timeout second part.
|
||||
* @param timeout_uSec: Timeout micro second part.
|
||||
* @return 0 on success, -1 for errors.
|
||||
*/
|
||||
int rs_setSockTimeout( int sockfd, bool forReceive = true, int timeout_Sec = 0, int timeout_uSec = 0);
|
||||
|
||||
#endif /* RS_UNIVERSAL_NETWORK_HEADER */
|
||||
|
@ -233,8 +233,7 @@ bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port)
|
||||
bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *addr_ipv4)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_setipv4()";
|
||||
std::cerr << std::endl;
|
||||
RS_ERR();
|
||||
#endif
|
||||
|
||||
sockaddr_storage_clear(addr);
|
||||
@ -249,7 +248,9 @@ bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *
|
||||
|
||||
bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6)
|
||||
{
|
||||
std::cerr << "sockaddr_storage_setipv6()" << std::endl;
|
||||
#ifdef SS_DEBUG
|
||||
RS_ERR();
|
||||
#endif
|
||||
|
||||
sockaddr_storage_clear(addr);
|
||||
struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr);
|
||||
@ -262,6 +263,7 @@ bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
#ifndef InetPtonA
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
sockaddr_storage ss;
|
||||
@ -288,6 +290,7 @@ int inet_pton(int af, const char *src, void *dst)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool sockaddr_storage_inet_pton( sockaddr_storage &addr,
|
||||
const std::string& ipStr )
|
||||
|
@ -66,11 +66,11 @@
|
||||
///
|
||||
|
||||
// Tabs numbers *after* non relevant tabs are removed. So do not use them to add/remove tabs!!
|
||||
const static uint32_t TAB_HIDDEN_SERVICE_OUTGOING = 0;
|
||||
//nst static uint32_t TAB_HIDDEN_SERVICE_OUTGOING = 0;
|
||||
const static uint32_t TAB_HIDDEN_SERVICE_INCOMING = 1;
|
||||
const static uint32_t TAB_HIDDEN_SERVICE_I2P = 2;
|
||||
|
||||
const static uint32_t TAB_NETWORK = 0;
|
||||
//nst static uint32_t TAB_NETWORK = 0;
|
||||
const static uint32_t TAB_HIDDEN_SERVICE = 1;
|
||||
const static uint32_t TAB_IP_FILTERS = 2;
|
||||
const static uint32_t TAB_RELAYS = 3;
|
||||
@ -155,8 +155,8 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
|
||||
ui.leBobB32Addr->hide();
|
||||
ui.pbBobGenAddr->hide();
|
||||
|
||||
QObject::connect(ui.filteredIpsTable,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(ipFilterContextMenu(const QPoint&))) ;
|
||||
QObject::connect(ui.whiteListIpsTable,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(ipWhiteListContextMenu(const QPoint&))) ;
|
||||
QObject::connect(ui.filteredIpsTable,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ipFilterContextMenu(QPoint))) ;
|
||||
QObject::connect(ui.whiteListIpsTable,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ipWhiteListContextMenu(QPoint))) ;
|
||||
QObject::connect(ui.denyAll_CB,SIGNAL(toggled(bool)),this,SLOT(toggleIpFiltering(bool)));
|
||||
QObject::connect(ui.includeFromDHT_CB,SIGNAL(toggled(bool)),this,SLOT(toggleAutoIncludeDHT(bool)));
|
||||
QObject::connect(ui.includeFromFriends_CB,SIGNAL(toggled(bool)),this,SLOT(toggleAutoIncludeFriends(bool)));
|
||||
@ -164,7 +164,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
|
||||
QObject::connect(ui.groupIPRanges_SB,SIGNAL(valueChanged(int)),this,SLOT(setGroupIpLimit(int)));
|
||||
QObject::connect(ui.ipInputAddBlackList_PB,SIGNAL(clicked()),this,SLOT(addIpRangeToBlackList()));
|
||||
QObject::connect(ui.ipInputAddWhiteList_PB,SIGNAL(clicked()),this,SLOT(addIpRangeToWhiteList()));
|
||||
QObject::connect(ui.ipInput_LE,SIGNAL(textChanged(const QString&)),this,SLOT(checkIpRange(const QString&)));
|
||||
QObject::connect(ui.ipInput_LE,SIGNAL(textChanged(QString)),this,SLOT(checkIpRange(QString)));
|
||||
QObject::connect(ui.filteredIpsTable,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(updateSelectedBlackListIP(int,int,int,int)));
|
||||
QObject::connect(ui.whiteListIpsTable,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(updateSelectedWhiteListIP(int,int,int,int)));
|
||||
|
||||
@ -193,10 +193,10 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
|
||||
QObject::connect(ui.localPort,SIGNAL(valueChanged(int)),this,SLOT(saveAddresses()));
|
||||
QObject::connect(ui.extPort,SIGNAL(valueChanged(int)),this,SLOT(saveAddresses()));
|
||||
|
||||
connect( ui.netModeComboBox, SIGNAL( activated ( int ) ), this, SLOT( toggleUPnP( ) ) );
|
||||
connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) );
|
||||
connect( ui.cleanKnownIPs_PB, SIGNAL( clicked( ) ), this, SLOT( clearKnownAddressList() ) );
|
||||
connect( ui.testIncoming_PB, SIGNAL( clicked( ) ), this, SLOT( saveAndTestInProxy() ) );
|
||||
connect( ui.netModeComboBox, SIGNAL( activated(int) ), this, SLOT( toggleUPnP() ) );
|
||||
connect( ui.allowIpDeterminationCB, SIGNAL( toggled(bool) ), this, SLOT( toggleIpDetermination(bool) ) );
|
||||
connect( ui.cleanKnownIPs_PB, SIGNAL( clicked() ), this, SLOT( clearKnownAddressList() ) );
|
||||
connect( ui.testIncoming_PB, SIGNAL( clicked() ), this, SLOT( saveAndTestInProxy() ) );
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
std::cerr << "ServerPage::ServerPage() called";
|
||||
@ -228,7 +228,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
|
||||
|
||||
QObject::connect(ui.addPushButton,SIGNAL(clicked()),this,SLOT(addServer()));
|
||||
QObject::connect(ui.removePushButton,SIGNAL(clicked()),this,SLOT(removeServer()));
|
||||
QObject::connect(ui.DhtLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(checkKey()));
|
||||
QObject::connect(ui.DhtLineEdit,SIGNAL(textChanged(QString)),this,SLOT(checkKey()));
|
||||
|
||||
QObject::connect(ui.enableCheckBox,SIGNAL(stateChanged(int)),this,SLOT(updateEnabled()));
|
||||
QObject::connect(ui.serverCheckBox,SIGNAL(stateChanged(int)),this,SLOT(updateEnabled()));
|
||||
@ -433,8 +433,8 @@ void ServerPage::load()
|
||||
{
|
||||
if (detail.vs_disc != RS_VS_DISC_OFF)
|
||||
netIndex = 1; // PRIVATE
|
||||
else
|
||||
netIndex = 3; // NONE
|
||||
//else //Use default value
|
||||
// netIndex = 3; // NONE
|
||||
}
|
||||
|
||||
whileBlocking(ui.discComboBox)->setCurrentIndex(netIndex);
|
||||
@ -459,6 +459,7 @@ void ServerPage::load()
|
||||
|
||||
|
||||
whileBlocking(ui.ipAddressList)->clear();
|
||||
detail.ipAddressList.sort();
|
||||
for(std::list<std::string>::const_iterator it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it)
|
||||
whileBlocking(ui.ipAddressList)->addItem(QString::fromStdString(*it));
|
||||
|
||||
@ -824,10 +825,10 @@ void ServerPage::ipWhiteListContextMenu(const QPoint& /* point */)
|
||||
return ;
|
||||
}
|
||||
|
||||
QString range0 = RsNetUtil::printAddrRange(addr,0) ;
|
||||
QString range1 = RsNetUtil::printAddrRange(addr,1) ;
|
||||
QString range2 = RsNetUtil::printAddrRange(addr,2) ;
|
||||
|
||||
// QString range0 = RsNetUtil::printAddrRange(addr,0) ;
|
||||
// QString range1 = RsNetUtil::printAddrRange(addr,1) ;
|
||||
// QString range2 = RsNetUtil::printAddrRange(addr,2) ;
|
||||
//
|
||||
// contextMenu.addAction(QObject::tr("Whitelist only IP " )+range0,this,SLOT(enableBannedIp()))->setEnabled(false) ;
|
||||
//#warning UNIMPLEMENTED CODE
|
||||
// contextMenu.addAction(QObject::tr("Whitelist entire range ")+range1,this,SLOT(enableBannedIp()))->setEnabled(false) ;
|
||||
@ -930,6 +931,28 @@ void ServerPage::updateStatus()
|
||||
else
|
||||
ui.iconlabel_ext->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/ledoff1.png"));
|
||||
|
||||
if (ui.ipAddressList->isEnabled() )
|
||||
{
|
||||
whileBlocking(ui.ipAddressList)->clear();
|
||||
detail.ipAddressList.sort();
|
||||
for(auto& it : detail.ipAddressList)
|
||||
whileBlocking(ui.ipAddressList)->addItem(QString::fromStdString(it).replace("sec",tr("sec")).replace("loc",tr("local")).replace("ext",tr("external")));
|
||||
}
|
||||
|
||||
QString toolTip = tr("List of OpenDns servers used.");
|
||||
if (ui.IPServersLV->isEnabled() )
|
||||
{
|
||||
std::list<std::string> ip_list;
|
||||
rsPeers->getCurrentExtIPList(ip_list);
|
||||
if ( !ip_list.empty() )
|
||||
{
|
||||
toolTip += tr("\n\nList of found external IP:\n");
|
||||
for(std::list<std::string>::const_iterator it(ip_list.begin());it!=ip_list.end();++it)
|
||||
toolTip += " " + QString::fromStdString(*it) +"\n" ;
|
||||
}
|
||||
}
|
||||
if(ui.IPServersLV->toolTip() != toolTip)
|
||||
ui.IPServersLV->setToolTip(toolTip);
|
||||
}
|
||||
|
||||
void ServerPage::toggleUPnP()
|
||||
@ -1158,6 +1181,7 @@ void ServerPage::loadHiddenNode()
|
||||
|
||||
// show what we have in ipAddresses. (should be nothing!)
|
||||
ui.ipAddressList->clear();
|
||||
detail.ipAddressList.sort();
|
||||
for(std::list<std::string>::const_iterator it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it)
|
||||
whileBlocking(ui.ipAddressList)->addItem(QString::fromStdString(*it));
|
||||
|
||||
|
@ -704,7 +704,7 @@ connecting when you have few friends. It also helps if you're
|
||||
behind a firewall or a VPN.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Allow RetroShare to ask my ip to these websites:</string>
|
||||
<string>Allow RetroShare to ask my ip to these DNS servers:</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
@ -719,6 +719,9 @@ behind a firewall or a VPN.</string>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>List of OpenDns servers used.</string>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
Loading…
Reference in New Issue
Block a user