diff options
| author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2016-04-12 12:11:34 -0700 |
|---|---|---|
| committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2016-04-12 12:11:34 -0700 |
| commit | 6f854c8391d94857b00f76ffaf127d087ccf130f (patch) | |
| tree | c2a03267080792dbcfdd586e7f39bc18ddc6958f /node/NetworkConfig.cpp | |
| parent | 9b8444fff104b9776c7dc3a4019375680a283fdc (diff) | |
| download | infinitytier-6f854c8391d94857b00f76ffaf127d087ccf130f.tar.gz infinitytier-6f854c8391d94857b00f76ffaf127d087ccf130f.zip | |
NetworkConfig refactor part 1
Diffstat (limited to 'node/NetworkConfig.cpp')
| -rw-r--r-- | node/NetworkConfig.cpp | 236 |
1 files changed, 134 insertions, 102 deletions
diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index a1606c47..aab9a650 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -23,62 +23,76 @@ namespace ZeroTier { -SharedPtr<NetworkConfig> NetworkConfig::createTestNetworkConfig(const Address &self) +namespace { + +struct ZT_VirtualNetworkStaticDevice_SortByAddress +{ + inline bool operator()(const ZT_VirtualNetworkStaticDevice &a,const ZT_VirtualNetworkStaticDevice &b) + { + return (a.address < b.address); + } +}; + +struct ZT_VirtualNetworkRule_SortByRuleNo +{ + inline bool operator()(const ZT_VirtualNetworkRule &a,const ZT_VirtualNetworkRule &b) + { + return (a.ruleNo < b.ruleNo); + } +}; + +} // anonymous namespace + +NetworkConfig NetworkConfig::createTestNetworkConfig(const Address &self) { - SharedPtr<NetworkConfig> nc(new NetworkConfig()); - - memset(nc->_etWhitelist,0,sizeof(nc->_etWhitelist)); - nc->_etWhitelist[0] |= 1; // allow all - nc->_nwid = ZT_TEST_NETWORK_ID; - nc->_timestamp = 1; - nc->_revision = 1; - nc->_issuedTo = self; - nc->_multicastLimit = ZT_MULTICAST_DEFAULT_LIMIT; - nc->_allowPassiveBridging = false; - nc->_private = false; - nc->_enableBroadcast = true; - nc->_name = "ZT_TEST_NETWORK"; + NetworkConfig nc; + + nc._nwid = ZT_TEST_NETWORK_ID; + nc._timestamp = 1; + nc._revision = 1; + nc._issuedTo = self; + nc._multicastLimit = ZT_MULTICAST_DEFAULT_LIMIT; + nc._allowPassiveBridging = false; + nc._type = ZT_NETWORK_TYPE_PUBLIC; + nc._enableBroadcast = true; + + nc._rules[nc._ruleCount].ruleNo = 0; + nc._rules[nc._ruleCount].vlanId = -1; + nc._rules[nc._ruleCount].vlanPcp = -1; + nc._rules[nc._ruleCount].etherType = -1; + nc._rules[nc._ruleCount].ipTos = -1; + nc._rules[nc._ruleCount].ipProtocol = -1; + nc._rules[nc._ruleCount].ipSourcePort = -1; + nc._rules[nc._ruleCount].ipDestPort = -1; + nc._rules[nc._ruleCount].action = ZT_NETWORK_RULE_ACTION_ACCEPT; + ++nc._ruleCount; + + Utils::snprintf(nc._name,sizeof(nc._name),"ZT_TEST_NETWORK"); // Make up a V4 IP from 'self' in the 10.0.0.0/8 range -- no // guarantee of uniqueness but collisions are unlikely. uint32_t ip = (uint32_t)((self.toInt() & 0x00ffffff) | 0x0a000000); // 10.x.x.x if ((ip & 0x000000ff) == 0x000000ff) ip ^= 0x00000001; // but not ending in .255 if ((ip & 0x000000ff) == 0x00000000) ip ^= 0x00000001; // or .0 - nc->_staticIps.push_back(InetAddress(Utils::hton(ip),8)); + nc._staticIps[0] = InetAddress(Utils::hton(ip),8); // Assign an RFC4193-compliant IPv6 address -- will never collide - nc->_staticIps.push_back(InetAddress::makeIpv6rfc4193(ZT_TEST_NETWORK_ID,self.toInt())); + nc._staticIps[1] = InetAddress::makeIpv6rfc4193(ZT_TEST_NETWORK_ID,self.toInt()); + + nc._staticIpCount = 2; return nc; } -std::vector<unsigned int> NetworkConfig::allowedEtherTypes() const -{ - std::vector<unsigned int> ets; - if ((_etWhitelist[0] & 1) != 0) { - ets.push_back(0); - } else { - for(unsigned int i=0;i<sizeof(_etWhitelist);++i) { - if (_etWhitelist[i]) { - unsigned char b = _etWhitelist[i]; - unsigned int et = i * 8; - while (b) { - if ((b & 1)) - ets.push_back(et); - b >>= 1; - ++et; - } - } - } - } - return ets; -} +#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF -void NetworkConfig::_fromDictionary(const Dictionary &d) +void NetworkConfig::fromDictionary(const Dictionary &d) { static const std::string zero("0"); static const std::string one("1"); + memset(this,0,sizeof(NetworkConfig)); + // NOTE: d.get(name) throws if not found, d.get(name,default) returns default _nwid = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,"0").c_str()); @@ -87,26 +101,32 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) _timestamp = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,"0").c_str()); _revision = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_REVISION,"1").c_str()); // older controllers don't send this, so default to 1 - - memset(_etWhitelist,0,sizeof(_etWhitelist)); - std::vector<std::string> ets(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES,"").c_str(),",","","")); - for(std::vector<std::string>::const_iterator et(ets.begin());et!=ets.end();++et) { - unsigned int tmp = Utils::hexStrToUInt(et->c_str()) & 0xffff; - _etWhitelist[tmp >> 3] |= (1 << (tmp & 7)); - } - _issuedTo = Address(d.get(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,"0")); + _multicastLimit = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,zero).c_str()); if (_multicastLimit == 0) _multicastLimit = ZT_MULTICAST_DEFAULT_LIMIT; + _allowPassiveBridging = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOW_PASSIVE_BRIDGING,zero).c_str()) != 0); - _private = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,one).c_str()) != 0); _enableBroadcast = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST,one).c_str()) != 0); - _name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME,""); - if (_name.length() > ZT_MAX_NETWORK_SHORT_NAME_LENGTH) - throw std::invalid_argument("network short name too long (max: 255 characters)"); + _type = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,one).c_str()) != 0) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC; + + std::string nametmp(d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME,"")); + for(unsigned long i=0;((i<ZT_MAX_NETWORK_SHORT_NAME_LENGTH)&&(i<nametmp.length()));++i) + _name[i] = (char)nametmp[i]; + // we zeroed the entire structure above and _name is ZT_MAX_NETWORK_SHORT_NAME_LENGTH+1, so it will always null-terminate + + std::vector<std::string> activeBridgesSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES,"").c_str(),",","","")); + for(std::vector<std::string>::const_iterator a(activeBridgesSplit.begin());a!=activeBridgesSplit.end();++a) { + if (a->length() == ZT_ADDRESS_LENGTH_HEX) { // ignore empty or garbage fields + Address tmp(*a); + if (!tmp.isReserved()) { + if ((_activeBridgeCount < ZT_MAX_NETWORK_ACTIVE_BRIDGES)&&(std::find(&(_activeBridges[0]),&(_activeBridges[_activeBridgeCount]),tmp) == &(_activeBridges[_activeBridgeCount]))) + _activeBridges[_activeBridgeCount++] = tmp; + } + } + } + std::sort(&(_activeBridges[0]),&(_activeBridges[_activeBridgeCount])); - // In dictionary IPs are split into V4 and V6 addresses, but we don't really - // need that so merge them here. std::string ipAddrs(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC,std::string())); { std::string v6s(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC,std::string())); @@ -116,7 +136,6 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) ipAddrs.append(v6s); } } - std::vector<std::string> ipAddrsSplit(Utils::split(ipAddrs.c_str(),",","","")); for(std::vector<std::string>::const_iterator ipstr(ipAddrsSplit.begin());ipstr!=ipAddrsSplit.end();++ipstr) { InetAddress addr(*ipstr); @@ -132,70 +151,83 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) default: // ignore unrecognized address types or junk/empty fields continue; } - if (addr.isNetwork()) - _localRoutes.push_back(addr); - else _staticIps.push_back(addr); + if (addr.isNetwork()) { + if ((_localRouteCount < ZT_MAX_NETWORK_LOCAL_ROUTES)&&(std::find(&(_localRoutes[0]),&(_localRoutes[_localRouteCount]),addr) == &(_localRoutes[_localRouteCount]))) + _localRoutes[_localRouteCount++] = addr; + } else { + if ((_staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)&&(std::find(&(_staticIps[0]),&(_staticIps[_staticIpCount]),addr) == &(_staticIps[_staticIpCount]))) + _staticIps[_staticIpCount++] = addr; + } } - if (_localRoutes.size() > ZT_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned routes"); - if (_staticIps.size() > ZT_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned IP addresses"); - std::sort(_localRoutes.begin(),_localRoutes.end()); - _localRoutes.erase(std::unique(_localRoutes.begin(),_localRoutes.end()),_localRoutes.end()); - std::sort(_staticIps.begin(),_staticIps.end()); - _staticIps.erase(std::unique(_staticIps.begin(),_staticIps.end()),_staticIps.end()); + std::sort(&(_localRoutes[0]),&(_localRoutes[_localRouteCount])); + std::sort(&(_staticIps[0]),&(_staticIps[_staticIpCount])); std::vector<std::string> gatewaysSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_GATEWAYS,"").c_str(),",","","")); for(std::vector<std::string>::const_iterator gwstr(gatewaysSplit.begin());gwstr!=gatewaysSplit.end();++gwstr) { InetAddress gw(*gwstr); - if ((std::find(_gateways.begin(),_gateways.end(),gw) == _gateways.end())&&((gw.ss_family == AF_INET)||(gw.ss_family == AF_INET6))) - _gateways.push_back(gw); + if ((gw)&&(_gatewayCount < ZT_MAX_NETWORK_GATEWAYS)&&(std::find(&(_gateways[0]),&(_gateways[_gatewayCount]),gw) == &(_gateways[_gatewayCount]))) + _gateways[_gatewayCount++] = gw; } + std::sort(&(_gateways[0]),&(_gateways[_gatewayCount])); - std::vector<std::string> activeBridgesSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES,"").c_str(),",","","")); - for(std::vector<std::string>::const_iterator a(activeBridgesSplit.begin());a!=activeBridgesSplit.end();++a) { - if (a->length() == ZT_ADDRESS_LENGTH_HEX) { // ignore empty or garbage fields - Address tmp(*a); - if (!tmp.isReserved()) - _activeBridges.push_back(tmp); + std::vector<std::string> relaysSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_RELAYS,"").c_str(),",","","")); + for(std::vector<std::string>::const_iterator r(relaysSplit.begin());r!=relaysSplit.end();++r) { + if (r->length() >= ZT_ADDRESS_LENGTH_HEX) { + Address addr(r->substr(0,ZT_ADDRESS_LENGTH_HEX).c_str()); + InetAddress phys[2]; + unsigned int physCount = 0; + const std::size_t semi(r->find(';')); + if ((semi > ZT_ADDRESS_LENGTH_HEX)&&(semi < (r->length() - 2))) { + std::vector<std::string> phySplit(Utils::split(r->substr(semi+1).c_str(),",","","")); + for(std::vector<std::string>::const_iterator p(phySplit.begin());((p!=phySplit.end())&&(physCount < 2));++p) { + phys[physCount] = InetAddress(*p); + if (phys[physCount]) + ++physCount; + else phys[physCount].zero(); + } + } + + unsigned int p = _staticCount; + for(unsigned int i=0;i<_staticCount;++i) { + if (_static[p].address == addr.toInt()) { + p = i; + break; + } + } + if ((p == _staticCount)&&(_staticCount < ZT_MAX_NETWORK_STATIC_DEVICES)) + ++_staticCount; + if (p < ZT_MAX_NETWORK_STATIC_DEVICES) { + _static[p].address = Address(r->c_str()); + for(unsigned int i=0;i<physCount;++i) + _static[p].physical[i] = phys[i]; + _static[p].flags |= ZT_NETWORK_STATIC_DEVICE_IS_RELAY; + } } } - std::sort(_activeBridges.begin(),_activeBridges.end()); - _activeBridges.erase(std::unique(_activeBridges.begin(),_activeBridges.end()),_activeBridges.end()); + std::sort(&(_static[0]),&(_static[_staticCount]),ZT_VirtualNetworkStaticDevice_SortByAddress()); - std::vector<std::string> relaysSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_RELAYS,"").c_str(),",","","")); - for(std::vector<std::string>::const_iterator r(relaysSplit.begin());r!=relaysSplit.end();++r) { - std::size_t semi(r->find(';')); // address;ip/port,... - if (semi == ZT_ADDRESS_LENGTH_HEX) { - std::pair<Address,InetAddress> relay( - Address(r->substr(0,semi)), - ((r->length() > (semi + 1)) ? InetAddress(r->substr(semi + 1)) : InetAddress()) ); - if ((relay.first)&&(!relay.first.isReserved())) - _relays.push_back(relay); + std::vector<std::string> ets(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES,"").c_str(),",","","")); + int rno = 0; + for(std::vector<std::string>::const_iterator et(ets.begin());et!=ets.end();++et) { + unsigned int et2 = Utils::hexStrToUInt(et->c_str()) & 0xffff; + if (_ruleCount < ZT_MAX_NETWORK_RULES) { + memset(&(_rules[_ruleCount]),0,sizeof(ZT_VirtualNetworkRule)); + _rules[_ruleCount].ruleNo = rno; rno += 10; + _rules[_ruleCount].vlanId = -1; + _rules[_ruleCount].vlanPcp = -1; + _rules[_ruleCount].etherType = (et2 == 0) ? -1 : (int)et2; + _rules[_ruleCount].ipTos = -1; + _rules[_ruleCount].ipProtocol = -1; + _rules[_ruleCount].ipSourcePort = -1; + _rules[_ruleCount].ipDestPort = -1; + _rules[_ruleCount].action = ZT_NETWORK_RULE_ACTION_ACCEPT; + ++_ruleCount; } } - std::sort(_relays.begin(),_relays.end()); - _relays.erase(std::unique(_relays.begin(),_relays.end()),_relays.end()); _com.fromString(d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP,std::string())); } -bool NetworkConfig::operator==(const NetworkConfig &nc) const -{ - if (_nwid != nc._nwid) return false; - if (_timestamp != nc._timestamp) return false; - if (memcmp(_etWhitelist,nc._etWhitelist,sizeof(_etWhitelist))) return false; - if (_issuedTo != nc._issuedTo) return false; - if (_multicastLimit != nc._multicastLimit) return false; - if (_allowPassiveBridging != nc._allowPassiveBridging) return false; - if (_private != nc._private) return false; - if (_enableBroadcast != nc._enableBroadcast) return false; - if (_name != nc._name) return false; - if (_localRoutes != nc._localRoutes) return false; - if (_staticIps != nc._staticIps) return false; - if (_gateways != nc._gateways) return false; - if (_activeBridges != nc._activeBridges) return false; - if (_relays != nc._relays) return false; - if (_com != nc._com) return false; - return true; -} +#endif // ZT_SUPPORT_OLD_STYLE_NETCONF } // namespace ZeroTier |
