Work in progress...

This commit is contained in:
Adam Ierymenko 2019-08-22 13:06:08 -07:00
parent 0e18b14087
commit b66431bc29
No known key found for this signature in database
GPG Key ID: 1657198823E52A61
15 changed files with 356 additions and 390 deletions

View File

@ -1,37 +1,143 @@
ZeroTier One - Network Virtualization Everywhere
Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
Business Source License 1.1
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.
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
"Business Source License" is a trademark of MariaDB Corporation Ab.
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/>.
Parameters
See LICENSE.GPL-3 for the full GNU GPL v3 license.
Licensor: ZeroTier, Inc.
Licensed Work: ZeroTier Network Virtualization Engine 2.0
The Licensed Work is (c)2019 ZeroTier, Inc.
Additional Use Grant: You may make use of the Licensed Work, provided you
do not use it in any of the following ways:
--
* Sell hosted ZeroTier services as a "SaaS" Product
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.
(1) Operate or sell access to ZeroTier root servers,
network controllers, or authorization key or certificate
generation components of the Licensed Work as a
for-profit service, regardless of whether the use of
these components is sold alone or is bundled with other
services.
--
* Create Non-Open-Source Commercial Derviative Works
The above license does not apply to third party code included with or
linked against by ZeroTier software. See the third party code section
of the AUTHORS.md for an index of third party software included in
this software repository.
(2) Link or directly include the Licensed Work in a
commercial or for-profit application or other product
not distributed under an Open Source Initiative (OSI)
compliant license. See: https://opensource.org/licenses
Licenses for third party code are all relatively permissive: MIT,
BSD, and public domain. The only exception is the tap-windows driver
which is under the GPLv2, but this is only needed to produce the
binary tap device driver used by the ZeroTier service on Windows.
(3) Remove the name, logo, copyright, or other branding
material from the Licensed Work to create a "rebranded"
or "white labeled" version to distribute as part of
any commercial or for-profit product or service.
* Certain Government Uses
(4) Use or deploy the Licensed Work in a government
setting in support of any active government function
or operation with the exception of the following:
physical or mental health care, family and social
services, social welfare, senior care, child care, and
the care of persons with disabilities.
Change Date: 2023-01-01
Change License: Apache License version 2.0 as published by the Apache
Software Foundation
https://www.apache.org/licenses/
Alternative Licensing
If you would like to use the Licensed Work in any way that conflicts with
the stipulations of the Additional Use Grant, contact ZeroTier, Inc. to
obtain an alternative commercial license.
Visit us on the web at: https://www.zerotier.com/
Notice
The Business Source License (this document, or the "License") is not an Open
Source license. However, the Licensed Work will eventually be made available
under an Open Source License, as stated in this License.
For more information on the use of the Business Source License for ZeroTier
products, please visit the ZeroTier Business Source License FAQ at
https://zerotier.com/bsl-license.
For more information on the use of the Business Source License generally,
please visit the Adopting and Developing Business Source License FAQ at
https://mariadb.com/bsl-faq-adopting.
-----------------------------------------------------------------------------
Business Source License 1.1
Terms
The Licensor hereby grants you the right to copy, modify, create derivative
works, redistribute, and make non-production use of the Licensed Work. The
Licensor may make an Additional Use Grant, above, permitting limited
production use.
Effective on the Change Date, or the fourth anniversary of the first publicly
available distribution of a specific version of the Licensed Work under this
License, whichever comes first, the Licensor hereby grants you rights under
the terms of the Change License, and the rights granted in the paragraph
above terminate.
If your use of the Licensed Work does not comply with the requirements
currently in effect as described in this License, you must purchase a
commercial license from the Licensor, its affiliated entities, or authorized
resellers, or you must refrain from using the Licensed Work.
All copies of the original and modified Licensed Work, and derivative works
of the Licensed Work, are subject to this License. This License applies
separately for each version of the Licensed Work and the Change Date may vary
for each version of the Licensed Work released by Licensor.
You must conspicuously display this License on each original or modified copy
of the Licensed Work. If you receive the Licensed Work in original or
modified form from a third party, the terms and conditions set forth in this
License apply to your use of that work.
Any use of the Licensed Work in violation of this License will automatically
terminate your rights under this License for the current and all other
versions of the Licensed Work.
This License does not grant you any right in any trademark or logo of
Licensor or its affiliates (provided that you may use a trademark or logo of
Licensor as expressly required by this License).
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
TITLE.
MariaDB hereby grants you permission to use this Licenses text to license
your works, and to refer to it using the trademark "Business Source License",
as long as you comply with the Covenants of Licensor below.
Covenants of Licensor
In consideration of the right to use this Licenses text and the "Business
Source License" name and trademark, Licensor covenants to MariaDB, and to all
other recipients of the licensed work to be provided by Licensor:
1. To specify as the Change License the GPL Version 2.0 or any later version,
or a license that is compatible with GPL Version 2.0 or a later version,
where "compatible" means that software provided under the Change License can
be included in a program with software provided under GPL Version 2.0 or a
later version. Licensor may specify additional Change Licenses without
limitation.
2. To either: (a) specify an additional grant of rights to use that does not
impose any additional restriction on the right granted in this License, as
the Additional Use Grant; or (b) insert the text "None".
3. To specify a Change Date.
4. Not to modify this License in any other way.

View File

