2013-07-04 20:56:19 +00:00
/*
2015-02-17 21:11:34 +00:00
* ZeroTier One - Network Virtualization Everywhere
2019-01-14 18:25:53 +00:00
* Copyright ( C ) 2011 - 2019 ZeroTier , Inc . https : //www.zerotier.com/
2013-07-04 20:56:19 +00:00
*
* 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
2019-01-14 18:25:53 +00:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2017-04-28 03:47:25 +00:00
*
* - -
*
* 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 .
2013-07-04 20:56:19 +00:00
*/
2013-12-07 00:49:20 +00:00
# ifndef ZT_NETWORK_HPP
# define ZT_NETWORK_HPP
2013-07-04 20:56:19 +00:00
2013-09-11 19:09:53 +00:00
# include <stdint.h>
2015-04-06 22:47:57 +00:00
# include "../include/ZeroTierOne.h"
2013-07-04 20:56:19 +00:00
# include <string>
2013-07-29 17:56:20 +00:00
# include <map>
2013-07-04 20:56:19 +00:00
# include <vector>
2013-09-11 20:08:31 +00:00
# include <algorithm>
2013-07-04 20:56:19 +00:00
# include <stdexcept>
2013-07-29 17:56:20 +00:00
# include "Constants.hpp"
2015-09-04 20:42:19 +00:00
# include "Hashtable.hpp"
2013-07-04 20:56:19 +00:00
# include "Address.hpp"
# include "Mutex.hpp"
# include "SharedPtr.hpp"
# include "AtomicCounter.hpp"
# include "MulticastGroup.hpp"
2013-07-10 21:24:27 +00:00
# include "MAC.hpp"
2013-07-29 17:56:20 +00:00
# include "Dictionary.hpp"
2014-09-24 21:02:16 +00:00
# include "Multicaster.hpp"
2016-08-05 22:02:01 +00:00
# include "Membership.hpp"
2013-10-18 16:01:48 +00:00
# include "NetworkConfig.hpp"
2013-10-07 19:29:03 +00:00
# include "CertificateOfMembership.hpp"
2013-07-04 20:56:19 +00:00
2016-09-27 18:33:48 +00:00
# define ZT_NETWORK_MAX_INCOMING_UPDATES 3
# define ZT_NETWORK_MAX_UPDATE_CHUNKS ((ZT_NETWORKCONFIG_DICT_CAPACITY / 1024) + 1)
2013-07-04 20:56:19 +00:00
namespace ZeroTier {
2013-07-29 17:56:20 +00:00
class RuntimeEnvironment ;
2015-10-01 18:11:52 +00:00
class Peer ;
2013-07-04 20:56:19 +00:00
/**
2013-07-27 20:20:08 +00:00
* A virtual LAN
2013-07-04 20:56:19 +00:00
*/
2018-01-27 02:34:56 +00:00
class Network
2013-07-04 20:56:19 +00:00
{
friend class SharedPtr < Network > ;
2013-09-04 13:27:56 +00:00
2015-04-02 02:09:18 +00:00
public :
2013-09-04 13:27:56 +00:00
/**
2015-04-15 20:09:20 +00:00
* Broadcast multicast group : ff : ff : ff : ff : ff : ff / 0
*/
static const MulticastGroup BROADCAST ;
2016-09-23 23:08:38 +00:00
/**
* Compute primary controller device ID from network ID
*/
2017-07-17 21:21:09 +00:00
static inline Address controllerFor ( uint64_t nwid ) { return Address ( nwid > > 24 ) ; }
2016-09-23 23:08:38 +00:00
2015-04-15 20:09:20 +00:00
/**
* Construct a new network
*
* Note that init ( ) should be called immediately after the network is
* constructed to actually configure the port .
*
2013-10-18 16:01:48 +00:00
* @ param renv Runtime environment
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2015-04-02 02:09:18 +00:00
* @ param nwid Network ID
2016-01-12 19:04:35 +00:00
* @ param uptr Arbitrary pointer used by externally - facing API ( for user use )
2017-06-01 19:33:05 +00:00
* @ param nconf Network config , if known
2013-09-04 13:27:56 +00:00
*/
2017-06-01 19:33:05 +00:00
Network ( const RuntimeEnvironment * renv , void * tPtr , uint64_t nwid , void * uptr , const NetworkConfig * nconf ) ;
2015-04-02 02:09:18 +00:00
~ Network ( ) ;
2013-07-29 21:11:00 +00:00
2016-09-23 23:08:38 +00:00
inline uint64_t id ( ) const { return _id ; }
inline Address controller ( ) const { return Address ( _id > > 24 ) ; }
inline bool multicastEnabled ( ) const { return ( _config . multicastLimit > 0 ) ; }
inline bool hasConfig ( ) const { return ( _config ) ; }
2017-07-17 21:21:09 +00:00
inline uint64_t lastConfigUpdate ( ) const { return _lastConfigUpdate ; }
2019-08-21 17:44:52 +00:00
inline ZT_VirtualNetworkStatus status ( ) const { return _status ( ) ; }
2016-09-23 23:08:38 +00:00
inline const NetworkConfig & config ( ) const { return _config ; }
inline const MAC & mac ( ) const { return _mac ; }
2016-08-04 20:01:14 +00:00
/**
* Apply filters to an outgoing packet
*
* This applies filters from our network config and , if that doesn ' t match ,
2016-08-31 23:50:22 +00:00
* our capabilities in ascending order of capability ID . Additional actions
2016-09-23 23:08:38 +00:00
* such as TEE may be taken , and credentials may be pushed , so this is not
* side - effect - free . It ' s basically step one in sending something over VL2 .
2016-08-04 20:01:14 +00:00
*
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-09-23 23:08:38 +00:00
* @ param noTee If true , do not TEE anything anywhere ( for two - pass filtering as done with multicast and bridging )
2016-08-04 20:01:14 +00:00
* @ param ztSource Source ZeroTier address
* @ param ztDest Destination ZeroTier address
* @ param macSource Ethernet layer source address
* @ param macDest Ethernet layer destination address
* @ param frameData Ethernet frame data
* @ param frameLen Ethernet frame payload length
* @ param etherType 16 - bit ethernet type ID
* @ param vlanId 16 - bit VLAN ID
2016-08-31 23:50:22 +00:00
* @ return True if packet should be sent , false if dropped or redirected
2016-08-04 20:01:14 +00:00
*/
bool filterOutgoingPacket (
2017-03-28 00:03:17 +00:00
void * tPtr ,
2016-08-31 23:50:22 +00:00
const bool noTee ,
2016-08-04 20:01:14 +00:00
const Address & ztSource ,
const Address & ztDest ,
const MAC & macSource ,
const MAC & macDest ,
const uint8_t * frameData ,
const unsigned int frameLen ,
const unsigned int etherType ,
2018-07-10 23:50:12 +00:00
const unsigned int vlanId ,
uint8_t & qosBucket ) ;
2016-08-04 20:01:14 +00:00
/**
* Apply filters to an incoming packet
*
* This applies filters from our network config and , if that doesn ' t match ,
* the peer ' s capabilities in ascending order of capability ID . If there is
* a match certain actions may be taken such as sending a copy of the packet
* to a TEE or REDIRECT target .
*
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-08-05 22:02:01 +00:00
* @ param sourcePeer Source Peer
2016-08-04 20:01:14 +00:00
* @ param ztDest Destination ZeroTier address
* @ param macSource Ethernet layer source address
* @ param macDest Ethernet layer destination address
* @ param frameData Ethernet frame data
* @ param frameLen Ethernet frame payload length
* @ param etherType 16 - bit ethernet type ID
* @ param vlanId 16 - bit VLAN ID
2016-08-29 22:54:06 +00:00
* @ return 0 = = drop , 1 = = accept , 2 = = accept even if bridged
2016-08-04 20:01:14 +00:00
*/
2016-08-29 22:54:06 +00:00
int filterIncomingPacket (
2017-03-28 00:03:17 +00:00
void * tPtr ,
2016-08-05 22:02:01 +00:00
const SharedPtr < Peer > & sourcePeer ,
2016-08-04 20:01:14 +00:00
const Address & ztDest ,
const MAC & macSource ,
const MAC & macDest ,
const uint8_t * frameData ,
const unsigned int frameLen ,
const unsigned int etherType ,
const unsigned int vlanId ) ;
2013-07-04 20:56:19 +00:00
/**
2016-09-23 23:08:38 +00:00
* Check whether we are subscribed to a multicast group
*
2014-10-10 01:32:05 +00:00
* @ param mg Multicast group
2016-09-23 23:08:38 +00:00
* @ param includeBridgedGroups If true , also check groups we ' ve learned via bridging
2014-10-10 01:32:05 +00:00
* @ return True if this network endpoint / peer is a member
*/
2019-08-14 22:59:45 +00:00
inline bool subscribedToMulticastGroup ( const MulticastGroup & mg , bool includeBridgedGroups ) const
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _myMulticastGroups_l ) ;
2019-08-14 22:59:45 +00:00
if ( std : : binary_search ( _myMulticastGroups . begin ( ) , _myMulticastGroups . end ( ) , mg ) )
return true ;
else if ( includeBridgedGroups )
return _multicastGroupsBehindMe . contains ( mg ) ;
return false ;
}
2019-08-21 17:44:52 +00:00
2015-04-07 01:27:24 +00:00
/**
* Subscribe to a multicast group
*
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2015-04-07 01:27:24 +00:00
* @ param mg New multicast group
*/
2019-08-14 22:59:45 +00:00
inline void multicastSubscribe ( void * tPtr , const MulticastGroup & mg )
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _myMulticastGroups_l ) ;
2019-08-14 22:59:45 +00:00
if ( ! std : : binary_search ( _myMulticastGroups . begin ( ) , _myMulticastGroups . end ( ) , mg ) ) {
_myMulticastGroups . insert ( std : : upper_bound ( _myMulticastGroups . begin ( ) , _myMulticastGroups . end ( ) , mg ) , mg ) ;
2019-08-21 17:44:52 +00:00
Mutex : : Lock l2 ( _memberships_l ) ;
_announceMulticastGroups ( tPtr ) ;
2019-08-14 22:59:45 +00:00
}
}
2019-08-15 17:49:50 +00:00
2015-04-07 01:27:24 +00:00
/**
* Unsubscribe from a multicast group
*
* @ param mg Multicast group
*/
2019-08-14 22:59:45 +00:00
inline void multicastUnsubscribe ( const MulticastGroup & mg )
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _myMulticastGroups_l ) ;
2019-08-14 22:59:45 +00:00
std : : vector < MulticastGroup > : : iterator i ( std : : lower_bound ( _myMulticastGroups . begin ( ) , _myMulticastGroups . end ( ) , mg ) ) ;
if ( ( i ! = _myMulticastGroups . end ( ) ) & & ( * i = = mg ) )
_myMulticastGroups . erase ( i ) ;
}
2019-08-21 17:44:52 +00:00
2016-08-09 20:14:38 +00:00
/**
* Handle an inbound network config chunk
*
2016-09-27 18:33:48 +00:00
* This is called from IncomingPacket to handle incoming network config
* chunks via OK ( NETWORK_CONFIG_REQUEST ) or NETWORK_CONFIG . It verifies
* each chunk and once assembled applies the configuration .
2016-08-09 20:14:38 +00:00
*
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2017-01-31 00:04:05 +00:00
* @ param packetId Packet ID or 0 if none ( e . g . via cluster path )
* @ param source Address of sender of chunk or NULL if none ( e . g . via cluster path )
* @ param chunk Buffer containing chunk
2016-09-27 18:33:48 +00:00
* @ param ptr Index of chunk and related fields in packet
* @ return Update ID if update was fully assembled and accepted or 0 otherwise
2016-08-09 20:14:38 +00:00
*/
2017-03-28 00:03:17 +00:00
uint64_t handleConfigChunk ( void * tPtr , const uint64_t packetId , const Address & source , const Buffer < ZT_PROTO_MAX_PACKET_LENGTH > & chunk , unsigned int ptr ) ;
2016-08-09 20:14:38 +00:00
2016-11-10 19:54:47 +00:00
/**
* Set network configuration
*
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-11-10 19:54:47 +00:00
* @ param nconf Network configuration
* @ param saveToDisk Save to disk ? Used during loading , should usually be true otherwise .
* @ return 0 = = bad , 1 = = accepted but duplicate / unchanged , 2 = = accepted and new
*/
2017-03-28 00:03:17 +00:00
int setConfiguration ( void * tPtr , const NetworkConfig & nconf , bool saveToDisk ) ;
2016-11-10 19:54:47 +00:00
2014-01-28 07:13:36 +00:00
/**
2015-04-15 22:12:09 +00:00
* Set netconf failure to ' access denied ' - - called in IncomingPacket when controller reports this
2013-07-29 17:56:20 +00:00
*/
2019-08-21 17:44:52 +00:00
inline void setAccessDenied ( ) { _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED ; }
2014-01-28 07:13:36 +00:00
/**
2016-09-23 23:08:38 +00:00
* Set netconf failure to ' not found ' - - called by IncomingPacket when controller reports this
2014-01-28 07:13:36 +00:00
*/
2019-08-21 17:44:52 +00:00
inline void setNotFound ( ) { _netconfFailure = NETCONF_FAILURE_NOT_FOUND ; }
2013-07-29 17:56:20 +00:00
/**
* Causes this network to request an updated configuration from its master node now
2017-03-28 00:03:17 +00:00
*
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2013-07-29 17:56:20 +00:00
*/
2017-03-28 00:03:17 +00:00
void requestConfiguration ( void * tPtr ) ;
2013-07-29 17:56:20 +00:00
2013-07-29 21:11:00 +00:00
/**
2016-09-21 04:21:34 +00:00
* Determine whether this peer is permitted to communicate on this network
2017-03-28 00:03:17 +00:00
*
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @ param peer Peer to check
2016-09-09 16:32:00 +00:00
*/
2017-03-28 00:03:17 +00:00
bool gate ( void * tPtr , const SharedPtr < Peer > & peer ) ;
2016-09-09 16:32:00 +00:00
2017-07-13 17:51:05 +00:00
/**
* 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 ) ;
2019-08-21 17:44:52 +00:00
2013-07-29 21:11:00 +00:00
/**
2016-09-23 23:08:38 +00:00
* Do periodic cleanup and housekeeping tasks
2013-07-29 21:11:00 +00:00
*/
void clean ( ) ;
2016-09-07 22:15:52 +00:00
/**
2016-09-09 02:48:05 +00:00
* Push state to members such as multicast group memberships and latest COM ( if needed )
2017-03-28 00:03:17 +00:00
*
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-09-07 22:15:52 +00:00
*/
2017-03-28 00:03:17 +00:00
inline void sendUpdatesToMembers ( void * tPtr )
2016-09-07 22:15:52 +00:00
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _myMulticastGroups_l ) ;
Mutex : : Lock _l2 ( _memberships_l ) ;
_announceMulticastGroups ( tPtr ) ;
2016-09-07 22:15:52 +00:00
}
2014-06-11 00:18:59 +00:00
/**
2014-09-26 19:23:43 +00:00
* Find the node on this network that has this MAC behind it ( if any )
*
2014-06-11 00:18:59 +00:00
* @ param mac MAC address
2014-09-26 19:23:43 +00:00
* @ return ZeroTier address of bridge to this MAC
2014-06-11 00:18:59 +00:00
*/
inline Address findBridgeTo ( const MAC & mac ) const
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _remoteBridgeRoutes_l ) ;
2015-09-04 20:53:48 +00:00
const Address * const br = _remoteBridgeRoutes . get ( mac ) ;
2016-09-09 18:36:10 +00:00
return ( ( br ) ? * br : Address ( ) ) ;
2014-06-11 00:18:59 +00:00
}
2019-03-14 21:29:15 +00:00
/**
* @ return True if QoS is in effect for this network
*/
inline bool qosEnabled ( ) { return false ; }
2014-06-11 00:18:59 +00:00
/**
* Set a bridge route
*
* @ param mac MAC address of destination
* @ param addr Bridge this MAC is reachable behind
*/
2019-08-20 02:21:33 +00:00
inline void learnBridgeRoute ( const MAC & mac , const Address & addr )
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _remoteBridgeRoutes_l ) ;
2019-08-20 02:21:33 +00:00
_remoteBridgeRoutes [ mac ] = addr ;
2019-08-21 17:44:52 +00:00
2019-08-20 02:21:33 +00:00
// Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes
while ( _remoteBridgeRoutes . size ( ) > ZT_MAX_BRIDGE_ROUTES ) {
Hashtable < Address , unsigned long > counts ;
Address maxAddr ;
unsigned long maxCount = 0 ;
2019-08-21 17:44:52 +00:00
2019-08-20 02:21:33 +00:00
MAC * m = ( MAC * ) 0 ;
Address * a = ( Address * ) 0 ;
2019-08-21 17:44:52 +00:00
2019-08-20 02:21:33 +00:00
// Find the address responsible for the most entries
{
Hashtable < MAC , Address > : : Iterator i ( _remoteBridgeRoutes ) ;
while ( i . next ( m , a ) ) {
const unsigned long c = + + counts [ * a ] ;
if ( c > maxCount ) {
maxCount = c ;
maxAddr = * a ;
}
}
}
2019-08-21 17:44:52 +00:00
2019-08-20 02:21:33 +00:00
// Kill this address from our table, since it's most likely spamming us
{
Hashtable < MAC , Address > : : Iterator i ( _remoteBridgeRoutes ) ;
while ( i . next ( m , a ) ) {
if ( * a = = maxAddr )
_remoteBridgeRoutes . erase ( * m ) ;
}
}
}
}
2019-08-21 17:44:52 +00:00
2014-06-13 21:06:34 +00:00
/**
* Learn a multicast group that is bridged to our tap device
*
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2014-06-13 21:06:34 +00:00
* @ param mg Multicast group
2014-06-27 01:13:48 +00:00
* @ param now Current time
2014-06-13 21:06:34 +00:00
*/
2019-08-20 02:21:33 +00:00
inline void learnBridgedMulticastGroup ( void * tPtr , const MulticastGroup & mg , int64_t now )
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _multicastGroupsBehindMe_l ) ;
2019-08-20 02:21:33 +00:00
_multicastGroupsBehindMe . set ( mg , now ) ;
}
2014-06-13 21:06:34 +00:00
2016-08-09 00:33:26 +00:00
/**
2016-09-23 23:08:38 +00:00
* Validate a credential and learn it if it passes certificate and other checks
2016-08-09 00:33:26 +00:00
*/
2017-03-28 00:03:17 +00:00
Membership : : AddCredentialResult addCredential ( void * tPtr , const CertificateOfMembership & com ) ;
2016-08-09 00:33:26 +00:00
/**
2016-09-23 23:08:38 +00:00
* Validate a credential and learn it if it passes certificate and other checks
2016-08-09 00:33:26 +00:00
*/
2017-03-28 00:03:17 +00:00
inline Membership : : AddCredentialResult addCredential ( void * tPtr , const Capability & cap )
2016-08-09 00:33:26 +00:00
{
if ( cap . networkId ( ) ! = _id )
2016-09-23 23:08:38 +00:00
return Membership : : ADD_REJECTED ;
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 22:59:45 +00:00
return _memberships [ cap . issuedTo ( ) ] . addCredential ( RR , tPtr , _config , cap ) ;
2016-08-09 00:33:26 +00:00
}
/**
2016-09-23 23:08:38 +00:00
* Validate a credential and learn it if it passes certificate and other checks
2016-08-09 00:33:26 +00:00
*/
2017-03-28 00:03:17 +00:00
inline Membership : : AddCredentialResult addCredential ( void * tPtr , const Tag & tag )
2016-08-09 00:33:26 +00:00
{
if ( tag . networkId ( ) ! = _id )
2016-09-23 23:08:38 +00:00
return Membership : : ADD_REJECTED ;
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 22:59:45 +00:00
return _memberships [ tag . issuedTo ( ) ] . addCredential ( RR , tPtr , _config , tag ) ;
2016-08-09 00:33:26 +00:00
}
2016-08-23 20:46:36 +00:00
/**
2016-09-23 23:08:38 +00:00
* Validate a credential and learn it if it passes certificate and other checks
*/
2017-03-28 00:03:17 +00:00
Membership : : AddCredentialResult addCredential ( void * tPtr , const Address & sentFrom , const Revocation & rev ) ;
2016-09-23 23:08:38 +00:00
2017-02-23 19:47:36 +00:00
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
2017-03-28 00:03:17 +00:00
inline Membership : : AddCredentialResult addCredential ( void * tPtr , const CertificateOfOwnership & coo )
2017-02-23 19:47:36 +00:00
{
if ( coo . networkId ( ) ! = _id )
return Membership : : ADD_REJECTED ;
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 22:59:45 +00:00
return _memberships [ coo . issuedTo ( ) ] . addCredential ( RR , tPtr , _config , coo ) ;
2017-02-23 19:47:36 +00:00
}
2016-09-23 23:08:38 +00:00
/**
* Force push credentials ( COM , etc . ) to a peer now
2016-08-23 20:46:36 +00:00
*
2017-03-28 00:03:17 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-09-23 23:08:38 +00:00
* @ param to Destination peer address
* @ param now Current time
2016-08-23 20:46:36 +00:00
*/
2017-10-02 22:52:57 +00:00
inline void pushCredentialsNow ( void * tPtr , const Address & to , const int64_t now )
2016-08-23 20:46:36 +00:00
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 22:59:45 +00:00
_memberships [ to ] . pushCredentials ( RR , tPtr , now , to , _config ) ;
2016-08-23 20:46:36 +00:00
}
2019-06-25 20:42:20 +00:00
/**
* Push credentials if we haven ' t done so in a very long time
2019-08-21 17:44:52 +00:00
*
2019-06-25 20:42:20 +00:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @ param to Destination peer address
* @ param now Current time
*/
inline void pushCredentialsIfNeeded ( void * tPtr , const Address & to , const int64_t now )
{
2019-08-21 17:44:52 +00:00
const int64_t tout = std : : min ( _config . credentialTimeMaxDelta , ( int64_t ) ZT_PEER_ACTIVITY_TIMEOUT ) ;
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 22:59:45 +00:00
Membership & m = _memberships [ to ] ;
2019-08-21 17:44:52 +00:00
if ( ( ( now - m . lastPushedCredentials ( ) ) + 5000 ) > = tout )
2019-08-03 03:43:02 +00:00
m . pushCredentials ( RR , tPtr , now , to , _config ) ;
2019-06-25 20:42:20 +00:00
}
2014-08-22 00:49:05 +00:00
/**
* Destroy this network
*
2017-04-11 15:47:02 +00:00
* This sets the network to completely remove itself on delete . This also prevents the
* call of the normal port shutdown event on delete .
2014-08-22 00:49:05 +00:00
*/
2019-08-21 17:44:52 +00:00
inline void destroy ( )
{
_memberships_l . lock ( ) ;
_config_l . lock ( ) ;
_destroyed = true ;
_config_l . unlock ( ) ;
_memberships_l . unlock ( ) ;
}
2014-08-22 00:49:05 +00:00
2016-01-12 19:04:35 +00:00
/**
2016-09-23 23:08:38 +00:00
* Get this network ' s config for export via the ZT core API
*
* @ param ec Buffer to fill with externally - visible network configuration
*/
inline void externalConfig ( ZT_VirtualNetworkConfig * ec ) const
{
2019-08-21 17:44:52 +00:00
Mutex : : Lock _l ( _config_l ) ;
2016-09-23 23:08:38 +00:00
_externalConfig ( ec ) ;
}
/**
* @ return Externally usable pointer - to - pointer exported via the core API
2016-01-12 19:04:35 +00:00
*/
2017-04-11 15:47:02 +00:00
inline void * * userPtr ( ) { return & _uPtr ; }
2016-01-12 19:04:35 +00:00
2013-07-04 20:56:19 +00:00
private :
2015-09-24 23:21:36 +00:00
ZT_VirtualNetworkStatus _status ( ) const ;
void _externalConfig ( ZT_VirtualNetworkConfig * ec ) const ; // assumes _lock is locked
2016-09-09 02:48:05 +00:00
bool _gate ( const SharedPtr < Peer > & peer ) ;
2019-08-21 17:44:52 +00:00
void _announceMulticastGroups ( void * tPtr ) ;
2017-03-28 00:03:17 +00:00
void _announceMulticastGroupsTo ( void * tPtr , const Address & peer , const std : : vector < MulticastGroup > & allMulticastGroups ) ;
2015-05-25 21:21:05 +00:00
std : : vector < MulticastGroup > _allMulticastGroups ( ) const ;
2015-04-06 23:52:52 +00:00
2016-09-23 23:08:38 +00:00
const RuntimeEnvironment * const RR ;
2016-01-12 21:17:30 +00:00
void * _uPtr ;
2016-09-23 23:08:38 +00:00
const uint64_t _id ;
2016-09-07 22:15:52 +00:00
uint64_t _lastAnnouncedMulticastGroupsUpstream ;
2014-06-11 00:18:59 +00:00
MAC _mac ; // local MAC address
2016-09-27 18:33:48 +00:00
bool _portInitialized ;
2014-06-11 00:18:59 +00:00
2015-09-04 20:53:48 +00:00
std : : vector < MulticastGroup > _myMulticastGroups ; // multicast groups that we belong to (according to tap)
Hashtable < MulticastGroup , uint64_t > _multicastGroupsBehindMe ; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge)
2015-09-04 21:14:32 +00:00
Hashtable < MAC , Address > _remoteBridgeRoutes ; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges)
2014-09-19 01:28:14 +00:00
2016-04-12 19:11:34 +00:00
NetworkConfig _config ;
2016-09-27 18:33:48 +00:00
uint64_t _lastConfigUpdate ;
struct _IncomingConfigChunk
{
2017-03-18 00:15:23 +00:00
_IncomingConfigChunk ( ) { memset ( this , 0 , sizeof ( _IncomingConfigChunk ) ) ; }
2016-09-27 18:33:48 +00:00
uint64_t ts ;
uint64_t updateId ;
uint64_t haveChunkIds [ ZT_NETWORK_MAX_UPDATE_CHUNKS ] ;
unsigned long haveChunks ;
unsigned long haveBytes ;
Dictionary < ZT_NETWORKCONFIG_DICT_CAPACITY > data ;
} ;
_IncomingConfigChunk _incomingConfigChunks [ ZT_NETWORK_MAX_INCOMING_UPDATES ] ;
2014-06-11 00:18:59 +00:00
2019-08-21 17:44:52 +00:00
volatile bool _destroyed ;
2014-06-11 00:18:59 +00:00
2019-08-21 17:44:52 +00:00
volatile enum {
2014-01-28 07:13:36 +00:00
NETCONF_FAILURE_NONE ,
NETCONF_FAILURE_ACCESS_DENIED ,
NETCONF_FAILURE_NOT_FOUND ,
NETCONF_FAILURE_INIT_FAILED
} _netconfFailure ;
2016-09-27 18:33:48 +00:00
int _portError ; // return value from port config callback
2014-06-11 00:18:59 +00:00
2016-08-05 22:02:01 +00:00
Hashtable < Address , Membership > _memberships ;
2019-08-21 17:44:52 +00:00
Mutex _myMulticastGroups_l ;
Mutex _multicastGroupsBehindMe_l ;
Mutex _remoteBridgeRoutes_l ;
Mutex _config_l ;
Mutex _memberships_l ;
2013-07-04 20:56:19 +00:00
AtomicCounter __refCount ;
} ;
2018-06-08 00:25:27 +00:00
} // namespace ZeroTier
2013-07-04 20:56:19 +00:00
# endif