Add better port binding controls

This commit is contained in:
Joseph Henry
2021-05-13 14:17:08 -07:00
parent 22f80797b8
commit 5d404034c3
7 changed files with 212 additions and 65 deletions

View File

@@ -1058,9 +1058,7 @@ int zts_py_getblocking(int fd);
// Central API // // Central API //
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#ifdef ZTS_ENABLE_PYTHON
#define ZTS_DISABLE_CENTRAL_API 1 #define ZTS_DISABLE_CENTRAL_API 1
#endif
#ifndef ZTS_DISABLE_CENTRAL_API #ifndef ZTS_DISABLE_CENTRAL_API
@@ -1332,6 +1330,40 @@ ZTS_API int ZTCALL zts_init_set_roots(const void* roots_data, unsigned int len);
*/ */
ZTS_API int ZTCALL zts_init_set_port(unsigned short port); ZTS_API int ZTCALL zts_init_set_port(unsigned short port);
/**
* @brief Set range that random ports will be selected from. This is an initialization function that can
* only be called before `zts_node_start()`.
*
* @param start_port Start of port range
* @param end_port End of port range
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
*/
ZTS_API int ZTCALL zts_init_set_random_port_range(unsigned short start_port, unsigned short end_port);
/**
* @brief Allow or disallow ZeroTier from automatically selecting a backup port to help get through
* buggy NAT. This is enabled by default. This port is randomly chosen and should be disabled if you
* want to control exactly which ports ZeroTier talks on and (iff) you know with absolute certainty
* that traffic on your chosen primary port is allowed. This is an initialization function that can
* only be called before `zts_node_start()`.
*
* @param port Port number
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
*/
ZTS_API int ZTCALL zts_init_allow_secondary_port(unsigned int allowed);
/**
* @brief Allow or disallow the use of port-mapping. This is enabled by default. This is an
* initialization function that can only be called before `zts_node_start()`.
*
* @param port Port number
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
*/
ZTS_API int ZTCALL zts_init_allow_port_mapping(unsigned int allowed);
/** /**
* @brief Enable or disable whether the node will cache network details * @brief Enable or disable whether the node will cache network details
* (enabled by default when `zts_init_from_storage()` is used.) Must be called before * (enabled by default when `zts_init_from_storage()` is used.) Must be called before

View File

@@ -130,7 +130,7 @@ int zts_init_blacklist_if(const char* prefix, unsigned int len)
int zts_init_set_roots(const void* roots_data, unsigned int len) int zts_init_set_roots(const void* roots_data, unsigned int len)
{ {
ACQUIRE_SERVICE_OFFLINE(); ACQUIRE_SERVICE_OFFLINE();
return zts_service->setWorld(roots_data, len); return zts_service->setRoots(roots_data, len);
} }
int zts_init_set_port(unsigned short port) int zts_init_set_port(unsigned short port)
@@ -140,6 +140,25 @@ int zts_init_set_port(unsigned short port)
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
int zts_init_set_random_port_range(unsigned short start_port, unsigned short end_port)
{
ACQUIRE_SERVICE_OFFLINE();
zts_service->setRandomPortRange(start_port, end_port);
return ZTS_ERR_OK;
}
int zts_init_allow_secondary_port(unsigned int allowed)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowSecondaryPort(allowed);
}
int zts_init_allow_port_mapping(unsigned int allowed)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowPortMapping(allowed);
}
int zts_init_allow_peer_cache(unsigned int allowed) int zts_init_allow_peer_cache(unsigned int allowed)
{ {
ACQUIRE_SERVICE_OFFLINE(); ACQUIRE_SERVICE_OFFLINE();
@@ -155,7 +174,7 @@ int zts_init_allow_net_cache(unsigned int allowed)
int zts_init_allow_roots_cache(unsigned int allowed) int zts_init_allow_roots_cache(unsigned int allowed)
{ {
ACQUIRE_SERVICE_OFFLINE(); ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowWorldCaching(allowed); return zts_service->allowRootSetCaching(allowed);
} }
int zts_init_allow_id_cache(unsigned int allowed) int zts_init_allow_id_cache(unsigned int allowed)

View File

@@ -167,20 +167,25 @@ NodeService::NodeService()
, _node((Node*)0) , _node((Node*)0)
, _nodeId(0x0) , _nodeId(0x0)
, _primaryPort() , _primaryPort()
, _secondaryPort(0)
, _tertiaryPort(0)
, _randomPortRangeStart(0)
, _randomPortRangeEnd(0)
, _udpPortPickerCounter(0) , _udpPortPickerCounter(0)
, _lastDirectReceiveFromGlobal(0) , _lastDirectReceiveFromGlobal(0)
, _lastRestart(0) , _lastRestart(0)
, _nextBackgroundTaskDeadline(0) , _nextBackgroundTaskDeadline(0)
, _run(false) , _run(false)
, _termReason(ONE_STILL_RUNNING) , _termReason(ONE_STILL_RUNNING)
, _portMappingEnabled(true) , _allowPortMapping(true)
#ifdef ZT_USE_MINIUPNPC #ifdef ZT_USE_MINIUPNPC
, _portMapper((PortMapper*)0) , _portMapper((PortMapper*)0)
#endif #endif
, _allowSecondaryPort(true)
, _allowNetworkCaching(true) , _allowNetworkCaching(true)
, _allowPeerCaching(true) , _allowPeerCaching(true)
, _allowIdentityCaching(true) , _allowIdentityCaching(true)
, _allowWorldCaching(true) , _allowRootSetCaching(true)
, _userDefinedWorld(false) , _userDefinedWorld(false)
, _nodeIsOnline(false) , _nodeIsOnline(false)
, _eventsEnabled(false) , _eventsEnabled(false)
@@ -240,6 +245,9 @@ NodeService::ReasonForTermination NodeService::run()
_node = new Node(this, (void*)0, &cb, OSUtils::now()); _node = new Node(this, (void*)0, &cb, OSUtils::now());
} }
unsigned int minPort = (_randomPortRangeStart ? _randomPortRangeStart : 20000);
unsigned int maxPort = (_randomPortRangeEnd ? _randomPortRangeEnd : 45500);
// Make sure we can use the primary port, and hunt for one if // Make sure we can use the primary port, and hunt for one if
// configured to do so // configured to do so
const int portTrials = (_primaryPort == 0) ? 256 : 1; // if port is 0, pick random const int portTrials = (_primaryPort == 0) ? 256 : 1; // if port is 0, pick random
@@ -247,10 +255,11 @@ NodeService::ReasonForTermination NodeService::run()
if (_primaryPort == 0) { if (_primaryPort == 0) {
unsigned int randp = 0; unsigned int randp = 0;
Utils::getSecureRandom(&randp, sizeof(randp)); Utils::getSecureRandom(&randp, sizeof(randp));
_primaryPort = 20000 + (randp % 45500); _primaryPort = (randp % (maxPort - minPort + 1)) + minPort;
} }
if (_trialBind(_primaryPort)) { if (_trialBind(_primaryPort)) {
_ports[0] = _primaryPort; _ports[0] = _primaryPort;
break;
} }
else { else {
_primaryPort = 0; _primaryPort = 0;
@@ -268,25 +277,32 @@ NodeService::ReasonForTermination NodeService::run()
// fail if more than one device behind the same NAT tries to use the // fail if more than one device behind the same NAT tries to use the
// same internal private address port number. Buggy NATs are a // same internal private address port number. Buggy NATs are a
// running theme. // running theme.
_ports[1] = (_secondaryPort == 0) ? 20000 + ((unsigned int)_node->address() % 45500) : _secondaryPort; if (_allowSecondaryPort) {
//_ports[1] = (_secondaryPort == 0) ? minPort + ((unsigned int)_node->address() % maxPort) : _secondaryPort;
_ports[1] = (_secondaryPort == 0) ? (((unsigned int)_node->address() % (maxPort - minPort + 1)) + minPort)
: _secondaryPort;
for (int i = 0;; ++i) { for (int i = 0;; ++i) {
if (i > 1000) { if (i > 1000) {
_ports[1] = 0; _ports[1] = 0;
break; break;
} }
else if (++_ports[1] >= 65536) { else if (++_ports[1] >= maxPort) {
_ports[1] = 20000; _ports[1] = minPort;
} }
if (_trialBind(_ports[1])) { if (_trialBind(_ports[1])) {
_secondaryPort = _ports[1];
break; break;
} }
} }
}
#ifdef ZT_USE_MINIUPNPC #ifdef ZT_USE_MINIUPNPC
if (_portMappingEnabled) { if (_allowPortMapping) {
// If we're running uPnP/NAT-PMP, bind a *third* port for that. // If we're running uPnP/NAT-PMP, bind a *third* port for that.
// We can't use the other two ports for that because some NATs // We can't use the other two ports for that because some NATs
// do really funky stuff with ports that are explicitly mapped // do really funky stuff with ports that are explicitly mapped
// that breaks things. // that breaks things.
maxPort = (_randomPortRangeEnd ? _randomPortRangeEnd : 65536);
if (_ports[1]) { if (_ports[1]) {
_ports[2] = (_tertiaryPort == 0) ? _ports[1] : _tertiaryPort; _ports[2] = (_tertiaryPort == 0) ? _ports[1] : _tertiaryPort;
for (int i = 0;; ++i) { for (int i = 0;; ++i) {
@@ -294,10 +310,11 @@ NodeService::ReasonForTermination NodeService::run()
_ports[2] = 0; _ports[2] = 0;
break; break;
} }
else if (++_ports[2] >= 65536) { else if (++_ports[2] >= maxPort) {
_ports[2] = 20000; _ports[2] = minPort;
} }
if (_trialBind(_ports[2])) { if (_trialBind(_ports[2])) {
_tertiaryPort = _ports[2];
break; break;
} }
} }
@@ -511,7 +528,7 @@ void NodeService::terminate()
_allowNetworkCaching = true; _allowNetworkCaching = true;
_allowPeerCaching = true; _allowPeerCaching = true;
_allowIdentityCaching = true; _allowIdentityCaching = true;
_allowWorldCaching = true; _allowRootSetCaching = true;
memset(_publicIdStr, 0, ZT_IDENTITY_STRING_BUFFER_LENGTH); memset(_publicIdStr, 0, ZT_IDENTITY_STRING_BUFFER_LENGTH);
memset(_secretIdStr, 0, ZT_IDENTITY_STRING_BUFFER_LENGTH); memset(_secretIdStr, 0, ZT_IDENTITY_STRING_BUFFER_LENGTH);
_interfacePrefixBlacklist.clear(); _interfacePrefixBlacklist.clear();
@@ -1270,7 +1287,7 @@ void NodeService::nodeStatePutFunction(
case ZT_STATE_OBJECT_PLANET: case ZT_STATE_OBJECT_PLANET:
sendEventToUser(ZTS_EVENT_STORE_PLANET, data, len); sendEventToUser(ZTS_EVENT_STORE_PLANET, data, len);
memcpy(_rootsData, data, len); memcpy(_rootsData, data, len);
if (_homePath.length() > 0 && _allowWorldCaching) { if (_homePath.length() > 0 && _allowRootSetCaching) {
OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "roots", _homePath.c_str()); OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "roots", _homePath.c_str());
} }
else { else {
@@ -1711,11 +1728,42 @@ int NodeService::setPrimaryPort(unsigned short primaryPort)
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
int NodeService::setRandomPortRange(unsigned short startPort, unsigned short endPort)
{
Mutex::Lock _lr(_run_m);
if (_run) {
return ZTS_ERR_SERVICE;
}
_randomPortRangeStart = startPort;
_randomPortRangeEnd = endPort;
return ZTS_ERR_OK;
}
unsigned short NodeService::getPrimaryPort() const unsigned short NodeService::getPrimaryPort() const
{ {
return _primaryPort; return _primaryPort;
} }
int NodeService::allowPortMapping(unsigned int allowed)
{
Mutex::Lock _lr(_run_m);
if (_run) {
return ZTS_ERR_SERVICE;
}
_allowPortMapping = allowed;
return ZTS_ERR_OK;
}
int NodeService::allowSecondaryPort(unsigned int allowed)
{
Mutex::Lock _lr(_run_m);
if (_run) {
return ZTS_ERR_SERVICE;
}
_allowSecondaryPort = allowed;
return ZTS_ERR_OK;
}
int NodeService::setUserEventSystem(Events* events) int NodeService::setUserEventSystem(Events* events)
{ {
Mutex::Lock _lr(_run_m); Mutex::Lock _lr(_run_m);
@@ -1735,7 +1783,7 @@ void NodeService::enableEvents()
_events->enable(); _events->enable();
} }
int NodeService::setWorld(const void* rootsData, unsigned int len) int NodeService::setRoots(const void* rootsData, unsigned int len)
{ {
if (! rootsData || len <= 0 || len > ZTS_STORE_DATA_LEN) { if (! rootsData || len <= 0 || len > ZTS_STORE_DATA_LEN) {
return ZTS_ERR_ARG; return ZTS_ERR_ARG;
@@ -1834,13 +1882,13 @@ int NodeService::allowIdentityCaching(unsigned int allowed)
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
int NodeService::allowWorldCaching(unsigned int allowed) int NodeService::allowRootSetCaching(unsigned int allowed)
{ {
Mutex::Lock _lr(_run_m); Mutex::Lock _lr(_run_m);
if (_run) { if (_run) {
return ZTS_ERR_SERVICE; return ZTS_ERR_SERVICE;
} }
_allowWorldCaching = allowed; _allowRootSetCaching = allowed;
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
int NodeService::getNetworkBroadcast(uint64_t net_id) int NodeService::getNetworkBroadcast(uint64_t net_id)

View File

@@ -117,9 +117,13 @@ class NodeService {
Node* _node; Node* _node;
uint64_t _nodeId; uint64_t _nodeId;
unsigned int _primaryPort = 0; unsigned int _primaryPort;
unsigned int _secondaryPort = 0; unsigned int _secondaryPort;
unsigned int _tertiaryPort = 0; unsigned int _tertiaryPort;
unsigned int _randomPortRangeStart;
unsigned int _randomPortRangeEnd;
volatile unsigned int _udpPortPickerCounter; volatile unsigned int _udpPortPickerCounter;
std::map<uint64_t, unsigned int> peerCache; std::map<uint64_t, unsigned int> peerCache;
@@ -197,15 +201,16 @@ class NodeService {
std::string _fatalErrorMessage; std::string _fatalErrorMessage;
// uPnP/NAT-PMP port mapper if enabled // uPnP/NAT-PMP port mapper if enabled
bool _portMappingEnabled; // local.conf settings bool _allowPortMapping;
#ifdef ZT_USE_MINIUPNPC #ifdef ZT_USE_MINIUPNPC
PortMapper* _portMapper; PortMapper* _portMapper;
#endif #endif
bool _allowSecondaryPort;
uint8_t _allowNetworkCaching; uint8_t _allowNetworkCaching;
uint8_t _allowPeerCaching; uint8_t _allowPeerCaching;
uint8_t _allowIdentityCaching; uint8_t _allowIdentityCaching;
uint8_t _allowWorldCaching; uint8_t _allowRootSetCaching;
char _publicIdStr[ZT_IDENTITY_STRING_BUFFER_LENGTH] = { 0 }; char _publicIdStr[ZT_IDENTITY_STRING_BUFFER_LENGTH] = { 0 };
char _secretIdStr[ZT_IDENTITY_STRING_BUFFER_LENGTH] = { 0 }; char _secretIdStr[ZT_IDENTITY_STRING_BUFFER_LENGTH] = { 0 };
@@ -368,19 +373,28 @@ class NodeService {
/** Instruct the NodeService on where to look for identity files and caches */ /** Instruct the NodeService on where to look for identity files and caches */
int setHomePath(const char* homePath); int setHomePath(const char* homePath);
/** Set the NodeService's primary port */ /** Set the primary port */
int setPrimaryPort(unsigned short primaryPort); int setPrimaryPort(unsigned short primaryPort);
/** Get the NodeService's primary port */ /** Set random range to select backup ports from */
int setRandomPortRange(unsigned short startPort, unsigned short endPort);
/** Get the primary port */
unsigned short getPrimaryPort() const; unsigned short getPrimaryPort() const;
/** Allow or disallow port-mapping */
int allowPortMapping(unsigned int allowed);
/** Allow or disallow backup port */
int allowSecondaryPort(unsigned int allowed);
/** Set the event system instance used to convey messages to the user */ /** Set the event system instance used to convey messages to the user */
int setUserEventSystem(Events* events); int setUserEventSystem(Events* events);
void enableEvents(); void enableEvents();
/** Set the roots definition */ /** Set the roots definition */
int setWorld(const void* data, unsigned int len); int setRoots(const void* data, unsigned int len);
/** Add Interface prefix to blacklist (prevents ZeroTier from using that interface) */ /** Add Interface prefix to blacklist (prevents ZeroTier from using that interface) */
int addInterfacePrefixToBlacklist(const char* prefix, unsigned int len); int addInterfacePrefixToBlacklist(const char* prefix, unsigned int len);
@@ -401,7 +415,7 @@ class NodeService {
int allowIdentityCaching(unsigned int allowed); int allowIdentityCaching(unsigned int allowed);
/** Allow ZeroTier to cache root definitions to storage */ /** Allow ZeroTier to cache root definitions to storage */
int allowWorldCaching(unsigned int allowed); int allowRootSetCaching(unsigned int allowed);
/** Return whether broadcast is enabled on the given network */ /** Return whether broadcast is enabled on the given network */
int getNetworkBroadcast(uint64_t net_id); int getNetworkBroadcast(uint64_t net_id);

View File

@@ -688,15 +688,24 @@ SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_set_roots(void* jarg1, int jarg2)
return jresult; return jresult;
} }
SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_set_port(unsigned short jarg1) SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_set_port(unsigned short port)
{ {
int jresult; return zts_init_set_port(port);
unsigned short arg1; }
int result;
arg1 = (unsigned short)jarg1; SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_set_random_port_range(unsigned short start_port, unsigned short end_port)
result = (int)zts_init_set_port(arg1); {
jresult = result; return zts_init_set_random_port_range(start_port, end_port);
return jresult; }
SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_allow_secondary_port(int allowed)
{
return zts_init_allow_secondary_port(allowed);
}
SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_allow_port_mapping(int allowed)
{
return zts_init_allow_port_mapping(allowed);
} }
SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_allow_net_cache(int jarg1) SWIGEXPORT int SWIGSTDCALL CSharp_zts_init_allow_net_cache(int jarg1)

