diff options
Diffstat (limited to 'node')
-rw-r--r-- | node/InetAddress.hpp | 10 | ||||
-rw-r--r-- | node/NetworkConfig.cpp | 9 | ||||
-rw-r--r-- | node/NetworkConfig.hpp | 39 | ||||
-rw-r--r-- | node/Packet.cpp | 1 | ||||
-rw-r--r-- | node/Packet.hpp | 32 |
5 files changed, 88 insertions, 3 deletions
diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 5b725174..16e3f4d5 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -266,6 +266,16 @@ struct InetAddress : public sockaddr_storage inline unsigned int netmaskBits() const throw() { return port(); } /** + * Alias for port() + * + * This just aliases port() because for gateways we use this field to + * store the gateway metric. + * + * @return Gateway metric + */ + inline unsigned int metric() const throw() { return port(); } + + /** * Construct a full netmask as an InetAddress */ InetAddress netmask() const diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index 4b9620a6..5ed1dd3f 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -163,6 +163,13 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) std::sort(_staticIps.begin(),_staticIps.end()); std::unique(_staticIps.begin(),_staticIps.end()); + 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); + } + 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 @@ -211,7 +218,9 @@ bool NetworkConfig::operator==(const NetworkConfig &nc) const if (_name != nc._name) return false; if (_description != nc._description) 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 (_multicastRates.size() == nc._multicastRates.size()) { // uclibc++ doesn't seem to implement map<> != map<> correctly, so do // it ourselves. Note that this depends on the maps being sorted. diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index 89d1aec5..2fb56d6a 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -49,24 +49,61 @@ namespace ZeroTier { // These dictionary keys are short so they don't take up much room in // netconf response packets. + +// integer(hex)[,integer(hex),...] #define ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES "et" + +// network ID #define ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID "nwid" + +// integer(hex) #define ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP "ts" + +// integer(hex) #define ZT_NETWORKCONFIG_DICT_KEY_REVISION "r" + +// address of member #define ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO "id" + +// integer(hex) #define ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT "ml" + +// dictionary of one or more of: MAC/ADI=preload,maxbalance,accrual #define ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_RATES "mr" + +// 0/1 #define ZT_NETWORKCONFIG_DICT_KEY_PRIVATE "p" + +// text #define ZT_NETWORKCONFIG_DICT_KEY_NAME "n" + +// text #define ZT_NETWORKCONFIG_DICT_KEY_DESC "d" + +// IP/bits[,IP/bits,...] #define ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC "v4s" + +// IP/bits[,IP/bits,...] #define ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC "v6s" + +// serialized CertificateOfMembership #define ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP "com" + +// 0/1 #define ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST "eb" + +// 0/1 #define ZT_NETWORKCONFIG_DICT_KEY_ALLOW_PASSIVE_BRIDGING "pb" + +// node[,node,...] #define ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES "ab" + +// node;IP/port[,node;IP/port] #define ZT_NETWORKCONFIG_DICT_KEY_RELAYS "rl" +// IP/metric[,IP/metric,...] +#define ZT_NETWORKCONFIG_DICT_KEY_GATEWAYS "gw" + /** * Network configuration received from network controller nodes * @@ -146,6 +183,7 @@ public: inline const std::string &name() const throw() { return _name; } inline const std::string &description() const throw() { return _description; } inline const std::vector<InetAddress> &staticIps() const throw() { return _staticIps; } + inline const std::vector<InetAddress> &gateways() const throw() { return _gateways; } inline const std::vector<Address> &activeBridges() const throw() { return _activeBridges; } inline const std::vector< std::pair<Address,InetAddress> > &relays() const throw() { return _relays; } inline const CertificateOfMembership &com() const throw() { return _com; } @@ -188,6 +226,7 @@ private: std::string _name; std::string _description; std::vector<InetAddress> _staticIps; + std::vector<InetAddress> _gateways; std::vector<Address> _activeBridges; std::vector< std::pair<Address,InetAddress> > _relays; std::map<MulticastGroup,MulticastRate> _multicastRates; diff --git a/node/Packet.cpp b/node/Packet.cpp index a81873ff..f75d1df0 100644 --- a/node/Packet.cpp +++ b/node/Packet.cpp @@ -51,6 +51,7 @@ const char *Packet::verbString(Verb v) case VERB_MULTICAST_GATHER: return "MULTICAST_GATHER"; case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME"; case VERB_SET_EPHEMERAL_KEY: return "SET_EPHEMERAL_KEY"; + case VERB_CMA: return "CMA"; } return "(unknown)"; } diff --git a/node/Packet.hpp b/node/Packet.hpp index 2dfb75e4..1ec145d5 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -513,8 +513,8 @@ public: * Destination address types and formats (not all of these are used now): * 0 - None -- no destination address data present * 1 - Ethernet address -- format: <[6] Ethernet MAC> - * 4 - 6-byte IPv4 address -- format: <[4] IP>, <[2] port> - * 6 - 18-byte IPv6 address -- format: <[16] IP>, <[2] port> + * 4 - 6-byte IPv4 UDP address/port -- format: <[4] IP>, <[2] port> + * 6 - 18-byte IPv6 UDP address/port -- format: <[16] IP>, <[2] port> * * OK payload: * <[8] timestamp (echoed from original HELLO)> @@ -770,6 +770,9 @@ public: VERB_MULTICAST_FRAME = 14, /* Ephemeral (PFS) key push: + * <[2] flags (unused and reserved, must be 0)> + * <[2] length of padding / extra field section> + * <[...] padding / extra field section> * <[8] 64-bit PFS key set ID sender holds for recipient (0==none)> * <[8] 64-bit PFS key set ID of this key set> * [... begin PFS key record ...] @@ -791,6 +794,12 @@ public: * the first record with common symmetric cipher, public key type, * and relevant flags must be used. * + * The padding section may be filled with an arbitrary amount of random + * or empty payload. This may be used as a countermeasure to prevent PFS + * key pushes from being recognized by packet size vs. other packets in + * the stream. This also provides potential space for additional fields + * that might be indicated in the future by flags. + * * Flags (all unspecified flags must be zero): * 0x01 - FIPS mode, only use record if FIPS compliant crypto in use * @@ -814,7 +823,24 @@ public: * <[8] PFS key set ID of received key set> * <[1] index in record list of chosen key record> */ - VERB_SET_EPHEMERAL_KEY = 15 + VERB_SET_EPHEMERAL_KEY = 15, + + /* "Call me at" -- push of potential endpoints for direct communication: + * <[1] flags> + * <[2] number of addresses> + * <[...] address types and addresses> + * + * Address types and addresses are of the same format as the destination + * address type and address in HELLO. + * + * The receiver may, upon receiving a CMA push, attempt to establish a + * direct link to one or more of the indicated addresses. Senders should + * only send CMA pushes to peers that they have some relationship + * with such as a shared network membership or a mutual trust. + * + * OK/ERROR are not generated. + */ + VERB_CMA = 16 }; /** |