summaryrefslogtreecommitdiff
path: root/node/SelfAwareness.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-04-07 11:56:10 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-04-07 11:56:10 -0700
commit52c3b7c34e52534ab4f3c92b28d65f8713cda299 (patch)
tree6a66f99b253059961a02e1fa07ebc9890ef91a61 /node/SelfAwareness.cpp
parent817824b88bce8d2e5659226b80d3f232633c557f (diff)
downloadinfinitytier-52c3b7c34e52534ab4f3c92b28d65f8713cda299.tar.gz
infinitytier-52c3b7c34e52534ab4f3c92b28d65f8713cda299.zip
Implemented empirical determination of external addressing, paritioned per scope.
Diffstat (limited to 'node/SelfAwareness.cpp')
-rw-r--r--node/SelfAwareness.cpp41
1 files changed, 40 insertions, 1 deletions
diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp
index c8b700a0..74c9f182 100644
--- a/node/SelfAwareness.cpp
+++ b/node/SelfAwareness.cpp
@@ -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);
}