mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-24 23:19:29 -05:00
Merge pull request #1184 from G10h4ck/linkLocalFallback
[0.6.4] Use link local address only if necessary fix #292
This commit is contained in:
commit
ff7633fefe
@ -3,7 +3,8 @@
|
||||
*
|
||||
* 3P/PQI network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2007-2011 by Robert Fernie.
|
||||
* Copyright (C) 2007-2011 Robert Fernie
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -24,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
|
||||
#include "pqi/p3netmgr.h"
|
||||
|
||||
@ -37,8 +39,7 @@
|
||||
#include "util/extaddrfinder.h"
|
||||
#include "util/dnsresolver.h"
|
||||
|
||||
//#include "util/rsprint.h"
|
||||
//#include "util/rsdebug.h"
|
||||
|
||||
struct RsLog::logInfo p3netmgrzoneInfo = {RsLog::Default, "p3netmgr"};
|
||||
#define p3netmgrzone &p3netmgrzoneInfo
|
||||
|
||||
@ -165,11 +166,6 @@ void p3NetMgrIMPL::setManagers(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr)
|
||||
mLinkMgr = linkMgr;
|
||||
}
|
||||
|
||||
//void p3NetMgrIMPL::setDhtMgr(p3DhtMgr *dhtMgr)
|
||||
//{
|
||||
// mDhtMgr = dhtMgr;
|
||||
//}
|
||||
|
||||
#ifdef RS_USE_DHT_STUNNER
|
||||
void p3NetMgrIMPL::setAddrAssist(pqiAddrAssist *dhtStun, pqiAddrAssist *proxyStun)
|
||||
{
|
||||
@ -1020,18 +1016,40 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local address is a flawed assumption, this should be redesigned soon.
|
||||
std::list<sockaddr_storage> addrs;
|
||||
std::list<sockaddr_storage>::iterator it;
|
||||
/* TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local
|
||||
* address is a flawed assumption, this should be redesigned as soon as
|
||||
* possible. It will require complete reenginering of the network layer
|
||||
* code. */
|
||||
|
||||
std::vector<sockaddr_storage> addrs;
|
||||
if (getLocalAddresses(addrs))
|
||||
for(it = addrs.begin(); (it != addrs.end() && !validAddr); ++it)
|
||||
if(sockaddr_storage_isValidNet(*it) && !sockaddr_storage_isLoopbackNet(*it))
|
||||
{
|
||||
prefAddr = *it;
|
||||
for (auto it = addrs.begin(); it!=addrs.end(); ++it)
|
||||
{
|
||||
sockaddr_storage& addr(*it);
|
||||
if( sockaddr_storage_isValidNet(addr) &&
|
||||
!sockaddr_storage_isLoopbackNet(addr) &&
|
||||
!sockaddr_storage_isLinkLocalNet(addr))
|
||||
{
|
||||
prefAddr = addr;
|
||||
validAddr = true;
|
||||
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
|
||||
std::cout << "p3NetMgrIMPL::checkNetAddress() prefAddr: " << sockaddr_storage_iptostring(prefAddr) << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no satisfactory local address has been found yet relax and
|
||||
* accept also link local addresses */
|
||||
if(!validAddr) for (auto it = addrs.begin(); it!=addrs.end(); ++it)
|
||||
{
|
||||
sockaddr_storage& addr(*it);
|
||||
if( sockaddr_storage_isValidNet(addr) &&
|
||||
!sockaddr_storage_isLoopbackNet(addr) )
|
||||
{
|
||||
prefAddr = addr;
|
||||
validAddr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "util/rsnet.h"
|
||||
#include "serialiser/rstlvaddrs.h"
|
||||
|
||||
#define MAX_ADDRESS_LIST_SIZE 4
|
||||
#define MAX_ADDRESS_LIST_SIZE 10
|
||||
|
||||
class pqiIpAddress
|
||||
{
|
||||
|
@ -3,7 +3,8 @@
|
||||
*
|
||||
* 3P/PQI network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2006 by Robert Fernie.
|
||||
* Copyright (C) 2004-2006 Robert Fernie.
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -284,7 +285,7 @@ int inet_aton(const char *name, struct in_addr *addr)
|
||||
# include <net/if.h>
|
||||
#endif // WINDOWS_SYS
|
||||
|
||||
bool getLocalAddresses(std::list<sockaddr_storage> & addrs)
|
||||
bool getLocalAddresses(std::vector<sockaddr_storage>& addrs)
|
||||
{
|
||||
addrs.clear();
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
*
|
||||
* 3P/PQI network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2006 by Robert Fernie.
|
||||
* Copyright (C) 2004-2006 Robert Fernie.
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -24,10 +25,10 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef MRK_PQI_NETWORKING_HEADER
|
||||
#define MRK_PQI_NETWORKING_HEADER
|
||||
|
||||
#include <vector>
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
@ -95,7 +96,7 @@ void showSocketError(std::string &out);
|
||||
|
||||
std::string socket_errorType(int err);
|
||||
|
||||
bool getLocalAddresses(std::list<struct sockaddr_storage> & addrs);
|
||||
bool getLocalAddresses(std::vector<sockaddr_storage> & addrs);
|
||||
|
||||
/* universal socket interface */
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2013 by Robert Fernie.
|
||||
* Copyright (C) 2004-2013 Robert Fernie.
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -25,11 +26,15 @@
|
||||
|
||||
#include "services/p3discovery2.h"
|
||||
#include "pqi/p3peermgr.h"
|
||||
#include "pqi/pqinetwork.h" // for getLocalAddresses
|
||||
#include "util/rsversioninfo.h"
|
||||
|
||||
#include "retroshare/rsiface.h"
|
||||
#include "rsserver/p3face.h"
|
||||
|
||||
#include <vector> // for std::vector
|
||||
#include <algorithm> // for std::random_shuffle
|
||||
|
||||
|
||||
// Interface pointer.
|
||||
RsDisc *rsDisc = NULL;
|
||||
@ -38,7 +43,9 @@ RsDisc *rsDisc = NULL;
|
||||
* #define P3DISC_DEBUG 1
|
||||
****/
|
||||
|
||||
static bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt,bool include_ip_information)
|
||||
static bool populateContactInfo( const peerState &detail,
|
||||
RsDiscContactItem *pkt,
|
||||
bool include_ip_information )
|
||||
{
|
||||
pkt->clear();
|
||||
|
||||
@ -343,8 +350,54 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
|
||||
peerState detail;
|
||||
if (mPeerMgr->getOwnNetStatus(detail))
|
||||
{
|
||||
/* Workaround to spread multiple local ip addresses when presents. This
|
||||
* is needed because RS wrongly assumes that there is just one active
|
||||
* local ip address at time. */
|
||||
std::vector<sockaddr_storage> addrs;
|
||||
if(!detail.hiddenNode && getLocalAddresses(addrs))
|
||||
{
|
||||
/* To work around MAX_ADDRESS_LIST_SIZE addresses limitation,
|
||||
* let's shuffle the list of
|
||||
* local addresses in the hope that with enough time every local
|
||||
* address is advertised to trusted nodes so they may try to
|
||||
* connect to all of them including the most convenient if a local
|
||||
* connection exists.*/
|
||||
std::random_shuffle(addrs.begin(), addrs.end());
|
||||
|
||||
for (auto it = addrs.begin(); it!=addrs.end(); ++it)
|
||||
{
|
||||
sockaddr_storage& addr(*it);
|
||||
if( sockaddr_storage_isValidNet(addr) &&
|
||||
!sockaddr_storage_isLoopbackNet(addr) &&
|
||||
!sockaddr_storage_sameip(addr, detail.localaddr) )
|
||||
{
|
||||
pqiIpAddress pqiIp;
|
||||
sockaddr_storage_clear(pqiIp.mAddr);
|
||||
pqiIp.mAddr.ss_family = addr.ss_family;
|
||||
sockaddr_storage_copyip(pqiIp.mAddr, addr);
|
||||
sockaddr_storage_setport(
|
||||
pqiIp.mAddr,
|
||||
sockaddr_storage_port(detail.localaddr) );
|
||||
pqiIp.mSeenTime = time(nullptr);
|
||||
pqiIp.mSrc = 0;
|
||||
detail.ipAddrs.updateLocalAddrs(pqiIp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RsDiscContactItem *pkt = new RsDiscContactItem();
|
||||
populateContactInfo(detail, pkt, !rsPeers->isHiddenNode(sslid)); // we dont send our own IP to an hidden node. It will not use it anyway.
|
||||
/* Cyril: we dont send our own IP to an hidden node. It will not use it
|
||||
* anyway. */
|
||||
populateContactInfo(detail, pkt, !rsPeers->isHiddenNode(sslid));
|
||||
/* G10h4ck: sending IP information also to hidden nodes has proven very
|
||||
* helpful in the usecase of non hidden nodes, that share a common
|
||||
* hidden trusted node, to discover each other IP.
|
||||
* Advanced/corner case non hidden node users that want to hide their
|
||||
* IP to a specific hidden ~trusted~ node can do it through the
|
||||
* permission matrix. Disabling this instead will make life more
|
||||
* difficult for average user, that moreover whould have no way to
|
||||
* revert an hardcoded policy. */
|
||||
//populateContactInfo(detail, pkt, true);
|
||||
pkt->version = RsUtil::retroshareVersion();
|
||||
pkt->PeerId(sslid);
|
||||
|
||||
@ -433,7 +486,8 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
|
||||
void p3discovery2::updatePeerAddresses(const RsDiscContactItem *item)
|
||||
{
|
||||
if (item->isHidden)
|
||||
mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr, item->hiddenPort);
|
||||
mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr,
|
||||
item->hiddenPort);
|
||||
else
|
||||
{
|
||||
mPeerMgr->setDynDNS(item->sslId, item->dyndns);
|
||||
@ -447,8 +501,19 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
|
||||
if (item->isHidden)
|
||||
{
|
||||
}
|
||||
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId())) // we don't store IP addresses if we're a hidden node. Normally they should not be sent to us, except for old peers.
|
||||
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId()))
|
||||
{
|
||||
/* Cyril: we don't store IP addresses if we're a hidden node.
|
||||
* Normally they should not be sent to us, except for old peers. */
|
||||
/* G10h4ck: sending IP information also to hidden nodes has proven very
|
||||
* helpful in the usecase of non hidden nodes, that share a common
|
||||
* hidden trusted node, to discover each other IP.
|
||||
* Advanced/corner case non hidden node users that want to hide their
|
||||
* IP to a specific hidden ~trusted~ node can do it through the
|
||||
* permission matrix. Disabling this instead will make life more
|
||||
* difficult for average user, that moreover whould have no way to
|
||||
* revert an hardcoded policy. */
|
||||
|
||||
pqiIpAddrSet addrsFromPeer;
|
||||
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
|
||||
addrsFromPeer.mExt.extractFromTlv(item->extAddrList);
|
||||
@ -472,12 +537,11 @@ void p3discovery2::sendPGPList(const SSLID &toId)
|
||||
{
|
||||
updatePgpFriendList();
|
||||
|
||||
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
|
||||
RS_STACK_MUTEX(mDiscMtx);
|
||||
|
||||
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "p3discovery2::sendPGPList() to " << toId;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3discovery2::sendPGPList() to " << toId << std::endl;
|
||||
#endif
|
||||
|
||||
RsDiscPgpListItem *pkt = new RsDiscPgpListItem();
|
||||
@ -508,7 +572,7 @@ void p3discovery2::updatePgpFriendList()
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
|
||||
RS_STACK_MUTEX(mDiscMtx);
|
||||
|
||||
#define PGP_MAX_UPDATE_PERIOD 300
|
||||
|
||||
@ -863,26 +927,20 @@ void p3discovery2::sendContactInfo_locked(const PGPID &aboutId, const SSLID &toI
|
||||
|
||||
void p3discovery2::processContactInfo(const SSLID &fromId, const RsDiscContactItem *item)
|
||||
{
|
||||
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
|
||||
(void) fromId; // remove unused parameter warnings, debug only
|
||||
|
||||
RS_STACK_MUTEX(mDiscMtx);
|
||||
|
||||
if (item->sslId == rsPeers->getOwnId())
|
||||
{
|
||||
if(sockaddr_storage_isExternalNet(item->currentConnectAddress.addr))
|
||||
mPeerMgr->addCandidateForOwnExternalAddress(item->PeerId(), item->currentConnectAddress.addr) ;
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "p3discovery2::processContactInfo(" << fromId << ") PGPID: ";
|
||||
std::cerr << item->pgpId << " Ignoring Info on self";
|
||||
std::cerr << std::endl;
|
||||
#else
|
||||
/* remove unused parameter warnings */
|
||||
(void) fromId;
|
||||
#endif
|
||||
mPeerMgr->addCandidateForOwnExternalAddress(
|
||||
item->PeerId(), item->currentConnectAddress.addr);
|
||||
|
||||
delete item;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
std::map<PGPID, DiscPgpInfo>::iterator it;
|
||||
it = mFriendList.find(item->pgpId);
|
||||
if (it == mFriendList.end())
|
||||
@ -895,7 +953,8 @@ void p3discovery2::processContactInfo(const SSLID &fromId, const RsDiscContactIt
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* THESE ARE OUR FRIEND OF FRIENDS ... pass this information along to NetMgr & DHT...
|
||||
/* THESE ARE OUR FRIEND OF FRIENDS ... pass this information along to
|
||||
* NetMgr & DHT...
|
||||
* as we can track FOF and use them as potential Proxies / Relays
|
||||
*/
|
||||
|
||||
@ -941,7 +1000,10 @@ void p3discovery2::processContactInfo(const SSLID &fromId, const RsDiscContactIt
|
||||
// set last seen to RS_PEER_OFFLINE_NO_DISC minus 1 so that it won't be shared with other friends
|
||||
// until a first connection is established
|
||||
|
||||
mPeerMgr->addFriend(item->sslId, item->pgpId, item->netMode, RS_VS_DISC_OFF, RS_VS_DHT_FULL, time(NULL) - RS_PEER_OFFLINE_NO_DISC - 1, RS_NODE_PERM_ALL);
|
||||
mPeerMgr->addFriend( item->sslId, item->pgpId, item->netMode,
|
||||
RS_VS_DISC_OFF, RS_VS_DHT_FULL,
|
||||
time(NULL) - RS_PEER_OFFLINE_NO_DISC - 1,
|
||||
RS_NODE_PERM_ALL );
|
||||
updatePeerAddresses(item);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Universal Networking Header for RetroShare.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie.
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -151,21 +152,21 @@ bool isPrivateNet(const struct in_addr *addr)
|
||||
{
|
||||
in_addr_t taddr = ntohl(addr->s_addr);
|
||||
|
||||
// 10.0.0.0/8
|
||||
// 172.16.0.0/12
|
||||
// 192.168.0.0/16
|
||||
// 169.254.0.0/16
|
||||
if ((taddr>>24 == 10) ||
|
||||
(taddr>>20 == (172<<4 | 16>>4)) ||
|
||||
(taddr>>16 == (192<<8 | 168)) ||
|
||||
(taddr>>16 == (169<<8 | 254)))
|
||||
{
|
||||
if ( (taddr>>24 == 10) || // 10.0.0.0/8
|
||||
(taddr>>20 == (172<<4 | 16>>4)) || // 172.16.0.0/12
|
||||
(taddr>>16 == (192<<8 | 168)) || // 192.168.0.0/16
|
||||
(taddr>>16 == (169<<8 | 254)) ) // 169.254.0.0/16
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isLinkLocalNet(const struct in_addr *addr)
|
||||
{
|
||||
in_addr_t taddr = ntohl(addr->s_addr);
|
||||
if ( taddr>>16 == (169<<8 | 254) ) return true; // 169.254.0.0/16
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isExternalNet(const struct in_addr *addr)
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Universal Networking Header for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2006 by Robert Fernie.
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -72,6 +73,7 @@ void sockaddr_clear(struct sockaddr_in *addr);
|
||||
bool isValidNet(const struct in_addr *addr);
|
||||
bool isLoopbackNet(const struct in_addr *addr);
|
||||
bool isPrivateNet(const struct in_addr *addr);
|
||||
bool isLinkLocalNet(const struct in_addr *addr);
|
||||
bool isExternalNet(const struct in_addr *addr);
|
||||
|
||||
// uses a re-entrant version of gethostbyname
|
||||
@ -128,6 +130,7 @@ bool sockaddr_storage_isnull(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr);
|
||||
|
||||
bool rs_inet_ntop(const sockaddr_storage &addr, std::string &dst);
|
||||
|
@ -4,6 +4,7 @@
|
||||
* sockaddr_storage functions for RetroShare.
|
||||
*
|
||||
* Copyright 2013-2013 by Robert Fernie.
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -389,7 +390,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
|
||||
std::stringstream output;
|
||||
output << "sockaddr_storage_dump(addr) ";
|
||||
|
||||
switch (addr.ss_family){
|
||||
switch (addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
const sockaddr_in * in = (const sockaddr_in *) & addr;
|
||||
@ -421,7 +423,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
|
||||
for( uint32_t i = 0; i < sizeof(addr); ++i )
|
||||
output << std::setw(2) << std::setfill('0') << std::hex << +buf[i];
|
||||
// The unary +buf[i] operation forces a no-op type conversion to an int with the correct sign
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
if(outputString)
|
||||
{
|
||||
@ -578,6 +581,31 @@ bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||
#endif
|
||||
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
return isLinkLocalNet(&(to_const_ipv4_ptr(addr)->sin_addr));
|
||||
case AF_INET6:
|
||||
std::cerr << __PRETTY_FUNCTION__ << " for AF_INET6 not implemented"
|
||||
<< std::endl;
|
||||
break;
|
||||
default:
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__ <<" INVALID Family:" << std::endl;
|
||||
sockaddr_storage_dump(addr);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user