This commit is contained in:
Grant Limberg 2016-07-14 19:29:10 -07:00
commit 2afe3d89d0
32 changed files with 322 additions and 49 deletions

19
debian/changelog vendored
View File

@ -1,3 +1,22 @@
zerotier-one (1.1.12) unstable; urgency=medium
* See https://github.com/zerotier/ZeroTierOne for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 12 Jul 2016 03:02:22 -0700
zerotier-one (1.1.10) unstable; urgency=medium
* See https://github.com/zerotier/ZeroTierOne for release notes.
* ZeroTier Debian packages no longer depend on http-parser since its ABI is too unstable.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 12 Jul 2016 12:29:00 -0700
zerotier-one (1.1.8) unstable; urgency=low
* See https://github.com/zerotier/ZeroTierOne for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 08 Jul 2016 01:56:00 -0700
zerotier-one (1.1.6) unstable; urgency=medium
* First Debian release on ZeroTier, Inc. private apt repository.

4
debian/control vendored
View File

@ -3,14 +3,14 @@ Maintainer: Adam Ierymenko <adam.ierymenko@zerotier.com>
Section: net
Priority: optional
Standards-Version: 3.9.6
Build-Depends: debhelper (>= 9), libhttp-parser-dev (>= 2.1), liblz4-dev, libnatpmp-dev, dh-systemd, ruby-ronn
Build-Depends: debhelper (>= 9), liblz4-dev, libnatpmp-dev, dh-systemd, ruby-ronn
Vcs-Git: git://github.com/zerotier/ZeroTierOne
Vcs-Browser: https://github.com/zerotier/ZeroTierOne
Homepage: https://www.zerotier.com/
Package: zerotier-one
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libhttp-parser2.1, liblz4-1, libnatpmp1, iproute2
Depends: ${shlibs:Depends}, ${misc:Depends}, liblz4-1, libnatpmp1, iproute2
Homepage: https://www.zerotier.com/
Description: ZeroTier network virtualization service
ZeroTier One lets you join ZeroTier virtual networks and

View File

@ -759,7 +759,7 @@
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>VERSION</key>
<string>1.1.6</string>
<string>1.1.12</string>
</dict>
<key>PROJECT_COMMENTS</key>
<dict>

View File

