This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
zhangyang-libzt/src/NodeService.hpp

576 lines
17 KiB
C++
Raw Normal View History

2019-02-06 22:00:39 -08:00
/*
2021-01-30 13:53:49 -08:00
* Copyright (c)2013-2021 ZeroTier, Inc.
2019-02-06 22:00:39 -08:00
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
2019-02-06 22:00:39 -08:00
*
2021-04-22 11:20:04 -07:00
* Change Date: 2026-01-01
2019-02-06 22:00:39 -08: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.
2019-02-06 22:00:39 -08:00
*/
/****/
2019-02-06 22:00:39 -08:00
/**
* @file
*
2021-04-22 11:20:04 -07:00
* ZeroTier Node Service
*/
2021-04-22 11:20:04 -07:00
#ifndef ZTS_NODE_SERVICE_HPP
#define ZTS_NODE_SERVICE_HPP
2019-02-06 22:00:39 -08:00
2021-04-22 11:20:04 -07:00
#include "Binder.hpp"
#include "Constants.hpp"
2021-04-22 11:20:04 -07:00
#include "Events.hpp"
#include "InetAddress.hpp"
#include "Mutex.hpp"
#include "Node.hpp"
2021-04-22 11:20:04 -07:00
#include "PortMapper.hpp"
#include "VirtualTap.hpp"
#include "ZeroTierSockets.h"
#include <string>
#include <vector>
#define ZTS_SERVICE_THREAD_NAME "ZTServiceThread"
#define ZTS_EVENT_CALLBACK_THREAD_NAME "ZTEventCallbackThread"
2021-04-22 11:20:04 -07:00
// Interface metric for ZeroTier taps -- this ensures that if we are on WiFi and
// also bridged via ZeroTier to the same LAN traffic will (if the OS is sane)
// prefer WiFi.
#define ZT_IF_METRIC 5000
// How often to check for new multicast subscriptions on a tap device
#define ZT_TAP_CHECK_MULTICAST_INTERVAL 5000
// How often to check for local interface addresses
#define ZT_LOCAL_INTERFACE_CHECK_INTERVAL 60000
#ifdef __WINDOWS__
2021-04-22 11:20:04 -07:00
#include <Windows.h>
2019-02-06 22:00:39 -08:00
#endif
namespace ZeroTier {
/**
2021-04-22 11:20:04 -07:00
* ZeroTier node service
2019-02-06 22:00:39 -08:00
*/
class NodeService {
public:
/**
* Returned by node main if/when it terminates
*/
enum ReasonForTermination {
/**
* Instance is still running
*/
ONE_STILL_RUNNING = 0,
/**
* Normal shutdown
*/
ONE_NORMAL_TERMINATION = 1,
/**
* A serious unrecoverable error has occurred
*/
ONE_UNRECOVERABLE_ERROR = 2,
/**
* Your identity has collided with another
*/
ONE_IDENTITY_COLLISION = 3
};
/**
* Local settings for each network
*/
struct NetworkSettings {
/**
* Allow this network to configure IP addresses and routes?
*/
bool allowManaged;
/**
* Whitelist of addresses that can be configured by this network.
* If empty and allowManaged is true, allow all
* private/pseudoprivate addresses.
*/
std::vector<InetAddress> allowManagedWhitelist;
/**
* Allow configuration of IPs and routes within global (Internet) IP
* space?
*/
bool allowGlobal;
/**
* Allow overriding of system default routes for "full tunnel"
* operation?
*/
bool allowDefault;
};
Phy<NodeService*> _phy;
Node* _node;
unsigned int _primaryPort = 0;
unsigned int _secondaryPort = 0;
unsigned int _tertiaryPort = 0;
volatile unsigned int _udpPortPickerCounter;
std::map<uint64_t, unsigned int> peerCache;
// Local configuration and memo-ized information from it
Hashtable<uint64_t, std::vector<InetAddress> > _v4Hints;
Hashtable<uint64_t, std::vector<InetAddress> > _v6Hints;
Hashtable<uint64_t, std::vector<InetAddress> > _v4Blacklists;
Hashtable<uint64_t, std::vector<InetAddress> > _v6Blacklists;
std::vector<InetAddress> _globalV4Blacklist;
std::vector<InetAddress> _globalV6Blacklist;
std::vector<InetAddress> _allowManagementFrom;
std::vector<std::string> _interfacePrefixBlacklist;
Mutex _localConfig_m;
std::vector<InetAddress> explicitBind;
/*
* To attempt to handle NAT/gateway craziness we use three local UDP
* ports:
*
* [0] is the normal/default port, usually 9993
* [1] is a port derived from our ZeroTier address
* [2] is a port computed from the normal/default for use with
* uPnP/NAT-PMP mappings
*
* [2] exists because on some gateways trying to do regular NAT-t
* interferes destructively with uPnP port mapping behavior in very
* weird buggy ways. It's only used if uPnP/NAT-PMP is enabled in this
* build.
*/
unsigned int _ports[3] = { 0 };
Binder _binder;
// Time we last received a packet from a global address
uint64_t _lastDirectReceiveFromGlobal;
// Last potential sleep/wake event
uint64_t _lastRestart;
// Deadline for the next background task service function
volatile int64_t _nextBackgroundTaskDeadline;
// Configured networks
struct NetworkState {
NetworkState() : tap((VirtualTap*)0)
{
// Real defaults are in network 'up' code in network event
// handler
settings.allowManaged = true;
settings.allowGlobal = false;
settings.allowDefault = false;
}
VirtualTap* tap;
ZT_VirtualNetworkConfig config; // memcpy() of raw config from core
std::vector<InetAddress> managedIps;
NetworkSettings settings;
};
std::map<uint64_t, NetworkState> _nets;
/** Lock to control access to network configuration data */
Mutex _nets_m;
/** Lock to control access to storage data */
Mutex _store_m;
/** Lock to control access to service run state */
Mutex _run_m;
// Set to false to force service to stop
volatile bool _run;
/** Lock to control access to termination reason */
Mutex _termReason_m;
// Termination status information
ReasonForTermination _termReason;
std::string _fatalErrorMessage;
// uPnP/NAT-PMP port mapper if enabled
bool _portMappingEnabled; // local.conf settings
2021-04-22 11:20:04 -07:00
#ifdef ZT_USE_MINIUPNPC
PortMapper* _portMapper;
2021-04-22 11:20:04 -07:00
#endif
2019-02-06 22:00:39 -08:00
uint8_t _allowNetworkCaching;
uint8_t _allowPeerCaching;
uint8_t _allowIdentityCaching;
uint8_t _allowWorldCaching;
2019-02-06 22:00:39 -08:00
char _publicIdStr[ZT_IDENTITY_STRING_BUFFER_LENGTH] = { 0 };
char _secretIdStr[ZT_IDENTITY_STRING_BUFFER_LENGTH] = { 0 };
bool _userDefinedWorld;
char _worldData[ZTS_STORE_DATA_LEN] = { 0 };
int _worldDataLen = 0;
2019-02-06 22:00:39 -08:00
/** Whether the node has successfully come online */
bool _nodeIsOnline;
2019-02-06 22:00:39 -08:00
/** Whether we allow the NodeService to generate events for the user */
bool _eventsEnabled;
2019-02-06 22:00:39 -08:00
/** Storage path defined by the user */
std::string _homePath;
2021-04-22 11:20:04 -07:00
/** System to ingest events from this class and emit them to the user */
Events* _events;
2019-02-06 22:00:39 -08:00
NodeService();
~NodeService();
2019-02-06 22:00:39 -08:00
/** Main service loop */
ReasonForTermination run();
ReasonForTermination reasonForTermination() const;
2019-02-06 22:00:39 -08:00
std::string fatalErrorMessage() const;
2019-02-06 22:00:39 -08:00
/** Stop the node and service */
void terminate();
2021-04-22 11:20:04 -07:00
/** Apply or update managed IPs for a configured network */
void syncManagedStuff(NetworkState& n);
2021-04-22 11:20:04 -07:00
void phyOnDatagram(
PhySocket* sock,
void** uptr,
const struct sockaddr* localAddr,
const struct sockaddr* from,
void* data,
unsigned long len);
2021-04-22 11:20:04 -07:00
int nodeVirtualNetworkConfigFunction(
uint64_t net_id,
void** nuptr,
enum ZT_VirtualNetworkConfigOperation op,
const ZT_VirtualNetworkConfig* nwc);
2021-04-22 11:20:04 -07:00
void nodeEventCallback(enum ZT_Event event, const void* metaData);
zts_net_info_t* prepare_network_details_msg(const NetworkState& n);
2021-04-22 11:20:04 -07:00
void generateEventMsgs();
2021-04-22 11:20:04 -07:00
void sendEventToUser(unsigned int event_code, const void* arg, unsigned int len = 0);
/** Join a network */
int join(uint64_t net_id);
2021-04-22 11:20:04 -07:00
/** Leave a network */
int leave(uint64_t net_id);
2021-04-22 11:20:04 -07:00
/** Return whether the network is ready for transport services */
bool networkIsReady(uint64_t net_id) const;
/** Lock the service so we can perform queries */
void obtainLock() const;
/** Unlock the service */
void releaseLock() const;
/** Return number of assigned addresses on the network. Service must be locked. */
int addressCount(uint64_t net_id) const;
/** Return number of managed routes on the network. Service must be locked. */
int routeCount(uint64_t net_id) const;
/** Return number of multicast subscriptions on the network. Service must be locked. */
int multicastSubCount(uint64_t net_id) const;
/** Return number of known physical paths to the peer. Service must be locked. */
int pathCount(uint64_t peer_id) const;
int getAddrAtIdx(uint64_t net_id, unsigned int idx, char* dst, unsigned int len);
int getRouteAtIdx(
uint64_t net_id,
unsigned int idx,
char* target,
char* via,
unsigned int len,
uint16_t* flags,
uint16_t* metric);
int getMulticastSubAtIdx(uint64_t net_id, unsigned int idx, uint64_t* mac, uint32_t* adi);
int getPathAtIdx(uint64_t peer_id, unsigned int idx, char* path, unsigned int len);
2021-04-22 11:20:04 -07:00
/** Orbit a moon */
int orbit(void* tptr, uint64_t moonWorldId, uint64_t moonSeed);
2021-04-22 11:20:04 -07:00
/** De-orbit a moon */
int deorbit(void* tptr, uint64_t moonWorldId);
2021-04-22 11:20:04 -07:00
/** Return the integer-form of the node's identity */
uint64_t getNodeId();
2021-04-22 11:20:04 -07:00
/** Gets the node's identity */
int getIdentity(char* keypair, unsigned int* len);
2021-04-22 11:20:04 -07:00
/** Set the node's identity */
int setIdentity(const char* keypair, unsigned int len);
2021-04-22 11:20:04 -07:00
void nodeStatePutFunction(enum ZT_StateObjectType type, const uint64_t id[2], const void* data, unsigned int len);
2021-04-22 11:20:04 -07:00
int nodeStateGetFunction(enum ZT_StateObjectType type, const uint64_t id[2], void* data, unsigned int maxlen);
2021-04-22 11:20:04 -07:00
int nodeWirePacketSendFunction(
const int64_t localSocket,
const struct sockaddr_storage* addr,
const void* data,
unsigned int len,
unsigned int ttl);
2021-04-22 11:20:04 -07:00
void nodeVirtualNetworkFrameFunction(
uint64_t net_id,
void** nuptr,
uint64_t sourceMac,
uint64_t destMac,
unsigned int etherType,
unsigned int vlanId,
const void* data,
unsigned int len);
2021-04-22 11:20:04 -07:00
int nodePathCheckFunction(uint64_t ztaddr, const int64_t localSocket, const struct sockaddr_storage* remoteAddr);
2021-04-22 11:20:04 -07:00
int nodePathLookupFunction(uint64_t ztaddr, unsigned int family, struct sockaddr_storage* result);
2021-04-22 11:20:04 -07:00
void tapFrameHandler(
uint64_t net_id,
const MAC& from,
const MAC& to,
unsigned int etherType,
unsigned int vlanId,
const void* data,
unsigned int len);
2021-04-22 11:20:04 -07:00
int shouldBindInterface(const char* ifname, const InetAddress& ifaddr);
2021-04-22 11:20:04 -07:00
int _trialBind(unsigned int port);
2021-04-22 11:20:04 -07:00
/** Return whether the NodeService is running */
int isRunning() const;
2021-04-22 11:20:04 -07:00
/** Return whether the node is online */
int nodeIsOnline() const;
2021-04-22 11:20:04 -07:00
/** Instruct the NodeService on where to look for identity files and caches */
int setHomePath(const char* homePath);
/** Set the NodeService's primary port */
int setPrimaryPort(unsigned short primaryPort);
/** Get the NodeService's primary port */
unsigned short getPrimaryPort() const;
/** Set the event system instance used to convey messages to the user */
int setUserEventSystem(Events* events);
void enableEvents();
/** Set the world definition */
int setWorld(const void* data, unsigned int len);
/** Add Interface prefix to blacklist (prevents ZeroTier from using that interface) */
int addInterfacePrefixToBlacklist(const char* prefix, unsigned int len);
/** Return the MAC Address of the node in the given network */
uint64_t getMACAddress(uint64_t net_id) const;
/** Get the string format name of a network */
int getNetworkName(uint64_t net_id, char* dst, unsigned int len) const;
/** Allow ZeroTier to cache peer hints to storage */
int allowPeerCaching(unsigned int allowed);
/** Allow ZeroTier to cache network info to storage */
int allowNetworkCaching(unsigned int allowed);
/** Allow ZeroTier to write identities to storage */
int allowIdentityCaching(unsigned int allowed);
/** Allow ZeroTier to cache world definitions to storage */
int allowWorldCaching(unsigned int allowed);
/** Return whether broadcast is enabled on the given network */
int getNetworkBroadcast(uint64_t net_id);
/** Return the MTU of the given network */
int getNetworkMTU(uint64_t net_id);
/** Return whether the network is public or private */
int getNetworkType(uint64_t net_id);
/** Return the status of the network join */
int getNetworkStatus(uint64_t net_id);
/** Get the first address assigned by the network */
int getFirstAssignedAddr(uint64_t net_id, unsigned int family, struct zts_sockaddr_storage* addr);
/** Get an array of assigned addresses for the given network */
int getAllAssignedAddr(uint64_t net_id, struct zts_sockaddr_storage* addr, unsigned int* count);
/** Return whether a managed route of the given family has been assigned by the network */
int networkHasRoute(uint64_t net_id, unsigned int family);
/** Return whether an address of the given family has been assigned by the network */
int addrIsAssigned(uint64_t net_id, unsigned int family);
void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success)
{
// Intentionally left empty
}
void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from)
{
// Intentionally left empty
}
void phyOnTcpClose(PhySocket* sock, void** uptr)
{
// Intentionally left empty
}
void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len)
{
// Intentionally left empty
}
void phyOnTcpWritable(PhySocket* sock, void** uptr)
{
// Intentionally left empty
}
void phyOnFileDescriptorActivity(PhySocket* sock, void** uptr, bool readable, bool writable)
{
// Intentionally left empty
}
void phyOnUnixAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN)
{
// Intentionally left empty
}
void phyOnUnixClose(PhySocket* sock, void** uptr)
{
// Intentionally left empty
}
void phyOnUnixData(PhySocket* sock, void** uptr, void* data, unsigned long len)
{
// Intentionally left empty
}
void phyOnUnixWritable(PhySocket* sock, void** uptr)
{
// Intentionally left empty
}
2019-02-06 22:00:39 -08:00
};
2021-04-22 11:20:04 -07:00
static int SnodeVirtualNetworkConfigFunction(
ZT_Node* node,
void* uptr,
void* tptr,
uint64_t net_id,
void** nuptr,
enum ZT_VirtualNetworkConfigOperation op,
const ZT_VirtualNetworkConfig* nwconf)
{
return reinterpret_cast<NodeService*>(uptr)->nodeVirtualNetworkConfigFunction(net_id, nuptr, op, nwconf);
2021-04-22 11:20:04 -07:00
}
static void SnodeEventCallback(ZT_Node* node, void* uptr, void* tptr, enum ZT_Event event, const void* metaData)
2021-04-22 11:20:04 -07:00
{
reinterpret_cast<NodeService*>(uptr)->nodeEventCallback(event, metaData);
2021-04-22 11:20:04 -07:00
}
static void SnodeStatePutFunction(
ZT_Node* node,
void* uptr,
void* tptr,
enum ZT_StateObjectType type,
const uint64_t id[2],
const void* data,
int len)
{
reinterpret_cast<NodeService*>(uptr)->nodeStatePutFunction(type, id, data, len);
2021-04-22 11:20:04 -07:00
}
static int SnodeStateGetFunction(
ZT_Node* node,
void* uptr,
void* tptr,
enum ZT_StateObjectType type,
const uint64_t id[2],
void* data,
unsigned int maxlen)
{
return reinterpret_cast<NodeService*>(uptr)->nodeStateGetFunction(type, id, data, maxlen);
2021-04-22 11:20:04 -07:00
}
static int SnodeWirePacketSendFunction(
ZT_Node* node,
void* uptr,
void* tptr,
int64_t localSocket,
const struct sockaddr_storage* addr,
const void* data,
unsigned int len,
unsigned int ttl)
{
return reinterpret_cast<NodeService*>(uptr)->nodeWirePacketSendFunction(localSocket, addr, data, len, ttl);
2021-04-22 11:20:04 -07:00
}
static void SnodeVirtualNetworkFrameFunction(
ZT_Node* node,
void* uptr,
void* tptr,
uint64_t net_id,
void** nuptr,
uint64_t sourceMac,
uint64_t destMac,
unsigned int etherType,
unsigned int vlanId,
const void* data,
unsigned int len)
{
reinterpret_cast<NodeService*>(uptr)
->nodeVirtualNetworkFrameFunction(net_id, nuptr, sourceMac, destMac, etherType, vlanId, data, len);
2021-04-22 11:20:04 -07:00
}
static int SnodePathCheckFunction(
ZT_Node* node,
void* uptr,
void* tptr,
uint64_t ztaddr,
int64_t localSocket,
const struct sockaddr_storage* remoteAddr)
{
return reinterpret_cast<NodeService*>(uptr)->nodePathCheckFunction(ztaddr, localSocket, remoteAddr);
2021-04-22 11:20:04 -07:00
}
static int SnodePathLookupFunction(
ZT_Node* node,
void* uptr,
void* tptr,
uint64_t ztaddr,
int family,
struct sockaddr_storage* result)
{
return reinterpret_cast<NodeService*>(uptr)->nodePathLookupFunction(ztaddr, family, result);
2021-04-22 11:20:04 -07:00
}
static void StapFrameHandler(
void* uptr,
void* tptr,
uint64_t net_id,
const MAC& from,
const MAC& to,
unsigned int etherType,
unsigned int vlanId,
const void* data,
unsigned int len)
{
reinterpret_cast<NodeService*>(uptr)->tapFrameHandler(net_id, from, to, etherType, vlanId, data, len);
2021-04-22 11:20:04 -07:00
}
} // namespace ZeroTier
2019-02-06 22:00:39 -08:00
#endif