Implemented empirical determination of external addressing, paritioned per scope.

This commit is contained in:
Adam Ierymenko 2015-04-07 11:56:10 -07:00
parent 817824b88b
commit 52c3b7c34e
10 changed files with 102 additions and 95 deletions

View file

@ -25,6 +25,10 @@
* LLC. Start here: http://www.zerotier.com/
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Constants.hpp"
#include "SelfAwareness.hpp"
#include "RuntimeEnvironment.hpp"
@ -35,17 +39,52 @@
namespace ZeroTier {
class _ResetWithinScope
{
public:
_ResetWithinScope(const RuntimeEnvironment *renv,uint64_t now,InetAddress::IpScope scope) :
RR(renv),
_now(now),
_scope(scope) {}
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { p->resetWithinScope(RR,_scope,_now); }
private:
const RuntimeEnvironment *RR;
uint64_t _now;
InetAddress::IpScope _scope;
};
SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) :
RR(renv)
{
memset(_lastPhysicalAddress,0,sizeof(_lastPhysicalAddress));
}
SelfAwareness::~SelfAwareness()
{
}
void SelfAwareness::iam(const InetAddress &physicalAddress,bool trusted)
void SelfAwareness::iam(const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted)
{
const unsigned int scope = (unsigned int)myPhysicalAddress.ipScope();
// This code depends on the numeric values assigned to scopes in InetAddress.hpp
if ((scope > 0)&&(scope < (unsigned int)InetAddress::IP_SCOPE_LOOPBACK)) {
/* For now only trusted peers are permitted to inform us of changes to
* our global Internet IP or to changes of NATed IPs. We'll let peers on
* private, shared, or link-local networks inform us of changes as long
* as they too are at the same scope. This discrimination avoids a DoS
* attack in which an attacker could force us to reset our connections. */
if ( (!trusted) && ((scope == (unsigned int)InetAddress::IP_SCOPE_GLOBAL)||(scope != (unsigned int)reporterPhysicalAddress.ipScope())) )
return;
InetAddress &lastPhy = _lastPhysicalAddress[scope - 1];
if ((lastPhy)&&(lastPhy != myPhysicalAddress)) {
lastPhy = myPhysicalAddress;
_ResetWithinScope rset(RR,RR->node->now(),(InetAddress::IpScope)scope);
RR->topology->eachPeer<_ResetWithinScope &>(rset);
}
}
Mutex::Lock _l(_lock);
}