@ -116,6 +116,11 @@ extern "C" {
*/
#define ZT_MAX_PEER_NETWORK_PATHS 4
/**
* Maximum number of trusted physical network paths
*/
#define ZT_MAX_TRUSTED_PATHS 16
/**
* Maximum number of hops in a ZeroTier circuit test
*
@ -887,6 +892,11 @@ typedef struct
*/
uint64_t lastReceive;
/**
* Is this a trusted path? If so this will be its nonzero ID.
*/
uint64_t trustedPathId;
/**
* Is path active?
*/
@ -1837,6 +1847,29 @@ void ZT_Node_clusterHandleIncomingMessage(ZT_Node *node,const void *msg,unsigned
*/
void ZT_Node_clusterStatus(ZT_Node *node,ZT_ClusterStatus *cs);
/**
* Set trusted paths
*
* A trusted path is a physical network (network/bits) over which both
* encryption and authentication can be skipped to improve performance.
* Each trusted path must have a non-zero unique ID that is the same across
* all participating nodes.
*
* We don't recommend using trusted paths at all unless you really *need*
* near-bare-metal performance. Even on a LAN authentication and encryption
* are never a bad thing, and anything that introduces an "escape hatch"
* for encryption should be treated with the utmost care.
*
* Calling with NULL pointers for networks and ids and a count of zero clears
* all trusted paths.
*
* @param node Node instance
* @param networks Array of [count] networks
* @param ids Array of [count] corresponding non-zero path IDs (zero path IDs are ignored)
* @param count Number of trusted paths-- values greater than ZT_MAX_TRUSTED_PATHS are clipped
*/
void ZT_Node_setTrustedPaths(ZT_Node *node,const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count);
/**
* Do things in the background until Node dies
*

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN ln -sf /usr/bin/clang++-3.5 /usr/bin/clang++
RUN ln -sf /usr/bin/clang-3.5 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN ln -sf /usr/bin/clang++-3.5 /usr/bin/clang++
RUN ln -sf /usr/bin/clang-3.5 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
#RUN ln -sf /usr/bin/clang++-3.5 /usr/bin/clang++
#RUN ln -sf /usr/bin/clang-3.5 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
#RUN ln -sf /usr/bin/clang++-3.5 /usr/bin/clang++
#RUN ln -sf /usr/bin/clang-3.5 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -4,6 +4,8 @@ MAINTAINER Adam Ierymenko <adam.ierymenko@zerotier.com>
RUN apt-get update
RUN apt-get install -y build-essential debhelper ruby-ronn g++ make devscripts
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /
RUN mv -f /ZeroTierOne/debian/control.wheezy /ZeroTierOne/debian/control

View File

@ -7,6 +7,8 @@
FROM zerotier/zt1-build-debian-wheezy-x86-base
MAINTAINER Adam Ierymenko <adam.ierymenko@zerotier.com>
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /
RUN mv -f /ZeroTierOne/debian/control.wheezy /ZeroTierOne/debian/control

View File

@ -5,5 +5,6 @@ RUN yum update -y
RUN yum install -y make rpmdevtools gcc-c++ rubygem-ronn json-parser-devel lz4-devel http-parser-devel libnatpmp-devel
RUN rpm --erase http-parser-devel
RUN yum install -y rubygem-ronn ruby
ADD zt1-src.tar.gz /

View File

@ -14,5 +14,6 @@ MAINTAINER Adam Ierymenko <adam.ierymenko@zerotier.com>
RUN echo 'i686-redhat-linux' >/etc/rpm/platform
RUN rpm --erase http-parser-devel
RUN yum install -y rubygem-ronn ruby
ADD zt1-src.tar.gz /

View File

@ -31,5 +31,34 @@ for db in `find /tmp/zt-rpm-repo -mindepth 2 -maxdepth 2 -type d`; do
createrepo --database $db
done
# Stupid RHEL stuff
cd /tmp/zt-rpm-repo/el
ln -sf 6 6Client
ln -sf 6 6Workstation
ln -sf 6 6Server
ln -sf 6 6.0
ln -sf 6 6.1
ln -sf 6 6.2
ln -sf 6 6.3
ln -sf 6 6.4
ln -sf 6 6.5
ln -sf 6 6.6
ln -sf 6 6.7
ln -sf 6 6.8
ln -sf 6 6.9
ln -sf 7 7Client
ln -sf 7 7Workstation
ln -sf 7 7Server
ln -sf 7 7.0
ln -sf 7 7.1
ln -sf 7 7.2
ln -sf 7 7.3
ln -sf 7 7.4
ln -sf 7 7.5
ln -sf 7 7.6
ln -sf 7 7.7
ln -sf 7 7.8
ln -sf 7 7.9
echo
echo Repo created in /tmp/zt-rpm-repo

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN ln -sf /usr/bin/clang++-3.6 /usr/bin/clang++
RUN ln -sf /usr/bin/clang-3.6 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN ln -sf /usr/bin/clang++-3.6 /usr/bin/clang++
RUN ln -sf /usr/bin/clang-3.6 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN ln -sf /usr/bin/clang++-3.7 /usr/bin/clang++
RUN ln -sf /usr/bin/clang-3.7 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -7,4 +7,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN ln -sf /usr/bin/clang++-3.7 /usr/bin/clang++
RUN ln -sf /usr/bin/clang-3.7 /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -9,4 +9,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN rm -f /usr/bin/clang++ /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -9,4 +9,6 @@ RUN apt-get install -y build-essential debhelper libhttp-parser-dev liblz4-dev l
RUN rm -f /usr/bin/clang++ /usr/bin/clang
RUN dpkg --purge libhttp-parser-dev
ADD zt1-src.tar.gz /

View File

@ -42,9 +42,24 @@ namespace ZeroTier {
bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,bool deferred)
{
const Address sourceAddress(source());
try {
if ((cipher() == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) {
const Address sourceAddress(source());
// Check for trusted paths or unencrypted HELLOs (HELLO is the only packet sent in the clear)
const unsigned int c = cipher();
bool trusted = false;
if (c == ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH) {
// If this is marked as a packet via a trusted path, check source address and path ID.
// Obviously if no trusted paths are configured this always returns false and such
// packets are dropped on the floor.
if (RR->topology->shouldInboundPathBeTrusted(_remoteAddress,trustedPathId())) {
trusted = true;
TRACE("TRUSTED PATH packet approved from %s(%s), trusted path ID %llx",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str(),trustedPathId());
} else {
TRACE("dropped packet from %s(%s), cipher set to trusted path mode but path %llx@%s is not trusted!",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str(),trustedPathId(),_remoteAddress.toString().c_str());
return true;
}
} else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) {
// Unencrypted HELLOs require some potentially expensive verification, so
// do this in the background if background processing is enabled.
if ((RR->dpEnabled > 0)&&(!deferred)) {
@ -61,12 +76,15 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,bool deferred)
SharedPtr<Peer> peer(RR->topology->getPeer(sourceAddress));
if (peer) {
if (!dearmor(peer->key())) {
TRACE("dropped packet from %s(%s), MAC authentication failed (size: %u)",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),size());
return true;
if (!trusted) {
if (!dearmor(peer->key())) {
TRACE("dropped packet from %s(%s), MAC authentication failed (size: %u)",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str(),size());
return true;
}
}
if (!uncompress()) {
TRACE("dropped packet from %s(%s), compressed data invalid",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
TRACE("dropped packet from %s(%s), compressed data invalid",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str());
return true;
}

View File

@ -447,6 +447,7 @@ ZT_PeerList *Node::peers() const
p->paths[p->pathCount].lastReceive = path->lastReceived();
p->paths[p->pathCount].active = path->active(_now) ? 1 : 0;
p->paths[p->pathCount].preferred = ((bestPath)&&(*path == *bestPath)) ? 1 : 0;
p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust(path->address());
++p->pathCount;
}
}
@ -745,6 +746,11 @@ void Node::postCircuitTestReport(const ZT_CircuitTestReport *report)
(reinterpret_cast<void (*)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)>((*i)->_internalPtr))(reinterpret_cast<ZT_Node *>(this),*i,report);
}
void Node::setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count)
{
RR->topology->setTrustedPaths(reinterpret_cast<const InetAddress *>(networks),ids,count);
}
} // namespace ZeroTier
/****************************************************************************/
@ -1014,6 +1020,13 @@ void ZT_Node_clusterStatus(ZT_Node *node,ZT_ClusterStatus *cs)
} catch ( ... ) {}
}
void ZT_Node_setTrustedPaths(ZT_Node *node,const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count)
{
try {
reinterpret_cast<ZeroTier::Node *>(node)->setTrustedPaths(networks,ids,count);
} catch ( ... ) {}
}
void ZT_Node_backgroundThreadMain(ZT_Node *node)
{
try {

View File

@ -248,26 +248,15 @@ public:
*/
inline int configureVirtualNetworkPort(uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,nwid,nuptr,op,nc); }
/**
* @return True if we appear to be online
*/
inline bool online() const throw() { return _online; }
#ifdef ZT_TRACE
void postTrace(const char *module,unsigned int line,const char *fmt,...);
#endif
/**
* @return Next 64-bit random number (not for cryptographic use)
*/
uint64_t prng();
/**
* Post a circuit test report to any listeners for a given test ID
*
* @param report Report (includes test ID)
*/
void postCircuitTestReport(const ZT_CircuitTestReport *report);
void setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count);
private:
inline SharedPtr<Network> _network(uint64_t nwid) const