@ -270,11 +270,6 @@
*/
#define ZT_MULTICAST_TRANSMIT_TIMEOUT 5000
/**
* Delay between checks of peer pings, etc., and also related housekeeping tasks
*/
#define ZT_PING_CHECK_INVERVAL 5000
/**
* How frequently to check for changes to the system's network interfaces. When
* the service decides to use this constant it's because we want to react more

View File

@ -384,10 +384,13 @@ public:
private:
template<typename O>
static inline unsigned long _hc(const O &obj) { return (unsigned long)obj.hashCode(); }
static inline unsigned long _hc(const uint64_t i) { return (unsigned long)(i ^ (i >> 32)); }
static inline unsigned long _hc(const uint32_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
static inline unsigned long _hc(const uint16_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
static inline unsigned long _hc(const int i) { return ((unsigned long)i * (unsigned long)0x9e3379b1); }
static inline unsigned long _hc(void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
static inline unsigned long _hc(const void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
inline void _grow()
{

View File

@ -132,6 +132,9 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
return ADD_ACCEPTED_REDUNDANT;
switch(com.verify(RR,tPtr)) {
default:
RR->t->credentialRejected(tPtr,com,"invalid");
return Membership::ADD_REJECTED;
case Credential::VERIFY_OK:
_com = com;
return ADD_ACCEPTED_NEW;

View File

@ -556,7 +556,6 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u
RR(renv),
_uPtr(uptr),
_id(nwid),
_lastAnnouncedMulticastGroupsUpstream(0),
_mac(renv->identity.address(),nwid),
_portInitialized(false),
_lastConfigUpdate(0),
@ -1006,7 +1005,7 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
ZT_VirtualNetworkConfig ctmp;
bool oldPortInitialized;
{ // do things that require lock here, but unlock before calling callbacks
Mutex::Lock _l(_config_l);
Mutex::Lock l1(_config_l);
_config = nconf;
_lastConfigUpdate = RR->node->now();
@ -1237,30 +1236,14 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer)
return false;
}
bool Network::recentlyAssociatedWith(const Address &addr)
{
Mutex::Lock _l(_memberships_l);
const Membership *m = _memberships.get(addr);
return ((m)&&(m->recentlyAssociated(RR->node->now())));
}
void Network::clean()
void Network::doPeriodicTasks(void *tPtr)
{
const int64_t now = RR->node->now();
Mutex::Lock _l(_memberships_l);
Mutex::Lock l1(_memberships_l);
if (_destroyed)
return;
{
Hashtable< MulticastGroup,uint64_t >::Iterator i(_multicastGroupsBehindMe);
MulticastGroup *mg = (MulticastGroup *)0;
uint64_t *ts = (uint64_t *)0;
while (i.next(mg,ts)) {
if ((now - *ts) > (ZT_MULTICAST_LIKE_EXPIRE * 2))
_multicastGroupsBehindMe.erase(*mg);
}
}
{
Address *a = (Address *)0;
Membership *m = (Membership *)0;
@ -1269,14 +1252,20 @@ void Network::clean()
m->clean(now,_config);
}
}
}
Membership::AddCredentialResult Network::addCredential(void *tPtr,const CertificateOfMembership &com)
{
if (com.networkId() != _id)
return Membership::ADD_REJECTED;
Mutex::Lock _l(_memberships_l);
return _memberships[com.issuedTo()].addCredential(RR,tPtr,_config,com);
{
Mutex::Lock l2(_myMulticastGroups_l);
Hashtable< MulticastGroup,uint64_t >::Iterator i(_multicastGroupsBehindMe);
MulticastGroup *mg = (MulticastGroup *)0;
uint64_t *ts = (uint64_t *)0;
while (i.next(mg,ts)) {
if ((now - *ts) > (ZT_MULTICAST_LIKE_EXPIRE * 2))
_multicastGroupsBehindMe.erase(*mg);
}
_announceMulticastGroups(tPtr,false);
}
}
Membership::AddCredentialResult Network::addCredential(void *tPtr,const Address &sentFrom,const Revocation &rev)
@ -1284,7 +1273,7 @@ Membership::AddCredentialResult Network::addCredential(void *tPtr,const Address
if (rev.networkId() != _id)
return Membership::ADD_REJECTED;
Mutex::Lock _l(_memberships_l);
Mutex::Lock l1(_memberships_l);
Membership &m = _memberships[rev.target()];
const Membership::AddCredentialResult result = m.addCredential(RR,tPtr,_config,rev);
@ -1371,9 +1360,10 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
}
}
void Network::_announceMulticastGroups(void *tPtr)
void Network::_announceMulticastGroups(void *tPtr,bool force)
{
// Assumes _myMulticastGroups_l and _memberships_l are locked
const int64_t now = RR->node->now();
const std::vector<MulticastGroup> groups(_allMulticastGroups());
_announceMulticastGroupsTo(tPtr,controller(),groups);
{
@ -1381,7 +1371,10 @@ void Network::_announceMulticastGroups(void *tPtr)
Membership *m = (Membership *)0;
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m)) {
if (m->isAllowedOnNetwork(_config))
bool announce = m->multicastLikeGate(now); // force this to be called even if 'force' is true since it updates last push time
if ((!announce)&&(force))
announce = true;
if ((announce)&&(m->isAllowedOnNetwork(_config)))
_announceMulticastGroupsTo(tPtr,*a,groups);
}
}
@ -1415,7 +1408,7 @@ void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const st
std::vector<MulticastGroup> Network::_allMulticastGroups() const
{
// Assumes _lock is locked
// Assumes _myMulticastGroups_l is locked
std::vector<MulticastGroup> mgs;
mgs.reserve(_myMulticastGroups.size() + _multicastGroupsBehindMe.size() + 1);
mgs.insert(mgs.end(),_myMulticastGroups.begin(),_myMulticastGroups.end());

View File

@ -172,9 +172,9 @@ public:
* @param includeBridgedGroups If true, also check groups we've learned via bridging
* @return True if this network endpoint / peer is a member
*/
inline bool subscribedToMulticastGroup(const MulticastGroup &mg,bool includeBridgedGroups) const
inline bool subscribedToMulticastGroup(const MulticastGroup &mg,const bool includeBridgedGroups) const
{
Mutex::Lock _l(_myMulticastGroups_l);
Mutex::Lock l(_myMulticastGroups_l);
if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg))
return true;
else if (includeBridgedGroups)
@ -190,11 +190,11 @@ public:
*/
inline void multicastSubscribe(void *tPtr,const MulticastGroup &mg)
{
Mutex::Lock _l(_myMulticastGroups_l);
Mutex::Lock l(_myMulticastGroups_l);
if (!std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) {
_myMulticastGroups.insert(std::upper_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg),mg);
Mutex::Lock l2(_memberships_l);
_announceMulticastGroups(tPtr);
_announceMulticastGroups(tPtr,true);
}
}
@ -205,7 +205,7 @@ public:
*/
inline void multicastUnsubscribe(const MulticastGroup &mg)
{
Mutex::Lock _l(_myMulticastGroups_l);
Mutex::Lock l(_myMulticastGroups_l);
std::vector<MulticastGroup>::iterator i(std::lower_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg));
if ( (i != _myMulticastGroups.end()) && (*i == mg) )
_myMulticastGroups.erase(i);
@ -262,35 +262,10 @@ public:
*/
bool gate(void *tPtr,const SharedPtr<Peer> &peer);
/**
* Check whether a given peer has recently had an association with this network
*
* This checks whether a peer has communicated with us recently about this
* network and has possessed a valid certificate of membership. This may return
* true even if the peer has been offline for a while or no longer has a valid
* certificate of membership but had one recently.
*
* @param addr Peer address
* @return True if peer has recently associated
*/
bool recentlyAssociatedWith(const Address &addr);
/**
* Do periodic cleanup and housekeeping tasks
*/
void clean();
/**
* Push state to members such as multicast group memberships and latest COM (if needed)
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
inline void sendUpdatesToMembers(void *tPtr)
{
Mutex::Lock _l(_myMulticastGroups_l);
Mutex::Lock _l2(_memberships_l);
_announceMulticastGroups(tPtr);
}
void doPeriodicTasks(void *tPtr);
/**
* Find the node on this network that has this MAC behind it (if any)
@ -362,14 +337,20 @@ public:
*/
inline void learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,int64_t now)
{
Mutex::Lock _l(_multicastGroupsBehindMe_l);
Mutex::Lock l(_myMulticastGroups_l);
_multicastGroupsBehindMe.set(mg,now);
}
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfMembership &com);
Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfMembership &com)
{
if (com.networkId() != _id)
return Membership::ADD_REJECTED;
Mutex::Lock _l(_memberships_l);
return _memberships[com.issuedTo()].addCredential(RR,tPtr,_config,com);
}
/**
* Validate a credential and learn it if it passes certificate and other checks
@ -423,7 +404,7 @@ public:
}
/**
* Push credentials if we haven't done so in a very long time
* Push credentials if we haven't done so in a long time
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param to Destination peer address
@ -473,14 +454,13 @@ private:
ZT_VirtualNetworkStatus _status() const;
void _externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
bool _gate(const SharedPtr<Peer> &peer);
void _announceMulticastGroups(void *tPtr);
void _announceMulticastGroups(void *tPtr,bool force);
void _announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups);
std::vector<MulticastGroup> _allMulticastGroups() const;
const RuntimeEnvironment *const RR;
void *_uPtr;
const uint64_t _id;
uint64_t _lastAnnouncedMulticastGroupsUpstream;
MAC _mac; // local MAC address
bool _portInitialized;
@ -493,7 +473,7 @@ private:
struct _IncomingConfigChunk
{
_IncomingConfigChunk() { memset(this,0,sizeof(_IncomingConfigChunk)); }
_IncomingConfigChunk() : ts(0),updateId(0),haveChunks(0),haveBytes(0),data() {}
uint64_t ts;
uint64_t updateId;
uint64_t haveChunkIds[ZT_NETWORK_MAX_UPDATE_CHUNKS];
@ -516,7 +496,6 @@ private:
Hashtable<Address,Membership> _memberships;
Mutex _myMulticastGroups_l;
Mutex _multicastGroupsBehindMe_l;
Mutex _remoteBridgeRoutes_l;
Mutex _config_l;
Mutex _memberships_l;

View File

@ -58,7 +58,7 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
_uPtr(uptr),
_networks(8),
_now(now),
_lastPingCheck(0),
_lastPing(0),
_lastHousekeepingRun(0),
_lastMemoizedTraceSettings(0)
{
@ -184,101 +184,91 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
}
/*
// Function object used to traverse the peer list, check peer status, and ping
// those that need pinging.
struct _PingPeersThatNeedPing
struct _processBackgroundTasks_ping_eachRoot
{
inline _PingPeersThatNeedPing(const RuntimeEnvironment *renv,void *tPtr,Hashtable< Address,std::vector<InetAddress> > &alwaysContact,int64_t now) :
RR(renv),
_tPtr(tPtr),
_alwaysContact(alwaysContact),
_now(now),
_bestCurrentUpstream(RR->topology->getUpstreamPeer()),
online(false)
Hashtable< void *,bool > roots;
int64_t now;
void *tPtr;
bool online;
inline void operator()(const Root &root,const SharedPtr<Peer> &peer)
{
unsigned int v4SendCount = 0,v6SendCount = 0;
peer->ping(tPtr,now,v4SendCount,v6SendCount);
const InetAddress *contactAddrs[2];
unsigned int contactAddrCount = 0;
if (v4SendCount == 0) {
if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET))))
++contactAddrCount;
}
if (v6SendCount == 0) {
if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET6))))
++contactAddrCount;
}
for(unsigned int i=0;i<contactAddrCount;++i)
peer->sendHELLO(tPtr,-1,*contactAddrs[i],now);
if (!online)
online = ((now - peer->lastReceive()) <= ((ZT_PEER_PING_PERIOD * 2) + 5000));
roots.set((void *)peer.ptr(),true);
}
};
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
struct _processBackgroundTasks_ping_eachPeer
{
int64_t now;
void *tPtr;
Hashtable< void *,bool > *roots;
inline void operator()(const SharedPtr<Peer> &peer)
{
const std::vector<InetAddress> *const alwaysContactEndpoints = _alwaysContact.get(p->address());
if (alwaysContactEndpoints) {
online |= p->isAlive(_now);
const unsigned int sent = p->doPingAndKeepalive(_tPtr,_now);
bool contacted = (sent != 0);
if ((sent & 0x1) == 0) { // bit 0x1 == IPv4 sent
for(unsigned long k=0,ptr=(unsigned long)Utils::random();k<(unsigned long)alwaysContactEndpoints->size();++k) {
const InetAddress &addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()];
if (addr.ss_family == AF_INET) {
p->sendHELLO(_tPtr,-1,addr,_now);
contacted = true;
break;
}
}
}
if ((sent & 0x2) == 0) { // bit 0x2 == IPv6 sent
for(unsigned long k=0,ptr=(unsigned long)Utils::random();k<(unsigned long)alwaysContactEndpoints->size();++k) {
const InetAddress &addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()];
if (addr.ss_family == AF_INET6) {
p->sendHELLO(_tPtr,-1,addr,_now);
contacted = true;
break;
}
}
}
if ((!contacted)&&(_bestCurrentUpstream)) {
const SharedPtr<Path> up(_bestCurrentUpstream->getAppropriatePath(_now,true));
if (up)
p->sendHELLO(_tPtr,up->localSocket(),up->address(),_now);
}
_alwaysContact.erase(p->address()); // after this we'll WHOIS all upstreams that remain
} else if (p->isActive(_now)) {
p->doPingAndKeepalive(_tPtr,_now);
if (!roots->contains((void *)peer.ptr())) {
unsigned int v4SendCount = 0,v6SendCount = 0;
peer->ping(tPtr,now,v4SendCount,v6SendCount);
}
}
const RuntimeEnvironment *RR;
void *_tPtr;
Hashtable< Address,std::vector<InetAddress> > &_alwaysContact;
const int64_t _now;
const SharedPtr<Peer> _bestCurrentUpstream;
bool online;
};
*/
ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64_t *nextBackgroundTaskDeadline)
{
_now = now;
Mutex::Lock bl(_backgroundTasksLock);
unsigned long timeUntilNextPingCheck = ZT_PING_CHECK_INVERVAL;
const int64_t timeSinceLastPingCheck = now - _lastPingCheck;
unsigned long timeUntilNextPing = ZT_PEER_PING_PERIOD;
const int64_t timeSinceLastPing = now - _lastPing;
if (timeSinceLastPing >= ZT_PEER_PING_PERIOD) {
_lastPing = now;
try {
_processBackgroundTasks_ping_eachRoot rf;
rf.now = now;
rf.tPtr = tptr;
rf.online = false;
RR->topology->eachRoot(rf);
_processBackgroundTasks_ping_eachPeer pf;
pf.now = now;
pf.tPtr = tptr;
pf.roots = &rf.roots;
RR->topology->eachPeer(pf);
if (rf.online != _online) {
_online = rf.online;
postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
}
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
}
/*
if (timeSinceLastPingCheck >= ZT_PING_CHECK_INVERVAL) {
try {
_lastPingCheck = now;
// Clean up any old local controller auth memoizations. This is an
// optimization for network controllers to know whether to accept
// or trust nodes without doing an extra cert check.
{
_localControllerAuthorizations_m.lock();
Hashtable< _LocalControllerAuth,int64_t >::Iterator i(_localControllerAuthorizations);
_LocalControllerAuth *k = (_LocalControllerAuth *)0;
int64_t *v = (int64_t *)0;
while (i.next(k,v)) {
if ((*v - now) > (ZT_NETWORK_AUTOCONF_DELAY * 3)) {
_localControllerAuthorizations.erase(*k);
}
}
_localControllerAuthorizations_m.unlock();
}
/*
// (1) Get peers we should remain connected to and (2) get networks that need config.
Hashtable< Address,std::vector<InetAddress> > alwaysContact;
RR->topology->getAlwaysContact(alwaysContact);
@ -319,13 +309,13 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
_online = pfunc.online;
if (oldOnline != _online)
postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
*/
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
} else {
timeUntilNextPingCheck -= (unsigned long)timeSinceLastPingCheck;
}
*/
if ((now - _lastMemoizedTraceSettings) >= (ZT_HOUSEKEEPING_PERIOD / 4)) {
_lastMemoizedTraceSettings = now;
@ -335,6 +325,22 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
if ((now - _lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) {
_lastHousekeepingRun = now;
try {
// Clean up any old local controller auth memoizations. This is an
// optimization for network controllers to know whether to accept
// or trust nodes without doing an extra cert check.
{
_localControllerAuthorizations_m.lock();
Hashtable< _LocalControllerAuth,int64_t >::Iterator i(_localControllerAuthorizations);
_LocalControllerAuth *k = (_LocalControllerAuth *)0;
int64_t *v = (int64_t *)0;
while (i.next(k,v)) {
if ((*v - now) > (ZT_NETWORK_AUTOCONF_DELAY * 3)) {
_localControllerAuthorizations.erase(*k);
}
}
_localControllerAuthorizations_m.unlock();
}
RR->topology->doPeriodicTasks(now);
RR->sa->clean(now);
RR->mc->clean(now);
@ -344,7 +350,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
}
try {
*nextBackgroundTaskDeadline = now + (int64_t)std::max(std::min(timeUntilNextPingCheck,RR->sw->doTimerTasks(tptr,now)),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY);
*nextBackgroundTaskDeadline = now + (int64_t)std::max(std::min(timeUntilNextPing,RR->sw->doTimerTasks(tptr,now)),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY);
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
@ -527,9 +533,9 @@ void Node::freeQueryResult(void *qr)
int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr)
{
if (Path::isAddressValidForPath(*(reinterpret_cast<const InetAddress *>(addr)))) {
Mutex::Lock _l(_directPaths_m);
if (std::find(_directPaths.begin(),_directPaths.end(),*(reinterpret_cast<const InetAddress *>(addr))) == _directPaths.end()) {
_directPaths.push_back(*(reinterpret_cast<const InetAddress *>(addr)));
Mutex::Lock _l(_localInterfaceAddresses_m);
if (std::find(_localInterfaceAddresses.begin(),_localInterfaceAddresses.end(),*(reinterpret_cast<const InetAddress *>(addr))) == _localInterfaceAddresses.end()) {
_localInterfaceAddresses.push_back(*(reinterpret_cast<const InetAddress *>(addr)));
return 1;
}
}
@ -538,8 +544,8 @@ int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr)
void Node::clearLocalInterfaceAddresses()
{
Mutex::Lock _l(_directPaths_m);
_directPaths.clear();
Mutex::Lock _l(_localInterfaceAddresses_m);
_localInterfaceAddresses.clear();
}
int Node::sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len)

View File

@ -170,8 +170,8 @@ public:
inline std::vector<InetAddress> directPaths() const
{
Mutex::Lock _l(_directPaths_m);
return _directPaths;
Mutex::Lock _l(_localInterfaceAddresses_m);
return _localInterfaceAddresses;
}
inline void postEvent(void *tPtr,ZT_Event ev,const void *md = (const void *)0) { _cb.eventCallback(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ev,md); }
@ -249,9 +249,6 @@ public:
virtual void ncSendRevocation(const Address &destination,const Revocation &rev);
virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode);
inline const Address &remoteTraceTarget() const { return _remoteTraceTarget; }
inline Trace::Level remoteTraceLevel() const { return _remoteTraceLevel; }
inline void setMultipathMode(uint8_t mode) { _multipathMode = mode; }
inline uint8_t getMultipathMode() { return _multipathMode; }
@ -278,8 +275,11 @@ private:
// Time of last identity verification indexed by InetAddress.rateGateHash() -- used in IncomingPacket::_doHELLO() via rateGateIdentityVerification()
int64_t _lastIdentityVerification[16384];
// Map that remembers if we have recently sent a network config to someone
// querying us as a controller.
/* Map that remembers if we have recently sent a network config to someone
* querying us as a controller. This is an optimization to allow network
* controllers to know whether to treat things like multicast queries the
* way authorized members would be treated without requiring an extra cert
* validation. */
struct _LocalControllerAuth
{
uint64_t nwid,address;
@ -291,21 +291,21 @@ private:
Hashtable< _LocalControllerAuth,int64_t > _localControllerAuthorizations;
Mutex _localControllerAuthorizations_m;
// Curreently joined networks
Hashtable< uint64_t,SharedPtr<Network> > _networks;
Mutex _networks_m;
std::vector<InetAddress> _directPaths;
Mutex _directPaths_m;
// Local interface addresses as reported by the code harnessing this Node
std::vector<InetAddress> _localInterfaceAddresses;
Mutex _localInterfaceAddresses_m;
// Lock to ensure processBackgroundTasks never gets run concurrently
Mutex _backgroundTasksLock;
Address _remoteTraceTarget;
enum Trace::Level _remoteTraceLevel;
uint8_t _multipathMode;
volatile int64_t _now;
int64_t _lastPingCheck;
int64_t _lastPing;
int64_t _lastHousekeepingRun;
int64_t _lastMemoizedTraceSettings;
bool _online;

View File

@ -256,16 +256,6 @@ public:
*/
void ping(void *tPtr,int64_t now,unsigned int &v4SendCount,unsigned int &v6SendCount);
/**
* Clear paths whose localSocket(s) are in a CLOSED state or have an otherwise INVALID state.
* This should be called frequently so that we can detect and remove unproductive or invalid paths.
*
* Under the hood this is done periodically based on ZT_CLOSED_PATH_PRUNING_INTERVAL.
*
* @return Number of paths that were pruned this round
*/
unsigned int prunePaths();
/**
* Reset paths within a given IP scope and address family
*
@ -304,7 +294,7 @@ public:
/**
* @return True if we've heard from this peer in less than ZT_PEER_ACTIVITY_TIMEOUT
*/
inline bool isAlive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
inline bool alive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
/**
* @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths

View File

@ -49,7 +49,7 @@ typedef struct sha512_ctx_tag {
uint64_t len[2];
uint64_t val[8];
uint8_t *payload_addr;
uint64_t payload_len;
unsigned long payload_len;
} sha512_ctx_t;
#define LSR(x,n) (x >> n)
@ -103,7 +103,7 @@ static inline void sha512_memclr(uint8_t *dst, uint32_t size)
for (;i < size;i++) { *dst++ = 0; }
}
static inline void sha512_init_512(sha512_ctx_t *sha512_ctx, uint8_t *payload_addr, uint64_t payload_len)
static inline void sha512_init_512(sha512_ctx_t *sha512_ctx, uint8_t *payload_addr, unsigned long payload_len)
{
sha512_memclr((uint8_t *)sha512_ctx,sizeof(sha512_ctx_t));
sha512_ctx->val[0] = 0x6A09E667F3BCC908ULL;
@ -121,7 +121,7 @@ static inline void sha512_init_512(sha512_ctx_t *sha512_ctx, uint8_t *payload_ad
sha512_ctx->len[1] = payload_len >> 61;
}
static inline void sha512_init_384(sha512_ctx_t *sha512_ctx, uint8_t *payload_addr, uint64_t payload_len)
static inline void sha512_init_384(sha512_ctx_t *sha512_ctx, uint8_t *payload_addr, unsigned long payload_len)
{
sha512_memclr((uint8_t *)sha512_ctx,sizeof(sha512_ctx_t));
sha512_ctx->val[0] = 0xCBBB9D5DC1059ED8ULL;

View File

@ -42,6 +42,8 @@
namespace ZeroTier {
#if 0
#ifdef __APPLE__
#define ZT_HAVE_NATIVE_SHA512 1
static inline void SHA512(void *digest,const void *data,unsigned int len)
@ -78,6 +80,8 @@ static inline void SHA384(void *digest,const void *data,unsigned int len)
}
#endif
#endif
#ifndef ZT_HAVE_NATIVE_SHA512
void SHA512(void *digest,const void *data,unsigned int len);
void SHA384(void *digest,const void *data,unsigned int len);

View File

@ -55,7 +55,7 @@ public:
_family(inetAddressFamily),
_scope(scope) {}
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { p->resetWithinScope(_tPtr,_scope,_family,_now); }
inline void operator()(const SharedPtr<Peer> &p) { p->resetWithinScope(_tPtr,_scope,_family,_now); }
private:
uint64_t _now;

View File

@ -177,7 +177,7 @@ public:
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
while (i.next(a,p)) {
if (!(*p)->isAlive(now)) {
if (!(*p)->alive(now)) {
_peers.erase(*a);
}
}
@ -230,16 +230,13 @@ public:
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
while (i.next(a,p)) {
f(*this,*((const SharedPtr<Peer> *)p));
f(*((const SharedPtr<Peer> *)p));
}
}
/**
* Apply a function or function object to all roots
*
* Arguments to the function are this topology object, the root in
* question, and a pointer to the peer corresponding to it.
*
* This locks the root list during execution but other operations
* are fine.
*
@ -262,7 +259,7 @@ public:
_peers.set(rp->address(),rp);
}
}
f(*this,*i,rp);
f(*i,rp);
}
}

View File

@ -47,7 +47,7 @@ namespace ZeroTier {
#ifdef ZT_TRACE
static void ZT_LOCAL_TRACE(void *const tPtr,const RuntimeEnvironment *const RR,const char *const fmt,...)
{
char traceMsgBuf[1024];
char traceMsgBuf[2048];
va_list ap;
va_start(ap,fmt);
vsnprintf(traceMsgBuf,sizeof(traceMsgBuf),fmt,ap);
@ -61,20 +61,10 @@ static void ZT_LOCAL_TRACE(void *const tPtr,const RuntimeEnvironment *const RR,c
void Trace::resettingPathsInScope(void *const tPtr,const Address &reporter,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,const InetAddress::IpScope scope)
{
#ifdef ZT_TRACE
char tmp[128];
ZT_LOCAL_TRACE(tPtr,RR,"RESET and revalidate paths in scope %d; new phy address %s reported by trusted peer %.10llx",(int)scope,myPhysicalAddress.toIpString(tmp),reporter.toInt());
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE_S);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,reporter);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,reporterPhysicalAddress.toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_PHYADDR,myPhysicalAddress.toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__IP_SCOPE,(uint64_t)scope);
if (_globalTarget)
_send(tPtr,d,_globalTarget);
_spamToAllNetworks(tPtr,d,Trace::LEVEL_NORMAL);
#endif
}
void Trace::peerConfirmingUnknownPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr<Path> &path,const uint64_t packetId,const Packet::Verb verb)
@ -87,7 +77,7 @@ void Trace::peerConfirmingUnknownPath(void *const tPtr,const uint64_t networkId,
std::pair<Address,Trace::Level> byn;
if (networkId) { Mutex::Lock l(_byNet_m); _byNet.get(networkId,byn); }
if ((_globalTarget)||(byn.first)) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_NORMAL)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
@ -99,11 +89,7 @@ void Trace::peerConfirmingUnknownPath(void *const tPtr,const uint64_t networkId,
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -137,7 +123,7 @@ void Trace::peerLearnedNewPath(void *const tPtr,const uint64_t networkId,Peer &p
std::pair<Address,Trace::Level> byn;
if (networkId) { Mutex::Lock l(_byNet_m); _byNet.get(networkId,byn); }
if ((_globalTarget)||(byn.first)) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_NORMAL)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
@ -146,37 +132,7 @@ void Trace::peerLearnedNewPath(void *const tPtr,const uint64_t networkId,Peer &p
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,peer.address());
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,newPath->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,newPath->localSocket());
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
}
}
void Trace::peerRedirected(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr<Path> &newPath)
{
char tmp[128];
if (!newPath) return; // sanity check
ZT_LOCAL_TRACE(tPtr,RR,"explicit redirect from %.10llx to path %s",peer.address().toInt(),newPath->address().toString(tmp));
std::pair<Address,Trace::Level> byn;
if (networkId) { Mutex::Lock l(_byNet_m); _byNet.get(networkId,byn); }
if ((_globalTarget)||(byn.first)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED_S);
if (networkId)
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,networkId);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,peer.address());
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,newPath->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,newPath->localSocket());
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -192,7 +148,7 @@ void Trace::outgoingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network
std::pair<Address,Trace::Level> byn;
{ Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); }
if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) ) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__OUTGOING_NETWORK_FRAME_DROPPED_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network->id());
@ -203,11 +159,7 @@ void Trace::outgoingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network
d.add(ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH,(uint64_t)frameLen);
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE))
_send(tPtr,d,_globalTarget);
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE))
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -221,7 +173,7 @@ void Trace::incomingNetworkAccessDenied(void *const tPtr,const SharedPtr<Network
std::pair<Address,Trace::Level> byn;
{ Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); }
if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) ) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_NORMAL)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_ACCESS_DENIED_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
@ -232,11 +184,7 @@ void Trace::incomingNetworkAccessDenied(void *const tPtr,const SharedPtr<Network
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network->id());
if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE))
_send(tPtr,d,_globalTarget);
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE))
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -250,7 +198,7 @@ void Trace::incomingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network
std::pair<Address,Trace::Level> byn;
{ Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); }
if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) ) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_FRAME_DROPPED_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
@ -265,11 +213,7 @@ void Trace::incomingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network
d.add(ZT_REMOTE_TRACE_FIELD__DEST_MAC,destMac.toInt());
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE))
_send(tPtr,d,_globalTarget);
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE))
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -279,21 +223,18 @@ void Trace::incomingPacketMessageAuthenticationFailure(void *const tPtr,const Sh
ZT_LOCAL_TRACE(tPtr,RR,"MAC failed for packet %.16llx from %.10llx(%s)",packetId,source.toInt(),(path) ? path->address().toString(tmp) : "???");
if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS,(uint64_t)hops);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source);
if (path) {
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
_send(tPtr,d,_globalTarget);
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS,(uint64_t)hops);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source);
if (path) {
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
_spamToAllNetworks(tPtr,d,Trace::LEVEL_DEBUG);
}
void Trace::incomingPacketInvalid(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops,const Packet::Verb verb,const char *reason)
@ -302,22 +243,19 @@ void Trace::incomingPacketInvalid(void *const tPtr,const SharedPtr<Path> &path,c
ZT_LOCAL_TRACE(tPtr,RR,"INVALID packet %.16llx from %.10llx(%s) (%s)",packetId,source.toInt(),(path) ? path->address().toString(tmp) : "???",(reason) ? reason : "unknown reason");
if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB,(uint64_t)verb);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source);
if (path) {
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS,(uint64_t)hops);
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
_send(tPtr,d,_globalTarget);
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB,(uint64_t)verb);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source);
if (path) {
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS,(uint64_t)hops);
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
_spamToAllNetworks(tPtr,d,Trace::LEVEL_DEBUG);
}
void Trace::incomingPacketDroppedHELLO(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const char *reason)
@ -326,32 +264,22 @@ void Trace::incomingPacketDroppedHELLO(void *const tPtr,const SharedPtr<Path> &p
ZT_LOCAL_TRACE(tPtr,RR,"DROPPED HELLO from %.10llx(%s) (%s)",source.toInt(),(path) ? path->address().toString(tmp) : "???",(reason) ? reason : "???");
if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source);
if (path) {
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
_send(tPtr,d,_globalTarget);
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S);
d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId);
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source);
if (path) {
d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp));
d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket());
}
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
_spamToAllNetworks(tPtr,d,Trace::LEVEL_DEBUG);
}
void Trace::networkConfigRequestSent(void *const tPtr,const Network &network,const Address &controller)
{
ZT_LOCAL_TRACE(tPtr,RR,"requesting configuration for network %.16llx",network.id());
if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network.id());
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_CONTROLLER_ID,controller);
_send(tPtr,d,_globalTarget);
}
}
void Trace::networkFilter(
@ -375,7 +303,7 @@ void Trace::networkFilter(
std::pair<Address,Trace::Level> byn;
{ Mutex::Lock l(_byNet_m); _byNet.get(network.id(),byn); }
if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_RULES)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_RULES)) ) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_RULES)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network.id());
@ -396,11 +324,7 @@ void Trace::networkFilter(
d.add(ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH,(uint64_t)frameLen);
if (frameLen > 0)
d.add(ZT_REMOTE_TRACE_FIELD__FRAME_DATA,(const char *)frameData,(frameLen > 256) ? (int)256 : (int)frameLen);
if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_RULES))
_send(tPtr,d,_globalTarget);
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_RULES))
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -409,7 +333,7 @@ void Trace::credentialRejected(void *const tPtr,const CertificateOfMembership &c
std::pair<Address,Trace::Level> byn;
if (c.networkId()) { Mutex::Lock l(_byNet_m); _byNet.get(c.networkId(),byn); }
if ((_globalTarget)||(byn.first)) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId());
@ -419,11 +343,7 @@ void Trace::credentialRejected(void *const tPtr,const CertificateOfMembership &c
d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo());
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -432,7 +352,7 @@ void Trace::credentialRejected(void *const tPtr,const CertificateOfOwnership &c,
std::pair<Address,Trace::Level> byn;
if (c.networkId()) { Mutex::Lock l(_byNet_m); _byNet.get(c.networkId(),byn); }
if ((_globalTarget)||(byn.first)) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId());
@ -442,11 +362,7 @@ void Trace::credentialRejected(void *const tPtr,const CertificateOfOwnership &c,
d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo());
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -455,7 +371,7 @@ void Trace::credentialRejected(void *const tPtr,const Capability &c,const char *
std::pair<Address,Trace::Level> byn;
if (c.networkId()) { Mutex::Lock l(_byNet_m); _byNet.get(c.networkId(),byn); }
if ((_globalTarget)||(byn.first)) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId());
@ -465,11 +381,7 @@ void Trace::credentialRejected(void *const tPtr,const Capability &c,const char *
d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo());
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -478,7 +390,7 @@ void Trace::credentialRejected(void *const tPtr,const Tag &c,const char *reason)
std::pair<Address,Trace::Level> byn;
if (c.networkId()) { Mutex::Lock l(_byNet_m); _byNet.get(c.networkId(),byn); }
if ((_globalTarget)||(byn.first)) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId());
@ -489,11 +401,7 @@ void Trace::credentialRejected(void *const tPtr,const Tag &c,const char *reason)
d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO,(uint64_t)c.value());
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
@ -502,7 +410,7 @@ void Trace::credentialRejected(void *const tPtr,const Revocation &c,const char *
std::pair<Address,Trace::Level> byn;
if (c.networkId()) { Mutex::Lock l(_byNet_m); _byNet.get(c.networkId(),byn); }
if ((_globalTarget)||(byn.first)) {
if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) {
Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d;
d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S);
d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId());
@ -511,18 +419,12 @@ void Trace::credentialRejected(void *const tPtr,const Revocation &c,const char *
d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_REVOCATION_TARGET,c.target());
if (reason)
d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason);
if (_globalTarget)
_send(tPtr,d,_globalTarget);
if (byn.first)
_send(tPtr,d,byn.first);
_send(tPtr,d,byn.first);
}
}
void Trace::updateMemoizedSettings()
{
_globalTarget = RR->node->remoteTraceTarget();
_globalLevel = RR->node->remoteTraceLevel();
const std::vector< SharedPtr<Network> > nws(RR->node->allNetworks());
{
Mutex::Lock l(_byNet_m);

View File

@ -73,8 +73,7 @@ public:
LEVEL_NORMAL = 0,
LEVEL_VERBOSE = 10,
LEVEL_RULES = 15,
LEVEL_DEBUG = 20,
LEVEL_INSANE = 30
LEVEL_DEBUG = 20
};
/**
@ -119,25 +118,17 @@ public:
}
void resettingPathsInScope(void *const tPtr,const Address &reporter,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,const InetAddress::IpScope scope);
void peerConfirmingUnknownPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr<Path> &path,const uint64_t packetId,const Packet::Verb verb);
void peerLinkNowRedundant(void *const tPtr,Peer &peer);
void peerLinkNoLongerRedundant(void *const tPtr,Peer &peer);
void peerLinkAggregateStatistics(void *const tPtr,Peer &peer);
void peerLearnedNewPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr<Path> &newPath,const uint64_t packetId);
void peerRedirected(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr<Path> &newPath);
void incomingPacketMessageAuthenticationFailure(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops,const char *reason);
void incomingPacketInvalid(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops,const Packet::Verb verb,const char *reason);
void incomingPacketDroppedHELLO(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const char *reason);
void outgoingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network> &network,const MAC &sourceMac,const MAC &destMac,const unsigned int etherType,const unsigned int vlanId,const unsigned int frameLen,const char *reason);
void incomingNetworkAccessDenied(void *const tPtr,const SharedPtr<Network> &network,const SharedPtr<Path> &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,bool credentialsRequested);
void incomingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network> &network,const SharedPtr<Path> &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,const MAC &sourceMac,const MAC &destMac,const char *reason);
void networkConfigRequestSent(void *const tPtr,const Network &network,const Address &controller);
void networkFilter(
void *const tPtr,
@ -156,7 +147,6 @@ public:
const bool noTee,
const bool inbound,
const int accept);
void credentialRejected(void *const tPtr,const CertificateOfMembership &c,const char *reason);
void credentialRejected(void *const tPtr,const CertificateOfOwnership &c,const char *reason);
void credentialRejected(void *const tPtr,const Capability &c,const char *reason);
@ -171,8 +161,6 @@ private:
void _send(void *const tPtr,const Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> &d,const Address &dest);
void _spamToAllNetworks(void *const tPtr,const Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> &d,const Level level);
Address _globalTarget;
Trace::Level _globalLevel;
Hashtable< uint64_t,std::pair< Address,Trace::Level > > _byNet;
Mutex _byNet_m;
};