diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-07 10:57:59 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-07 10:57:59 -0700 |
commit | 817824b88bce8d2e5659226b80d3f232633c557f (patch) | |
tree | 61f0ea204332a13e5e11c2e0baf46d231c1390b1 | |
parent | a2821e90007ac7af490f044f0c2579309f6c8a01 (diff) | |
download | infinitytier-817824b88bce8d2e5659226b80d3f232633c557f.tar.gz infinitytier-817824b88bce8d2e5659226b80d3f232633c557f.zip |
Some external surface awareness work, and IP scope classification.
-rw-r--r-- | node/IncomingPacket.cpp | 4 | ||||
-rw-r--r-- | node/InetAddress.cpp | 81 | ||||
-rw-r--r-- | node/InetAddress.hpp | 43 | ||||
-rw-r--r-- | node/SelfAwareness.cpp | 52 | ||||
-rw-r--r-- | node/SelfAwareness.hpp | 6 | ||||
-rw-r--r-- | node/Topology.cpp | 2 |
6 files changed, 160 insertions, 28 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 99f66561..17eb09d9 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -264,7 +264,9 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) if (RR->topology->isSupernode(id.address())) { RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision); - RR->sa->iam(destAddr); + RR->sa->iam(destAddr,true); + } else { + RR->sa->iam(destAddr,false); } Packet outp(id.address(),RR->identity.address(),Packet::VERB_OK); diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index 9452086a..b9d07ea5 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -42,6 +42,74 @@ const InetAddress InetAddress::LO6("::1",0); const InetAddress InetAddress::DEFAULT4((uint32_t)0,0); const InetAddress InetAddress::DEFAULT6((const void *)0,16,0); +InetAddress::IpScope InetAddress::ipScope() const + throw() +{ + switch(ss_family) { + + case AF_INET: { + const uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr); + switch(ip >> 24) { + case 0x00: return IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used) + case 0x06: return IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army) + case 0x0a: return IP_SCOPE_PRIVATE; // 10.0.0.0/8 + case 0x0b: return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD) + case 0x15: return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN) + case 0x16: return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA) + case 0x19: return IP_SCOPE_PSEUDOPRIVATE; // 25.0.0.0/8 (UK Ministry of Defense) + case 0x1a: return IP_SCOPE_PSEUDOPRIVATE; // 26.0.0.0/8 (US DISA) + case 0x1c: return IP_SCOPE_PSEUDOPRIVATE; // 28.0.0.0/8 (US DSI-North) + case 0x1d: return IP_SCOPE_PSEUDOPRIVATE; // 29.0.0.0/8 (US DISA) + case 0x1e: return IP_SCOPE_PSEUDOPRIVATE; // 30.0.0.0/8 (US DISA) + case 0x2c: return IP_SCOPE_PSEUDOPRIVATE; // 44.0.0.0/8 (Amateur Radio) + case 0x33: return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security) + case 0x37: return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD) + case 0x38: return IP_SCOPE_PSEUDOPRIVATE; // 56.0.0.0/8 (US Postal Service) + case 0x64: + if ((ip & 0xffc00000) == 0x64400000) return IP_SCOPE_SHARED; // 100.64.0.0/10 + break; + case 0x7f: return IP_SCOPE_LOOPBACK; // 127.0.0.0/8 + case 0xa9: + if ((ip & 0xffff0000) == 0xa9fe0000) return IP_SCOPE_LINK_LOCAL; // 169.254.0.0/16 + break; + case 0xac: + if ((ip & 0xfff00000) == 0xac100000) return IP_SCOPE_PRIVATE; // 172.16.0.0/12 + break; + case 0xc0: + if ((ip & 0xffff0000) == 0xc9a80000) return IP_SCOPE_PRIVATE; // 192.168.0.0/16 + break; + case 0xff: return IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable) + default: + switch(ip >> 28) { + case 0xe: return IP_SCOPE_MULTICAST; // 224.0.0.0/4 + case 0xf: return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable) + default: return IP_SCOPE_GLOBAL; // everything else + } + break; + } + } break; + + case AF_INET6: { + const unsigned char *ip = reinterpret_cast<const unsigned char *>(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr); + if ((ip[0] & 0xf0) == 0xf0) { + if (ip[0] == 0xff) return IP_SCOPE_MULTICAST; // ff00::/8 + if ((ip[0] == 0xfe)&&((ip[1] & 0xc0) == 0x80)) return IP_SCOPE_LINK_LOCAL; // fe80::/10 + if ((ip[0] & 0xfe) == 0xfc) return IP_SCOPE_PRIVATE; // fc00::/7 + } + unsigned int k = 0; + while ((!ip[k])&&(k < 15)) ++k; + if (k == 15) { // all 0's except last byte + if (ip[15] == 0x01) return IP_SCOPE_LOOPBACK; // ::1/128 + if (ip[15] == 0x00) return IP_SCOPE_NONE; // ::/128 + } + return IP_SCOPE_GLOBAL; + } break; + + } + + return IP_SCOPE_NONE; +} + void InetAddress::set(const std::string &ip,unsigned int port) throw() { @@ -81,19 +149,6 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port) } } -bool InetAddress::isLinkLocal() const - throw() -{ - static const unsigned char v6llPrefix[8] = { 0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00 }; - switch(ss_family) { - case AF_INET: - return ((Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000); - case AF_INET6: - return (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,v6llPrefix,8) == 0); - } - return false; -} - std::string InetAddress::toString() const { char buf[128]; diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 381c6ba2..2ed23761 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -44,8 +44,10 @@ namespace ZeroTier { /** * Extends sockaddr_storage with friendly C++ methods * - * This adds no new fields, so it can be memcpy'd and assigned to/from - * raw sockaddr_storage structures. This is used in a few places. + * This is basically a "mixin" for sockaddr_storage. It adds methods and + * operators, but does not modify the structure. This can be cast to/from + * sockaddr_storage and used interchangeably. Don't change this as it's + * used in a few places. */ struct InetAddress : public sockaddr_storage { @@ -69,6 +71,26 @@ struct InetAddress : public sockaddr_storage */ static const InetAddress DEFAULT6; + /** + * IP address scope + * + * Be sure the integer values of these start at 0 and increment + * monotonically without gaps, as they're used as an array index. + * The NONE entry must be the last, since it's the count. It's + * okay to change these since they are not exported via the API. + */ + enum IpScope + { + IP_SCOPE_LOOPBACK = 0, // 127.0.0.1 + IP_SCOPE_MULTICAST = 1, // 224.0.0.0 and other multicast IPs + IP_SCOPE_LINK_LOCAL = 2, // 169.254.x.x, IPv6 LL + IP_SCOPE_PRIVATE = 3, // 10.x.x.x, etc. + IP_SCOPE_PSEUDOPRIVATE = 4, // 28.x.x.x, etc. -- unofficially unrouted IP blocks often "bogarted" + IP_SCOPE_SHARED = 5, // 100.64.0.0/10, shared space for e.g. carrier-grade NAT + IP_SCOPE_GLOBAL = 6, // globally routable IP address (all others) + IP_SCOPE_NONE = 7 // not an IP address -- also the number of classes, must be last entry + }; + InetAddress() throw() { memset(this,0,sizeof(InetAddress)); } InetAddress(const InetAddress &a) throw() { memcpy(this,&a,sizeof(InetAddress)); } InetAddress(const struct sockaddr_storage &ss) throw() { *this = ss; } @@ -169,6 +191,12 @@ struct InetAddress : public sockaddr_storage } /** + * @return IP scope classification (e.g. loopback, link-local, private, global) + */ + IpScope ipScope() const + throw(); + + /** * Set from a string-format IP and a port * * @param ip IP address in V4 or V6 ASCII notation @@ -206,17 +234,6 @@ struct InetAddress : public sockaddr_storage } /** - * @return True if this is a link-local IP address - */ - bool isLinkLocal() const - throw(); - - /** - * @return True if this is a loopback address - */ - inline bool isLoopback() const throw() { return ((*this == LO4)||(*this == LO6)); } - - /** * @return ASCII IP/port format representation */ std::string toString() const; diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp new file mode 100644 index 00000000..c8b700a0 --- /dev/null +++ b/node/SelfAwareness.cpp @@ -0,0 +1,52 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include "Constants.hpp" +#include "SelfAwareness.hpp" +#include "RuntimeEnvironment.hpp" +#include "Node.hpp" +#include "Topology.hpp" +#include "Packet.hpp" +#include "Peer.hpp" + +namespace ZeroTier { + +SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) : + RR(renv) +{ +} + +SelfAwareness::~SelfAwareness() +{ +} + +void SelfAwareness::iam(const InetAddress &physicalAddress,bool trusted) +{ + Mutex::Lock _l(_lock); +} + +} // namespace ZeroTier diff --git a/node/SelfAwareness.hpp b/node/SelfAwareness.hpp index 93af34f4..6d0b9ebb 100644 --- a/node/SelfAwareness.hpp +++ b/node/SelfAwareness.hpp @@ -29,6 +29,7 @@ #define ZT_SELFAWARENESS_HPP #include "InetAddress.hpp" +#include "Mutex.hpp" namespace ZeroTier { @@ -47,10 +48,13 @@ public: * Called when a trusted remote peer informs us of our external network address * * @param physicalAddress Physical address as reflected by any trusted peer + * @param trusted True if this peer is trusted */ - void iam(const InetAddress &physicalAddress); + void iam(const InetAddress &physicalAddress,bool trusted); private: + const RuntimeEnvironment *RR; + Mutex _lock; }; } // namespace ZeroTier diff --git a/node/Topology.cpp b/node/Topology.cpp index 77583d55..8b3d2e71 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -253,6 +253,7 @@ void Topology::clean(uint64_t now) } } +/* bool Topology::updateSurface(const SharedPtr<Peer> &remotePeer,const InetAddress &mirroredAddress,uint64_t now) { Mutex::Lock _l(_lock); @@ -280,6 +281,7 @@ bool Topology::updateSurface(const SharedPtr<Peer> &remotePeer,const InetAddress return false; } +*/ bool Topology::authenticateRootTopology(const Dictionary &rt) { |