View File

@ -57,11 +57,13 @@
* + Supports in-band world (root server definition) updates
* + Clustering! (Though this will work with protocol v4 clients.)
* + Otherwise backward compatible with protocol v4
* 6 - 1.1.5 ... CURRENT
* 6 - 1.1.5 ... 1.1.10
* + Deprecate old dictionary-based network config format
* + Introduce new binary serialized network config and meta-data
* 7 - 1.1.10 -- CURRENT
* + Introduce trusted paths for local SDN use
*/
#define ZT_PROTO_VERSION 6
#define ZT_PROTO_VERSION 7
/**
* Minimum supported protocol version
@ -100,10 +102,21 @@
#define ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 1
/**
* DEPRECATED payload encrypted flag, will be removed for re-use soon.
* Cipher suite: NONE
*
* This has been replaced by the three-bit cipher suite selection field where
* a value of 0 indicates unencrypted (but authenticated) messages.
* This differs from POLY1305/NONE in that *no* crypto is done, not even
* authentication. This is for trusted local LAN interconnects for internal
* SDN use within a data center.
*
* For this mode the MAC field becomes a trusted path ID and must match the
* configured ID of a trusted path or the packet is discarded.
*/
#define ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH 2
/**
* DEPRECATED payload encrypted flag, may be re-used in the future.
*
* This has been replaced by the three-bit cipher suite selection field.
*/
#define ZT_PROTO_FLAG_ENCRYPTED 0x80
@ -337,7 +350,7 @@ namespace ZeroTier {
* <[5] destination ZT address>
* <[5] source ZT address>
* <[1] flags/cipher/hops>
* <[8] 64-bit MAC>
* <[8] 64-bit MAC (or trusted path ID in trusted path mode)>
* [... -- begin encryption envelope -- ...]
* <[1] encrypted flags (MS 3 bits) and verb (LS 5 bits)>
* [... verb-specific payload ...]
@ -1218,7 +1231,6 @@ public:
*/
inline unsigned int cipher() const
{
// Note: this uses the new cipher spec field, which is incompatible with <1.0.0 peers
return (((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x38) >> 3);
}
@ -1229,12 +1241,30 @@ public:
{
unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS];
b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH
// DEPRECATED "encrypted" flag -- used by pre-1.0.3 peers
// Set DEPRECATED "encrypted" flag -- used by pre-1.0.3 peers
if (c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)
b |= ZT_PROTO_FLAG_ENCRYPTED;
else b &= (~ZT_PROTO_FLAG_ENCRYPTED);
}
/**
* Get the trusted path ID for this packet (only meaningful if cipher is trusted path)
*
* @return Trusted path ID (from MAC field)
*/
inline uint64_t trustedPathId() const { return at<uint64_t>(ZT_PACKET_IDX_MAC); }
/**
* Set this packet's trusted path ID and set the cipher spec to trusted path
*
* @param tpid Trusted path ID
*/
inline void setTrusted(const uint64_t tpid)
{
setCipher(ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH);
setAt(ZT_PACKET_IDX_MAC,tpid);
}
/**
* Get this packet's unique ID (the IV field interpreted as uint64_t)
*
@ -1278,6 +1308,10 @@ public:
/**
* Verify and (if encrypted) decrypt packet
*
* This does not handle trusted path mode packets and will return false
* for these. These are handled in IncomingPacket if the sending physical
* address and MAC field match a trusted path.
*
* @param key 32-byte key
* @return False if packet is invalid or failed MAC authenticity check
*/

View File

@ -849,7 +849,12 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid)
unsigned int chunkSize = std::min(tmp.size(),(unsigned int)ZT_UDP_DEFAULT_PAYLOAD_MTU);
tmp.setFragmented(chunkSize < tmp.size());
tmp.armor(peer->key(),encrypt);
const uint64_t trustedPathId = RR->topology->getOutboundPathTrust(viaPath->address());
if (trustedPathId) {
tmp.setTrusted(trustedPathId);
} else {
tmp.armor(peer->key(),encrypt);
}
if (viaPath->send(RR,tmp.data(),chunkSize,now)) {
if (chunkSize < tmp.size()) {

View File

@ -28,6 +28,7 @@
#include <utility>
#include "Constants.hpp"
#include "../include/ZeroTierOne.h"
#include "Address.hpp"
#include "Identity.hpp"
@ -252,12 +253,64 @@ public:
*/
inline bool amRoot() const throw() { return _amRoot; }
/**
* Get the outbound trusted path ID for a physical address, or 0 if none
*
* @param physicalAddress Physical address to which we are sending the packet
* @return Trusted path ID or 0 if none (0 is not a valid trusted path ID)
*/
inline uint64_t getOutboundPathTrust(const InetAddress &physicalAddress)
{
for(unsigned int i=0;i<_trustedPathCount;++i) {
if (_trustedPathNetworks[i].containsAddress(physicalAddress))
return _trustedPathIds[i];
}
return 0;
}
/**
* Check whether in incoming trusted path marked packet is valid
*
* @param physicalAddress Originating physical address
* @param trustedPathId Trusted path ID from packet (from MAC field)
*/
inline bool shouldInboundPathBeTrusted(const InetAddress &physicalAddress,const uint64_t trustedPathId)
{
for(unsigned int i=0;i<_trustedPathCount;++i) {
if ((_trustedPathIds[i] == trustedPathId)&&(_trustedPathNetworks[i].containsAddress(physicalAddress)))
return true;
}
return false;
}
/**
* Set trusted paths in this topology
*
* @param networks Array of networks (prefix/netmask bits)
* @param ids Array of trusted path IDs
* @param count Number of trusted paths (if larger than ZT_MAX_TRUSTED_PATHS overflow is ignored)
*/
inline void setTrustedPaths(const InetAddress *networks,const uint64_t *ids,unsigned int count)
{
if (count > ZT_MAX_TRUSTED_PATHS)
count = ZT_MAX_TRUSTED_PATHS;
Mutex::Lock _l(_lock);
for(unsigned int i=0;i<count;++i) {
_trustedPathIds[i] = ids[i];
_trustedPathNetworks[i] = networks[i];
}
_trustedPathCount = count;
}
private:
Identity _getIdentity(const Address &zta);
void _setWorld(const World &newWorld);
const RuntimeEnvironment *const RR;
uint64_t _trustedPathIds[ZT_MAX_TRUSTED_PATHS];
InetAddress _trustedPathNetworks[ZT_MAX_TRUSTED_PATHS];
unsigned int _trustedPathCount;
World _world;
Hashtable< Address,SharedPtr<Peer> > _peers;
std::vector< Address > _rootAddresses;

View File

@ -57,6 +57,8 @@
#define ZT_LINUX_IP_COMMAND "/sbin/ip"
#define ZT_LINUX_IP_COMMAND_2 "/usr/sbin/ip"
// NOTE: BSD is mostly tested on Apple/Mac but is likely to work on other BSD too
namespace ZeroTier {
namespace {
@ -413,7 +415,7 @@ bool ManagedRoute::sync()
// Shadow system route if it exists, also delete any obsolete shadows
// and replace them with the new state. sync() is called periodically to
// allow us to do that if underlying connectivity changes.
if ((_systemVia != newSystemVia)||(!strcmp(_systemDevice,newSystemDevice))) {
if ( ((_systemVia != newSystemVia)||(strcmp(_systemDevice,newSystemDevice))) && (strcmp(_device,newSystemDevice)) ) {
if ((_systemVia)&&(_systemDevice[0])) {
_routeCmd("delete",leftt,_systemVia,_systemDevice,(const char *)0);
_routeCmd("delete",rightt,_systemVia,_systemDevice,(const char *)0);

View File

@ -54,8 +54,8 @@ public:
* "device name."
*
* @param target Route target (e.g. 0.0.0.0/0 for default)
* @param via Route next L3 hop or NULL InetAddress if local
* @param device Device name/ID if 'via' is null and route is local, otherwise ignored
* @param via Route next L3 hop or NULL InetAddress if local in which case it will be routed via device
* @param device Name or hex LUID of ZeroTier device (e.g. zt#)
* @return True if route was successfully set
*/
inline bool set(const InetAddress &target,const InetAddress &via,const char *device)

View File

@ -474,7 +474,7 @@ bool OSXEthernetTap::addIp(const InetAddress &ip)
long cpid = (long)vfork();
if (cpid == 0) {
::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0);
::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toString().c_str(),"alias",(const char *)0);
::_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;
@ -494,7 +494,7 @@ bool OSXEthernetTap::removeIp(const InetAddress &ip)
if (*i == ip) {
long cpid = (long)vfork();
if (cpid == 0) {
execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString().c_str(),"-alias",(const char *)0);
execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toIpString().c_str(),"-alias",(const char *)0);
_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;

View File

@ -190,13 +190,15 @@ static std::string _jsonEnumerate(unsigned int depth,const ZT_PeerPhysicalPath *
"%s\t\"lastSend\": %llu,\n"
"%s\t\"lastReceive\": %llu,\n"
"%s\t\"active\": %s,\n"
"%s\t\"preferred\": %s\n"
"%s\t\"preferred\": %s,\n"
"%s\t\"trustedPathId\": %llu\n"
"%s}",
prefix,_jsonEscape(reinterpret_cast<const InetAddress *>(&(pp[i].address))->toString()).c_str(),
prefix,pp[i].lastSend,
prefix,pp[i].lastReceive,
prefix,(pp[i].active == 0) ? "false" : "true",
prefix,(pp[i].preferred == 0) ? "false" : "true",
prefix,pp[i].trustedPathId,
prefix);
buf.append(json);
}

View File

@ -759,6 +759,38 @@ public:
for(int i=0;i<3;++i)
_portsBE[i] = Utils::hton((uint16_t)_ports[i]);
{
FILE *trustpaths = fopen((_homePath + ZT_PATH_SEPARATOR_S + "trustedpaths").c_str(),"r");
uint64_t ids[ZT_MAX_TRUSTED_PATHS];
InetAddress addresses[ZT_MAX_TRUSTED_PATHS];
if (trustpaths) {
char buf[1024];
unsigned int count = 0;
while ((fgets(buf,sizeof(buf),trustpaths))&&(count < ZT_MAX_TRUSTED_PATHS)) {
int fno = 0;
char *saveptr = (char *)0;
uint64_t trustedPathId = 0;
InetAddress trustedPathNetwork;
for(char *f=Utils::stok(buf,"=\r\n \t",&saveptr);(f);f=Utils::stok((char *)0,"=\r\n \t",&saveptr)) {
if (fno == 0) {
trustedPathId = Utils::hexStrToU64(f);
} else if (fno == 1) {
trustedPathNetwork = InetAddress(f);
} else break;
++fno;
}
if ( (trustedPathId != 0) && ((trustedPathNetwork.ss_family == AF_INET)||(trustedPathNetwork.ss_family == AF_INET6)) && (trustedPathNetwork.ipScope() != InetAddress::IP_SCOPE_GLOBAL) && (trustedPathNetwork.netmaskBits() > 0) ) {
ids[count] = trustedPathId;
addresses[count] = trustedPathNetwork;
++count;
}
}
fclose(trustpaths);
if (count)
_node->setTrustedPaths(reinterpret_cast<const struct sockaddr_storage *>(addresses),ids,count);
}
}
#ifdef ZT_ENABLE_NETWORK_CONTROLLER
_controller = new SqliteNetworkController(_node,(_homePath + ZT_PATH_SEPARATOR_S + ZT_CONTROLLER_DB_PATH).c_str(),(_homePath + ZT_PATH_SEPARATOR_S + "circuitTestResults.d").c_str());
_node->setNetconfMaster((void *)_controller);
@ -1041,13 +1073,13 @@ public:
// Begin private implementation methods
// Checks if a managed IP or route target is allowed
bool checkIfManagedIsAllowed(const NetworkState &n,const InetAddress &addr)
bool checkIfManagedIsAllowed(const NetworkState &n,const InetAddress &target)
{
if (!n.settings.allowManaged)
return false;
if (addr.isDefaultRoute())
if (target.isDefaultRoute())
return n.settings.allowDefault;
switch(addr.ipScope()) {
switch(target.ipScope()) {
case InetAddress::IP_SCOPE_NONE:
case InetAddress::IP_SCOPE_MULTICAST:
case InetAddress::IP_SCOPE_LOOPBACK:
@ -1060,6 +1092,16 @@ public:
}
}
// Match only an IP from a vector of IPs -- used in syncManagedStuff()
bool matchIpOnly(const std::vector<InetAddress> &ips,const InetAddress &ip) const
{
for(std::vector<InetAddress>::const_iterator i(ips.begin());i!=ips.end();++i) {
if (i->ipsEqual(ip))
return true;
}
return false;
}
// Apply or update managed IPs for a configured network (be sure n.tap exists)
void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes)
{
@ -1075,18 +1117,18 @@ public:
std::sort(newManagedIps.begin(),newManagedIps.end());
newManagedIps.erase(std::unique(newManagedIps.begin(),newManagedIps.end()),newManagedIps.end());
for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) {
if (!n.tap->addIp(*ip))
fprintf(stderr,"ERROR: unable to add ip address %s"ZT_EOL_S, ip->toString().c_str());
}
}
for(std::vector<InetAddress>::iterator ip(n.managedIps.begin());ip!=n.managedIps.end();++ip) {
if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) {
if (!n.tap->removeIp(*ip))
fprintf(stderr,"ERROR: unable to remove ip address %s"ZT_EOL_S, ip->toString().c_str());
}
}
for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) {
if (!n.tap->addIp(*ip))
fprintf(stderr,"ERROR: unable to add ip address %s"ZT_EOL_S, ip->toString().c_str());
}
}
n.managedIps.swap(newManagedIps);
}
@ -1099,10 +1141,12 @@ public:
Utils::scopy(tapdev,sizeof(tapdev),n.tap->deviceName().c_str());
#endif
std::vector<InetAddress> myIps(n.tap->ips());
// Nuke applied routes that are no longer in n.config.routes[] and/or are not allowed
for(std::list<ManagedRoute>::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();) {
bool haveRoute = false;
if (checkIfManagedIsAllowed(n,mr->target())) {
if ( (checkIfManagedIsAllowed(n,mr->target())) && ((mr->via().ss_family != mr->target().ss_family)||(!matchIpOnly(myIps,mr->via()))) ) {
for(unsigned int i=0;i<n.config.routeCount;++i) {
const InetAddress *const target = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].target));
const InetAddress *const via = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].via));
@ -1124,7 +1168,7 @@ public:
const InetAddress *const target = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].target));
const InetAddress *const via = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].via));
if (!checkIfManagedIsAllowed(n,*target))
if ( (!checkIfManagedIsAllowed(n,*target)) || ((via->ss_family == target->ss_family)&&(matchIpOnly(myIps,*via))) )
continue;
bool haveRoute = false;

View File

@ -32,6 +32,6 @@
/**
* Revision
*/
#define ZEROTIER_ONE_VERSION_REVISION 8
#define ZEROTIER_ONE_VERSION_REVISION 12
#endif

View File

@ -1,5 +1,5 @@
Name: zerotier-one
Version: 1.1.6
Version: 1.1.12
Release: 0.1%{?dist}
Summary: ZeroTier One network virtualization service
@ -149,6 +149,12 @@ esac
%endif
%changelog
* Tue Jul 12 2016 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.1.10-0.1
- see https://github.com/zerotier/ZeroTierOne for release notes
* Fri Jul 08 2016 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.1.8-0.1
- see https://github.com/zerotier/ZeroTierOne for release notes
* Sat Jun 25 2016 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.1.6-0.1
- now builds on CentOS 6 as well as newer distros, and some cleanup