summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/InetAddress.hpp10
-rw-r--r--node/NetworkConfig.cpp9
-rw-r--r--node/NetworkConfig.hpp39
-rw-r--r--node/Packet.cpp1
-rw-r--r--node/Packet.hpp32
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
};
/**