2013-07-04 16:56:19 -04:00
/*
2019-08-23 09:23:39 -07:00
* Copyright ( c ) 2019 ZeroTier , Inc .
2013-07-04 16:56:19 -04:00
*
2019-08-23 09:23:39 -07:00
* Use of this software is governed by the Business Source License included
* in the LICENSE . TXT file in the project ' s root directory .
2013-07-04 16:56:19 -04:00
*
2019-08-23 09:23:39 -07:00
* Change Date : 2023 - 01 - 01
2013-07-04 16:56:19 -04:00
*
2019-08-23 09:23:39 -07:00
* On the date above , in accordance with the Business Source License , use
* of this software will be governed by version 2.0 of the Apache License .
2013-07-04 16:56:19 -04:00
*/
2019-08-23 09:23:39 -07:00
/****/
2013-07-04 16:56:19 -04:00
2013-12-06 16:49:20 -08:00
# ifndef ZT_NETWORK_HPP
# define ZT_NETWORK_HPP
2013-07-04 16:56:19 -04:00
2013-09-11 15:09:53 -04:00
# include <stdint.h>
2015-04-06 15:47:57 -07:00
# include "../include/ZeroTierOne.h"
2013-07-04 16:56:19 -04:00
# include <string>
2013-07-29 13:56:20 -04:00
# include <map>
2013-07-04 16:56:19 -04:00
# include <vector>
2013-09-11 16:08:31 -04:00
# include <algorithm>
2013-07-04 16:56:19 -04:00
# include <stdexcept>
2013-07-29 13:56:20 -04:00
# include "Constants.hpp"
2015-09-04 13:42:19 -07:00
# include "Hashtable.hpp"
2013-07-04 16:56:19 -04:00
# include "Address.hpp"
# include "Mutex.hpp"
# include "SharedPtr.hpp"
# include "AtomicCounter.hpp"
# include "MulticastGroup.hpp"
2013-07-10 17:24:27 -04:00
# include "MAC.hpp"
2013-07-29 13:56:20 -04:00
# include "Dictionary.hpp"
2014-09-24 14:02:16 -07:00
# include "Multicaster.hpp"
2016-08-05 15:02:01 -07:00
# include "Membership.hpp"
2013-10-18 12:01:48 -04:00
# include "NetworkConfig.hpp"
2013-10-07 15:29:03 -04:00
# include "CertificateOfMembership.hpp"
2013-07-04 16:56:19 -04:00
2016-09-27 11:33:48 -07:00
# define ZT_NETWORK_MAX_INCOMING_UPDATES 3
# define ZT_NETWORK_MAX_UPDATE_CHUNKS ((ZT_NETWORKCONFIG_DICT_CAPACITY / 1024) + 1)
2013-07-04 16:56:19 -04:00
namespace ZeroTier {
2013-07-29 13:56:20 -04:00
class RuntimeEnvironment ;
2015-10-01 11:11:52 -07:00
class Peer ;
2013-07-04 16:56:19 -04:00
/**
2013-07-27 16:20:08 -04:00
* A virtual LAN
2013-07-04 16:56:19 -04:00
*/
2018-01-26 21:34:56 -05:00
class Network
2013-07-04 16:56:19 -04:00
{
friend class SharedPtr < Network > ;
2013-09-04 09:27:56 -04:00
2015-04-01 19:09:18 -07:00
public :
2013-09-04 09:27:56 -04:00
/**
2015-04-15 13:09:20 -07:00
* Broadcast multicast group : ff : ff : ff : ff : ff : ff / 0
*/
static const MulticastGroup BROADCAST ;
2016-09-23 16:08:38 -07:00
/**
* Compute primary controller device ID from network ID
*/
2019-09-12 10:37:26 -07:00
static ZT_ALWAYS_INLINE Address controllerFor ( uint64_t nwid ) { return Address ( nwid > > 24 ) ; }
2016-09-23 16:08:38 -07:00
2015-04-15 13:09:20 -07: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 12:01:48 -04:00
* @ param renv Runtime environment
2017-03-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2015-04-01 19:09:18 -07:00
* @ param nwid Network ID
2016-01-12 11:04:35 -08:00
* @ param uptr Arbitrary pointer used by externally - facing API ( for user use )
2017-06-01 12:33:05 -07:00
* @ param nconf Network config , if known
2013-09-04 09:27:56 -04:00
*/
2017-06-01 12:33:05 -07:00
Network ( const RuntimeEnvironment * renv , void * tPtr , uint64_t nwid , void * uptr , const NetworkConfig * nconf ) ;
2015-04-01 19:09:18 -07:00
~ Network ( ) ;
2013-07-29 17:11:00 -04:00
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE uint64_t id ( ) const { return _id ; }
ZT_ALWAYS_INLINE Address controller ( ) const { return Address ( _id > > 24 ) ; }
ZT_ALWAYS_INLINE bool multicastEnabled ( ) const { return ( _config . multicastLimit > 0 ) ; }
ZT_ALWAYS_INLINE bool hasConfig ( ) const { return ( _config ) ; }
ZT_ALWAYS_INLINE uint64_t lastConfigUpdate ( ) const { return _lastConfigUpdate ; }
ZT_ALWAYS_INLINE ZT_VirtualNetworkStatus status ( ) const { return _status ( ) ; }
ZT_ALWAYS_INLINE const NetworkConfig & config ( ) const { return _config ; }
ZT_ALWAYS_INLINE const MAC & mac ( ) const { return _mac ; }
2016-09-23 16:08:38 -07:00
2016-08-04 13:01:14 -07:00
/**
* Apply filters to an outgoing packet
*
* This applies filters from our network config and , if that doesn ' t match ,
2016-08-31 16:50:22 -07:00
* our capabilities in ascending order of capability ID . Additional actions
2016-09-23 16:08:38 -07: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 13:01:14 -07:00
*
2017-03-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-09-23 16:08:38 -07:00
* @ param noTee If true , do not TEE anything anywhere ( for two - pass filtering as done with multicast and bridging )
2016-08-04 13:01:14 -07: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 16:50:22 -07:00
* @ return True if packet should be sent , false if dropped or redirected
2016-08-04 13:01:14 -07:00
*/
bool filterOutgoingPacket (
2017-03-27 17:03:17 -07:00
void * tPtr ,
2016-08-31 16:50:22 -07:00
const bool noTee ,
2016-08-04 13:01:14 -07: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 16:50:12 -07:00
const unsigned int vlanId ,
uint8_t & qosBucket ) ;
2016-08-04 13:01:14 -07: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-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-08-05 15:02:01 -07:00
* @ param sourcePeer Source Peer
2016-08-04 13:01:14 -07: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 15:54:06 -07:00
* @ return 0 = = drop , 1 = = accept , 2 = = accept even if bridged
2016-08-04 13:01:14 -07:00
*/
2016-08-29 15:54:06 -07:00
int filterIncomingPacket (
2017-03-27 17:03:17 -07:00
void * tPtr ,
2016-08-05 15:02:01 -07:00
const SharedPtr < Peer > & sourcePeer ,
2016-08-04 13:01:14 -07: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 16:56:19 -04:00
/**
2016-09-23 16:08:38 -07:00
* Check whether we are subscribed to a multicast group
*
2014-10-09 18:32:05 -07:00
* @ param mg Multicast group
2016-09-23 16:08:38 -07:00
* @ param includeBridgedGroups If true , also check groups we ' ve learned via bridging
2014-10-09 18:32:05 -07:00
* @ return True if this network endpoint / peer is a member
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE bool subscribedToMulticastGroup ( const MulticastGroup & mg , const bool includeBridgedGroups ) const
2019-08-14 15:59:45 -07:00
{
2019-08-22 13:06:08 -07:00
Mutex : : Lock l ( _myMulticastGroups_l ) ;
2019-08-14 15:59:45 -07:00
if ( std : : binary_search ( _myMulticastGroups . begin ( ) , _myMulticastGroups . end ( ) , mg ) )
return true ;
else if ( includeBridgedGroups )
return _multicastGroupsBehindMe . contains ( mg ) ;
return false ;
}
2019-08-21 10:44:52 -07:00
2015-04-06 18:27:24 -07:00
/**
* Subscribe to a multicast group
*
2017-03-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2015-04-06 18:27:24 -07:00
* @ param mg New multicast group
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void multicastSubscribe ( void * tPtr , const MulticastGroup & mg )
2019-08-14 15:59:45 -07:00
{
2019-08-22 13:06:08 -07:00
Mutex : : Lock l ( _myMulticastGroups_l ) ;
2019-08-14 15:59:45 -07:00
if ( ! std : : binary_search ( _myMulticastGroups . begin ( ) , _myMulticastGroups . end ( ) , mg ) ) {
_myMulticastGroups . insert ( std : : upper_bound ( _myMulticastGroups . begin ( ) , _myMulticastGroups . end ( ) , mg ) , mg ) ;
2019-08-21 10:44:52 -07:00
Mutex : : Lock l2 ( _memberships_l ) ;
2019-08-22 13:06:08 -07:00
_announceMulticastGroups ( tPtr , true ) ;
2019-08-14 15:59:45 -07:00
}
}
2019-08-15 10:49:50 -07:00
2015-04-06 18:27:24 -07:00
/**
* Unsubscribe from a multicast group
*
* @ param mg Multicast group
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void multicastUnsubscribe ( const MulticastGroup & mg )
2019-08-14 15:59:45 -07:00
{
2019-08-22 13:06:08 -07:00
Mutex : : Lock l ( _myMulticastGroups_l ) ;
2019-08-14 15:59:45 -07: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 10:44:52 -07:00
2016-08-09 13:14:38 -07:00
/**
* Handle an inbound network config chunk
*
2016-09-27 11:33:48 -07: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 13:14:38 -07:00
*
2017-03-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2017-01-30 16:04:05 -08: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 11:33:48 -07: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 13:14:38 -07:00
*/
2017-03-27 17:03:17 -07: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 13:14:38 -07:00
2016-11-10 11:54:47 -08:00
/**
* Set network configuration
*
2019-08-23 07:04:20 -07:00
* This is normally called internally when a configuration is received
* and fully assembled , but it can also be called on Node startup when
* cached configurations are re - read from the data store .
*
2017-03-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-11-10 11:54:47 -08: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-27 17:03:17 -07:00
int setConfiguration ( void * tPtr , const NetworkConfig & nconf , bool saveToDisk ) ;
2016-11-10 11:54:47 -08:00
2014-01-27 23:13:36 -08:00
/**
2015-04-15 15:12:09 -07:00
* Set netconf failure to ' access denied ' - - called in IncomingPacket when controller reports this
2013-07-29 13:56:20 -04:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void setAccessDenied ( ) { _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED ; }
2014-01-27 23:13:36 -08:00
/**
2016-09-23 16:08:38 -07:00
* Set netconf failure to ' not found ' - - called by IncomingPacket when controller reports this
2014-01-27 23:13:36 -08:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void setNotFound ( ) { _netconfFailure = NETCONF_FAILURE_NOT_FOUND ; }
2013-07-29 13:56:20 -04:00
2013-07-29 17:11:00 -04:00
/**
2016-09-20 21:21:34 -07:00
* Determine whether this peer is permitted to communicate on this network
2017-03-27 17:03:17 -07: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 09:32:00 -07:00
*/
2017-03-27 17:03:17 -07:00
bool gate ( void * tPtr , const SharedPtr < Peer > & peer ) ;
2016-09-09 09:32:00 -07:00
2013-07-29 17:11:00 -04:00
/**
2016-09-23 16:08:38 -07:00
* Do periodic cleanup and housekeeping tasks
2013-07-29 17:11:00 -04:00
*/
2019-08-23 07:04:20 -07:00
void doPeriodicTasks ( void * tPtr , const int64_t now ) ;
2016-09-07 15:15:52 -07:00
2014-06-10 17:18:59 -07:00
/**
2014-09-26 12:23:43 -07:00
* Find the node on this network that has this MAC behind it ( if any )
*
2014-06-10 17:18:59 -07:00
* @ param mac MAC address
2014-09-26 12:23:43 -07:00
* @ return ZeroTier address of bridge to this MAC
2014-06-10 17:18:59 -07:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE Address findBridgeTo ( const MAC & mac ) const
2014-06-10 17:18:59 -07:00
{
2019-08-21 10:44:52 -07:00
Mutex : : Lock _l ( _remoteBridgeRoutes_l ) ;
2015-09-04 13:53:48 -07:00
const Address * const br = _remoteBridgeRoutes . get ( mac ) ;
2016-09-09 11:36:10 -07:00
return ( ( br ) ? * br : Address ( ) ) ;
2014-06-10 17:18:59 -07:00
}
2019-03-14 14:29:15 -07:00
/**
* @ return True if QoS is in effect for this network
*/
inline bool qosEnabled ( ) { return false ; }
2014-06-10 17:18:59 -07:00
/**
* Set a bridge route
*
* @ param mac MAC address of destination
* @ param addr Bridge this MAC is reachable behind
*/
2019-09-10 16:20:28 -07:00
void learnBridgeRoute ( const MAC & mac , const Address & addr ) ;
2019-08-21 10:44:52 -07:00
2014-06-13 14:06:34 -07:00
/**
* Learn a multicast group that is bridged to our tap device
*
2017-03-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2014-06-13 14:06:34 -07:00
* @ param mg Multicast group
2014-06-26 18:13:48 -07:00
* @ param now Current time
2014-06-13 14:06:34 -07:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void learnBridgedMulticastGroup ( void * tPtr , const MulticastGroup & mg , int64_t now )
2019-08-19 19:21:33 -07:00
{
2019-08-22 13:06:08 -07:00
Mutex : : Lock l ( _myMulticastGroups_l ) ;
2019-08-19 19:21:33 -07:00
_multicastGroupsBehindMe . set ( mg , now ) ;
}
2014-06-13 14:06:34 -07:00
2016-08-08 17:33:26 -07:00
/**
2016-09-23 16:08:38 -07:00
* Validate a credential and learn it if it passes certificate and other checks
2016-08-08 17:33:26 -07:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE Membership : : AddCredentialResult addCredential ( void * tPtr , const CertificateOfMembership & com )
2019-08-22 13:06:08 -07:00
{
if ( com . networkId ( ) ! = _id )
return Membership : : ADD_REJECTED ;
Mutex : : Lock _l ( _memberships_l ) ;
return _memberships [ com . issuedTo ( ) ] . addCredential ( RR , tPtr , _config , com ) ;
}
2016-08-08 17:33:26 -07:00
/**
2016-09-23 16:08:38 -07:00
* Validate a credential and learn it if it passes certificate and other checks
2016-08-08 17:33:26 -07:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE Membership : : AddCredentialResult addCredential ( void * tPtr , const Capability & cap )
2016-08-08 17:33:26 -07:00
{
if ( cap . networkId ( ) ! = _id )
2016-09-23 16:08:38 -07:00
return Membership : : ADD_REJECTED ;
2019-08-21 10:44:52 -07:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 15:59:45 -07:00
return _memberships [ cap . issuedTo ( ) ] . addCredential ( RR , tPtr , _config , cap ) ;
2016-08-08 17:33:26 -07:00
}
/**
2016-09-23 16:08:38 -07:00
* Validate a credential and learn it if it passes certificate and other checks
2016-08-08 17:33:26 -07:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE Membership : : AddCredentialResult addCredential ( void * tPtr , const Tag & tag )
2016-08-08 17:33:26 -07:00
{
if ( tag . networkId ( ) ! = _id )
2016-09-23 16:08:38 -07:00
return Membership : : ADD_REJECTED ;
2019-08-21 10:44:52 -07:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 15:59:45 -07:00
return _memberships [ tag . issuedTo ( ) ] . addCredential ( RR , tPtr , _config , tag ) ;
2016-08-08 17:33:26 -07:00
}
2016-08-23 13:46:36 -07:00
/**
2016-09-23 16:08:38 -07:00
* Validate a credential and learn it if it passes certificate and other checks
*/
2017-03-27 17:03:17 -07:00
Membership : : AddCredentialResult addCredential ( void * tPtr , const Address & sentFrom , const Revocation & rev ) ;
2016-09-23 16:08:38 -07:00
2017-02-23 11:47:36 -08:00
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE Membership : : AddCredentialResult addCredential ( void * tPtr , const CertificateOfOwnership & coo )
2017-02-23 11:47:36 -08:00
{
if ( coo . networkId ( ) ! = _id )
return Membership : : ADD_REJECTED ;
2019-08-21 10:44:52 -07:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 15:59:45 -07:00
return _memberships [ coo . issuedTo ( ) ] . addCredential ( RR , tPtr , _config , coo ) ;
2017-02-23 11:47:36 -08:00
}
2016-09-23 16:08:38 -07:00
/**
* Force push credentials ( COM , etc . ) to a peer now
2016-08-23 13:46:36 -07:00
*
2017-03-27 17:03:17 -07:00
* @ param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
2016-09-23 16:08:38 -07:00
* @ param to Destination peer address
* @ param now Current time
2016-08-23 13:46:36 -07:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void pushCredentialsNow ( void * tPtr , const Address & to , const int64_t now )
2016-08-23 13:46:36 -07:00
{
2019-08-21 10:44:52 -07:00
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 15:59:45 -07:00
_memberships [ to ] . pushCredentials ( RR , tPtr , now , to , _config ) ;
2016-08-23 13:46:36 -07:00
}
2019-06-25 13:42:20 -07:00
/**
2019-08-22 13:06:08 -07:00
* Push credentials if we haven ' t done so in a long time
2019-08-21 10:44:52 -07:00
*
2019-06-25 13:42:20 -07: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
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void pushCredentialsIfNeeded ( void * tPtr , const Address & to , const int64_t now )
2019-06-25 13:42:20 -07:00
{
2019-08-21 10:44:52 -07:00
const int64_t tout = std : : min ( _config . credentialTimeMaxDelta , ( int64_t ) ZT_PEER_ACTIVITY_TIMEOUT ) ;
Mutex : : Lock _l ( _memberships_l ) ;
2019-08-14 15:59:45 -07:00
Membership & m = _memberships [ to ] ;
2019-08-21 10:44:52 -07:00
if ( ( ( now - m . lastPushedCredentials ( ) ) + 5000 ) > = tout )
2019-08-02 20:43:02 -07:00
m . pushCredentials ( RR , tPtr , now , to , _config ) ;
2019-06-25 13:42:20 -07:00
}
2014-08-21 17:49:05 -07:00
/**
* Destroy this network
*
2017-04-11 08:47:02 -07: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-21 17:49:05 -07:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void destroy ( )
2019-08-21 10:44:52 -07:00
{
_memberships_l . lock ( ) ;
_config_l . lock ( ) ;
_destroyed = true ;
_config_l . unlock ( ) ;
_memberships_l . unlock ( ) ;
}
2014-08-21 17:49:05 -07:00
2016-01-12 11:04:35 -08:00
/**
2016-09-23 16:08:38 -07:00
* Get this network ' s config for export via the ZT core API
*
* @ param ec Buffer to fill with externally - visible network configuration
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void externalConfig ( ZT_VirtualNetworkConfig * ec ) const
2016-09-23 16:08:38 -07:00
{
2019-08-21 10:44:52 -07:00
Mutex : : Lock _l ( _config_l ) ;
2016-09-23 16:08:38 -07:00
_externalConfig ( ec ) ;
}
2019-09-10 16:20:28 -07:00
/**
* Iterate through memberships
*
* @ param f Function of ( const Address , const Membership )
*/
template < typename F >
ZT_ALWAYS_INLINE void eachMember ( F f )
{
Mutex : : Lock ml ( _memberships_l ) ;
Hashtable < Address , Membership > : : Iterator i ( _memberships ) ;
2019-09-11 15:52:18 -07:00
Address * a = nullptr ;
Membership * m = nullptr ;
2019-09-10 16:20:28 -07:00
while ( i . next ( a , m ) ) {
if ( ! f ( * a , * m ) )
break ;
}
}
2016-09-23 16:08:38 -07:00
/**
* @ return Externally usable pointer - to - pointer exported via the core API
2016-01-12 11:04:35 -08:00
*/
2019-09-10 16:20:28 -07:00
ZT_ALWAYS_INLINE void * * userPtr ( ) { return & _uPtr ; }
2016-01-12 11:04:35 -08:00
2013-07-04 16:56:19 -04:00
private :
2019-08-23 07:04:20 -07:00
void _requestConfiguration ( void * tPtr ) ;
2015-09-24 16:21:36 -07:00
ZT_VirtualNetworkStatus _status ( ) const ;
void _externalConfig ( ZT_VirtualNetworkConfig * ec ) const ; // assumes _lock is locked
2016-09-08 19:48:05 -07:00
bool _gate ( const SharedPtr < Peer > & peer ) ;
2019-08-22 13:06:08 -07:00
void _announceMulticastGroups ( void * tPtr , bool force ) ;
2017-03-27 17:03:17 -07:00
void _announceMulticastGroupsTo ( void * tPtr , const Address & peer , const std : : vector < MulticastGroup > & allMulticastGroups ) ;
2015-05-25 14:21:05 -07:00
std : : vector < MulticastGroup > _allMulticastGroups ( ) const ;
2015-04-06 16:52:52 -07:00
2016-09-23 16:08:38 -07:00
const RuntimeEnvironment * const RR ;
2016-01-12 13:17:30 -08:00
void * _uPtr ;
2016-09-23 16:08:38 -07:00
const uint64_t _id ;
2014-06-10 17:18:59 -07:00
MAC _mac ; // local MAC address
2016-09-27 11:33:48 -07:00
bool _portInitialized ;
2014-06-10 17:18:59 -07:00
2015-09-04 13:53:48 -07: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 14:14:32 -07:00
Hashtable < MAC , Address > _remoteBridgeRoutes ; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges)
2014-09-18 18:28:14 -07:00
2016-04-12 12:11:34 -07:00
NetworkConfig _config ;
2016-09-27 11:33:48 -07:00
uint64_t _lastConfigUpdate ;
struct _IncomingConfigChunk
{
2019-09-12 10:37:26 -07:00
ZT_ALWAYS_INLINE _IncomingConfigChunk ( ) : ts ( 0 ) , updateId ( 0 ) , haveChunks ( 0 ) , haveBytes ( 0 ) , data ( ) { }
2016-09-27 11:33:48 -07: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-10 17:18:59 -07:00
2019-08-21 10:44:52 -07:00
volatile bool _destroyed ;
2014-06-10 17:18:59 -07:00
2019-08-21 10:44:52 -07:00
volatile enum {
2014-01-27 23:13:36 -08:00
NETCONF_FAILURE_NONE ,
NETCONF_FAILURE_ACCESS_DENIED ,
NETCONF_FAILURE_NOT_FOUND ,
NETCONF_FAILURE_INIT_FAILED
} _netconfFailure ;
2014-06-10 17:18:59 -07:00
2016-08-05 15:02:01 -07:00
Hashtable < Address , Membership > _memberships ;
2019-08-21 10:44:52 -07:00
Mutex _myMulticastGroups_l ;
Mutex _remoteBridgeRoutes_l ;
Mutex _config_l ;
Mutex _memberships_l ;
2013-07-04 16:56:19 -04:00
AtomicCounter __refCount ;
} ;
2018-06-07 17:25:27 -07:00
} // namespace ZeroTier
2013-07-04 16:56:19 -04:00
# endif