diff --git a/node/Cluster.cpp b/Cluster.cpp similarity index 100% rename from node/Cluster.cpp rename to Cluster.cpp diff --git a/node/Cluster.hpp b/Cluster.hpp similarity index 100% rename from node/Cluster.hpp rename to Cluster.hpp diff --git a/make-linux.mk b/make-linux.mk index eb77326ed..5af8a92d3 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -65,9 +65,9 @@ ifeq ($(ZT_DEBUG),1) node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CXXFLAGS=-Wall -O2 -g -pthread $(INCLUDES) $(DEFS) else override DEFS+=-D_FORTIFY_SOURCE=2 - CFLAGS?=-O3 -fstack-protector + CFLAGS?=-Os -fstack-protector override CFLAGS+=-Wall -Wno-deprecated -fPIE -pthread $(INCLUDES) -DNDEBUG $(DEFS) - CXXFLAGS?=-O3 -fstack-protector + CXXFLAGS?=-Os -fstack-protector override CXXFLAGS+=-Wall -Wno-deprecated -Wno-unused-result -Wreorder -fPIE -std=c++11 -pthread $(INCLUDES) -DNDEBUG $(DEFS) override LDFLAGS+=-pie -Wl,-z,relro,-z,now STRIP?=strip diff --git a/objects.mk b/objects.mk index fd25a3d39..c8231f08b 100644 --- a/objects.mk +++ b/objects.mk @@ -3,7 +3,6 @@ CORE_OBJS=\ node/Capability.o \ node/CertificateOfMembership.o \ node/CertificateOfOwnership.o \ - node/Cluster.o \ node/Identity.o \ node/IncomingPacket.o \ node/InetAddress.o \ diff --git a/osdep/Binder.hpp b/osdep/Binder.hpp index 1839ecc29..a0b473678 100644 --- a/osdep/Binder.hpp +++ b/osdep/Binder.hpp @@ -57,6 +57,7 @@ #include #include #include +#include #include "../node/NonCopyable.hpp" #include "../node/InetAddress.hpp" @@ -471,6 +472,20 @@ Binder_send_packet: return aa; } + /** + * @param addr Address to check + * @return True if this is a bound local interface address + */ + inline bool isBoundLocalInterfaceAddress(const InetAddress &addr) const + { + Mutex::Lock _l(_lock); + for(std::vector<_Binding>::const_iterator b(_bindings.begin());b!=_bindings.end();++b) { + if (b->address == addr) + return true; + } + return false; + } + private: std::vector<_Binding> _bindings; Mutex _lock; diff --git a/service/OneService.cpp b/service/OneService.cpp index 0fadc191f..644454bcf 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -736,57 +736,6 @@ public: _controller = new EmbeddedNetworkController(_node,_controllerDbPath.c_str()); _node->setNetconfMaster((void *)_controller); -/* -#ifdef ZT_ENABLE_CLUSTER - if (OSUtils::fileExists((_homePath + ZT_PATH_SEPARATOR_S "cluster").c_str())) { - _clusterDefinition = new ClusterDefinition(_node->address(),(_homePath + ZT_PATH_SEPARATOR_S "cluster").c_str()); - if (_clusterDefinition->size() > 0) { - std::vector members(_clusterDefinition->members()); - for(std::vector::iterator m(members.begin());m!=members.end();++m) { - PhySocket *cs = _phy.udpBind(reinterpret_cast(&(m->clusterEndpoint))); - if (cs) { - if (_clusterMessageSocket) { - _phy.close(_clusterMessageSocket,false); - _phy.close(cs,false); - - Mutex::Lock _l(_termReason_m); - _termReason = ONE_UNRECOVERABLE_ERROR; - _fatalErrorMessage = "cluster: can't determine my cluster member ID: able to bind more than one cluster message socket IP/port!"; - return _termReason; - } - _clusterMessageSocket = cs; - _clusterMemberId = m->id; - } - } - - if (!_clusterMessageSocket) { - Mutex::Lock _l(_termReason_m); - _termReason = ONE_UNRECOVERABLE_ERROR; - _fatalErrorMessage = "cluster: can't determine my cluster member ID: unable to bind to any cluster message socket IP/port."; - return _termReason; - } - - const ClusterDefinition::MemberDefinition &me = (*_clusterDefinition)[_clusterMemberId]; - InetAddress endpoints[255]; - unsigned int numEndpoints = 0; - for(std::vector::const_iterator i(me.zeroTierEndpoints.begin());i!=me.zeroTierEndpoints.end();++i) - endpoints[numEndpoints++] = *i; - - if (_node->clusterInit(_clusterMemberId,reinterpret_cast(endpoints),numEndpoints,me.x,me.y,me.z,&SclusterSendFunction,this,_clusterDefinition->geo().available() ? &SclusterGeoIpFunction : 0,this) == ZT_RESULT_OK) { - std::vector members(_clusterDefinition->members()); - for(std::vector::iterator m(members.begin());m!=members.end();++m) { - if (m->id != _clusterMemberId) - _node->clusterAddMember(m->id); - } - } - } else { - delete _clusterDefinition; - _clusterDefinition = (ClusterDefinition *)0; - } - } -#endif -*/ - // Join existing networks in networks.d { std::vector networksDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S "networks.d").c_str())); @@ -810,10 +759,18 @@ public: // Derive the cluster's shared secret backplane encryption key by hashing its shared secret identity { uint8_t tmp[64]; - SHA512::hash(tmp,_node->identity().privateKeyPair().priv.data,ZT_C25519_PRIVATE_KEY_LEN); + uint8_t sk[ZT_C25519_PRIVATE_KEY_LEN + 4]; + memcpy(sk,_node->identity().privateKeyPair().priv.data,ZT_C25519_PRIVATE_KEY_LEN); + sk[ZT_C25519_PRIVATE_KEY_LEN] = 0xab; + sk[ZT_C25519_PRIVATE_KEY_LEN + 1] = 0xcd; + sk[ZT_C25519_PRIVATE_KEY_LEN + 2] = 0xef; + sk[ZT_C25519_PRIVATE_KEY_LEN + 3] = 0xab; // add an arbitrary nonce, just because + SHA512::hash(tmp,sk,ZT_C25519_PRIVATE_KEY_LEN + 4); memcpy(_clusterKey,tmp,32); } - _clusterMemberId = _node->prng(); + + // Assign a random non-zero cluster member ID to identify vs. other cluster members + Utils::getSecureRandom(&_clusterMemberId,sizeof(_clusterMemberId)); if (!_clusterMemberId) _clusterMemberId = 1; // Main I/O loop @@ -929,6 +886,7 @@ public: if ((now - lastTcpCheck) >= ZT_TCP_CHECK_PERIOD) { lastTcpCheck = now; + // Send status to active cluster links and close overflowed and dead ones std::vector toClose; std::vector clusterLinksUp; { @@ -949,10 +907,11 @@ public: for(std::vector::iterator s(toClose.begin());s!=toClose.end();++s) _phy.close(*s,true); + // Attempt to connect to cluster links we don't have an active connection to { Mutex::Lock _l(_localConfig_m); for(std::vector::const_iterator ca(_clusterBackplaneAddresses.begin());ca!=_clusterBackplaneAddresses.end();++ca) { - if (std::find(clusterLinksUp.begin(),clusterLinksUp.end(),*ca) == clusterLinksUp.end()) { + if ( (std::find(clusterLinksUp.begin(),clusterLinksUp.end(),*ca) == clusterLinksUp.end()) && (!_binder.isBoundLocalInterfaceAddress(*ca)) ) { TcpConnection *tc = new TcpConnection(); { Mutex::Lock _l(_tcpConnections_m); @@ -1640,6 +1599,16 @@ public: } } + json &cl = settings["cluster"]; + _clusterBackplaneAddresses.clear(); + if (cl.is_array()) { + for(unsigned long i=0;i