Enable IPv6 DNS ExtIpFinder

Now empty node with only IPv6 can connect to other.
This commit is contained in:
Phenom 2021-11-03 15:08:55 +01:00
parent a09db6717b
commit 81d2ddd7c7
12 changed files with 407 additions and 188 deletions

View File

@ -55,6 +55,7 @@ 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;
const 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 *******/
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 */
{
RsStackMutex stack(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
{
@ -284,7 +285,6 @@ void p3NetMgrIMPL::netReset()
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
mNetStatus = RS_NET_UNKNOWN;
netStatusReset_locked();
}
@ -312,7 +312,7 @@ bool p3NetMgrIMPL::shutdown() /* blocking shutdown call */
#endif
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
mNetStatus = RS_NET_UNKNOWN;
mNetStatus = RS_NET_SHUTDOWN;
mNetInitTS = time(NULL);
netStatusReset_locked();
}
@ -460,35 +460,50 @@ void p3NetMgrIMPL::netStatusTick()
uint32_t netStatus = 0;
rstime_t age = 0;
bool needExtFinderUpdate = false;
{
RsStackMutex stack(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 = mLocalAddr; // 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;
RsDbg(__PRETTY_FUNCTION__, " 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;
RsDbg(__PRETTY_FUNCTION__, " Ext supplied by ExtAddrFinder", " ExtAddr: ", sockaddr_storage_tostring(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;
RsDbg(__PRETTY_FUNCTION__, " Ext supplied by ExtAddrFinder", " ExtAddr: ", sockaddr_storage_tostring(tmpip));
#endif
setExtAddress(tmpip);
}
}
setExtAddress(tmpip);
}
}
}
switch(netStatus)
{
@ -745,25 +760,18 @@ void p3NetMgrIMPL::netExtCheck()
if (mUseExtAddrFinder)
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() checking ExtAddrFinder" << std::endl;
RsDbg(__PRETTY_FUNCTION__, " checking ExtAddrFinder");
#endif
sockaddr_storage tmpip = mLocalAddr; // copies local port and correctly inits the IP family
sockaddr_storage tmpip = mLocalAddr; // 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;
RsDbg(__PRETTY_FUNCTION__, " Ext IPv4 supplied by ExtAddrFinder", sockaddr_storage_tostring(tmpip));
#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 +781,25 @@ 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;
RsErr(__PRETTY_FUNCTION__, " reported external IPv4 address ", sockaddr_storage_iptostring(tmpip));
}
else if (mExtAddrFinder->hasValidIPV6(tmpip))
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
RsDbg(__PRETTY_FUNCTION__, " Ext IPv6 supplied by ExtAddrFinder", sockaddr_storage_tostring(tmpip));
#endif
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;
RsErr(__PRETTY_FUNCTION__, " reported external IPv6 address ", sockaddr_storage_iptostring(tmpip));
}
}
}
@ -967,7 +990,7 @@ void p3NetMgrIMPL::netExtCheck()
if (netSetupDone)
{
std::cerr << "p3NetMgrIMPL::netExtCheck() netSetupDone" << std::endl;
RsDbg(__PRETTY_FUNCTION__, " netSetupDone");
/* Setup NetStateBox with this info */
updateNetStateBox_startup();
@ -978,12 +1001,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;
RsDbg(__PRETTY_FUNCTION__, " Network Setup Complete");
}
}
@ -994,7 +1019,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;
@ -1109,6 +1135,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 +1150,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;
}
@ -1661,15 +1701,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)
{
mExtAddrFinder->reset(true);
if (b)
mExtAddrFinder->start_request();
}
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
mUseExtAddrFinder = b;
}
#ifdef NETMGR_DEBUG
std::cerr << "p3NetMgr: setIPServers to " << b << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " set mUseExtAddrFinder to ", b);
#endif
}
@ -1973,8 +2030,8 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
/* ExtAddrFinder */
if (mUseExtAddrFinder)
{
tmpip = mLocalAddr;
bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip);
tmpip = mLocalAddr;
bool extFinderOk = mExtAddrFinder->hasValidIPV4(tmpip);
if (extFinderOk)
{

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)
{
@ -1305,6 +1311,7 @@ bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, Retros
}
sockaddr_storage tExt;
struct in6_addr sin6_addr;
if(sockaddr_storage_inet_pton(tExt, tDetails.extAddr) && sockaddr_storage_isValidNet(tExt) && sockaddr_storage_ipv6_to_ipv4(tExt) && tDetails.extPort )
{
uint32_t t4Addr = reinterpret_cast<sockaddr_in&>(tExt).sin_addr.s_addr;
@ -1321,6 +1328,16 @@ bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, Retros
offset += 4+2;
}
else if(inet_pton(AF_INET6, tDetails.extAddr.c_str(), &(sin6_addr)))
{
// External address is IPv6, save it on LOCATOR
std::string tLocator = "ipv6://[" + tDetails.extAddr + "]:" + std::to_string(tDetails.extPort);
addPacketHeader(RsShortInviteFieldType::LOCATOR, tLocator.size(),buf,offset,buf_size);
memcpy(&buf[offset],tLocator.c_str(),tLocator.size());
offset += tLocator.size();
}
#endif
}
@ -1595,13 +1612,24 @@ 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.
struct in6_addr sin6_addr;
if( inet_pton(AF_INET6, detail.extAddr.c_str(), &(sin6_addr))
&& !(invite_flags & RetroshareInviteFlags::FULL_IP_HISTORY)
&& !detail.isHiddenNode)
{
detail.ipAddressList.push_front("ipv6://[" + detail.extAddr + "]:" + std::to_string(detail.extPort) + " ");
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

@ -22,6 +22,7 @@
#include "extaddrfinder.h"
#include "pqi/pqinetwork.h"
#include "rsdebug.h"
#include "util/rsstring.h"
#include "util/rsmemory.h"
@ -38,10 +39,19 @@
#include <stdio.h>
#include "util/rstime.h"
#include <map>
const uint32_t MAX_IP_STORE = 300; /* seconds ip address timeout */
//#define EXTADDRSEARCH_DEBUG
class ZeroInt
{
public:
ZeroInt() : n(0) {}
uint32_t n ;
};
void* doExtAddrSearch(void *p)
{
@ -52,49 +62,90 @@ void* doExtAddrSearch(void *p)
for(std::list<std::string>::const_iterator it(af->_ip_servers.begin());it!=af->_ip_servers.end();++it)
{
std::string ip = "";
rsGetHostByNameSpecDNS(*it,"myip.opendns.com",ip);
rsGetHostByNameSpecDNS(*it,"myip.opendns.com",ip,2);
if(ip != "")
res.push_back(ip) ;
#ifdef EXTADDRSEARCH_DEBUG
std::cout << "ip found through DNS " << *it << ": \"" << ip << "\"" << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " 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 ;
}
af->reset();
return NULL ;
}
sort(res.begin(),res.end()) ; // eliminates outliers.
std::map<sockaddr_storage,ZeroInt> addrV4_votes;
std::map<sockaddr_storage,ZeroInt> addrV6_votes;
std::string addrV4_Found;
std::string 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);
//sockaddr_storage_inet_pton convert IPv4 to IPv6
struct sockaddr_in * addrv4p = (struct sockaddr_in *) &addr;
struct sockaddr_in6 * addrv6p = (struct sockaddr_in6 *) &addr;
if( inet_pton(AF_INET, curRes.c_str(), &(addrv4p->sin_addr)) )
{
RsStackMutex mtx(af->mAddrMtx) ;
af->mFound = false ;
af->mFoundTS = time(NULL) ;
af->mSearching = false ;
addr.ss_family = AF_INET;
addrV4_votes[addr].n++ ;
addrV4_Found += sockaddr_storage_tostring(addr) + "\n";
}
else if( inet_pton(AF_INET6, curRes.c_str(), &(addrv6p->sin6_addr)) )
{
addr.ss_family = AF_INET6;
addrV6_votes[addr].n++ ;
addrV6_Found += sockaddr_storage_tostring(addr) + "\n";
}
else
RsErr(__PRETTY_FUNCTION__, " Invalid addresse reported: ", curRes) ;
}
if( (0 == addrV4_votes.size()) && (0 == addrV6_votes.size()) )
{
RsErr(__PRETTY_FUNCTION__, " Could not find any external address.");
af->reset();
return NULL ;
}
if( 1 < addrV4_votes.size() )
RsErr(__PRETTY_FUNCTION__, " Multiple external IPv4 addresses reported: "
, addrV4_Found ) ;
if( 1 < addrV6_votes.size() )
RsErr(__PRETTY_FUNCTION__, " Multiple external IPv6 addresses reported: "
, addrV6_Found ) ;
{
RsStackMutex mtx(af->mAddrMtx) ;
af->mFound = true ;
af->mFoundTS = time(NULL) ;
af->mSearching = false ;
af->mFoundTS = time(NULL) ;
// Only save more reported address if not only once.
uint32_t admax = 0 ;
sockaddr_storage_clear(af->mAddrV4);
for (auto it : addrV4_votes)
if (admax < it.second.n)
{
af->mAddrV4 = it.first ;
af->mFoundV4 = true ;
admax = it.second.n ;
}
admax = 0 ;
sockaddr_storage_clear(af->mAddrV6);
for (auto it : addrV6_votes)
if (admax < it.second.n)
{
af->mAddrV6 = it.first ;
af->mFoundV6 = true ;
admax = it.second.n ;
}
}
return NULL ;
@ -105,75 +156,112 @@ void ExtAddrFinder::start_request()
{
void *data = (void *)this;
pthread_t tid ;
if(! pthread_create(&tid, 0, &doExtAddrSearch, data))
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;
else
RsErr(__PRETTY_FUNCTION__, " Could not start ExtAddrFinder thread.");
}
bool ExtAddrFinder::hasValidIP(struct sockaddr_storage &addr)
bool ExtAddrFinder::hasValidIPV4(struct sockaddr_storage &addr)
{
#ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: Getting ip." << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " Getting ip.");
#endif
{
RsStackMutex mut(mAddrMtx) ;
if(mFound)
if(mFoundV4)
{
#ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: Has stored ip: responding with this ip." << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " 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();
RsStackMutex mut(mAddrMtx) ;
return mFoundV4;
}
bool ExtAddrFinder::hasValidIPV6(struct sockaddr_storage &addr)
{
#ifdef EXTADDRSEARCH_DEBUG
RsDbg(__PRETTY_FUNCTION__, " Getting ip.");
#endif
{
RsStackMutex mut(mAddrMtx) ;
if(mFoundV6)
{
#ifdef EXTADDRSEARCH_DEBUG
RsDbg(__PRETTY_FUNCTION__, " 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.
}
}
testTimeOut();
RsStackMutex mut(mAddrMtx) ;
return mFoundV6;
}
void ExtAddrFinder::testTimeOut()
{
bool timeOut;
{
RsStackMutex mut(mAddrMtx) ;
//timeout the current ip
delta = time(NULL) - mFoundTS;
timeOut = (mFoundTS + MAX_IP_STORE < time(NULL));
}
if((uint32_t)delta > MAX_IP_STORE) {//launch a research
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 ;
RsDbg(__PRETTY_FUNCTION__, " No stored ip: Initiating new search.");
#endif
mSearching = true ;
start_request() ;
}
#ifdef EXTADDRSEARCH_DEBUG
else
std::cerr << "ExtAddrFinder: Already searching." << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " Already searching.");
#endif
mFirstTime = false;
mAddrMtx.unlock();
}
#ifdef EXTADDRSEARCH_DEBUG
else
std::cerr << "ExtAddrFinder: (Note) Could not acquire lock. Busy." << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " (Note) Could not acquire lock. Busy.");
#endif
}
RsStackMutex mut(mAddrMtx) ;
return mFound ;
}
void ExtAddrFinder::reset()
void ExtAddrFinder::reset(bool firstTime /*=false*/)
{
#ifdef EXTADDRSEARCH_DEBUG
RsDbg(__PRETTY_FUNCTION__, " firstTime=", firstTime?"true":"false");
#endif
RsStackMutex mut(mAddrMtx) ;
mFound = false ;
mSearching = false ;
mFoundTS = time(NULL) - MAX_IP_STORE;
mFoundV4 = false ;
mFoundV6 = false ;
mFirstTime = firstTime;
mFoundTS = time(NULL);
sockaddr_storage_clear(mAddrV4);
sockaddr_storage_clear(mAddrV6);
}
ExtAddrFinder::~ExtAddrFinder()
{
#ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: Deleting ExtAddrFinder." << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " Deleting ExtAddrFinder.");
#endif
}
@ -181,14 +269,9 @@ ExtAddrFinder::~ExtAddrFinder()
ExtAddrFinder::ExtAddrFinder() : mAddrMtx("ExtAddrFinder")
{
#ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: Creating new ExtAddrFinder." << std::endl ;
RsDbg(__PRETTY_FUNCTION__, " Creating new ExtAddrFinder.");
#endif
RsStackMutex mut(mAddrMtx) ;
mFound = false;
mSearching = false;
mFoundTS = time(NULL) - MAX_IP_STORE;
sockaddr_storage_clear(mAddr);
reset( true );
//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.
@ -197,8 +280,7 @@ ExtAddrFinder::ExtAddrFinder() : mAddrMtx("ExtAddrFinder")
_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
//Ipv6 server disabled as Current ip only manage ipv4 for now.
//_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
_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

@ -36,20 +36,25 @@ class ExtAddrFinder
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) ;
friend void* doExtAddrSearch(void *p);
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