View File

@@ -30,7 +30,6 @@ namespace ZeroTier.Core
public class Node { public class Node {
static ulong _id = 0x0; static ulong _id = 0x0;
static ushort _primaryPort;
static ushort _secondaryPort; static ushort _secondaryPort;
static ushort _tertiaryPort; static ushort _tertiaryPort;
static int _versionMajor; static int _versionMajor;
@@ -39,7 +38,7 @@ namespace ZeroTier.Core
static bool _isOnline = false; static bool _isOnline = false;
static bool _hasBeenFreed = false; static bool _hasBeenFreed = false;
string _configFilePath; string _configFilePath;
ushort _servicePort; ushort _primaryPort;
static ZeroTierManagedEventCallback _managedCallback; static ZeroTierManagedEventCallback _managedCallback;
CSharpCallbackWithStruct _unmanagedCallback; CSharpCallbackWithStruct _unmanagedCallback;
@@ -64,7 +63,6 @@ namespace ZeroTier.Core
_versionRev = 0; _versionRev = 0;
_isOnline = false; _isOnline = false;
_configFilePath = string.Empty; _configFilePath = string.Empty;
_servicePort = 0;
_networks.Clear(); _networks.Clear();
_peers.Clear(); _peers.Clear();
} }
@@ -99,11 +97,16 @@ namespace ZeroTier.Core
{ {
int res = Constants.ERR_OK; int res = Constants.ERR_OK;
if ((res = zts_init_set_port(port)) == Constants.ERR_OK) { if ((res = zts_init_set_port(port)) == Constants.ERR_OK) {
_servicePort = port; _primaryPort = port;
} }
return res; return res;
} }
public int InitSetRandomPortRange(UInt16 startPort, UInt16 endPort)
{
return zts_init_set_random_port_range(startPort, endPort);
}
public int InitSetRoots(byte[] roots_data, int len) public int InitSetRoots(byte[] roots_data, int len)
{ {
IntPtr unmanagedPointer = Marshal.AllocHGlobal(roots_data.Length); IntPtr unmanagedPointer = Marshal.AllocHGlobal(roots_data.Length);
@@ -118,6 +121,16 @@ namespace ZeroTier.Core
return zts_init_allow_net_cache(Convert.ToByte(allowed)); return zts_init_allow_net_cache(Convert.ToByte(allowed));
} }
public int InitAllowSecondaryPort(bool allowed)
{
return zts_init_allow_secondary_port(Convert.ToByte(allowed));
}
public int InitAllowPortMapping(bool allowed)
{
return zts_init_allow_port_mapping(Convert.ToByte(allowed));
}
public int InitAllowPeerCaching(bool allowed) public int InitAllowPeerCaching(bool allowed)
{ {
return zts_init_allow_peer_cache(Convert.ToByte(allowed)); return zts_init_allow_peer_cache(Convert.ToByte(allowed));
@@ -338,7 +351,7 @@ namespace ZeroTier.Core
(zts_route_info_t)Marshal.PtrToStructure(msg.route, typeof(zts_route_info_t)); (zts_route_info_t)Marshal.PtrToStructure(msg.route, typeof(zts_route_info_t));
newEvent = new ZeroTier.Core.Event(); newEvent = new ZeroTier.Core.Event();
newEvent.Code = msg.event_code; newEvent.Code = msg.event_code;
newEvent.RouteInfo = default; // new RouteInfo(); // newEvent.RouteInfo = default; // new RouteInfo();
if (msg.event_code == Constants.EVENT_ROUTE_ADDED) { if (msg.event_code == Constants.EVENT_ROUTE_ADDED) {
newEvent.Name = "EVENT_ROUTE_ADDED"; newEvent.Name = "EVENT_ROUTE_ADDED";
@@ -354,10 +367,10 @@ namespace ZeroTier.Core
zts_peer_info_t peer_info = (zts_peer_info_t)Marshal.PtrToStructure(msg.peer, typeof(zts_peer_info_t)); zts_peer_info_t peer_info = (zts_peer_info_t)Marshal.PtrToStructure(msg.peer, typeof(zts_peer_info_t));
newEvent = new ZeroTier.Core.Event(); newEvent = new ZeroTier.Core.Event();
newEvent.Code = msg.event_code; newEvent.Code = msg.event_code;
newEvent.PeerInfo = default; // new PeerInfo(); // newEvent.PeerInfo = default; // new PeerInfo();
if (peer_info.role == Constants.PEER_ROLE_PLANET) { if (peer_info.role == Constants.PEER_ROLE_PLANET) {
Console.WriteLine("ROOT"); newEvent.Name = "PEER_ROLE_PLANET";
} }
if (msg.event_code == Constants.EVENT_PEER_DIRECT) { if (msg.event_code == Constants.EVENT_PEER_DIRECT) {
newEvent.Name = "EVENT_PEER_DIRECT"; newEvent.Name = "EVENT_PEER_DIRECT";
@@ -381,7 +394,7 @@ namespace ZeroTier.Core
(zts_addr_info_t)Marshal.PtrToStructure(msg.addr, typeof(zts_addr_info_t)); (zts_addr_info_t)Marshal.PtrToStructure(msg.addr, typeof(zts_addr_info_t));
newEvent = new ZeroTier.Core.Event(); newEvent = new ZeroTier.Core.Event();
newEvent.Code = msg.event_code; newEvent.Code = msg.event_code;
newEvent.AddressInfo = default; // new AddressInfo(); // newEvent.AddressInfo = default; // new AddressInfo();
if (msg.event_code == Constants.EVENT_ADDR_ADDED_IP4) { if (msg.event_code == Constants.EVENT_ADDR_ADDED_IP4) {
newEvent.Name = "EVENT_ADDR_ADDED_IP4"; newEvent.Name = "EVENT_ADDR_ADDED_IP4";
@@ -402,7 +415,7 @@ namespace ZeroTier.Core
if (msg.cache != IntPtr.Zero) { if (msg.cache != IntPtr.Zero) {
newEvent = new ZeroTier.Core.Event(); newEvent = new ZeroTier.Core.Event();
newEvent.Code = msg.event_code; newEvent.Code = msg.event_code;
newEvent.AddressInfo = default; // new AddressInfo(); // newEvent.AddressInfo = default; // new AddressInfo();
if (msg.event_code == Constants.EVENT_STORE_IDENTITY_SECRET) { if (msg.event_code == Constants.EVENT_STORE_IDENTITY_SECRET) {
newEvent.Name = "EVENT_STORE_IDENTITY_SECRET"; newEvent.Name = "EVENT_STORE_IDENTITY_SECRET";
@@ -580,12 +593,22 @@ namespace ZeroTier.Core
} }
} }
// id
[DllImport("libzt", CharSet = CharSet.Ansi, EntryPoint = "CSharp_zts_id_new")] static extern int [DllImport("libzt", CharSet = CharSet.Ansi, EntryPoint = "CSharp_zts_id_new")] static extern int
zts_id_new(string arg1, IntPtr arg2); zts_id_new(string arg1, IntPtr arg2);
[DllImport("libzt", CharSet = CharSet.Ansi, EntryPoint = "CSharp_zts_id_pair_is_valid")] [DllImport("libzt", CharSet = CharSet.Ansi, EntryPoint = "CSharp_zts_id_pair_is_valid")]
static extern int zts_id_pair_is_valid(string arg1, int arg2); static extern int zts_id_pair_is_valid(string arg1, int arg2);
// init
[DllImport("libzt", EntryPoint = "CSharp_zts_init_allow_net_cache")]
static extern int zts_init_allow_net_cache(int arg1);
[DllImport("libzt", EntryPoint = "CSharp_zts_init_allow_peer_cache")]
static extern int zts_init_allow_peer_cache(int arg1);
[DllImport("libzt", CharSet = CharSet.Ansi, EntryPoint = "CSharp_zts_init_from_storage")] [DllImport("libzt", CharSet = CharSet.Ansi, EntryPoint = "CSharp_zts_init_from_storage")]
static extern int zts_init_from_storage(string arg1); static extern int zts_init_from_storage(string arg1);
@@ -604,6 +627,15 @@ namespace ZeroTier.Core
[DllImport("libzt", EntryPoint = "CSharp_zts_init_set_port")] [DllImport("libzt", EntryPoint = "CSharp_zts_init_set_port")]
static extern int zts_init_set_port(ushort arg1); static extern int zts_init_set_port(ushort arg1);
[DllImport("libzt", EntryPoint = "CSharp_zts_init_set_random_port_range")]
static extern int zts_init_set_random_port_range(ushort arg1, ushort arg2);
[DllImport("libzt", EntryPoint = "CSharp_zts_init_allow_secondary_port")]
static extern int zts_init_allow_secondary_port(int arg1);
[DllImport("libzt", EntryPoint = "CSharp_zts_init_allow_port_mapping")]
static extern int zts_init_allow_port_mapping(int arg1);
// Core query API // Core query API
[DllImport("libzt", EntryPoint = "CSharp_zts_core_lock_obtain")] [DllImport("libzt", EntryPoint = "CSharp_zts_core_lock_obtain")]
@@ -643,17 +675,6 @@ namespace ZeroTier.Core
[DllImport("libzt", EntryPoint = "CSharp_zts_core_query_mc")] [DllImport("libzt", EntryPoint = "CSharp_zts_core_query_mc")]
static extern int zts_core_query_mc(ulong net_id, int idx, ref ulong mac, ref uint adi); static extern int zts_core_query_mc(ulong net_id, int idx, ref ulong mac, ref uint adi);
// init
[DllImport("libzt", EntryPoint = "CSharp_zts_init_allow_net_cache")]
static extern int zts_init_allow_net_cache(int arg1);
[DllImport("libzt", EntryPoint = "CSharp_zts_init_allow_peer_cache")]
static extern int zts_init_allow_peer_cache(int arg1);
[DllImport("libzt", EntryPoint = "CSharp_zts_init_clear")]
static extern int zts_init_clear();
// addr // addr
[DllImport("libzt", EntryPoint = "CSharp_zts_addr_is_assigned")] [DllImport("libzt", EntryPoint = "CSharp_zts_addr_is_assigned")]

View File

@@ -26,13 +26,16 @@ public class ExampleApp {
// node.InitAllowIdentityCaching(true); // node.InitAllowIdentityCaching(true);
// node.InitAllowWorldCaching(false); // node.InitAllowWorldCaching(false);
node.InitSetEventHandler(OnZeroTierEvent); node.InitSetEventHandler(OnZeroTierEvent);
node.InitSetPort(0); // Will randomly attempt ports if set to 0 //node.InitSetPort(0); // Will randomly attempt ports if not specified or is set to 0
node.InitSetRandomPortRange(40000, 50000);
// node.InitAllowSecondaryPort(false);
// (OPTIONAL) Set custom signed roots // (OPTIONAL) Set custom signed roots
// In this case we only allow ZeroTier to contact our Amsterdam root server // In this case we only allow ZeroTier to contact our Amsterdam root server
// To see examples of how to generate and sign roots definitions see docs.zerotier.com // To see examples of how to generate and sign roots definitions see docs.zerotier.com
/*
var rootsData = new byte[] { var rootsData = new byte[] {
0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xea, 0xc9, 0x0a, 0x00, 0x00, 0x01, 0x6c, 0xe3, 0xe2, 0x39, 0x55, 0x74, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xea, 0xc9, 0x0a, 0x00, 0x00, 0x01, 0x6c, 0xe3, 0xe2, 0x39, 0x55, 0x74,
0xeb, 0x27, 0x9d, 0xc9, 0xe7, 0x5a, 0x52, 0xbb, 0x91, 0x8f, 0xf7, 0x43, 0x3c, 0xbf, 0x77, 0x5a, 0x4b, 0x57, 0xeb, 0x27, 0x9d, 0xc9, 0xe7, 0x5a, 0x52, 0xbb, 0x91, 0x8f, 0xf7, 0x43, 0x3c, 0xbf, 0x77, 0x5a, 0x4b, 0x57,
@@ -52,6 +55,7 @@ public class ExampleApp {
0x00, 0x00, 0x00, 0x00, 0x27, 0x09 0x00, 0x00, 0x00, 0x00, 0x27, 0x09
}; };
node.InitSetRoots(rootsData, rootsData.Length); node.InitSetRoots(rootsData, rootsData.Length);
*/
node.Start(); // Network activity only begins after calling Start() node.Start(); // Network activity only begins after calling Start()
while (! node.Online) { while (! node.Online) {