updated core to 1.2.4, fixed pico_device init bug
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_ADDRESS_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_ARRAY_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_ATOMICCOUNTER_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_BUFFER_HPP
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Code taken from NaCl by D. J. Bernstein and others
|
||||
|
||||
/*
|
||||
Matthew Dempsky
|
||||
Public domain.
|
||||
@@ -7,7 +5,7 @@ Derived from public domain code by D. J. Bernstein.
|
||||
*/
|
||||
|
||||
// Modified very slightly for ZeroTier One by Adam Ierymenko
|
||||
// (no functional changes)
|
||||
// This code remains in the public domain.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_C25519_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "Capability.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_CAPABILITY_HPP
|
||||
@@ -24,6 +32,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "C25519.hpp"
|
||||
#include "Utils.hpp"
|
||||
@@ -58,9 +67,11 @@ class RuntimeEnvironment;
|
||||
* handed off between nodes. Limited transferrability of capabilities is
|
||||
* a feature of true capability based security.
|
||||
*/
|
||||
class Capability
|
||||
class Capability : public Credential
|
||||
{
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; }
|
||||
|
||||
Capability()
|
||||
{
|
||||
memset(this,0,sizeof(Capability));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "CertificateOfMembership.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_CERTIFICATEOFMEMBERSHIP_HPP
|
||||
@@ -27,6 +35,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "C25519.hpp"
|
||||
@@ -68,9 +77,11 @@ class RuntimeEnvironment;
|
||||
* This is a memcpy()'able structure and is safe (in a crash sense) to modify
|
||||
* without locks.
|
||||
*/
|
||||
class CertificateOfMembership
|
||||
class CertificateOfMembership : public Credential
|
||||
{
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COM; }
|
||||
|
||||
/**
|
||||
* Reserved qualifier IDs
|
||||
*
|
||||
@@ -155,18 +166,23 @@ public:
|
||||
/**
|
||||
* @return True if there's something here
|
||||
*/
|
||||
inline operator bool() const throw() { return (_qualifierCount != 0); }
|
||||
inline operator bool() const { return (_qualifierCount != 0); }
|
||||
|
||||
/**
|
||||
* @return Credential ID, always 0 for COMs
|
||||
*/
|
||||
inline uint32_t id() const { return 0; }
|
||||
|
||||
/**
|
||||
* @return Timestamp for this cert and maximum delta for timestamp
|
||||
*/
|
||||
inline std::pair<uint64_t,uint64_t> timestamp() const
|
||||
inline uint64_t timestamp() const
|
||||
{
|
||||
for(unsigned int i=0;i<_qualifierCount;++i) {
|
||||
if (_qualifiers[i].id == COM_RESERVED_ID_TIMESTAMP)
|
||||
return std::pair<uint64_t,uint64_t>(_qualifiers[i].value,_qualifiers[i].maxDelta);
|
||||
return _qualifiers[i].value;
|
||||
}
|
||||
return std::pair<uint64_t,uint64_t>(0ULL,0ULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,12 +274,12 @@ public:
|
||||
/**
|
||||
* @return True if signed
|
||||
*/
|
||||
inline bool isSigned() const throw() { return (_signedBy); }
|
||||
inline bool isSigned() const { return (_signedBy); }
|
||||
|
||||
/**
|
||||
* @return Address that signed this certificate or null address if none
|
||||
*/
|
||||
inline const Address &signedBy() const throw() { return _signedBy; }
|
||||
inline const Address &signedBy() const { return _signedBy; }
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
@@ -321,7 +337,6 @@ public:
|
||||
}
|
||||
|
||||
inline bool operator==(const CertificateOfMembership &c) const
|
||||
throw()
|
||||
{
|
||||
if (_signedBy != c._signedBy)
|
||||
return false;
|
||||
@@ -335,7 +350,7 @@ public:
|
||||
}
|
||||
return (_signature == c._signature);
|
||||
}
|
||||
inline bool operator!=(const CertificateOfMembership &c) const throw() { return (!(*this == c)); }
|
||||
inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); }
|
||||
|
||||
private:
|
||||
struct _Qualifier
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "CertificateOfOwnership.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_CERTIFICATEOFOWNERSHIP_HPP
|
||||
@@ -25,6 +33,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "C25519.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Identity.hpp"
|
||||
@@ -45,9 +54,11 @@ class RuntimeEnvironment;
|
||||
/**
|
||||
* Certificate indicating ownership of a network identifier
|
||||
*/
|
||||
class CertificateOfOwnership
|
||||
class CertificateOfOwnership : public Credential
|
||||
{
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COO; }
|
||||
|
||||
enum Thing
|
||||
{
|
||||
THING_NULL = 0,
|
||||
@@ -69,6 +80,8 @@ public:
|
||||
_thingCount(0),
|
||||
_issuedTo(issuedTo)
|
||||
{
|
||||
memset(_thingTypes,0,sizeof(_thingTypes));
|
||||
memset(_thingValues,0,sizeof(_thingValues));
|
||||
}
|
||||
|
||||
inline uint64_t networkId() const { return _networkId; }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,12 +14,21 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_CERTIFICATEOFREPRESENTATION_HPP
|
||||
#define ZT_CERTIFICATEOFREPRESENTATION_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "C25519.hpp"
|
||||
#include "Identity.hpp"
|
||||
@@ -47,14 +56,17 @@ namespace ZeroTier {
|
||||
* roots can shield nodes entirely and p2p connectivity behind them can
|
||||
* be disabled. This will be desirable for a number of use cases.
|
||||
*/
|
||||
class CertificateOfRepresentation
|
||||
class CertificateOfRepresentation : public Credential
|
||||
{
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COR; }
|
||||
|
||||
CertificateOfRepresentation()
|
||||
{
|
||||
memset(this,0,sizeof(CertificateOfRepresentation));
|
||||
}
|
||||
|
||||
inline uint32_t id() const { return 0; }
|
||||
inline uint64_t timestamp() const { return _timestamp; }
|
||||
inline const Address &representative(const unsigned int i) const { return _reps[i]; }
|
||||
inline unsigned int repCount() const { return _repCount; }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_CLUSTER_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_CONSTANTS_HPP
|
||||
@@ -289,7 +297,7 @@
|
||||
#define ZT_PEER_PING_PERIOD 60000
|
||||
|
||||
/**
|
||||
* Paths are considered expired if they have not produced a real packet in this long
|
||||
* Paths are considered expired if they have not sent us a real packet in this long
|
||||
*/
|
||||
#define ZT_PEER_PATH_EXPIRATION ((ZT_PEER_PING_PERIOD * 4) + 3000)
|
||||
|
||||
|
||||
66
zto/node/Credential.hpp
Normal file
66
zto/node/Credential.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_CREDENTIAL_HPP
|
||||
#define ZT_CREDENTIAL_HPP
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Base class for credentials
|
||||
*/
|
||||
class Credential
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Do not change type code IDs -- these are used in Revocation objects and elsewhere
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
CREDENTIAL_TYPE_NULL = 0,
|
||||
CREDENTIAL_TYPE_COM = 1, // CertificateOfMembership
|
||||
CREDENTIAL_TYPE_CAPABILITY = 2,
|
||||
CREDENTIAL_TYPE_TAG = 3,
|
||||
CREDENTIAL_TYPE_COO = 4, // CertificateOfOwnership
|
||||
CREDENTIAL_TYPE_COR = 5, // CertificateOfRepresentation
|
||||
CREDENTIAL_TYPE_REVOCATION = 6
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_DICTIONARY_HPP
|
||||
@@ -91,6 +99,8 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator bool() const { return (_d[0] != 0); }
|
||||
|
||||
/**
|
||||
* Load a dictionary from a C-string
|
||||
*
|
||||
@@ -176,12 +186,12 @@ public:
|
||||
j = 0;
|
||||
esc = false;
|
||||
++p;
|
||||
while ((*p != 0)&&(*p != '\r')&&(*p != '\n')) {
|
||||
while ((*p != 0)&&(*p != 13)&&(*p != 10)) {
|
||||
if (esc) {
|
||||
esc = false;
|
||||
switch(*p) {
|
||||
case 'r': dest[j++] = '\r'; break;
|
||||
case 'n': dest[j++] = '\n'; break;
|
||||
case 'r': dest[j++] = 13; break;
|
||||
case 'n': dest[j++] = 10; break;
|
||||
case '0': dest[j++] = (char)0; break;
|
||||
case 'e': dest[j++] = '='; break;
|
||||
default: dest[j++] = *p; break;
|
||||
@@ -207,7 +217,7 @@ public:
|
||||
dest[j] = (char)0;
|
||||
return j;
|
||||
} else {
|
||||
while ((*p)&&(*p != '\r')&&(*p != '\n')) {
|
||||
while ((*p)&&(*p != 13)&&(*p != 10)) {
|
||||
if (++p == eof) {
|
||||
dest[0] = (char)0;
|
||||
return -1;
|
||||
@@ -299,7 +309,7 @@ public:
|
||||
unsigned int j = i;
|
||||
|
||||
if (j > 0) {
|
||||
_d[j++] = '\n';
|
||||
_d[j++] = (char)10;
|
||||
if (j == C) {
|
||||
_d[i] = (char)0;
|
||||
return false;
|
||||
@@ -326,8 +336,8 @@ public:
|
||||
while ( ((vlen < 0)&&(*p)) || (k < vlen) ) {
|
||||
switch(*p) {
|
||||
case 0:
|
||||
case '\r':
|
||||
case '\n':
|
||||
case 13:
|
||||
case 10:
|
||||
case '\\':
|
||||
case '=':
|
||||
_d[j++] = '\\';
|
||||
@@ -337,8 +347,8 @@ public:
|
||||
}
|
||||
switch(*p) {
|
||||
case 0: _d[j++] = '0'; break;
|
||||
case '\r': _d[j++] = 'r'; break;
|
||||
case '\n': _d[j++] = 'n'; break;
|
||||
case 13: _d[j++] = 'r'; break;
|
||||
case 10: _d[j++] = 'n'; break;
|
||||
case '\\': _d[j++] = '\\'; break;
|
||||
case '=': _d[j++] = 'e'; break;
|
||||
}
|
||||
@@ -416,46 +426,6 @@ public:
|
||||
return (this->get(key,tmp,2) >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase a key from this dictionary
|
||||
*
|
||||
* Use this before add() to ensure that a key is replaced if it might
|
||||
* already be present.
|
||||
*
|
||||
* @param key Key to erase
|
||||
* @return True if key was found and erased
|
||||
*/
|
||||
inline bool erase(const char *key)
|
||||
{
|
||||
char d2[C];
|
||||
char *saveptr = (char *)0;
|
||||
unsigned int d2ptr = 0;
|
||||
bool found = false;
|
||||
for(char *f=Utils::stok(_d,"\r\n",&saveptr);(f);f=Utils::stok((char *)0,"\r\n",&saveptr)) {
|
||||
if (*f) {
|
||||
const char *p = f;
|
||||
const char *k = key;
|
||||
while ((*k)&&(*p)) {
|
||||
if (*k != *p)
|
||||
break;
|
||||
++k;
|
||||
++p;
|
||||
}
|
||||
if (*k) {
|
||||
p = f;
|
||||
while (*p)
|
||||
d2[d2ptr++] = *(p++);
|
||||
d2[d2ptr++] = '\n';
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
d2[d2ptr++] = (char)0;
|
||||
memcpy(_d,d2,d2ptr);
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Value of C template parameter
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_HASHTABLE_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -45,7 +53,7 @@ static inline void _computeMemoryHardHash(const void *publicKey,unsigned int pub
|
||||
// ordinary Salsa20 is randomly seekable. This is good for a cipher
|
||||
// but is not what we want for sequential memory-harndess.
|
||||
memset(genmem,0,ZT_IDENTITY_GEN_MEMORY);
|
||||
Salsa20 s20(digest,256,(char *)digest + 32);
|
||||
Salsa20 s20(digest,(char *)digest + 32);
|
||||
s20.crypt20((char *)genmem,(char *)genmem,64);
|
||||
for(unsigned long i=64;i<ZT_IDENTITY_GEN_MEMORY;i+=64) {
|
||||
unsigned long k = i - 64;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_IDENTITY_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -1200,16 +1208,14 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
|
||||
|
||||
switch(addrType) {
|
||||
case 4: {
|
||||
InetAddress a(field(ptr,4),4,at<uint16_t>(ptr + 4));
|
||||
|
||||
bool redundant = false;
|
||||
if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0) {
|
||||
peer->setClusterOptimal(a);
|
||||
} else {
|
||||
redundant = peer->hasActivePathTo(now,a);
|
||||
}
|
||||
|
||||
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) {
|
||||
const InetAddress a(field(ptr,4),4,at<uint16_t>(ptr + 4));
|
||||
if (
|
||||
((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
|
||||
(!( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now,a)) )) && // not already known
|
||||
(RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) // should use path
|
||||
{
|
||||
if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0)
|
||||
peer->setClusterPreferred(a);
|
||||
if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||
peer->attemptToContactAt(tPtr,InetAddress(),a,now,false,0);
|
||||
@@ -1219,16 +1225,14 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
|
||||
}
|
||||
} break;
|
||||
case 6: {
|
||||
InetAddress a(field(ptr,16),16,at<uint16_t>(ptr + 16));
|
||||
|
||||
bool redundant = false;
|
||||
if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0) {
|
||||
peer->setClusterOptimal(a);
|
||||
} else {
|
||||
redundant = peer->hasActivePathTo(now,a);
|
||||
}
|
||||
|
||||
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) {
|
||||
const InetAddress a(field(ptr,16),16,at<uint16_t>(ptr + 16));
|
||||
if (
|
||||
((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
|
||||
(!( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now,a)) )) && // not already known
|
||||
(RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) // should use path
|
||||
{
|
||||
if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0)
|
||||
peer->setClusterPreferred(a);
|
||||
if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||
peer->attemptToContactAt(tPtr,InetAddress(),a,now,false,0);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_INCOMINGPACKET_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -302,7 +310,7 @@ InetAddress InetAddress::network() const
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool InetAddress::containsAddress(const InetAddress &addr) const
|
||||
{
|
||||
if (addr.ss_family == ss_family) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_INETADDRESS_HPP
|
||||
@@ -347,16 +355,16 @@ struct InetAddress : public sockaddr_storage
|
||||
*/
|
||||
InetAddress network() const;
|
||||
|
||||
#ifdef ZT_SDK
|
||||
/**
|
||||
#ifdef ZT_SDK
|
||||
/**
|
||||
* Test whether this IPv6 prefix matches the prefix of a given IPv6 address
|
||||
*
|
||||
* @param addr Address to check
|
||||
* @return True if this IPv6 prefix matches the prefix of a given IPv6 address
|
||||
*/
|
||||
bool isEqualPrefix(const InetAddress &addr) const;
|
||||
bool isEqualPrefix(const InetAddress &addr) const;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Test whether this IP/netmask contains this address
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_MAC_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
@@ -33,11 +41,13 @@ namespace ZeroTier {
|
||||
Membership::Membership() :
|
||||
_lastUpdatedMulticast(0),
|
||||
_lastPushedCom(0),
|
||||
_comRevocationThreshold(0)
|
||||
_comRevocationThreshold(0),
|
||||
_revocations(4),
|
||||
_remoteTags(4),
|
||||
_remoteCaps(4),
|
||||
_remoteCoos(4)
|
||||
{
|
||||
for(unsigned int i=0;i<ZT_MAX_NETWORK_TAGS;++i) _remoteTags[i] = &(_tagMem[i]);
|
||||
for(unsigned int i=0;i<ZT_MAX_NETWORK_CAPABILITIES;++i) _remoteCaps[i] = &(_capMem[i]);
|
||||
for(unsigned int i=0;i<ZT_MAX_CERTIFICATES_OF_OWNERSHIP;++i) _remoteCoos[i] = &(_cooMem[i]);
|
||||
resetPushState();
|
||||
}
|
||||
|
||||
void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force)
|
||||
@@ -47,18 +57,16 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const u
|
||||
const Capability *sendCap;
|
||||
if (localCapabilityIndex >= 0) {
|
||||
sendCap = &(nconf.capabilities[localCapabilityIndex]);
|
||||
if ( (_localCaps[localCapabilityIndex].id != sendCap->id()) || ((now - _localCaps[localCapabilityIndex].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
|
||||
_localCaps[localCapabilityIndex].lastPushed = now;
|
||||
_localCaps[localCapabilityIndex].id = sendCap->id();
|
||||
} else sendCap = (const Capability *)0;
|
||||
if ( ((now - _localCredLastPushed.cap[localCapabilityIndex]) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) )
|
||||
_localCredLastPushed.cap[localCapabilityIndex] = now;
|
||||
else sendCap = (const Capability *)0;
|
||||
} else sendCap = (const Capability *)0;
|
||||
|
||||
const Tag *sendTags[ZT_MAX_NETWORK_TAGS];
|
||||
unsigned int sendTagCount = 0;
|
||||
for(unsigned int t=0;t<nconf.tagCount;++t) {
|
||||
if ( (_localTags[t].id != nconf.tags[t].id()) || ((now - _localTags[t].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
|
||||
_localTags[t].lastPushed = now;
|
||||
_localTags[t].id = nconf.tags[t].id();
|
||||
if ( ((now - _localCredLastPushed.tag[t]) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
|
||||
_localCredLastPushed.tag[t] = now;
|
||||
sendTags[sendTagCount++] = &(nconf.tags[t]);
|
||||
}
|
||||
}
|
||||
@@ -66,9 +74,8 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const u
|
||||
const CertificateOfOwnership *sendCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
|
||||
unsigned int sendCooCount = 0;
|
||||
for(unsigned int c=0;c<nconf.certificateOfOwnershipCount;++c) {
|
||||
if ( (_localCoos[c].id != nconf.certificatesOfOwnership[c].id()) || ((now - _localCoos[c].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
|
||||
_localCoos[c].lastPushed = now;
|
||||
_localCoos[c].id = nconf.certificatesOfOwnership[c].id();
|
||||
if ( ((now - _localCredLastPushed.coo[c]) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
|
||||
_localCredLastPushed.coo[c] = now;
|
||||
sendCoos[sendCooCount++] = &(nconf.certificatesOfOwnership[c]);
|
||||
}
|
||||
}
|
||||
@@ -117,21 +124,15 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const u
|
||||
}
|
||||
}
|
||||
|
||||
const Tag *Membership::getTag(const NetworkConfig &nconf,const uint32_t id) const
|
||||
{
|
||||
const _RemoteCredential<Tag> *const *t = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)id,_RemoteCredentialComp<Tag>());
|
||||
return ( ((t != &(_remoteTags[ZT_MAX_NETWORK_CAPABILITIES]))&&((*t)->id == (uint64_t)id)) ? ((((*t)->lastReceived)&&(_isCredentialTimestampValid(nconf,**t))) ? &((*t)->credential) : (const Tag *)0) : (const Tag *)0);
|
||||
}
|
||||
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfMembership &com)
|
||||
{
|
||||
const uint64_t newts = com.timestamp().first;
|
||||
const uint64_t newts = com.timestamp();
|
||||
if (newts <= _comRevocationThreshold) {
|
||||
TRACE("addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (revoked)",com.issuedTo().toString().c_str(),com.networkId());
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
|
||||
const uint64_t oldts = _com.timestamp().first;
|
||||
const uint64_t oldts = _com.timestamp();
|
||||
if (newts < oldts) {
|
||||
TRACE("addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (older than current)",com.issuedTo().toString().c_str(),com.networkId());
|
||||
return ADD_REJECTED;
|
||||
@@ -154,84 +155,73 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
|
||||
}
|
||||
}
|
||||
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Tag &tag)
|
||||
// Template out addCredential() for many cred types to avoid copypasta
|
||||
template<typename C>
|
||||
static Membership::AddCredentialResult _addCredImpl(Hashtable<uint32_t,C> &remoteCreds,const Hashtable<uint64_t,uint64_t> &revocations,const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const C &cred)
|
||||
{
|
||||
_RemoteCredential<Tag> *const *htmp = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)tag.id(),_RemoteCredentialComp<Tag>());
|
||||
_RemoteCredential<Tag> *have = ((htmp != &(_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*htmp)->id == (uint64_t)tag.id())) ? *htmp : (_RemoteCredential<Tag> *)0;
|
||||
if (have) {
|
||||
if ( (!_isCredentialTimestampValid(nconf,*have)) || (have->credential.timestamp() > tag.timestamp()) ) {
|
||||
TRACE("addCredential(Tag) for %s on %.16llx REJECTED (revoked or too old)",tag.issuedTo().toString().c_str(),tag.networkId());
|
||||
return ADD_REJECTED;
|
||||
C *rc = remoteCreds.get(cred.id());
|
||||
if (rc) {
|
||||
if (rc->timestamp() > cred.timestamp()) {
|
||||
TRACE("addCredential(type==%d) for %s on %.16llx REJECTED (older than credential we have)",(int)C::credentialType(),cred.issuedTo().toString().c_str(),cred.networkId());
|
||||
return Membership::ADD_REJECTED;
|
||||
}
|
||||
if (have->credential == tag) {
|
||||
TRACE("addCredential(Tag) for %s on %.16llx ACCEPTED (redundant)",tag.issuedTo().toString().c_str(),tag.networkId());
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
if (*rc == cred) {
|
||||
//TRACE("addCredential(type==%d) for %s on %.16llx ACCEPTED (redundant)",(int)C::credentialType(),cred.issuedTo().toString().c_str(),cred.networkId());
|
||||
return Membership::ADD_ACCEPTED_REDUNDANT;
|
||||
}
|
||||
}
|
||||
|
||||
switch(tag.verify(RR,tPtr)) {
|
||||
const uint64_t *const rt = revocations.get(Membership::credentialKey(C::credentialType(),cred.id()));
|
||||
if ((rt)&&(*rt >= cred.timestamp())) {
|
||||
TRACE("addCredential(type==%d) for %s on %.16llx REJECTED (timestamp below revocation threshold)",(int)C::credentialType(),cred.issuedTo().toString().c_str(),cred.networkId());
|
||||
return Membership::ADD_REJECTED;
|
||||
}
|
||||
|
||||
switch(cred.verify(RR,tPtr)) {
|
||||
default:
|
||||
TRACE("addCredential(Tag) for %s on %.16llx REJECTED (invalid)",tag.issuedTo().toString().c_str(),tag.networkId());
|
||||
return ADD_REJECTED;
|
||||
TRACE("addCredential(type==%d) for %s on %.16llx REJECTED (invalid)",(int)C::credentialType(),cred.issuedTo().toString().c_str(),cred.networkId());
|
||||
return Membership::ADD_REJECTED;
|
||||
case 0:
|
||||
TRACE("addCredential(Tag) for %s on %.16llx ACCEPTED (new)",tag.issuedTo().toString().c_str(),tag.networkId());
|
||||
if (!have) have = _newTag(tag.id());
|
||||
have->lastReceived = RR->node->now();
|
||||
have->credential = tag;
|
||||
return ADD_ACCEPTED_NEW;
|
||||
TRACE("addCredential(type==%d) for %s on %.16llx ACCEPTED (new)",(int)C::credentialType(),cred.issuedTo().toString().c_str(),cred.networkId());
|
||||
if (!rc)
|
||||
rc = &(remoteCreds[cred.id()]);
|
||||
*rc = cred;
|
||||
return Membership::ADD_ACCEPTED_NEW;
|
||||
case 1:
|
||||
return ADD_DEFERRED_FOR_WHOIS;
|
||||
return Membership::ADD_DEFERRED_FOR_WHOIS;
|
||||
}
|
||||
}
|
||||
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Capability &cap)
|
||||
{
|
||||
_RemoteCredential<Capability> *const *htmp = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)cap.id(),_RemoteCredentialComp<Capability>());
|
||||
_RemoteCredential<Capability> *have = ((htmp != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*htmp)->id == (uint64_t)cap.id())) ? *htmp : (_RemoteCredential<Capability> *)0;
|
||||
if (have) {
|
||||
if ( (!_isCredentialTimestampValid(nconf,*have)) || (have->credential.timestamp() > cap.timestamp()) ) {
|
||||
TRACE("addCredential(Capability) for %s on %.16llx REJECTED (revoked or too old)",cap.issuedTo().toString().c_str(),cap.networkId());
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
if (have->credential == cap) {
|
||||
TRACE("addCredential(Capability) for %s on %.16llx ACCEPTED (redundant)",cap.issuedTo().toString().c_str(),cap.networkId());
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
}
|
||||
}
|
||||
|
||||
switch(cap.verify(RR,tPtr)) {
|
||||
default:
|
||||
TRACE("addCredential(Capability) for %s on %.16llx REJECTED (invalid)",cap.issuedTo().toString().c_str(),cap.networkId());
|
||||
return ADD_REJECTED;
|
||||
case 0:
|
||||
TRACE("addCredential(Capability) for %s on %.16llx ACCEPTED (new)",cap.issuedTo().toString().c_str(),cap.networkId());
|
||||
if (!have) have = _newCapability(cap.id());
|
||||
have->lastReceived = RR->node->now();
|
||||
have->credential = cap;
|
||||
return ADD_ACCEPTED_NEW;
|
||||
case 1:
|
||||
return ADD_DEFERRED_FOR_WHOIS;
|
||||
}
|
||||
}
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Tag &tag) { return _addCredImpl<Tag>(_remoteTags,_revocations,RR,tPtr,nconf,tag); }
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Capability &cap) { return _addCredImpl<Capability>(_remoteCaps,_revocations,RR,tPtr,nconf,cap); }
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo) { return _addCredImpl<CertificateOfOwnership>(_remoteCoos,_revocations,RR,tPtr,nconf,coo); }
|
||||
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Revocation &rev)
|
||||
{
|
||||
uint64_t *rt;
|
||||
switch(rev.verify(RR,tPtr)) {
|
||||
default:
|
||||
return ADD_REJECTED;
|
||||
case 0: {
|
||||
const uint64_t now = RR->node->now();
|
||||
switch(rev.type()) {
|
||||
const Credential::Type ct = rev.type();
|
||||
switch(ct) {
|
||||
case Credential::CREDENTIAL_TYPE_COM:
|
||||
if (rev.threshold() > _comRevocationThreshold) {
|
||||
_comRevocationThreshold = rev.threshold();
|
||||
return ADD_ACCEPTED_NEW;
|
||||
}
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
case Credential::CREDENTIAL_TYPE_CAPABILITY:
|
||||
case Credential::CREDENTIAL_TYPE_TAG:
|
||||
case Credential::CREDENTIAL_TYPE_COO:
|
||||
rt = &(_revocations[credentialKey(ct,rev.credentialId())]);
|
||||
if (*rt < rev.threshold()) {
|
||||
*rt = rev.threshold();
|
||||
return ADD_ACCEPTED_NEW;
|
||||
}
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
default:
|
||||
return ADD_REJECTED;
|
||||
case Revocation::CREDENTIAL_TYPE_COM:
|
||||
return (_revokeCom(rev) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT);
|
||||
case Revocation::CREDENTIAL_TYPE_CAPABILITY:
|
||||
return (_revokeCap(rev,now) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT);
|
||||
case Revocation::CREDENTIAL_TYPE_TAG:
|
||||
return (_revokeTag(rev,now) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT);
|
||||
case Revocation::CREDENTIAL_TYPE_COO:
|
||||
return (_revokeCoo(rev,now) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT);
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
@@ -239,157 +229,11 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
|
||||
}
|
||||
}
|
||||
|
||||
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo)
|
||||
void Membership::clean(const uint64_t now,const NetworkConfig &nconf)
|
||||
{
|
||||
_RemoteCredential<CertificateOfOwnership> *const *htmp = std::lower_bound(&(_remoteCoos[0]),&(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]),(uint64_t)coo.id(),_RemoteCredentialComp<CertificateOfOwnership>());
|
||||
_RemoteCredential<CertificateOfOwnership> *have = ((htmp != &(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]))&&((*htmp)->id == (uint64_t)coo.id())) ? *htmp : (_RemoteCredential<CertificateOfOwnership> *)0;
|
||||
if (have) {
|
||||
if ( (!_isCredentialTimestampValid(nconf,*have)) || (have->credential.timestamp() > coo.timestamp()) ) {
|
||||
TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx REJECTED (revoked or too old)",coo.issuedTo().toString().c_str(),coo.networkId());
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
if (have->credential == coo) {
|
||||
TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx ACCEPTED (redundant)",coo.issuedTo().toString().c_str(),coo.networkId());
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
}
|
||||
}
|
||||
|
||||
switch(coo.verify(RR,tPtr)) {
|
||||
default:
|
||||
TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx REJECTED (invalid)",coo.issuedTo().toString().c_str(),coo.networkId());
|
||||
return ADD_REJECTED;
|
||||
case 0:
|
||||
TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx ACCEPTED (new)",coo.issuedTo().toString().c_str(),coo.networkId());
|
||||
if (!have) have = _newCoo(coo.id());
|
||||
have->lastReceived = RR->node->now();
|
||||
have->credential = coo;
|
||||
return ADD_ACCEPTED_NEW;
|
||||
case 1:
|
||||
return ADD_DEFERRED_FOR_WHOIS;
|
||||
}
|
||||
}
|
||||
|
||||
Membership::_RemoteCredential<Tag> *Membership::_newTag(const uint64_t id)
|
||||
{
|
||||
_RemoteCredential<Tag> *t = NULL;
|
||||
uint64_t minlr = 0xffffffffffffffffULL;
|
||||
for(unsigned int i=0;i<ZT_MAX_NETWORK_TAGS;++i) {
|
||||
if (_remoteTags[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED) {
|
||||
t = _remoteTags[i];
|
||||
break;
|
||||
} else if (_remoteTags[i]->lastReceived <= minlr) {
|
||||
t = _remoteTags[i];
|
||||
minlr = _remoteTags[i]->lastReceived;
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
t->id = id;
|
||||
t->lastReceived = 0;
|
||||
t->revocationThreshold = 0;
|
||||
t->credential = Tag();
|
||||
}
|
||||
|
||||
std::sort(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),_RemoteCredentialComp<Tag>());
|
||||
return t;
|
||||
}
|
||||
|
||||
Membership::_RemoteCredential<Capability> *Membership::_newCapability(const uint64_t id)
|
||||
{
|
||||
_RemoteCredential<Capability> *c = NULL;
|
||||
uint64_t minlr = 0xffffffffffffffffULL;
|
||||
for(unsigned int i=0;i<ZT_MAX_NETWORK_CAPABILITIES;++i) {
|
||||
if (_remoteCaps[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED) {
|
||||
c = _remoteCaps[i];
|
||||
break;
|
||||
} else if (_remoteCaps[i]->lastReceived <= minlr) {
|
||||
c = _remoteCaps[i];
|
||||
minlr = _remoteCaps[i]->lastReceived;
|
||||
}
|
||||
}
|
||||
|
||||
if (c) {
|
||||
c->id = id;
|
||||
c->lastReceived = 0;
|
||||
c->revocationThreshold = 0;
|
||||
c->credential = Capability();
|
||||
}
|
||||
|
||||
std::sort(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),_RemoteCredentialComp<Capability>());
|
||||
return c;
|
||||
}
|
||||
|
||||
Membership::_RemoteCredential<CertificateOfOwnership> *Membership::_newCoo(const uint64_t id)
|
||||
{
|
||||
_RemoteCredential<CertificateOfOwnership> *c = NULL;
|
||||
uint64_t minlr = 0xffffffffffffffffULL;
|
||||
for(unsigned int i=0;i<ZT_MAX_CERTIFICATES_OF_OWNERSHIP;++i) {
|
||||
if (_remoteCoos[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED) {
|
||||
c = _remoteCoos[i];
|
||||
break;
|
||||
} else if (_remoteCoos[i]->lastReceived <= minlr) {
|
||||
c = _remoteCoos[i];
|
||||
minlr = _remoteCoos[i]->lastReceived;
|
||||
}
|
||||
}
|
||||
|
||||
if (c) {
|
||||
c->id = id;
|
||||
c->lastReceived = 0;
|
||||
c->revocationThreshold = 0;
|
||||
c->credential = CertificateOfOwnership();
|
||||
}
|
||||
|
||||
std::sort(&(_remoteCoos[0]),&(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]),_RemoteCredentialComp<CertificateOfOwnership>());
|
||||
return c;
|
||||
}
|
||||
|
||||
bool Membership::_revokeCom(const Revocation &rev)
|
||||
{
|
||||
if (rev.threshold() > _comRevocationThreshold) {
|
||||
_comRevocationThreshold = rev.threshold();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Membership::_revokeCap(const Revocation &rev,const uint64_t now)
|
||||
{
|
||||
_RemoteCredential<Capability> *const *htmp = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)rev.credentialId(),_RemoteCredentialComp<Capability>());
|
||||
_RemoteCredential<Capability> *have = ((htmp != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteCredential<Capability> *)0;
|
||||
if (!have) have = _newCapability(rev.credentialId());
|
||||
if (rev.threshold() > have->revocationThreshold) {
|
||||
have->lastReceived = now;
|
||||
have->revocationThreshold = rev.threshold();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Membership::_revokeTag(const Revocation &rev,const uint64_t now)
|
||||
{
|
||||
_RemoteCredential<Tag> *const *htmp = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)rev.credentialId(),_RemoteCredentialComp<Tag>());
|
||||
_RemoteCredential<Tag> *have = ((htmp != &(_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteCredential<Tag> *)0;
|
||||
if (!have) have = _newTag(rev.credentialId());
|
||||
if (rev.threshold() > have->revocationThreshold) {
|
||||
have->lastReceived = now;
|
||||
have->revocationThreshold = rev.threshold();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Membership::_revokeCoo(const Revocation &rev,const uint64_t now)
|
||||
{
|
||||
_RemoteCredential<CertificateOfOwnership> *const *htmp = std::lower_bound(&(_remoteCoos[0]),&(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]),(uint64_t)rev.credentialId(),_RemoteCredentialComp<CertificateOfOwnership>());
|
||||
_RemoteCredential<CertificateOfOwnership> *have = ((htmp != &(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteCredential<CertificateOfOwnership> *)0;
|
||||
if (!have) have = _newCoo(rev.credentialId());
|
||||
if (rev.threshold() > have->revocationThreshold) {
|
||||
have->lastReceived = now;
|
||||
have->revocationThreshold = rev.threshold();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
_cleanCredImpl<Tag>(nconf,_remoteTags);
|
||||
_cleanCredImpl<Capability>(nconf,_remoteCaps);
|
||||
_cleanCredImpl<CertificateOfOwnership>(nconf,_remoteCoos);
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_MEMBERSHIP_HPP
|
||||
@@ -23,6 +31,8 @@
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Credential.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "CertificateOfMembership.hpp"
|
||||
#include "Capability.hpp"
|
||||
#include "Tag.hpp"
|
||||
@@ -45,35 +55,6 @@ class Network;
|
||||
*/
|
||||
class Membership
|
||||
{
|
||||
private:
|
||||
template<typename T>
|
||||
struct _RemoteCredential
|
||||
{
|
||||
_RemoteCredential() : id(ZT_MEMBERSHIP_CRED_ID_UNUSED),lastReceived(0),revocationThreshold(0) {}
|
||||
uint64_t id;
|
||||
uint64_t lastReceived; // last time we got this credential
|
||||
uint64_t revocationThreshold; // credentials before this time are invalid
|
||||
T credential;
|
||||
inline bool operator<(const _RemoteCredential &c) const { return (id < c.id); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _RemoteCredentialComp
|
||||
{
|
||||
inline bool operator()(const _RemoteCredential<T> *a,const _RemoteCredential<T> *b) const { return (a->id < b->id); }
|
||||
inline bool operator()(const uint64_t a,const _RemoteCredential<T> *b) const { return (a < b->id); }
|
||||
inline bool operator()(const _RemoteCredential<T> *a,const uint64_t b) const { return (a->id < b); }
|
||||
inline bool operator()(const uint64_t a,const uint64_t b) const { return (a < b); }
|
||||
};
|
||||
|
||||
// Used to track push state for network config tags[] and capabilities[] entries
|
||||
struct _LocalCredentialPushState
|
||||
{
|
||||
_LocalCredentialPushState() : lastPushed(0),id(0) {}
|
||||
uint64_t lastPushed; // last time we sent our own copy of this credential
|
||||
uint64_t id;
|
||||
};
|
||||
|
||||
public:
|
||||
enum AddCredentialResult
|
||||
{
|
||||
@@ -83,72 +64,6 @@ public:
|
||||
ADD_DEFERRED_FOR_WHOIS
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterator to scan forward through capabilities in ascending order of ID
|
||||
*/
|
||||
class CapabilityIterator
|
||||
{
|
||||
public:
|
||||
CapabilityIterator(const Membership &m,const NetworkConfig &nconf) :
|
||||
_m(&m),
|
||||
_c(&nconf),
|
||||
_i(&(m._remoteCaps[0])) {}
|
||||
|
||||
inline const Capability *next()
|
||||
{
|
||||
for(;;) {
|
||||
if ((_i != &(_m->_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*_i)->id != ZT_MEMBERSHIP_CRED_ID_UNUSED)) {
|
||||
const Capability *tmp = &((*_i)->credential);
|
||||
if (_m->_isCredentialTimestampValid(*_c,**_i)) {
|
||||
++_i;
|
||||
return tmp;
|
||||
} else ++_i;
|
||||
} else {
|
||||
return (const Capability *)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const Membership *_m;
|
||||
const NetworkConfig *_c;
|
||||
const _RemoteCredential<Capability> *const *_i;
|
||||
};
|
||||
friend class CapabilityIterator;
|
||||
|
||||
/**
|
||||
* Iterator to scan forward through tags in ascending order of ID
|
||||
*/
|
||||
class TagIterator
|
||||
{
|
||||
public:
|
||||
TagIterator(const Membership &m,const NetworkConfig &nconf) :
|
||||
_m(&m),
|
||||
_c(&nconf),
|
||||
_i(&(m._remoteTags[0])) {}
|
||||
|
||||
inline const Tag *next()
|
||||
{
|
||||
for(;;) {
|
||||
if ((_i != &(_m->_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*_i)->id != ZT_MEMBERSHIP_CRED_ID_UNUSED)) {
|
||||
const Tag *tmp = &((*_i)->credential);
|
||||
if (_m->_isCredentialTimestampValid(*_c,**_i)) {
|
||||
++_i;
|
||||
return tmp;
|
||||
} else ++_i;
|
||||
} else {
|
||||
return (const Tag *)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const Membership *_m;
|
||||
const NetworkConfig *_c;
|
||||
const _RemoteCredential<Tag> *const *_i;
|
||||
};
|
||||
friend class TagIterator;
|
||||
|
||||
Membership();
|
||||
|
||||
/**
|
||||
@@ -168,19 +83,19 @@ public:
|
||||
void pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force);
|
||||
|
||||
/**
|
||||
* Check whether we should push MULTICAST_LIKEs to this peer
|
||||
* Check whether we should push MULTICAST_LIKEs to this peer, and update last sent time if true
|
||||
*
|
||||
* @param now Current time
|
||||
* @return True if we should update multicasts
|
||||
*/
|
||||
inline bool shouldLikeMulticasts(const uint64_t now) const { return ((now - _lastUpdatedMulticast) >= ZT_MULTICAST_ANNOUNCE_PERIOD); }
|
||||
|
||||
/**
|
||||
* Set time we last updated multicasts for this peer
|
||||
*
|
||||
* @param now Current time
|
||||
*/
|
||||
inline void likingMulticasts(const uint64_t now) { _lastUpdatedMulticast = now; }
|
||||
inline bool multicastLikeGate(const uint64_t now)
|
||||
{
|
||||
if ((now - _lastUpdatedMulticast) >= ZT_MULTICAST_ANNOUNCE_PERIOD) {
|
||||
_lastUpdatedMulticast = now;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the peer represented by this Membership should be allowed on this network at all
|
||||
@@ -190,10 +105,8 @@ public:
|
||||
*/
|
||||
inline bool isAllowedOnNetwork(const NetworkConfig &nconf) const
|
||||
{
|
||||
if (nconf.isPublic())
|
||||
return true;
|
||||
if (_com.timestamp().first <= _comRevocationThreshold)
|
||||
return false;
|
||||
if (nconf.isPublic()) return true;
|
||||
if (_com.timestamp() <= _comRevocationThreshold) return false;
|
||||
return nconf.com.agreesWith(_com);
|
||||
}
|
||||
|
||||
@@ -208,21 +121,28 @@ public:
|
||||
template<typename T>
|
||||
inline bool hasCertificateOfOwnershipFor(const NetworkConfig &nconf,const T &r) const
|
||||
{
|
||||
for(unsigned int i=0;i<ZT_MAX_CERTIFICATES_OF_OWNERSHIP;++i) {
|
||||
if (_remoteCoos[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED)
|
||||
break;
|
||||
if ((_isCredentialTimestampValid(nconf,*_remoteCoos[i]))&&(_remoteCoos[i]->credential.owns(r)))
|
||||
uint32_t *k = (uint32_t *)0;
|
||||
CertificateOfOwnership *v = (CertificateOfOwnership *)0;
|
||||
Hashtable< uint32_t,CertificateOfOwnership >::Iterator i(*(const_cast< Hashtable< uint32_t,CertificateOfOwnership> *>(&_remoteCoos)));
|
||||
while (i.next(k,v)) {
|
||||
if (_isCredentialTimestampValid(nconf,*v)&&(v->owns(r)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a remote member's tag (if we have it)
|
||||
*
|
||||
* @param nconf Network configuration
|
||||
* @param id Tag ID
|
||||
* @return Pointer to tag or NULL if not found
|
||||
*/
|
||||
const Tag *getTag(const NetworkConfig &nconf,const uint32_t id) const;
|
||||
inline const Tag *getTag(const NetworkConfig &nconf,const uint32_t id) const
|
||||
{
|
||||
const Tag *const t = _remoteTags.get(id);
|
||||
return (((t)&&(_isCredentialTimestampValid(nconf,*t))) ? t : (Tag *)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and add a credential if signature is okay and it's otherwise good
|
||||
@@ -242,29 +162,59 @@ public:
|
||||
/**
|
||||
* Validate and add a credential if signature is okay and it's otherwise good
|
||||
*/
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Revocation &rev);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo);
|
||||
|
||||
/**
|
||||
* Validate and add a credential if signature is okay and it's otherwise good
|
||||
*/
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Revocation &rev);
|
||||
|
||||
/**
|
||||
* Clean internal databases of stale entries
|
||||
*
|
||||
* @param now Current time
|
||||
* @param nconf Current network configuration
|
||||
*/
|
||||
void clean(const uint64_t now,const NetworkConfig &nconf);
|
||||
|
||||
/**
|
||||
* Reset last pushed time for local credentials
|
||||
*
|
||||
* This is done when we update our network configuration and our credentials have changed
|
||||
*/
|
||||
inline void resetPushState()
|
||||
{
|
||||
_lastPushedCom = 0;
|
||||
memset(&_localCredLastPushed,0,sizeof(_localCredLastPushed));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a key for the internal use in indexing credentials by type and credential ID
|
||||
*/
|
||||
static uint64_t credentialKey(const Credential::Type &t,const uint32_t i) { return (((uint64_t)t << 32) | (uint64_t)i); }
|
||||
|
||||
private:
|
||||
_RemoteCredential<Tag> *_newTag(const uint64_t id);
|
||||
_RemoteCredential<Capability> *_newCapability(const uint64_t id);
|
||||
_RemoteCredential<CertificateOfOwnership> *_newCoo(const uint64_t id);
|
||||
bool _revokeCom(const Revocation &rev);
|
||||
bool _revokeCap(const Revocation &rev,const uint64_t now);
|
||||
bool _revokeTag(const Revocation &rev,const uint64_t now);
|
||||
bool _revokeCoo(const Revocation &rev,const uint64_t now);
|
||||
template<typename C>
|
||||
inline bool _isCredentialTimestampValid(const NetworkConfig &nconf,const C &remoteCredential) const
|
||||
{
|
||||
const uint64_t ts = remoteCredential.timestamp();
|
||||
if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
|
||||
const uint64_t *threshold = _revocations.get(credentialKey(C::credentialType(),remoteCredential.id()));
|
||||
return ((!threshold)||(ts > *threshold));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
inline bool _isCredentialTimestampValid(const NetworkConfig &nconf,const _RemoteCredential<C> &remoteCredential) const
|
||||
void _cleanCredImpl(const NetworkConfig &nconf,Hashtable<uint32_t,C> &remoteCreds)
|
||||
{
|
||||
if (!remoteCredential.lastReceived)
|
||||
return false;
|
||||
const uint64_t ts = remoteCredential.credential.timestamp();
|
||||
return ( (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) && (ts > remoteCredential.revocationThreshold) );
|
||||
uint32_t *k = (uint32_t *)0;
|
||||
C *v = (C *)0;
|
||||
typename Hashtable<uint32_t,C>::Iterator i(remoteCreds);
|
||||
while (i.next(k,v)) {
|
||||
if (!_isCredentialTimestampValid(nconf,*v))
|
||||
remoteCreds.erase(*k);
|
||||
}
|
||||
}
|
||||
|
||||
// Last time we pushed MULTICAST_LIKE(s)
|
||||
@@ -279,20 +229,50 @@ private:
|
||||
// Remote member's latest network COM
|
||||
CertificateOfMembership _com;
|
||||
|
||||
// Sorted (in ascending order of ID) arrays of pointers to remote credentials
|
||||
_RemoteCredential<Tag> *_remoteTags[ZT_MAX_NETWORK_TAGS];
|
||||
_RemoteCredential<Capability> *_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES];
|
||||
_RemoteCredential<CertificateOfOwnership> *_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
|
||||
// Revocations by credentialKey()
|
||||
Hashtable< uint64_t,uint64_t > _revocations;
|
||||
|
||||
// This is the RAM allocated for remote credential cache objects
|
||||
_RemoteCredential<Tag> _tagMem[ZT_MAX_NETWORK_TAGS];
|
||||
_RemoteCredential<Capability> _capMem[ZT_MAX_NETWORK_CAPABILITIES];
|
||||
_RemoteCredential<CertificateOfOwnership> _cooMem[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
|
||||
// Remote credentials that we have received from this member (and that are valid)
|
||||
Hashtable< uint32_t,Tag > _remoteTags;
|
||||
Hashtable< uint32_t,Capability > _remoteCaps;
|
||||
Hashtable< uint32_t,CertificateOfOwnership > _remoteCoos;
|
||||
|
||||
// Local credential push state tracking
|
||||
_LocalCredentialPushState _localTags[ZT_MAX_NETWORK_TAGS];
|
||||
_LocalCredentialPushState _localCaps[ZT_MAX_NETWORK_CAPABILITIES];
|
||||
_LocalCredentialPushState _localCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
|
||||
// Time we last pushed our local credentials to this member
|
||||
struct {
|
||||
uint64_t tag[ZT_MAX_NETWORK_TAGS];
|
||||
uint64_t cap[ZT_MAX_NETWORK_CAPABILITIES];
|
||||
uint64_t coo[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
|
||||
} _localCredLastPushed;
|
||||
|
||||
public:
|
||||
class CapabilityIterator
|
||||
{
|
||||
public:
|
||||
CapabilityIterator(Membership &m,const NetworkConfig &nconf) :
|
||||
_hti(m._remoteCaps),
|
||||
_k((uint32_t *)0),
|
||||
_c((Capability *)0),
|
||||
_m(m),
|
||||
_nconf(nconf)
|
||||
{
|
||||
}
|
||||
|
||||
inline Capability *next()
|
||||
{
|
||||
while (_hti.next(_k,_c)) {
|
||||
if (_m._isCredentialTimestampValid(_nconf,*_c))
|
||||
return _c;
|
||||
}
|
||||
return (Capability *)0;
|
||||
}
|
||||
|
||||
private:
|
||||
Hashtable< uint32_t,Capability >::Iterator _hti;
|
||||
uint32_t *_k;
|
||||
Capability *_c;
|
||||
Membership &_m;
|
||||
const NetworkConfig &_nconf;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_MULTICASTGROUP_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_MULTICASTER_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_MUTEX_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -534,9 +542,9 @@ static _doZtFilterResult _doZtFilter(
|
||||
}
|
||||
if (inbound) {
|
||||
if (membership) {
|
||||
if ((src)&&(membership->hasCertificateOfOwnershipFor(nconf,src)))
|
||||
if ((src)&&(membership->hasCertificateOfOwnershipFor<InetAddress>(nconf,src)))
|
||||
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
||||
if (membership->hasCertificateOfOwnershipFor(nconf,macSource))
|
||||
if (membership->hasCertificateOfOwnershipFor<MAC>(nconf,macSource))
|
||||
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED;
|
||||
}
|
||||
} else {
|
||||
@@ -729,7 +737,8 @@ Network::~Network()
|
||||
|
||||
char n[128];
|
||||
if (_destroyed) {
|
||||
RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
|
||||
// This is done in Node::leave() so we can pass tPtr
|
||||
//RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
|
||||
Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
|
||||
RR->node->dataStoreDelete((void *)0,n);
|
||||
} else {
|
||||
@@ -993,6 +1002,9 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg)
|
||||
|
||||
uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr)
|
||||
{
|
||||
if (_destroyed)
|
||||
return 0;
|
||||
|
||||
const unsigned int start = ptr;
|
||||
|
||||
ptr += 8; // skip network ID, which is already obviously known
|
||||
@@ -1140,24 +1152,37 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
||||
|
||||
int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk)
|
||||
{
|
||||
if (_destroyed)
|
||||
return 0;
|
||||
|
||||
// _lock is NOT locked when this is called
|
||||
try {
|
||||
if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != _id))
|
||||
return 0;
|
||||
return 0; // invalid config that is not for us or not for this network
|
||||
if (_config == nconf)
|
||||
return 1; // OK config, but duplicate of what we already have
|
||||
|
||||
ZT_VirtualNetworkConfig ctmp;
|
||||
bool oldPortInitialized;
|
||||
{
|
||||
{ // do things that require lock here, but unlock before calling callbacks
|
||||
Mutex::Lock _l(_lock);
|
||||
|
||||
_config = nconf;
|
||||
_lastConfigUpdate = RR->node->now();
|
||||
_netconfFailure = NETCONF_FAILURE_NONE;
|
||||
|
||||
oldPortInitialized = _portInitialized;
|
||||
_portInitialized = true;
|
||||
|
||||
_externalConfig(&ctmp);
|
||||
|
||||
Address *a = (Address *)0;
|
||||
Membership *m = (Membership *)0;
|
||||
Hashtable<Address,Membership>::Iterator i(_memberships);
|
||||
while (i.next(a,m))
|
||||
m->resetPushState();
|
||||
}
|
||||
|
||||
_portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
|
||||
|
||||
if (saveToDisk) {
|
||||
@@ -1180,6 +1205,9 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
|
||||
|
||||
void Network::requestConfiguration(void *tPtr)
|
||||
{
|
||||
if (_destroyed)
|
||||
return;
|
||||
|
||||
/* ZeroTier addresses can't begin with 0xff, so this is used to mark controllerless
|
||||
* network IDs. Controllerless network IDs only support unicast IPv6 using the 6plane
|
||||
* addressing scheme and have the following format: 0xffSSSSEEEE000000 where SSSS
|
||||
@@ -1299,10 +1327,9 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer)
|
||||
if ( (_config.isPublic()) || ((m)&&(m->isAllowedOnNetwork(_config))) ) {
|
||||
if (!m)
|
||||
m = &(_membership(peer->address()));
|
||||
if (m->shouldLikeMulticasts(now)) {
|
||||
if (m->multicastLikeGate(now)) {
|
||||
m->pushCredentials(RR,tPtr,now,peer->address(),_config,-1,false);
|
||||
_announceMulticastGroupsTo(tPtr,peer->address(),_allMulticastGroups());
|
||||
m->likingMulticasts(now);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1338,6 +1365,7 @@ void Network::clean()
|
||||
while (i.next(a,m)) {
|
||||
if (!RR->topology->getPeerNoCache(*a))
|
||||
_memberships.erase(*a);
|
||||
else m->clean(now,_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1546,8 +1574,7 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu
|
||||
}
|
||||
|
||||
// Make sure that all "network anchors" have Membership records so we will
|
||||
// push multicasts to them. Note that _membership() also does this but in a
|
||||
// piecemeal on-demand fashion.
|
||||
// push multicasts to them.
|
||||
const std::vector<Address> anchors(_config.anchors());
|
||||
for(std::vector<Address>::const_iterator a(anchors.begin());a!=anchors.end();++a)
|
||||
_membership(*a);
|
||||
@@ -1559,11 +1586,8 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu
|
||||
Hashtable<Address,Membership>::Iterator i(_memberships);
|
||||
while (i.next(a,m)) {
|
||||
m->pushCredentials(RR,tPtr,now,*a,_config,-1,false);
|
||||
if ( ((newMulticastGroup)||(m->shouldLikeMulticasts(now))) && (m->isAllowedOnNetwork(_config)) ) {
|
||||
if (!newMulticastGroup)
|
||||
m->likingMulticasts(now);
|
||||
if ( ( m->multicastLikeGate(now) || (newMulticastGroup) ) && (m->isAllowedOnNetwork(_config)) )
|
||||
_announceMulticastGroupsTo(tPtr,*a,groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_NETWORK_HPP
|
||||
@@ -344,9 +352,8 @@ public:
|
||||
/**
|
||||
* Destroy this network
|
||||
*
|
||||
* This causes the network to disable itself, destroy its tap device, and on
|
||||
* delete to delete all trace of itself on disk and remove any persistent tap
|
||||
* device instances. Call this when a network is being removed from the system.
|
||||
* This sets the network to completely remove itself on delete. This also prevents the
|
||||
* call of the normal port shutdown event on delete.
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
@@ -364,7 +371,7 @@ public:
|
||||
/**
|
||||
* @return Externally usable pointer-to-pointer exported via the core API
|
||||
*/
|
||||
inline void **userPtr() throw() { return &_uPtr; }
|
||||
inline void **userPtr() { return &_uPtr; }
|
||||
|
||||
private:
|
||||
ZT_VirtualNetworkStatus _status() const;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_NETWORKCONFIG_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_NETWORKCONFIGMASTER_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -50,7 +58,6 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint6
|
||||
_RR(this),
|
||||
RR(&_RR),
|
||||
_uPtr(uptr),
|
||||
_prngStreamPtr(0),
|
||||
_now(now),
|
||||
_lastPingCheck(0),
|
||||
_lastHousekeepingRun(0)
|
||||
@@ -59,19 +66,14 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint6
|
||||
throw std::runtime_error("callbacks struct version mismatch");
|
||||
memcpy(&_cb,callbacks,sizeof(ZT_Node_Callbacks));
|
||||
|
||||
Utils::getSecureRandom((void *)_prngState,sizeof(_prngState));
|
||||
|
||||
_online = false;
|
||||
|
||||
memset(_expectingRepliesToBucketPtr,0,sizeof(_expectingRepliesToBucketPtr));
|
||||
memset(_expectingRepliesTo,0,sizeof(_expectingRepliesTo));
|
||||
memset(_lastIdentityVerification,0,sizeof(_lastIdentityVerification));
|
||||
|
||||
// Use Salsa20 alone as a high-quality non-crypto PRNG
|
||||
char foo[32];
|
||||
Utils::getSecureRandom(foo,32);
|
||||
_prng.init(foo,256,foo);
|
||||
memset(_prngStream,0,sizeof(_prngStream));
|
||||
_prng.crypt12(_prngStream,_prngStream,sizeof(_prngStream));
|
||||
|
||||
std::string idtmp(dataStoreGet(tptr,"identity.secret"));
|
||||
if ((!idtmp.length())||(!RR->identity.fromString(idtmp))||(!RR->identity.hasPrivate())) {
|
||||
TRACE("identity.secret not found, generating...");
|
||||
@@ -305,26 +307,35 @@ ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr)
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
SharedPtr<Network> nw = _network(nwid);
|
||||
if(!nw)
|
||||
_networks.push_back(std::pair< uint64_t,SharedPtr<Network> >(nwid,SharedPtr<Network>(new Network(RR,tptr,nwid,uptr))));
|
||||
std::sort(_networks.begin(),_networks.end()); // will sort by nwid since it's the first in a pair<>
|
||||
if(!nw) {
|
||||
const std::pair< uint64_t,SharedPtr<Network> > nn(nwid,SharedPtr<Network>(new Network(RR,tptr,nwid,uptr)));
|
||||
_networks.insert(std::upper_bound(_networks.begin(),_networks.end(),nn),nn);
|
||||
}
|
||||
return ZT_RESULT_OK;
|
||||
}
|
||||
|
||||
ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr)
|
||||
{
|
||||
ZT_VirtualNetworkConfig ctmp;
|
||||
std::vector< std::pair< uint64_t,SharedPtr<Network> > > newn;
|
||||
void **nUserPtr = (void **)0;
|
||||
Mutex::Lock _l(_networks_m);
|
||||
|
||||
for(std::vector< std::pair< uint64_t,SharedPtr<Network> > >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
|
||||
if (n->first != nwid)
|
||||
if (n->first != nwid) {
|
||||
newn.push_back(*n);
|
||||
else {
|
||||
} else {
|
||||
if (uptr)
|
||||
*uptr = n->second->userPtr();
|
||||
*uptr = *n->second->userPtr();
|
||||
n->second->destroy();
|
||||
nUserPtr = n->second->userPtr();
|
||||
}
|
||||
}
|
||||
_networks.swap(newn);
|
||||
|
||||
if (nUserPtr)
|
||||
RR->node->configureVirtualNetworkPort(tptr,nwid,nUserPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
|
||||
|
||||
return ZT_RESULT_OK;
|
||||
}
|
||||
|
||||
@@ -398,17 +409,17 @@ ZT_PeerList *Node::peers() const
|
||||
p->latency = pi->second->latency();
|
||||
p->role = RR->topology->role(pi->second->identity().address());
|
||||
|
||||
std::vector< std::pair< SharedPtr<Path>,bool > > paths(pi->second->paths(_now));
|
||||
std::vector< SharedPtr<Path> > paths(pi->second->paths(_now));
|
||||
SharedPtr<Path> bestp(pi->second->getBestPath(_now,false));
|
||||
p->pathCount = 0;
|
||||
for(std::vector< std::pair< SharedPtr<Path>,bool > >::iterator path(paths.begin());path!=paths.end();++path) {
|
||||
memcpy(&(p->paths[p->pathCount].address),&(path->first->address()),sizeof(struct sockaddr_storage));
|
||||
p->paths[p->pathCount].lastSend = path->first->lastOut();
|
||||
p->paths[p->pathCount].lastReceive = path->first->lastIn();
|
||||
p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust(path->first->address());
|
||||
p->paths[p->pathCount].linkQuality = (int)path->first->linkQuality();
|
||||
p->paths[p->pathCount].expired = path->second;
|
||||
p->paths[p->pathCount].preferred = (path->first == bestp) ? 1 : 0;
|
||||
for(std::vector< SharedPtr<Path> >::iterator path(paths.begin());path!=paths.end();++path) {
|
||||
memcpy(&(p->paths[p->pathCount].address),&((*path)->address()),sizeof(struct sockaddr_storage));
|
||||
p->paths[p->pathCount].lastSend = (*path)->lastOut();
|
||||
p->paths[p->pathCount].lastReceive = (*path)->lastIn();
|
||||
p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address());
|
||||
p->paths[p->pathCount].linkQuality = (int)(*path)->linkQuality();
|
||||
p->paths[p->pathCount].expired = 0;
|
||||
p->paths[p->pathCount].preferred = ((*path) == bestp) ? 1 : 0;
|
||||
++p->pathCount;
|
||||
}
|
||||
}
|
||||
@@ -487,7 +498,8 @@ int Node::sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *d
|
||||
void Node::setNetconfMaster(void *networkControllerInstance)
|
||||
{
|
||||
RR->localNetworkController = reinterpret_cast<NetworkController *>(networkControllerInstance);
|
||||
RR->localNetworkController->init(RR->identity,this);
|
||||
if (networkControllerInstance)
|
||||
RR->localNetworkController->init(RR->identity,this);
|
||||
}
|
||||
|
||||
ZT_ResultCode Node::circuitTestBegin(void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *))
|
||||
@@ -692,10 +704,14 @@ void Node::postTrace(const char *module,unsigned int line,const char *fmt,...)
|
||||
|
||||
uint64_t Node::prng()
|
||||
{
|
||||
unsigned int p = (++_prngStreamPtr % ZT_NODE_PRNG_BUF_SIZE);
|
||||
if (!p)
|
||||
_prng.crypt12(_prngStream,_prngStream,sizeof(_prngStream));
|
||||
return _prngStream[p];
|
||||
// https://en.wikipedia.org/wiki/Xorshift#xorshift.2B
|
||||
uint64_t x = _prngState[0];
|
||||
const uint64_t y = _prngState[1];
|
||||
_prngState[0] = y;
|
||||
x ^= x << 23;
|
||||
const uint64_t z = x ^ y ^ (x >> 17) ^ (y >> 26);
|
||||
_prngState[1] = z;
|
||||
return z + y;
|
||||
}
|
||||
|
||||
void Node::postCircuitTestReport(const ZT_CircuitTestReport *report)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_NODE_HPP
|
||||
@@ -50,9 +58,6 @@
|
||||
#define ZT_EXPECTING_REPLIES_BUCKET_MASK1 255
|
||||
#define ZT_EXPECTING_REPLIES_BUCKET_MASK2 31
|
||||
|
||||
// Size of PRNG stream buffer
|
||||
#define ZT_NODE_PRNG_BUF_SIZE 64
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class World;
|
||||
@@ -312,13 +317,10 @@ private:
|
||||
|
||||
Mutex _backgroundTasksLock;
|
||||
|
||||
unsigned int _prngStreamPtr;
|
||||
Salsa20 _prng;
|
||||
uint64_t _prngStream[ZT_NODE_PRNG_BUF_SIZE]; // repeatedly encrypted with _prng to yield a high-quality non-crypto PRNG stream
|
||||
|
||||
uint64_t _now;
|
||||
uint64_t _lastPingCheck;
|
||||
uint64_t _lastHousekeepingRun;
|
||||
volatile uint64_t _prngState[2];
|
||||
bool _online;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_NONCOPYABLE_HPP__
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_OUTBOUNDMULTICAST_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -24,6 +32,13 @@
|
||||
|
||||
#include "Packet.hpp"
|
||||
|
||||
#ifdef ZT_USE_X64_ASM_SALSA2012
|
||||
#include "../ext/x64-salsa2012-asm/salsa2012.h"
|
||||
#endif
|
||||
#ifdef ZT_USE_ARM32_NEON_ASM_SALSA2012
|
||||
#include "../ext/arm32-neon-salsa2012-asm/salsa2012.h"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define FORCE_INLINE static __forceinline
|
||||
#include <intrin.h>
|
||||
@@ -36,6 +51,34 @@
|
||||
namespace ZeroTier {
|
||||
|
||||
/************************************************************************** */
|
||||
|
||||
/* Set up macros for fast single-pass ASM Salsa20/12 crypto, if we have it */
|
||||
|
||||
// x64 SSE crypto
|
||||
#ifdef ZT_USE_X64_ASM_SALSA2012
|
||||
#define ZT_HAS_FAST_CRYPTO() (true)
|
||||
#define ZT_FAST_SINGLE_PASS_SALSA2012(b,l,n,k) zt_salsa2012_amd64_xmm6(reinterpret_cast<unsigned char *>(b),(l),reinterpret_cast<const unsigned char *>(n),reinterpret_cast<const unsigned char *>(k))
|
||||
#endif
|
||||
|
||||
// ARM (32-bit) NEON crypto (must be detected)
|
||||
#ifdef ZT_USE_ARM32_NEON_ASM_SALSA2012
|
||||
class _FastCryptoChecker
|
||||
{
|
||||
public:
|
||||
_FastCryptoChecker() : canHas(zt_arm_has_neon()) {}
|
||||
bool canHas;
|
||||
};
|
||||
static const _FastCryptoChecker _ZT_FAST_CRYPTO_CHECK;
|
||||
#define ZT_HAS_FAST_CRYPTO() (_ZT_FAST_CRYPTO_CHECK.canHas)
|
||||
#define ZT_FAST_SINGLE_PASS_SALSA2012(b,l,n,k) zt_salsa2012_armneon3_xor(reinterpret_cast<unsigned char *>(b),(const unsigned char *)0,(l),reinterpret_cast<const unsigned char *>(n),reinterpret_cast<const unsigned char *>(k))
|
||||
#endif
|
||||
|
||||
// No fast crypto available
|
||||
#ifndef ZT_HAS_FAST_CRYPTO
|
||||
#define ZT_HAS_FAST_CRYPTO() (false)
|
||||
#define ZT_FAST_SINGLE_PASS_SALSA2012(b,l,n,k) {}
|
||||
#endif
|
||||
|
||||
/************************************************************************** */
|
||||
|
||||
/* LZ4 is shipped encapsulated into Packet in an anonymous namespace.
|
||||
@@ -1064,7 +1107,7 @@ const char *Packet::errorString(ErrorCode e)
|
||||
|
||||
void Packet::armor(const void *key,bool encryptPayload,unsigned int counter)
|
||||
{
|
||||
uint8_t mangledKey[32],macKey[32],mac[16];
|
||||
uint8_t mangledKey[32];
|
||||
uint8_t *const data = reinterpret_cast<uint8_t *>(unsafeData());
|
||||
|
||||
// Mask least significant 3 bits of packet ID with counter to embed packet send counter for QoS use
|
||||
@@ -1074,23 +1117,35 @@ void Packet::armor(const void *key,bool encryptPayload,unsigned int counter)
|
||||
setCipher(encryptPayload ? ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 : ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE);
|
||||
|
||||
_salsa20MangleKey((const unsigned char *)key,mangledKey);
|
||||
Salsa20 s20(mangledKey,256,data + ZT_PACKET_IDX_IV);
|
||||
|
||||
// MAC key is always the first 32 bytes of the Salsa20 key stream
|
||||
// This is the same construction DJB's NaCl library uses
|
||||
s20.crypt12(ZERO_KEY,macKey,sizeof(macKey));
|
||||
|
||||
uint8_t *const payload = data + ZT_PACKET_IDX_VERB;
|
||||
const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB;
|
||||
if (encryptPayload)
|
||||
s20.crypt12(payload,payload,payloadLen);
|
||||
Poly1305::compute(mac,payload,payloadLen,macKey);
|
||||
memcpy(data + ZT_PACKET_IDX_MAC,mac,8);
|
||||
if (ZT_HAS_FAST_CRYPTO()) {
|
||||
const unsigned int encryptLen = (encryptPayload) ? (size() - ZT_PACKET_IDX_VERB) : 0;
|
||||
uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8];
|
||||
ZT_FAST_SINGLE_PASS_SALSA2012(keyStream,encryptLen + 64,(data + ZT_PACKET_IDX_IV),mangledKey);
|
||||
Salsa20::memxor(data + ZT_PACKET_IDX_VERB,reinterpret_cast<const uint8_t *>(keyStream + 8),encryptLen);
|
||||
uint64_t mac[2];
|
||||
Poly1305::compute(mac,data + ZT_PACKET_IDX_VERB,size() - ZT_PACKET_IDX_VERB,keyStream);
|
||||
#ifdef ZT_NO_TYPE_PUNNING
|
||||
memcpy(data + ZT_PACKET_IDX_MAC,mac,8);
|
||||
#else
|
||||
(*reinterpret_cast<uint64_t *>(data + ZT_PACKET_IDX_MAC)) = mac[0];
|
||||
#endif
|
||||
} else {
|
||||
Salsa20 s20(mangledKey,data + ZT_PACKET_IDX_IV);
|
||||
uint64_t macKey[4];
|
||||
s20.crypt12(ZERO_KEY,macKey,sizeof(macKey));
|
||||
uint8_t *const payload = data + ZT_PACKET_IDX_VERB;
|
||||
const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB;
|
||||
if (encryptPayload)
|
||||
s20.crypt12(payload,payload,payloadLen);
|
||||
uint64_t mac[2];
|
||||
Poly1305::compute(mac,payload,payloadLen,macKey);
|
||||
memcpy(data + ZT_PACKET_IDX_MAC,mac,8);
|
||||
}
|
||||
}
|
||||
|
||||
bool Packet::dearmor(const void *key)
|
||||
{
|
||||
uint8_t mangledKey[32],macKey[32],mac[16];
|
||||
uint8_t mangledKey[32];
|
||||
uint8_t *const data = reinterpret_cast<uint8_t *>(unsafeData());
|
||||
const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB;
|
||||
unsigned char *const payload = data + ZT_PACKET_IDX_VERB;
|
||||
@@ -1098,15 +1153,36 @@ bool Packet::dearmor(const void *key)
|
||||
|
||||
if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)||(cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) {
|
||||
_salsa20MangleKey((const unsigned char *)key,mangledKey);
|
||||
Salsa20 s20(mangledKey,256,data + ZT_PACKET_IDX_IV);
|
||||
|
||||
s20.crypt12(ZERO_KEY,macKey,sizeof(macKey));
|
||||
Poly1305::compute(mac,payload,payloadLen,macKey);
|
||||
if (!Utils::secureEq(mac,data + ZT_PACKET_IDX_MAC,8))
|
||||
return false; // MAC failed, packet is corrupt, modified, or is not from the sender
|
||||
|
||||
if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)
|
||||
s20.crypt12(payload,payload,payloadLen);
|
||||
if (ZT_HAS_FAST_CRYPTO()) {
|
||||
uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8];
|
||||
ZT_FAST_SINGLE_PASS_SALSA2012(keyStream,((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) ? (payloadLen + 64) : 64),(data + ZT_PACKET_IDX_IV),mangledKey);
|
||||
uint64_t mac[2];
|
||||
Poly1305::compute(mac,payload,payloadLen,keyStream);
|
||||
#ifdef ZT_NO_TYPE_PUNNING
|
||||
if (!Utils::secureEq(mac,data + ZT_PACKET_IDX_MAC,8))
|
||||
return false;
|
||||
#else
|
||||
if ((*reinterpret_cast<const uint64_t *>(data + ZT_PACKET_IDX_MAC)) != mac[0]) // also secure, constant time
|
||||
return false;
|
||||
#endif
|
||||
if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)
|
||||
Salsa20::memxor(data + ZT_PACKET_IDX_VERB,reinterpret_cast<const uint8_t *>(keyStream + 8),payloadLen);
|
||||
} else {
|
||||
Salsa20 s20(mangledKey,data + ZT_PACKET_IDX_IV);
|
||||
uint64_t macKey[4];
|
||||
s20.crypt12(ZERO_KEY,macKey,sizeof(macKey));
|
||||
uint64_t mac[2];
|
||||
Poly1305::compute(mac,payload,payloadLen,macKey);
|
||||
#ifdef ZT_NO_TYPE_PUNNING
|
||||
if (!Utils::secureEq(mac,data + ZT_PACKET_IDX_MAC,8))
|
||||
return false;
|
||||
#else
|
||||
if ((*reinterpret_cast<const uint64_t *>(data + ZT_PACKET_IDX_MAC)) != mac[0]) // also secure, constant time
|
||||
return false;
|
||||
#endif
|
||||
if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)
|
||||
s20.crypt12(payload,payload,payloadLen);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@@ -1120,7 +1196,7 @@ void Packet::cryptField(const void *key,unsigned int start,unsigned int len)
|
||||
uint8_t iv[8];
|
||||
for(int i=0;i<8;++i) iv[i] = data[i];
|
||||
iv[7] &= 0xf8; // mask off least significant 3 bits of packet ID / IV since this is unset when this function gets called
|
||||
Salsa20 s20(key,256,iv);
|
||||
Salsa20 s20(key,iv);
|
||||
s20.crypt12(data + start,data + start,len);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_N_PACKET_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "Path.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_PATH_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "../version.h"
|
||||
@@ -27,14 +35,6 @@
|
||||
#include "Cluster.hpp"
|
||||
#include "Packet.hpp"
|
||||
|
||||
#ifndef AF_MAX
|
||||
#if AF_INET > AF_INET6
|
||||
#define AF_MAX AF_INET
|
||||
#else
|
||||
#define AF_MAX AF_INET6
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Identity &peerIdentity) :
|
||||
@@ -51,18 +51,15 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
|
||||
_lastComRequestSent(0),
|
||||
_lastCredentialsReceived(0),
|
||||
_lastTrustEstablishedPacketReceived(0),
|
||||
_remoteClusterOptimal4(0),
|
||||
_vProto(0),
|
||||
_vMajor(0),
|
||||
_vMinor(0),
|
||||
_vRevision(0),
|
||||
_id(peerIdentity),
|
||||
_numPaths(0),
|
||||
_latency(0),
|
||||
_directPathPushCutoffCount(0),
|
||||
_credentialsCutoffCount(0)
|
||||
{
|
||||
memset(_remoteClusterOptimal6,0,sizeof(_remoteClusterOptimal6));
|
||||
if (!myIdentity.agree(peerIdentity,_key,ZT_PEER_SECRET_KEY_LENGTH))
|
||||
throw std::runtime_error("new peer identity key agreement failed");
|
||||
}
|
||||
@@ -80,7 +77,7 @@ void Peer::received(
|
||||
const uint64_t now = RR->node->now();
|
||||
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
bool suboptimalPath = false;
|
||||
bool isClusterSuboptimalPath = false;
|
||||
if ((RR->cluster)&&(hops == 0)) {
|
||||
// Note: findBetterEndpoint() is first since we still want to check
|
||||
// for a better endpoint even if we don't actually send a redirect.
|
||||
@@ -120,7 +117,7 @@ void Peer::received(
|
||||
outp.armor(_key,true,path->nextOutgoingCounter());
|
||||
path->send(RR,tPtr,outp.data(),outp.size(),now);
|
||||
}
|
||||
suboptimalPath = true;
|
||||
isClusterSuboptimalPath = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -146,78 +143,71 @@ void Peer::received(
|
||||
path->updateLinkQuality((unsigned int)(packetId & 7));
|
||||
|
||||
if (hops == 0) {
|
||||
bool pathIsConfirmed = false;
|
||||
bool pathAlreadyKnown = false;
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if (_paths[p].path->address() == path->address()) {
|
||||
_paths[p].lastReceive = now;
|
||||
_paths[p].path = path; // local address may have changed!
|
||||
if ((path->address().ss_family == AF_INET)&&(_v4Path.p)) {
|
||||
const struct sockaddr_in *const r = reinterpret_cast<const struct sockaddr_in *>(&(path->address()));
|
||||
const struct sockaddr_in *const l = reinterpret_cast<const struct sockaddr_in *>(&(_v4Path.p->address()));
|
||||
const struct sockaddr_in *const rl = reinterpret_cast<const struct sockaddr_in *>(&(path->localAddress()));
|
||||
const struct sockaddr_in *const ll = reinterpret_cast<const struct sockaddr_in *>(&(_v4Path.p->localAddress()));
|
||||
if ((r->sin_addr.s_addr == l->sin_addr.s_addr)&&(r->sin_port == l->sin_port)&&(rl->sin_addr.s_addr == ll->sin_addr.s_addr)&&(rl->sin_port == ll->sin_port)) {
|
||||
_v4Path.lr = now;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
_paths[p].localClusterSuboptimal = suboptimalPath;
|
||||
_v4Path.localClusterSuboptimal = isClusterSuboptimalPath;
|
||||
#endif
|
||||
pathIsConfirmed = true;
|
||||
break;
|
||||
pathAlreadyKnown = true;
|
||||
}
|
||||
} else if ((path->address().ss_family == AF_INET6)&&(_v6Path.p)) {
|
||||
const struct sockaddr_in6 *const r = reinterpret_cast<const struct sockaddr_in6 *>(&(path->address()));
|
||||
const struct sockaddr_in6 *const l = reinterpret_cast<const struct sockaddr_in6 *>(&(_v6Path.p->address()));
|
||||
const struct sockaddr_in6 *const rl = reinterpret_cast<const struct sockaddr_in6 *>(&(path->localAddress()));
|
||||
const struct sockaddr_in6 *const ll = reinterpret_cast<const struct sockaddr_in6 *>(&(_v6Path.p->localAddress()));
|
||||
if ((!memcmp(r->sin6_addr.s6_addr,l->sin6_addr.s6_addr,16))&&(r->sin6_port == l->sin6_port)&&(!memcmp(rl->sin6_addr.s6_addr,ll->sin6_addr.s6_addr,16))&&(rl->sin6_port == ll->sin6_port)) {
|
||||
_v6Path.lr = now;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
_v6Path.localClusterSuboptimal = isClusterSuboptimalPath;
|
||||
#endif
|
||||
pathAlreadyKnown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( (!pathIsConfirmed) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id.address(),path->localAddress(),path->address())) ) {
|
||||
if (verb == Packet::VERB_OK) {
|
||||
Mutex::Lock _l(_paths_m);
|
||||
|
||||
// Since this is a new path, figure out where to put it (possibly replacing an old/dead one)
|
||||
unsigned int slot;
|
||||
if (_numPaths < ZT_MAX_PEER_NETWORK_PATHS) {
|
||||
slot = _numPaths++;
|
||||
} else {
|
||||
// First try to replace the worst within the same address family, if possible
|
||||
int worstSlot = -1;
|
||||
uint64_t worstScore = 0xffffffffffffffffULL;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if (_paths[p].path->address().ss_family == path->address().ss_family) {
|
||||
const uint64_t s = _pathScore(p,now);
|
||||
if (s < worstScore) {
|
||||
worstScore = s;
|
||||
worstSlot = (int)p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (worstSlot >= 0) {
|
||||
slot = (unsigned int)worstSlot;
|
||||
} else {
|
||||
// If we can't find one with the same family, replace the worst of any family
|
||||
slot = ZT_MAX_PEER_NETWORK_PATHS - 1;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
const uint64_t s = _pathScore(p,now);
|
||||
if (s < worstScore) {
|
||||
worstScore = s;
|
||||
slot = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( (!pathAlreadyKnown) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id.address(),path->localAddress(),path->address())) ) {
|
||||
Mutex::Lock _l(_paths_m);
|
||||
_PeerPath *potentialNewPeerPath = (_PeerPath *)0;
|
||||
if (path->address().ss_family == AF_INET) {
|
||||
if ( (!_v4Path.p) || (!_v4Path.p->alive(now)) || ((_v4Path.p->address() != _v4ClusterPreferred)&&(path->preferenceRank() >= _v4Path.p->preferenceRank())) ) {
|
||||
potentialNewPeerPath = &_v4Path;
|
||||
}
|
||||
|
||||
_paths[slot].lastReceive = now;
|
||||
_paths[slot].path = path;
|
||||
} else if (path->address().ss_family == AF_INET6) {
|
||||
if ( (!_v6Path.p) || (!_v6Path.p->alive(now)) || ((_v6Path.p->address() != _v6ClusterPreferred)&&(path->preferenceRank() >= _v6Path.p->preferenceRank())) ) {
|
||||
potentialNewPeerPath = &_v6Path;
|
||||
}
|
||||
}
|
||||
if (potentialNewPeerPath) {
|
||||
if (verb == Packet::VERB_OK) {
|
||||
potentialNewPeerPath->lr = now;
|
||||
potentialNewPeerPath->p = path;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
_paths[slot].localClusterSuboptimal = suboptimalPath;
|
||||
if (RR->cluster)
|
||||
RR->cluster->broadcastHavePeer(_id);
|
||||
potentialNewPeerPath->localClusterSuboptimal = isClusterSuboptimalPath;
|
||||
if (RR->cluster)
|
||||
RR->cluster->broadcastHavePeer(_id);
|
||||
#endif
|
||||
} else {
|
||||
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),path->address().toString().c_str());
|
||||
attemptToContactAt(tPtr,path->localAddress(),path->address(),now,true,path->nextOutgoingCounter());
|
||||
path->sent(now);
|
||||
} else {
|
||||
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),path->address().toString().c_str());
|
||||
attemptToContactAt(tPtr,path->localAddress(),path->address(),now,true,path->nextOutgoingCounter());
|
||||
path->sent(now);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (this->trustEstablished(now)) {
|
||||
// Send PUSH_DIRECT_PATHS if hops>0 (relayed) and we have a trust relationship (common network membership)
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
// Cluster mode disables normal PUSH_DIRECT_PATHS in favor of cluster-based peer redirection
|
||||
const bool haveCluster = (RR->cluster);
|
||||
// Cluster mode disables normal PUSH_DIRECT_PATHS in favor of cluster-based peer redirection
|
||||
const bool haveCluster = (RR->cluster);
|
||||
#else
|
||||
const bool haveCluster = false;
|
||||
const bool haveCluster = false;
|
||||
#endif
|
||||
if ( ((now - _lastDirectPathPushSent) >= ZT_DIRECT_PATH_PUSH_INTERVAL) && (!haveCluster) ) {
|
||||
_lastDirectPathPushSent = now;
|
||||
@@ -290,60 +280,50 @@ void Peer::received(
|
||||
}
|
||||
}
|
||||
|
||||
bool Peer::hasActivePathTo(uint64_t now,const InetAddress &addr) const
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if ( (_paths[p].path->address() == addr) && ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && (_paths[p].path->alive(now)) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Peer::sendDirect(void *tPtr,const void *data,unsigned int len,uint64_t now,bool forceEvenIfDead)
|
||||
bool Peer::sendDirect(void *tPtr,const void *data,unsigned int len,uint64_t now,bool force)
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
|
||||
int bestp = -1;
|
||||
uint64_t best = 0ULL;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if ( ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && (_paths[p].path->alive(now)||(forceEvenIfDead)) ) {
|
||||
const uint64_t s = _pathScore(p,now);
|
||||
if (s >= best) {
|
||||
best = s;
|
||||
bestp = (int)p;
|
||||
}
|
||||
uint64_t v6lr = 0;
|
||||
if ( ((now - _v6Path.lr) < ZT_PEER_PATH_EXPIRATION) && (_v6Path.p) )
|
||||
v6lr = _v6Path.p->lastIn();
|
||||
uint64_t v4lr = 0;
|
||||
if ( ((now - _v4Path.lr) < ZT_PEER_PATH_EXPIRATION) && (_v4Path.p) )
|
||||
v4lr = _v4Path.p->lastIn();
|
||||
|
||||
if ( (v6lr > v4lr) && ((now - v6lr) < ZT_PATH_ALIVE_TIMEOUT) ) {
|
||||
return _v6Path.p->send(RR,tPtr,data,len,now);
|
||||
} else if ((now - v4lr) < ZT_PATH_ALIVE_TIMEOUT) {
|
||||
return _v4Path.p->send(RR,tPtr,data,len,now);
|
||||
} else if (force) {
|
||||
if (v6lr > v4lr) {
|
||||
return _v6Path.p->send(RR,tPtr,data,len,now);
|
||||
} else if (v4lr) {
|
||||
return _v4Path.p->send(RR,tPtr,data,len,now);
|
||||
}
|
||||
}
|
||||
|
||||
if (bestp >= 0) {
|
||||
return _paths[bestp].path->send(RR,tPtr,data,len,now);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SharedPtr<Path> Peer::getBestPath(uint64_t now,bool includeExpired)
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
|
||||
int bestp = -1;
|
||||
uint64_t best = 0ULL;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if ( ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) || (includeExpired) ) {
|
||||
const uint64_t s = _pathScore(p,now);
|
||||
if (s >= best) {
|
||||
best = s;
|
||||
bestp = (int)p;
|
||||
}
|
||||
}
|
||||
uint64_t v6lr = 0;
|
||||
if ( ( includeExpired || ((now - _v6Path.lr) < ZT_PEER_PATH_EXPIRATION) ) && (_v6Path.p) )
|
||||
v6lr = _v6Path.p->lastIn();
|
||||
uint64_t v4lr = 0;
|
||||
if ( ( includeExpired || ((now - _v4Path.lr) < ZT_PEER_PATH_EXPIRATION) ) && (_v4Path.p) )
|
||||
v4lr = _v4Path.p->lastIn();
|
||||
|
||||
if (v6lr > v4lr) {
|
||||
return _v6Path.p;
|
||||
} else if (v4lr) {
|
||||
return _v4Path.p;
|
||||
}
|
||||
|
||||
if (bestp >= 0) {
|
||||
return _paths[bestp].path;
|
||||
} else {
|
||||
return SharedPtr<Path>();
|
||||
}
|
||||
return SharedPtr<Path>();
|
||||
}
|
||||
|
||||
void Peer::sendHELLO(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter)
|
||||
@@ -420,79 +400,44 @@ bool Peer::doPingAndKeepalive(void *tPtr,uint64_t now,int inetAddressFamily)
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
|
||||
int bestp = -1;
|
||||
uint64_t best = 0ULL;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if ( ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && ((inetAddressFamily < 0)||((int)_paths[p].path->address().ss_family == inetAddressFamily)) ) {
|
||||
const uint64_t s = _pathScore(p,now);
|
||||
if (s >= best) {
|
||||
best = s;
|
||||
bestp = (int)p;
|
||||
if (inetAddressFamily < 0) {
|
||||
uint64_t v6lr = 0;
|
||||
if ( ((now - _v6Path.lr) < ZT_PEER_PATH_EXPIRATION) && (_v6Path.p) )
|
||||
v6lr = _v6Path.p->lastIn();
|
||||
uint64_t v4lr = 0;
|
||||
if ( ((now - _v4Path.lr) < ZT_PEER_PATH_EXPIRATION) && (_v4Path.p) )
|
||||
v4lr = _v4Path.p->lastIn();
|
||||
|
||||
if (v6lr > v4lr) {
|
||||
if ( ((now - _v6Path.lr) >= ZT_PEER_PING_PERIOD) || (_v6Path.p->needsHeartbeat(now)) ) {
|
||||
attemptToContactAt(tPtr,_v6Path.p->localAddress(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
|
||||
_v6Path.p->sent(now);
|
||||
return true;
|
||||
}
|
||||
} else if (v4lr) {
|
||||
if ( ((now - _v4Path.lr) >= ZT_PEER_PING_PERIOD) || (_v4Path.p->needsHeartbeat(now)) ) {
|
||||
attemptToContactAt(tPtr,_v4Path.p->localAddress(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
|
||||
_v4Path.p->sent(now);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( (inetAddressFamily == AF_INET) && ((now - _v4Path.lr) < ZT_PEER_PATH_EXPIRATION) ) {
|
||||
if ( ((now - _v4Path.lr) >= ZT_PEER_PING_PERIOD) || (_v4Path.p->needsHeartbeat(now)) ) {
|
||||
attemptToContactAt(tPtr,_v4Path.p->localAddress(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
|
||||
_v4Path.p->sent(now);
|
||||
return true;
|
||||
}
|
||||
} else if ( (inetAddressFamily == AF_INET6) && ((now - _v6Path.lr) < ZT_PEER_PATH_EXPIRATION) ) {
|
||||
if ( ((now - _v6Path.lr) >= ZT_PEER_PING_PERIOD) || (_v6Path.p->needsHeartbeat(now)) ) {
|
||||
attemptToContactAt(tPtr,_v6Path.p->localAddress(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
|
||||
_v6Path.p->sent(now);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestp >= 0) {
|
||||
if ( ((now - _paths[bestp].lastReceive) >= ZT_PEER_PING_PERIOD) || (_paths[bestp].path->needsHeartbeat(now)) ) {
|
||||
attemptToContactAt(tPtr,_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now,false,_paths[bestp].path->nextOutgoingCounter());
|
||||
_paths[bestp].path->sent(now);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Peer::hasActiveDirectPath(uint64_t now) const
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if (((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION)&&(_paths[p].path->alive(now)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Peer::resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,uint64_t now)
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if ( (_paths[p].path->address().ss_family == inetAddressFamily) && (_paths[p].path->address().ipScope() == scope) ) {
|
||||
attemptToContactAt(tPtr,_paths[p].path->localAddress(),_paths[p].path->address(),now,false,_paths[p].path->nextOutgoingCounter());
|
||||
_paths[p].path->sent(now);
|
||||
_paths[p].lastReceive = 0; // path will not be used unless it speaks again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Peer::getRendezvousAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
|
||||
int bestp4 = -1,bestp6 = -1;
|
||||
uint64_t best4 = 0ULL,best6 = 0ULL;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if ( ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && (_paths[p].path->alive(now)) ) {
|
||||
if (_paths[p].path->address().ss_family == AF_INET) {
|
||||
const uint64_t s = _pathScore(p,now);
|
||||
if (s >= best4) {
|
||||
best4 = s;
|
||||
bestp4 = (int)p;
|
||||
}
|
||||
} else if (_paths[p].path->address().ss_family == AF_INET6) {
|
||||
const uint64_t s = _pathScore(p,now);
|
||||
if (s >= best6) {
|
||||
best6 = s;
|
||||
bestp6 = (int)p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestp4 >= 0)
|
||||
v4 = _paths[bestp4].path->address();
|
||||
if (bestp6 >= 0)
|
||||
v6 = _paths[bestp6].path->address();
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_PEER_HPP
|
||||
@@ -108,20 +116,10 @@ public:
|
||||
* @param addr Remote address
|
||||
* @return True if we have an active path to this destination
|
||||
*/
|
||||
bool hasActivePathTo(uint64_t now,const InetAddress &addr) const;
|
||||
|
||||
/**
|
||||
* Set which known path for an address family is optimal
|
||||
*
|
||||
* @param addr Address to make exclusive
|
||||
*/
|
||||
inline void setClusterOptimal(const InetAddress &addr)
|
||||
inline bool hasActivePathTo(uint64_t now,const InetAddress &addr) const
|
||||
{
|
||||
if (addr.ss_family == AF_INET) {
|
||||
_remoteClusterOptimal4 = (uint32_t)reinterpret_cast<const struct sockaddr_in *>(&addr)->sin_addr.s_addr;
|
||||
} else if (addr.ss_family == AF_INET6) {
|
||||
memcpy(_remoteClusterOptimal6,reinterpret_cast<const struct sockaddr_in6 *>(&addr)->sin6_addr.s6_addr,16);
|
||||
}
|
||||
Mutex::Lock _l(_paths_m);
|
||||
return ( ((addr.ss_family == AF_INET)&&(_v4Path.p)&&(_v4Path.p->address() == addr)&&(_v4Path.p->alive(now))) || ((addr.ss_family == AF_INET6)&&(_v6Path.p)&&(_v6Path.p->address() == addr)&&(_v6Path.p->alive(now))) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,14 +129,17 @@ public:
|
||||
* @param data Packet data
|
||||
* @param len Packet length
|
||||
* @param now Current time
|
||||
* @param forceEvenIfDead If true, send even if the path is not 'alive'
|
||||
* @param force If true, send even if path is not alive
|
||||
* @return True if we actually sent something
|
||||
*/
|
||||
bool sendDirect(void *tPtr,const void *data,unsigned int len,uint64_t now,bool forceEvenIfDead);
|
||||
bool sendDirect(void *tPtr,const void *data,unsigned int len,uint64_t now,bool force);
|
||||
|
||||
/**
|
||||
* Get the best current direct path
|
||||
*
|
||||
* This does not check Path::alive(), but does return the most recently
|
||||
* active path and does check expiration (which is a longer timeout).
|
||||
*
|
||||
* @param now Current time
|
||||
* @param includeExpired If true, include even expired paths
|
||||
* @return Best current path or NULL if none
|
||||
@@ -192,12 +193,6 @@ public:
|
||||
*/
|
||||
bool doPingAndKeepalive(void *tPtr,uint64_t now,int inetAddressFamily);
|
||||
|
||||
/**
|
||||
* @param now Current time
|
||||
* @return True if this peer has at least one active and alive direct path
|
||||
*/
|
||||
bool hasActiveDirectPath(uint64_t now) const;
|
||||
|
||||
/**
|
||||
* Reset paths within a given IP scope and address family
|
||||
*
|
||||
@@ -209,30 +204,61 @@ public:
|
||||
* @param inetAddressFamily Family e.g. AF_INET
|
||||
* @param now Current time
|
||||
*/
|
||||
void resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,uint64_t now);
|
||||
inline void resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,uint64_t now)
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
if ((inetAddressFamily == AF_INET)&&(_v4Path.lr)&&(_v4Path.p->address().ipScope() == scope)) {
|
||||
attemptToContactAt(tPtr,_v4Path.p->localAddress(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
|
||||
_v4Path.p->sent(now);
|
||||
_v4Path.lr = 0; // path will not be used unless it speaks again
|
||||
} else if ((inetAddressFamily == AF_INET6)&&(_v6Path.lr)&&(_v6Path.p->address().ipScope() == scope)) {
|
||||
attemptToContactAt(tPtr,_v6Path.p->localAddress(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
|
||||
_v6Path.p->sent(now);
|
||||
_v6Path.lr = 0; // path will not be used unless it speaks again
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get most recently active path addresses for IPv4 and/or IPv6
|
||||
* Indicate that the given address was provided by a cluster as a preferred destination
|
||||
*
|
||||
* Note that v4 and v6 are not modified if they are not found, so
|
||||
* initialize these to a NULL address to be able to check.
|
||||
* @param addr Address cluster prefers that we use
|
||||
*/
|
||||
inline void setClusterPreferred(const InetAddress &addr)
|
||||
{
|
||||
if (addr.ss_family == AF_INET)
|
||||
_v4ClusterPreferred = addr;
|
||||
else if (addr.ss_family == AF_INET6)
|
||||
_v6ClusterPreferred = addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill parameters with V4 and V6 addresses if known and alive
|
||||
*
|
||||
* @param now Current time
|
||||
* @param v4 Result parameter to receive active IPv4 address, if any
|
||||
* @param v6 Result parameter to receive active IPv6 address, if any
|
||||
*/
|
||||
void getRendezvousAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const;
|
||||
inline void getRendezvousAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
if (((now - _v4Path.lr) < ZT_PEER_PATH_EXPIRATION)&&(_v4Path.p->alive(now)))
|
||||
v4 = _v4Path.p->address();
|
||||
if (((now - _v6Path.lr) < ZT_PEER_PATH_EXPIRATION)&&(_v6Path.p->alive(now)))
|
||||
v6 = _v6Path.p->address();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param now Current time
|
||||
* @return All known direct paths to this peer and whether they are expired (true == expired)
|
||||
* @return All known paths to this peer
|
||||
*/
|
||||
inline std::vector< std::pair< SharedPtr<Path>,bool > > paths(const uint64_t now) const
|
||||
inline std::vector< SharedPtr<Path> > paths(const uint64_t now) const
|
||||
{
|
||||
std::vector< std::pair< SharedPtr<Path>,bool > > pp;
|
||||
std::vector< SharedPtr<Path> > pp;
|
||||
Mutex::Lock _l(_paths_m);
|
||||
for(unsigned int p=0,np=_numPaths;p<np;++p)
|
||||
pp.push_back(std::pair< SharedPtr<Path>,bool >(_paths[p].path,(now - _paths[p].lastReceive) > ZT_PEER_PATH_EXPIRATION));
|
||||
if (((now - _v4Path.lr) < ZT_PEER_PATH_EXPIRATION)&&(_v4Path.p->alive(now)))
|
||||
pp.push_back(_v4Path.p);
|
||||
if (((now - _v6Path.lr) < ZT_PEER_PATH_EXPIRATION)&&(_v6Path.p->alive(now)))
|
||||
pp.push_back(_v6Path.p);
|
||||
return pp;
|
||||
}
|
||||
|
||||
@@ -298,11 +324,8 @@ public:
|
||||
*/
|
||||
inline bool hasLocalClusterOptimalPath(uint64_t now) const
|
||||
{
|
||||
for(unsigned int p=0,np=_numPaths;p<np;++p) {
|
||||
if ( (_paths[p].path->alive(now)) && (!_paths[p].localClusterSuboptimal) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
Mutex::Lock _l(_paths_m);
|
||||
return ( ((_v4Path.p)&&(_v4Path.p->alive(now))&&(!_v4Path.localClusterSuboptimal)) || ((_v6Path.p)&&(_v6Path.p->alive(now))&&(!_v6Path.localClusterSuboptimal)) );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -424,32 +447,19 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
inline uint64_t _pathScore(const unsigned int p,const uint64_t now) const
|
||||
struct _PeerPath
|
||||
{
|
||||
uint64_t s = ZT_PEER_PING_PERIOD + _paths[p].lastReceive + (uint64_t)(_paths[p].path->preferenceRank() * (ZT_PEER_PING_PERIOD / ZT_PATH_MAX_PREFERENCE_RANK));
|
||||
|
||||
if (_paths[p].path->address().ss_family == AF_INET) {
|
||||
s += (uint64_t)(ZT_PEER_PING_PERIOD * (unsigned long)(reinterpret_cast<const struct sockaddr_in *>(&(_paths[p].path->address()))->sin_addr.s_addr == _remoteClusterOptimal4));
|
||||
} else if (_paths[p].path->address().ss_family == AF_INET6) {
|
||||
uint64_t clusterWeight = ZT_PEER_PING_PERIOD;
|
||||
const uint8_t *a = reinterpret_cast<const uint8_t *>(reinterpret_cast<const struct sockaddr_in6 *>(&(_paths[p].path->address()))->sin6_addr.s6_addr);
|
||||
for(long i=0;i<16;++i) {
|
||||
if (a[i] != _remoteClusterOptimal6[i]) {
|
||||
clusterWeight = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s += clusterWeight;
|
||||
}
|
||||
|
||||
s += (ZT_PEER_PING_PERIOD / 2) * (uint64_t)_paths[p].path->alive(now);
|
||||
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
s -= ZT_PEER_PING_PERIOD * (uint64_t)_paths[p].localClusterSuboptimal;
|
||||
_PeerPath() : lr(0),p(),localClusterSuboptimal(false) {}
|
||||
#else
|
||||
_PeerPath() : lr(0),p() {}
|
||||
#endif
|
||||
|
||||
return s;
|
||||
}
|
||||
uint64_t lr; // time of last valid ZeroTier packet
|
||||
SharedPtr<Path> p;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
bool localClusterSuboptimal; // true if our cluster has determined that we should not be serving this peer
|
||||
#endif
|
||||
};
|
||||
|
||||
uint8_t _key[ZT_PEER_SECRET_KEY_LENGTH];
|
||||
|
||||
@@ -468,26 +478,20 @@ private:
|
||||
uint64_t _lastCredentialsReceived;
|
||||
uint64_t _lastTrustEstablishedPacketReceived;
|
||||
|
||||
uint8_t _remoteClusterOptimal6[16];
|
||||
uint32_t _remoteClusterOptimal4;
|
||||
|
||||
uint16_t _vProto;
|
||||
uint16_t _vMajor;
|
||||
uint16_t _vMinor;
|
||||
uint16_t _vRevision;
|
||||
|
||||
Identity _id;
|
||||
InetAddress _v4ClusterPreferred;
|
||||
InetAddress _v6ClusterPreferred;
|
||||
|
||||
struct {
|
||||
uint64_t lastReceive;
|
||||
SharedPtr<Path> path;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
bool localClusterSuboptimal;
|
||||
#endif
|
||||
} _paths[ZT_MAX_PEER_NETWORK_PATHS];
|
||||
_PeerPath _v4Path; // IPv4 direct path
|
||||
_PeerPath _v6Path; // IPv6 direct path
|
||||
Mutex _paths_m;
|
||||
|
||||
unsigned int _numPaths;
|
||||
Identity _id;
|
||||
|
||||
unsigned int _latency;
|
||||
unsigned int _directPathPushCutoffCount;
|
||||
unsigned int _credentialsCutoffCount;
|
||||
|
||||
@@ -135,11 +135,12 @@ typedef struct poly1305_context {
|
||||
unsigned char opaque[136];
|
||||
} poly1305_context;
|
||||
|
||||
#if (defined(_MSC_VER) || defined(__GNUC__)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__))
|
||||
#if (defined(_MSC_VER) || defined(__GNUC__)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// 128-bit implementation for MSC and GCC from Poly1305-donna
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
|
||||
@@ -183,9 +184,9 @@ typedef struct poly1305_state_internal_t {
|
||||
unsigned char final;
|
||||
} poly1305_state_internal_t;
|
||||
|
||||
/* interpret eight 8 bit unsigned integers as a 64 bit unsigned integer in little endian */
|
||||
static inline unsigned long long
|
||||
U8TO64(const unsigned char *p) {
|
||||
#if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN)
|
||||
static inline unsigned long long U8TO64(const unsigned char *p)
|
||||
{
|
||||
return
|
||||
(((unsigned long long)(p[0] & 0xff) ) |
|
||||
((unsigned long long)(p[1] & 0xff) << 8) |
|
||||
@@ -196,10 +197,13 @@ U8TO64(const unsigned char *p) {
|
||||
((unsigned long long)(p[6] & 0xff) << 48) |
|
||||
((unsigned long long)(p[7] & 0xff) << 56));
|
||||
}
|
||||
#else
|
||||
#define U8TO64(p) (*reinterpret_cast<const unsigned long long *>(p))
|
||||
#endif
|
||||
|
||||
/* store a 64 bit unsigned integer as eight 8 bit unsigned integers in little endian */
|
||||
static inline void
|
||||
U64TO8(unsigned char *p, unsigned long long v) {
|
||||
#if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN)
|
||||
static inline void U64TO8(unsigned char *p, unsigned long long v)
|
||||
{
|
||||
p[0] = (v ) & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
@@ -209,6 +213,9 @@ U64TO8(unsigned char *p, unsigned long long v) {
|
||||
p[6] = (v >> 48) & 0xff;
|
||||
p[7] = (v >> 56) & 0xff;
|
||||
}
|
||||
#else
|
||||
#define U64TO8(p,v) ((*reinterpret_cast<unsigned long long *>(p)) = (v))
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_POLY1305_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "Revocation.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_REVOCATION_HPP
|
||||
@@ -26,6 +34,7 @@
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Credential.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "C25519.hpp"
|
||||
#include "Utils.hpp"
|
||||
@@ -44,20 +53,10 @@ class RuntimeEnvironment;
|
||||
/**
|
||||
* Revocation certificate to instantaneously revoke a COM, capability, or tag
|
||||
*/
|
||||
class Revocation
|
||||
class Revocation : public Credential
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Credential type being revoked
|
||||
*/
|
||||
enum CredentialType
|
||||
{
|
||||
CREDENTIAL_TYPE_NULL = 0,
|
||||
CREDENTIAL_TYPE_COM = 1, // CertificateOfMembership
|
||||
CREDENTIAL_TYPE_CAPABILITY = 2,
|
||||
CREDENTIAL_TYPE_TAG = 3,
|
||||
CREDENTIAL_TYPE_COO = 4 // CertificateOfOwnership
|
||||
};
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_REVOCATION; }
|
||||
|
||||
Revocation()
|
||||
{
|
||||
@@ -73,23 +72,23 @@ public:
|
||||
* @param tgt Target node whose credential(s) are being revoked
|
||||
* @param ct Credential type being revoked
|
||||
*/
|
||||
Revocation(const uint64_t i,const uint64_t nwid,const uint64_t cid,const uint64_t thr,const uint64_t fl,const Address &tgt,const CredentialType ct) :
|
||||
Revocation(const uint32_t i,const uint64_t nwid,const uint32_t cid,const uint64_t thr,const uint64_t fl,const Address &tgt,const Credential::Type ct) :
|
||||
_id(i),
|
||||
_networkId(nwid),
|
||||
_credentialId(cid),
|
||||
_networkId(nwid),
|
||||
_threshold(thr),
|
||||
_flags(fl),
|
||||
_target(tgt),
|
||||
_signedBy(),
|
||||
_type(ct) {}
|
||||
|
||||
inline uint64_t id() const { return _id; }
|
||||
inline uint32_t id() const { return _id; }
|
||||
inline uint32_t credentialId() const { return _credentialId; }
|
||||
inline uint64_t networkId() const { return _networkId; }
|
||||
inline uint64_t credentialId() const { return _credentialId; }
|
||||
inline uint64_t threshold() const { return _threshold; }
|
||||
inline const Address &target() const { return _target; }
|
||||
inline const Address &signer() const { return _signedBy; }
|
||||
inline CredentialType type() const { return _type; }
|
||||
inline Credential::Type type() const { return _type; }
|
||||
|
||||
inline bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); }
|
||||
|
||||
@@ -123,8 +122,10 @@ public:
|
||||
{
|
||||
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
|
||||
b.append((uint32_t)0); // 4 unused bytes, currently set to 0
|
||||
b.append(_id);
|
||||
b.append(_networkId);
|
||||
b.append((uint32_t)0); // 4 unused bytes, currently set to 0
|
||||
b.append(_credentialId);
|
||||
b.append(_threshold);
|
||||
b.append(_flags);
|
||||
@@ -151,14 +152,16 @@ public:
|
||||
|
||||
unsigned int p = startAt;
|
||||
|
||||
_id = b.template at<uint64_t>(p); p += 8;
|
||||
p += 4; // 4 bytes, currently unused
|
||||
_id = b.template at<uint32_t>(p); p += 4;
|
||||
_networkId = b.template at<uint64_t>(p); p += 8;
|
||||
_credentialId = b.template at<uint64_t>(p); p += 8;
|
||||
p += 4; // 4 bytes, currently unused
|
||||
_credentialId = b.template at<uint32_t>(p); p += 4;
|
||||
_threshold = b.template at<uint64_t>(p); p += 8;
|
||||
_flags = b.template at<uint64_t>(p); p += 8;
|
||||
_target.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
|
||||
_signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
|
||||
_type = (CredentialType)b[p++];
|
||||
_type = (Credential::Type)b[p++];
|
||||
|
||||
if (b[p++] == 1) {
|
||||
if (b.template at<uint16_t>(p) == ZT_C25519_SIGNATURE_LEN) {
|
||||
@@ -178,14 +181,14 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t _id;
|
||||
uint32_t _id;
|
||||
uint32_t _credentialId;
|
||||
uint64_t _networkId;
|
||||
uint64_t _credentialId;
|
||||
uint64_t _threshold;
|
||||
uint64_t _flags;
|
||||
Address _target;
|
||||
Address _signedBy;
|
||||
CredentialType _type;
|
||||
Credential::Type _type;
|
||||
C25519::Signature _signature;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_RUNTIMEENVIRONMENT_HPP
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
// Code taken from NaCl by D. J. Bernstein and others
|
||||
// Public domain
|
||||
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
20080913
|
||||
D. J. Bernstein
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -25,18 +16,6 @@
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Code taken from NaCl by D. J. Bernstein and others
|
||||
// Public domain
|
||||
|
||||
/*
|
||||
20080913
|
||||
D. J. Bernstein
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
#define uint64 uint64_t
|
||||
|
||||
#ifdef ZT_NO_TYPE_PUNNING
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_SHA512_HPP
|
||||
|
||||
@@ -66,65 +66,49 @@ static const _s20sseconsts _S20SSECONSTANTS;
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
void Salsa20::init(const void *key,unsigned int kbits,const void *iv)
|
||||
throw()
|
||||
void Salsa20::init(const void *key,const void *iv)
|
||||
{
|
||||
#ifdef ZT_SALSA20_SSE
|
||||
const uint32_t *k = (const uint32_t *)key;
|
||||
|
||||
const uint32_t *const k = (const uint32_t *)key;
|
||||
_state.i[0] = 0x61707865;
|
||||
_state.i[1] = 0x3320646e;
|
||||
_state.i[2] = 0x79622d32;
|
||||
_state.i[3] = 0x6b206574;
|
||||
_state.i[13] = k[0];
|
||||
_state.i[10] = k[1];
|
||||
_state.i[7] = k[2];
|
||||
_state.i[4] = k[3];
|
||||
if (kbits == 256) {
|
||||
k += 4;
|
||||
_state.i[1] = 0x3320646e;
|
||||
_state.i[2] = 0x79622d32;
|
||||
} else {
|
||||
_state.i[1] = 0x3120646e;
|
||||
_state.i[2] = 0x79622d36;
|
||||
}
|
||||
_state.i[15] = k[0];
|
||||
_state.i[12] = k[1];
|
||||
_state.i[9] = k[2];
|
||||
_state.i[6] = k[3];
|
||||
_state.i[14] = ((const uint32_t *)iv)[0];
|
||||
_state.i[11] = ((const uint32_t *)iv)[1];
|
||||
_state.i[5] = 0;
|
||||
_state.i[6] = k[7];
|
||||
_state.i[7] = k[2];
|
||||
_state.i[8] = 0;
|
||||
_state.i[9] = k[6];
|
||||
_state.i[10] = k[1];
|
||||
_state.i[11] = ((const uint32_t *)iv)[1];
|
||||
_state.i[12] = k[5];
|
||||
_state.i[13] = k[0];
|
||||
_state.i[14] = ((const uint32_t *)iv)[0];
|
||||
_state.i[15] = k[4];
|
||||
#else
|
||||
const char *constants;
|
||||
const uint8_t *k = (const uint8_t *)key;
|
||||
|
||||
const char *const constants = "expand 32-byte k";
|
||||
const uint8_t *const k = (const uint8_t *)key;
|
||||
_state.i[0] = U8TO32_LITTLE(constants + 0);
|
||||
_state.i[1] = U8TO32_LITTLE(k + 0);
|
||||
_state.i[2] = U8TO32_LITTLE(k + 4);
|
||||
_state.i[3] = U8TO32_LITTLE(k + 8);
|
||||
_state.i[4] = U8TO32_LITTLE(k + 12);
|
||||
if (kbits == 256) { /* recommended */
|
||||
k += 16;
|
||||
constants = "expand 32-byte k";
|
||||
} else { /* kbits == 128 */
|
||||
constants = "expand 16-byte k";
|
||||
}
|
||||
_state.i[5] = U8TO32_LITTLE(constants + 4);
|
||||
_state.i[6] = U8TO32_LITTLE(((const uint8_t *)iv) + 0);
|
||||
_state.i[7] = U8TO32_LITTLE(((const uint8_t *)iv) + 4);
|
||||
_state.i[8] = 0;
|
||||
_state.i[9] = 0;
|
||||
_state.i[10] = U8TO32_LITTLE(constants + 8);
|
||||
_state.i[11] = U8TO32_LITTLE(k + 0);
|
||||
_state.i[12] = U8TO32_LITTLE(k + 4);
|
||||
_state.i[13] = U8TO32_LITTLE(k + 8);
|
||||
_state.i[14] = U8TO32_LITTLE(k + 12);
|
||||
_state.i[11] = U8TO32_LITTLE(k + 16);
|
||||
_state.i[12] = U8TO32_LITTLE(k + 20);
|
||||
_state.i[13] = U8TO32_LITTLE(k + 24);
|
||||
_state.i[14] = U8TO32_LITTLE(k + 28);
|
||||
_state.i[15] = U8TO32_LITTLE(constants + 12);
|
||||
_state.i[0] = U8TO32_LITTLE(constants + 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Salsa20::crypt12(const void *in,void *out,unsigned int bytes)
|
||||
throw()
|
||||
{
|
||||
uint8_t tmp[64];
|
||||
const uint8_t *m = (const uint8_t *)in;
|
||||
@@ -624,7 +608,6 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes)
|
||||
}
|
||||
|
||||
void Salsa20::crypt20(const void *in,void *out,unsigned int bytes)
|
||||
throw()
|
||||
{
|
||||
uint8_t tmp[64];
|
||||
const uint8_t *m = (const uint8_t *)in;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
@@ -30,30 +31,101 @@ namespace ZeroTier {
|
||||
class Salsa20
|
||||
{
|
||||
public:
|
||||
Salsa20() throw() {}
|
||||
|
||||
Salsa20() {}
|
||||
~Salsa20() { Utils::burn(&_state,sizeof(_state)); }
|
||||
|
||||
/**
|
||||
* @param key Key bits
|
||||
* @param kbits Number of key bits: 128 or 256 (recommended)
|
||||
* XOR d with s
|
||||
*
|
||||
* This is done efficiently using e.g. SSE if available. It's used when
|
||||
* alternative Salsa20 implementations are used in Packet and is here
|
||||
* since this is where all the SSE stuff is already included.
|
||||
*
|
||||
* @param d Destination to XOR
|
||||
* @param s Source bytes to XOR with destination
|
||||
* @param len Length of s and d
|
||||
*/
|
||||
static inline void memxor(uint8_t *d,const uint8_t *s,unsigned int len)
|
||||
{
|
||||
#ifdef ZT_SALSA20_SSE
|
||||
while (len >= 128) {
|
||||
__m128i s0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s));
|
||||
__m128i s1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s + 16));
|
||||
__m128i s2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s + 32));
|
||||
__m128i s3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s + 48));
|
||||
__m128i s4 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s + 64));
|
||||
__m128i s5 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s + 80));
|
||||
__m128i s6 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s + 96));
|
||||
__m128i s7 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s + 112));
|
||||
__m128i d0 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d));
|
||||
__m128i d1 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 16));
|
||||
__m128i d2 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 32));
|
||||
__m128i d3 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 48));
|
||||
__m128i d4 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 64));
|
||||
__m128i d5 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 80));
|
||||
__m128i d6 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 96));
|
||||
__m128i d7 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 112));
|
||||
d0 = _mm_xor_si128(d0,s0);
|
||||
d1 = _mm_xor_si128(d1,s1);
|
||||
d2 = _mm_xor_si128(d2,s2);
|
||||
d3 = _mm_xor_si128(d3,s3);
|
||||
d4 = _mm_xor_si128(d4,s4);
|
||||
d5 = _mm_xor_si128(d5,s5);
|
||||
d6 = _mm_xor_si128(d6,s6);
|
||||
d7 = _mm_xor_si128(d7,s7);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d),d0);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 16),d1);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 32),d2);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 48),d3);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 64),d4);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 80),d5);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 96),d6);
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 112),d7);
|
||||
s += 128;
|
||||
d += 128;
|
||||
len -= 128;
|
||||
}
|
||||
while (len >= 16) {
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(d),_mm_xor_si128(_mm_loadu_si128(reinterpret_cast<__m128i *>(d)),_mm_loadu_si128(reinterpret_cast<const __m128i *>(s))));
|
||||
s += 16;
|
||||
d += 16;
|
||||
len -= 16;
|
||||
}
|
||||
#else
|
||||
#ifndef ZT_NO_TYPE_PUNNING
|
||||
while (len >= 16) {
|
||||
(*reinterpret_cast<uint64_t *>(d)) ^= (*reinterpret_cast<const uint64_t *>(s));
|
||||
s += 8;
|
||||
d += 8;
|
||||
(*reinterpret_cast<uint64_t *>(d)) ^= (*reinterpret_cast<const uint64_t *>(s));
|
||||
s += 8;
|
||||
d += 8;
|
||||
len -= 16;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
while (len) {
|
||||
--len;
|
||||
*(d++) ^= *(s++);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key 256-bit (32 byte) key
|
||||
* @param iv 64-bit initialization vector
|
||||
*/
|
||||
Salsa20(const void *key,unsigned int kbits,const void *iv)
|
||||
throw()
|
||||
Salsa20(const void *key,const void *iv)
|
||||
{
|
||||
init(key,kbits,iv);
|
||||
init(key,iv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize cipher
|
||||
*
|
||||
* @param key Key bits
|
||||
* @param kbits Number of key bits: 128 or 256 (recommended)
|
||||
* @param iv 64-bit initialization vector
|
||||
*/
|
||||
void init(const void *key,unsigned int kbits,const void *iv)
|
||||
throw();
|
||||
void init(const void *key,const void *iv);
|
||||
|
||||
/**
|
||||
* Encrypt/decrypt data using Salsa20/12
|
||||
@@ -62,8 +134,7 @@ public:
|
||||
* @param out Output buffer
|
||||
* @param bytes Length of data
|
||||
*/
|
||||
void crypt12(const void *in,void *out,unsigned int bytes)
|
||||
throw();
|
||||
void crypt12(const void *in,void *out,unsigned int bytes);
|
||||
|
||||
/**
|
||||
* Encrypt/decrypt data using Salsa20/20
|
||||
@@ -72,8 +143,7 @@ public:
|
||||
* @param out Output buffer
|
||||
* @param bytes Length of data
|
||||
*/
|
||||
void crypt20(const void *in,void *out,unsigned int bytes)
|
||||
throw();
|
||||
void crypt20(const void *in,void *out,unsigned int bytes);
|
||||
|
||||
private:
|
||||
union {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_SELFAWARENESS_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_SHAREDPTR_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_N_SWITCH_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_TAG_HPP
|
||||
@@ -25,6 +33,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Credential.hpp"
|
||||
#include "C25519.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Identity.hpp"
|
||||
@@ -51,9 +60,11 @@ class RuntimeEnvironment;
|
||||
* Unlike capabilities tags are signed only by the issuer and are never
|
||||
* transferrable.
|
||||
*/
|
||||
class Tag
|
||||
class Tag : public Credential
|
||||
{
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_TAG; }
|
||||
|
||||
Tag()
|
||||
{
|
||||
memset(this,0,sizeof(Tag));
|
||||
@@ -67,19 +78,19 @@ public:
|
||||
* @param value Tag value
|
||||
*/
|
||||
Tag(const uint64_t nwid,const uint64_t ts,const Address &issuedTo,const uint32_t id,const uint32_t value) :
|
||||
_networkId(nwid),
|
||||
_ts(ts),
|
||||
_id(id),
|
||||
_value(value),
|
||||
_networkId(nwid),
|
||||
_ts(ts),
|
||||
_issuedTo(issuedTo),
|
||||
_signedBy()
|
||||
{
|
||||
}
|
||||
|
||||
inline uint64_t networkId() const { return _networkId; }
|
||||
inline uint64_t timestamp() const { return _ts; }
|
||||
inline uint32_t id() const { return _id; }
|
||||
inline const uint32_t &value() const { return _value; }
|
||||
inline uint64_t networkId() const { return _networkId; }
|
||||
inline uint64_t timestamp() const { return _ts; }
|
||||
inline const Address &issuedTo() const { return _issuedTo; }
|
||||
inline const Address &signedBy() const { return _signedBy; }
|
||||
|
||||
@@ -115,11 +126,9 @@ public:
|
||||
{
|
||||
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
|
||||
// These are the same between Tag and Capability
|
||||
b.append(_networkId);
|
||||
b.append(_ts);
|
||||
b.append(_id);
|
||||
|
||||
b.append(_value);
|
||||
|
||||
_issuedTo.appendTo(b);
|
||||
@@ -187,10 +196,10 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
uint64_t _networkId;
|
||||
uint64_t _ts;
|
||||
uint32_t _id;
|
||||
uint32_t _value;
|
||||
uint64_t _networkId;
|
||||
uint64_t _ts;
|
||||
Address _issuedTo;
|
||||
Address _signedBy;
|
||||
C25519::Signature _signature;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_TOPOLOGY_HPP
|
||||
@@ -314,7 +322,9 @@ public:
|
||||
Address *a = (Address *)0;
|
||||
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
|
||||
while (i.next(a,p)) {
|
||||
cnt += (unsigned long)((*p)->hasActiveDirectPath(now));
|
||||
const SharedPtr<Path> pp((*p)->getBestPath(now,false));
|
||||
if ((pp)&&(pp->alive(now)))
|
||||
++cnt;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -156,7 +164,7 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||
s20Key[1] = (uint64_t)buf; // address of buf
|
||||
s20Key[2] = (uint64_t)s20Key; // address of s20Key[]
|
||||
s20Key[3] = (uint64_t)&s20; // address of s20
|
||||
s20.init(s20Key,256,s20Key);
|
||||
s20.init(s20Key,s20Key);
|
||||
}
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
@@ -177,6 +185,7 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||
}
|
||||
randomPtr = 0;
|
||||
s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
|
||||
s20.init(randomBuf,randomBuf);
|
||||
}
|
||||
((uint8_t *)buf)[i] = randomBuf[randomPtr++];
|
||||
}
|
||||
@@ -209,6 +218,7 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||
}
|
||||
randomPtr = 0;
|
||||
s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
|
||||
s20.init(randomBuf,randomBuf);
|
||||
}
|
||||
((uint8_t *)buf)[i] = randomBuf[randomPtr++];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_UTILS_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial closed-source software that incorporates or links
|
||||
* directly against ZeroTier software without disclosing the source code
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
#ifndef ZT_WORLD_HPP
|
||||
|
||||
Reference in New Issue
Block a user