@ -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);
}
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@ -319,46 +366,7 @@ void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg
#define PQL_DEBUG_BASIC RSL_DEBUG_BASIC
#define PQL_DEBUG_ALL RSL_DEBUG_ALL
//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);
}
};
/// All the lines before are DEPRECATED!!
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

View File

@ -168,7 +168,7 @@ bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr)
return ok;
}
bool rsGetHostByNameSpecDNS(const std::string& servername, const std::string& hostname, std::string& returned_addr)
bool rsGetHostByNameSpecDNS(const std::string& servername, const std::string& hostname, std::string& returned_addr, int timeout_s /*= -1*/)
{
#ifdef DEBUG_SPEC_DNS
RsDbg()<<__PRETTY_FUNCTION__<<" servername="<< servername << " hostname=" << hostname << std::endl;
@ -265,6 +265,18 @@ bool rsGetHostByNameSpecDNS(const std::string& servername, const std::string& ho
#endif
int s = isIPV4 ? socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP)
: socket(AF_INET6 , SOCK_DGRAM , IPPROTO_UDP) ; //UDP packet for DNS queries
if (timeout_s > -1)
{
#ifdef WINDOWS_SYS
DWORD timeout = timeout_s * 1000;
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
#else
struct timeval tv;
tv.tv_sec = timeout_s;
tv.tv_usec = 0;
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
#endif
}
ssize_t send_size = sendto(s, (char*)buf, curSendSize, 0
,isIPV4 ? (struct sockaddr*)&dest4
: (struct sockaddr*)&dest6

View File

@ -87,7 +87,7 @@ bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) ;
// 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.
bool rsGetHostByNameSpecDNS(const std::string& servername, const std::string& hostname, std::string& returned_addr);
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&);

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);
@ -824,9 +824,9 @@ 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
@ -930,6 +930,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()

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>