|
@@ -16,7 +16,6 @@
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
-
|
|
|
|
#include <string>
|
|
#include <string>
|
|
#include <map>
|
|
#include <map>
|
|
#include <vector>
|
|
#include <vector>
|
|
@@ -26,6 +25,11 @@
|
|
#include <mutex>
|
|
#include <mutex>
|
|
#include <condition_variable>
|
|
#include <condition_variable>
|
|
|
|
|
|
|
|
+#ifdef __FreeBSD__
|
|
|
|
+#include <sched.h>
|
|
|
|
+#include <pthread_np.h>
|
|
|
|
+#endif
|
|
|
|
+
|
|
#include "../version.h"
|
|
#include "../version.h"
|
|
#include "../include/ZeroTierOne.h"
|
|
#include "../include/ZeroTierOne.h"
|
|
|
|
|
|
@@ -42,6 +46,7 @@
|
|
#include "../node/SHA512.hpp"
|
|
#include "../node/SHA512.hpp"
|
|
#include "../node/Bond.hpp"
|
|
#include "../node/Bond.hpp"
|
|
#include "../node/Peer.hpp"
|
|
#include "../node/Peer.hpp"
|
|
|
|
+#include "../node/PacketMultiplexer.hpp"
|
|
|
|
|
|
#include "../osdep/Phy.hpp"
|
|
#include "../osdep/Phy.hpp"
|
|
#include "../osdep/OSUtils.hpp"
|
|
#include "../osdep/OSUtils.hpp"
|
|
@@ -759,7 +764,7 @@ struct TcpConnection
|
|
Mutex writeq_m;
|
|
Mutex writeq_m;
|
|
};
|
|
};
|
|
|
|
|
|
-struct OneServiceIncomingPacket
|
|
|
|
|
|
+struct PacketRecord
|
|
{
|
|
{
|
|
uint64_t now;
|
|
uint64_t now;
|
|
int64_t sock;
|
|
int64_t sock;
|
|
@@ -786,14 +791,22 @@ public:
|
|
SoftwareUpdater *_updater;
|
|
SoftwareUpdater *_updater;
|
|
bool _updateAutoApply;
|
|
bool _updateAutoApply;
|
|
|
|
|
|
- httplib::Server _controlPlane;
|
|
|
|
|
|
+ httplib::Server _controlPlane;
|
|
httplib::Server _controlPlaneV6;
|
|
httplib::Server _controlPlaneV6;
|
|
- std::thread _serverThread;
|
|
|
|
|
|
+ std::thread _serverThread;
|
|
std::thread _serverThreadV6;
|
|
std::thread _serverThreadV6;
|
|
bool _serverThreadRunning;
|
|
bool _serverThreadRunning;
|
|
bool _serverThreadRunningV6;
|
|
bool _serverThreadRunningV6;
|
|
|
|
|
|
- bool _allowTcpFallbackRelay;
|
|
|
|
|
|
+ BlockingQueue<PacketRecord *> _rxPacketQueue;
|
|
|
|
+ std::vector<PacketRecord *> _rxPacketVector;
|
|
|
|
+ std::vector<std::thread> _rxPacketThreads;
|
|
|
|
+ Mutex _rxPacketVector_m,_rxPacketThreads_m;
|
|
|
|
+ bool _multicoreEnabled;
|
|
|
|
+ bool _cpuPinningEnabled;
|
|
|
|
+ unsigned int _concurrency;
|
|
|
|
+
|
|
|
|
+ bool _allowTcpFallbackRelay;
|
|
bool _forceTcpRelay;
|
|
bool _forceTcpRelay;
|
|
bool _allowSecondaryPort;
|
|
bool _allowSecondaryPort;
|
|
bool _enableWebServer;
|
|
bool _enableWebServer;
|
|
@@ -844,8 +857,6 @@ public:
|
|
// Deadline for the next background task service function
|
|
// Deadline for the next background task service function
|
|
volatile int64_t _nextBackgroundTaskDeadline;
|
|
volatile int64_t _nextBackgroundTaskDeadline;
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
std::map<uint64_t,NetworkState> _nets;
|
|
std::map<uint64_t,NetworkState> _nets;
|
|
Mutex _nets_m;
|
|
Mutex _nets_m;
|
|
|
|
|
|
@@ -892,9 +903,9 @@ public:
|
|
,_node((Node *)0)
|
|
,_node((Node *)0)
|
|
,_updater((SoftwareUpdater *)0)
|
|
,_updater((SoftwareUpdater *)0)
|
|
,_updateAutoApply(false)
|
|
,_updateAutoApply(false)
|
|
- ,_controlPlane()
|
|
|
|
|
|
+ ,_controlPlane()
|
|
,_controlPlaneV6()
|
|
,_controlPlaneV6()
|
|
- ,_serverThread()
|
|
|
|
|
|
+ ,_serverThread()
|
|
,_serverThreadV6()
|
|
,_serverThreadV6()
|
|
,_serverThreadRunning(false)
|
|
,_serverThreadRunning(false)
|
|
,_serverThreadRunningV6(false)
|
|
,_serverThreadRunningV6(false)
|
|
@@ -928,9 +939,9 @@ public:
|
|
_ports[1] = 0;
|
|
_ports[1] = 0;
|
|
_ports[2] = 0;
|
|
_ports[2] = 0;
|
|
|
|
|
|
- prometheus::simpleapi::saver.set_registry(prometheus::simpleapi::registry_ptr);
|
|
|
|
- prometheus::simpleapi::saver.set_delay(std::chrono::seconds(5));
|
|
|
|
- prometheus::simpleapi::saver.set_out_file(_homePath + ZT_PATH_SEPARATOR + "metrics.prom");
|
|
|
|
|
|
+ prometheus::simpleapi::saver.set_registry(prometheus::simpleapi::registry_ptr);
|
|
|
|
+ prometheus::simpleapi::saver.set_delay(std::chrono::seconds(5));
|
|
|
|
+ prometheus::simpleapi::saver.set_out_file(_homePath + ZT_PATH_SEPARATOR + "metrics.prom");
|
|
|
|
|
|
#if ZT_VAULT_SUPPORT
|
|
#if ZT_VAULT_SUPPORT
|
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
@@ -942,20 +953,34 @@ public:
|
|
#ifdef __WINDOWS__
|
|
#ifdef __WINDOWS__
|
|
WinFWHelper::removeICMPRules();
|
|
WinFWHelper::removeICMPRules();
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+ _rxPacketQueue.stop();
|
|
|
|
+ _rxPacketThreads_m.lock();
|
|
|
|
+ for(auto t=_rxPacketThreads.begin();t!=_rxPacketThreads.end();++t) {
|
|
|
|
+ t->join();
|
|
|
|
+ }
|
|
|
|
+ _rxPacketThreads_m.unlock();
|
|
_binder.closeAll(_phy);
|
|
_binder.closeAll(_phy);
|
|
|
|
|
|
#if ZT_VAULT_SUPPORT
|
|
#if ZT_VAULT_SUPPORT
|
|
curl_global_cleanup();
|
|
curl_global_cleanup();
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- _controlPlane.stop();
|
|
|
|
|
|
+ _controlPlane.stop();
|
|
if (_serverThreadRunning) {
|
|
if (_serverThreadRunning) {
|
|
- _serverThread.join();
|
|
|
|
|
|
+ _serverThread.join();
|
|
}
|
|
}
|
|
_controlPlaneV6.stop();
|
|
_controlPlaneV6.stop();
|
|
if (_serverThreadRunningV6) {
|
|
if (_serverThreadRunningV6) {
|
|
_serverThreadV6.join();
|
|
_serverThreadV6.join();
|
|
}
|
|
}
|
|
|
|
+ _rxPacketVector_m.lock();
|
|
|
|
+ while (!_rxPacketVector.empty()) {
|
|
|
|
+ delete _rxPacketVector.back();
|
|
|
|
+ _rxPacketVector.pop_back();
|
|
|
|
+ }
|
|
|
|
+ _rxPacketVector_m.unlock();
|
|
|
|
+
|
|
|
|
|
|
#ifdef ZT_USE_MINIUPNPC
|
|
#ifdef ZT_USE_MINIUPNPC
|
|
delete _portMapper;
|
|
delete _portMapper;
|
|
@@ -964,6 +989,15 @@ public:
|
|
delete _rc;
|
|
delete _rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ void setUpMultithreading()
|
|
|
|
+ {
|
|
|
|
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__WINDOWS__)
|
|
|
|
+ return;
|
|
|
|
+#endif
|
|
|
|
+ _node->initMultithreading(_concurrency, _cpuPinningEnabled);
|
|
|
|
+ bool pinning = _cpuPinningEnabled;
|
|
|
|
+ }
|
|
|
|
+
|
|
virtual ReasonForTermination run()
|
|
virtual ReasonForTermination run()
|
|
{
|
|
{
|
|
try {
|
|
try {
|
|
@@ -1272,6 +1306,9 @@ public:
|
|
const unsigned long delay = (dl > now) ? (unsigned long)(dl - now) : 500;
|
|
const unsigned long delay = (dl > now) ? (unsigned long)(dl - now) : 500;
|
|
clockShouldBe = now + (int64_t)delay;
|
|
clockShouldBe = now + (int64_t)delay;
|
|
_phy.poll(delay);
|
|
_phy.poll(delay);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|
|
} catch (std::exception &e) {
|
|
} catch (std::exception &e) {
|
|
Mutex::Lock _l(_termReason_m);
|
|
Mutex::Lock _l(_termReason_m);
|
|
@@ -2562,7 +2599,25 @@ public:
|
|
fprintf(stderr,"WARNING: using manually-specified secondary and/or tertiary ports. This can cause NAT issues." ZT_EOL_S);
|
|
fprintf(stderr,"WARNING: using manually-specified secondary and/or tertiary ports. This can cause NAT issues." ZT_EOL_S);
|
|
}
|
|
}
|
|
_portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true);
|
|
_portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true);
|
|
- _node->setLowBandwidthMode(OSUtils::jsonBool(settings["lowBandwidthMode"],false));
|
|
|
|
|
|
+#if defined(__LINUX__) || defined(__FreeBSD__)
|
|
|
|
+ _multicoreEnabled = OSUtils::jsonBool(settings["multicoreEnabled"],false);
|
|
|
|
+ _concurrency = OSUtils::jsonInt(settings["concurrency"],1);
|
|
|
|
+ _cpuPinningEnabled = OSUtils::jsonBool(settings["cpuPinningEnabled"],false);
|
|
|
|
+ if (_multicoreEnabled) {
|
|
|
|
+ unsigned int maxConcurrency = std::thread::hardware_concurrency();
|
|
|
|
+ if (_concurrency <= 1 || _concurrency >= maxConcurrency) {
|
|
|
|
+ unsigned int conservativeDefault = (std::thread::hardware_concurrency() >= 4 ? 2 : 1);
|
|
|
|
+ fprintf(stderr, "Concurrency level provided (%d) is invalid, assigning conservative default value of (%d)\n", _concurrency, conservativeDefault);
|
|
|
|
+ _concurrency = conservativeDefault;
|
|
|
|
+ }
|
|
|
|
+ setUpMultithreading();
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ // Force values in case the user accidentally defined them with multicore disabled
|
|
|
|
+ _concurrency = 1;
|
|
|
|
+ _cpuPinningEnabled = false;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
|
|
#ifndef ZT_SDK
|
|
#ifndef ZT_SDK
|
|
const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT));
|
|
const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT));
|
|
@@ -2877,16 +2932,19 @@ public:
|
|
// Handlers for Node and Phy<> callbacks
|
|
// Handlers for Node and Phy<> callbacks
|
|
// =========================================================================
|
|
// =========================================================================
|
|
|
|
|
|
- inline void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len)
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ inline void phyOnDatagram(PhySocket* sock, void** uptr, const struct sockaddr* localAddr, const struct sockaddr* from, void* data, unsigned long len)
|
|
{
|
|
{
|
|
if (_forceTcpRelay) {
|
|
if (_forceTcpRelay) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- Metrics::udp_recv += len;
|
|
|
|
|
|
+ Metrics::udp_recv += len;
|
|
const uint64_t now = OSUtils::now();
|
|
const uint64_t now = OSUtils::now();
|
|
- if ((len >= 16)&&(reinterpret_cast<const InetAddress *>(from)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) {
|
|
|
|
|
|
+ if ((len >= 16) && (reinterpret_cast<const InetAddress*>(from)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) {
|
|
_lastDirectReceiveFromGlobal = now;
|
|
_lastDirectReceiveFromGlobal = now;
|
|
- }
|
|
|
|
|
|
+ }
|
|
const ZT_ResultCode rc = _node->processWirePacket(nullptr,now,reinterpret_cast<int64_t>(sock),reinterpret_cast<const struct sockaddr_storage *>(from),data,len,&_nextBackgroundTaskDeadline);
|
|
const ZT_ResultCode rc = _node->processWirePacket(nullptr,now,reinterpret_cast<int64_t>(sock),reinterpret_cast<const struct sockaddr_storage *>(from),data,len,&_nextBackgroundTaskDeadline);
|
|
if (ZT_ResultCode_isFatal(rc)) {
|
|
if (ZT_ResultCode_isFatal(rc)) {
|
|
char tmp[256];
|
|
char tmp[256];
|
|
@@ -2898,6 +2956,7 @@ public:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
inline void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success)
|
|
inline void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success)
|
|
{
|
|
{
|
|
if (!success) {
|
|
if (!success) {
|
|
@@ -3116,6 +3175,8 @@ public:
|
|
|
|
|
|
n.setTap(EthernetTap::newInstance(
|
|
n.setTap(EthernetTap::newInstance(
|
|
nullptr,
|
|
nullptr,
|
|
|
|
+ _concurrency,
|
|
|
|
+ _cpuPinningEnabled,
|
|
_homePath.c_str(),
|
|
_homePath.c_str(),
|
|
MAC(nwc->mac),
|
|
MAC(nwc->mac),
|
|
nwc->mtu,
|
|
nwc->mtu,
|
|
@@ -3630,8 +3691,9 @@ public:
|
|
inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
|
inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
|
{
|
|
{
|
|
NetworkState *n = reinterpret_cast<NetworkState *>(*nuptr);
|
|
NetworkState *n = reinterpret_cast<NetworkState *>(*nuptr);
|
|
- if ((!n)||(!n->tap()))
|
|
|
|
|
|
+ if ((!n)||(!n->tap())) {
|
|
return;
|
|
return;
|
|
|
|
+ }
|
|
n->tap()->put(MAC(sourceMac),MAC(destMac),etherType,data,len);
|
|
n->tap()->put(MAC(sourceMac),MAC(destMac),etherType,data,len);
|
|
}
|
|
}
|
|
|
|
|