Merge pull request #1874 from PhenomRetroShare/Add_ExtIPFinderUsingDNS

Add ability to retrieve External IP using Specific DNS server.
This commit is contained in:
G10h4ck 2021-11-06 04:08:41 +01:00 committed by GitHub
commit bfbb2a5ae6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 918 additions and 338 deletions

View File

@ -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 \

View File

@ -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();

View File

@ -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;

View File

@ -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 ;

View File

@ -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;

View File

@ -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;

View File

@ -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 ;

View File

@ -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
}

View File

@ -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;
};

View File

@ -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!!
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

View File

@ -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!!
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

View 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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 )

View File

@ -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));

View File

@ -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>