Update C++, Objective-C and Swift examples

This commit is contained in:
Joseph Henry
2020-05-28 18:32:39 -07:00
parent be9af71238
commit f0d6330735
8 changed files with 698 additions and 394 deletions

View File

@@ -12,7 +12,7 @@
* the location given in the first argument to zts_start(path, ...). If you accidentally * the location given in the first argument to zts_start(path, ...). If you accidentally
* duplicate the identity files and use them simultaneously in a different node instance * duplicate the identity files and use them simultaneously in a different node instance
* you will experience undefined behavior and it is likely nothing will work. * you will experience undefined behavior and it is likely nothing will work.
* *
* - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join * - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join
* your network, otherwise nothing will happen. This can be done manually or via * your network, otherwise nothing will happen. This can be done manually or via
* our web API: https://my.zerotier.com/help/api * our web API: https://my.zerotier.com/help/api
@@ -51,12 +51,12 @@
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors * Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
* returned by these functions can be any of the following: * returned by these functions can be any of the following:
* *
* ZTS_ERR_OK 0 // No error * ZTS_ERR_OK // No error
* ZTS_ERR_SOCKET -1 // Socket error, see zts_errno * ZTS_ERR_SOCKET // Socket error, see zts_errno
* ZTS_ERR_SERVICE -2 // You probably did something at the wrong time * ZTS_ERR_SERVICE // You probably did something at the wrong time
* ZTS_ERR_ARG -3 // Invalid argument * ZTS_ERR_ARG // Invalid argument
* ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) * ZTS_ERR_NO_RESULT // No result (not necessarily an error)
* ZTS_ERR_GENERAL -5 // Consider filing a bug report * ZTS_ERR_GENERAL // Consider filing a bug report
* *
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc). * Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
* Errors returned by these functions can be the same as the above. With * Errors returned by these functions can be the same as the above. With
@@ -74,7 +74,7 @@
* are a few guidelines: * are a few guidelines:
* *
* If you are calling a zts_* function, use the appropriate ZTS_* constants: * If you are calling a zts_* function, use the appropriate ZTS_* constants:
* *
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT) * zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT) * zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
* *
@@ -91,10 +91,19 @@
#include "ZeroTierSockets.h" #include "ZeroTierSockets.h"
bool nodeReady = false; struct Node
bool networkReady = false; {
Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
bool online;
bool joinedAtLeastOneNetwork;
uint64_t id;
// etc
} myNode;
// Example callbacks /* Callback handler, you should return control from this function as quickly as you can
to ensure timely receipt of future events. You should not call libzt API functions from
this function unless it's something trivial like zts_inet_ntop() or similar that has
no state-change implications. */
void myZeroTierEventCallback(void *msgPtr) void myZeroTierEventCallback(void *msgPtr)
{ {
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr; struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr;
@@ -102,11 +111,12 @@ void myZeroTierEventCallback(void *msgPtr)
// Node events // Node events
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) { if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address); printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address);
nodeReady = true; myNode.id = msg->node->address;
myNode.online = true;
} }
if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) { if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) {
printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n"); printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n");
nodeReady = false; myNode.online = false;
} }
// Virtual network events // Virtual network events
@@ -116,7 +126,7 @@ void myZeroTierEventCallback(void *msgPtr)
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) { if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) {
printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid);
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) { if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) {
printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n", printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n",
msg->network->nwid); msg->network->nwid);
@@ -124,7 +134,7 @@ void myZeroTierEventCallback(void *msgPtr)
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) { if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) {
printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n", printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n",
msg->network->nwid); msg->network->nwid);
networkReady = true; myNode.joinedAtLeastOneNetwork = true;
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) { if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
@@ -132,17 +142,15 @@ void myZeroTierEventCallback(void *msgPtr)
// Network stack events // Network stack events
if (msg->eventCode == ZTS_EVENT_NETIF_UP) { if (msg->eventCode == ZTS_EVENT_NETIF_UP) {
printf("ZTS_EVENT_NETIF_UP --- network=%llx, mac=%llx, mtu=%d\n", printf("ZTS_EVENT_NETIF_UP --- network=%llx, mac=%llx, mtu=%d\n",
msg->netif->nwid, msg->netif->nwid,
msg->netif->mac, msg->netif->mac,
msg->netif->mtu); msg->netif->mtu);
networkReady = true;
} }
if (msg->eventCode == ZTS_EVENT_NETIF_DOWN) { if (msg->eventCode == ZTS_EVENT_NETIF_DOWN) {
printf("ZTS_EVENT_NETIF_DOWN --- network=%llx, mac=%llx\n", printf("ZTS_EVENT_NETIF_DOWN --- network=%llx, mac=%llx\n",
msg->netif->nwid, msg->netif->nwid,
msg->netif->mac); msg->netif->mac);
networkReady = true;
} }
// Address events // Address events
@@ -150,19 +158,32 @@ void myZeroTierEventCallback(void *msgPtr)
char ipstr[ZTS_INET6_ADDRSTRLEN]; char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr); struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP6 --- Join %llx and ping me at %s\n", printf("ZTS_EVENT_ADDR_NEW_IP6 --- Join %llx and ping me at %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
// Peer events // Peer events
// Don't worry if you don't recognize a peer ID, it's most likely our infrastructure if (msg->peer) {
if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) { if (msg->peer->role == ZTS_PEER_ROLE_PLANET) {
printf("ZTS_EVENT_PEER_DIRECT --- There is now a direct path to peer %llx\n", /* Safe to ignore, these are our roots. They orchestrate the P2P connection.
msg->peer->address); You might also see other unknown peers, these are our network controllers. */
} return;
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) { }
printf("ZTS_EVENT_PEER_RELAY --- No direct path to peer %llx\n", if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) {
msg->peer->address); printf("ZTS_EVENT_PEER_DIRECT --- A direct path is known for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) {
printf("ZTS_EVENT_PEER_RELAY --- No direct path to node=%llx\n", msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DISCOVERED) {
printf("ZTS_EVENT_PEER_PATH_DISCOVERED --- A new direct path was discovered for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DEAD) {
printf("ZTS_EVENT_PEER_PATH_DEAD --- A direct path has died for node=%llx\n",
msg->peer->address);
}
} }
} }
@@ -191,7 +212,7 @@ be taken to avoid exposing vulnerable services or sharing unwanted files or othe
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 5) { if (argc != 5) {
printf("\nlibzt example\n"); printf("\nlibzt example\n");
@@ -212,7 +233,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
printf("Waiting for node to come online...\n"); printf("Waiting for node to come online...\n");
while (!nodeReady) { zts_delay_ms(50); } while (!myNode.online) { zts_delay_ms(50); }
printf("This node's identity is stored in %s\n", argv[1]); printf("This node's identity is stored in %s\n", argv[1]);
if((err = zts_join(adhoc_nwid)) != ZTS_ERR_OK) { if((err = zts_join(adhoc_nwid)) != ZTS_ERR_OK) {
@@ -220,7 +241,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
printf("Joining network %llx\n", adhoc_nwid); printf("Joining network %llx\n", adhoc_nwid);
while (!networkReady) { zts_delay_ms(50); } while (!myNode.joinedAtLeastOneNetwork) { zts_delay_ms(50); }
// Idle and just show callback events, stack statistics, etc // Idle and just show callback events, stack statistics, etc

View File

@@ -9,10 +9,19 @@
#include "ZeroTierSockets.h" #include "ZeroTierSockets.h"
bool nodeReady = false; struct Node
bool networkReady = false; {
Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
bool online;
bool joinedAtLeastOneNetwork;
uint64_t id;
// etc
} myNode;
// Example callbacks /* Callback handler, you should return control from this function as quickly as you can
to ensure timely receipt of future events. You should not call libzt API functions from
this function unless it's something trivial like zts_inet_ntop() or similar that has
no state-change implications. */
void myZeroTierEventCallback(void *msgPtr) void myZeroTierEventCallback(void *msgPtr)
{ {
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr; struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr;
@@ -20,11 +29,12 @@ void myZeroTierEventCallback(void *msgPtr)
// Node events // Node events
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) { if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address); printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address);
nodeReady = true; myNode.id = msg->node->address;
myNode.online = true;
} }
if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) { if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) {
printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n"); printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n");
nodeReady = false; myNode.online = false;
} }
if (msg->eventCode == ZTS_EVENT_NODE_NORMAL_TERMINATION) { if (msg->eventCode == ZTS_EVENT_NODE_NORMAL_TERMINATION) {
printf("ZTS_EVENT_NODE_NORMAL_TERMINATION\n"); printf("ZTS_EVENT_NODE_NORMAL_TERMINATION\n");
@@ -37,7 +47,7 @@ void myZeroTierEventCallback(void *msgPtr)
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) { if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) {
printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid);
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) { if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) {
printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n", printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n",
msg->network->nwid); msg->network->nwid);
@@ -45,12 +55,12 @@ void myZeroTierEventCallback(void *msgPtr)
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) { if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) {
printf("ZTS_EVENT_NETWORK_READY_IP4 --- Network config received. IPv4 traffic can now be sent over network %llx\n", printf("ZTS_EVENT_NETWORK_READY_IP4 --- Network config received. IPv4 traffic can now be sent over network %llx\n",
msg->network->nwid); msg->network->nwid);
networkReady = true; myNode.joinedAtLeastOneNetwork = true;
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) { if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) {
printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n", printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n",
msg->network->nwid); msg->network->nwid);
networkReady = true; myNode.joinedAtLeastOneNetwork = true;
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) { if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
@@ -61,38 +71,52 @@ void myZeroTierEventCallback(void *msgPtr)
char ipstr[ZTS_INET_ADDRSTRLEN]; char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr); struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP4 --- This node's virtual address on network %llx is %s\n", printf("ZTS_EVENT_ADDR_NEW_IP4 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) { if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN]; char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr); struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP6 --- This node's virtual address on network %llx is %s\n", printf("ZTS_EVENT_ADDR_NEW_IP6 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP4) { if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP4) {
char ipstr[ZTS_INET_ADDRSTRLEN]; char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr); struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_REMOVED_IP4 --- The virtual address %s for this node on network %llx has been removed.\n", printf("ZTS_EVENT_ADDR_REMOVED_IP4 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid); ipstr, msg->addr->nwid);
} }
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP6) { if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN]; char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr); struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_REMOVED_IP6 --- The virtual address %s for this node on network %llx has been removed.\n", printf("ZTS_EVENT_ADDR_REMOVED_IP6 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid); ipstr, msg->addr->nwid);
} }
// Peer events // Peer events
if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) { if (msg->peer) {
printf("ZTS_EVENT_PEER_DIRECT --- node=%llx\n", msg->peer->address); if (msg->peer->role == ZTS_PEER_ROLE_PLANET) {
// A direct path is known for nodeId /* Safe to ignore, these are our roots. They orchestrate the P2P connection.
} You might also see other unknown peers, these are our network controllers. */
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) { return;
printf("ZTS_EVENT_PEER_RELAY --- node=%llx\n", msg->peer->address); }
// No direct path is known for nodeId if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) {
printf("ZTS_EVENT_PEER_DIRECT --- A direct path is known for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) {
printf("ZTS_EVENT_PEER_RELAY --- No direct path to node=%llx\n", msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DISCOVERED) {
printf("ZTS_EVENT_PEER_PATH_DISCOVERED --- A new direct path was discovered for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DEAD) {
printf("ZTS_EVENT_PEER_PATH_DEAD --- A direct path has died for node=%llx\n",
msg->peer->address);
}
} }
} }
@@ -104,7 +128,7 @@ void myZeroTierEventCallback(void *msgPtr)
* the location given in the first argument to zts_start(path, ...). If you accidentally * the location given in the first argument to zts_start(path, ...). If you accidentally
* duplicate the identity files and use them simultaneously in a different node instance * duplicate the identity files and use them simultaneously in a different node instance
* you will experience undefined behavior and it is likely nothing will work. * you will experience undefined behavior and it is likely nothing will work.
* *
* - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join * - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join
* your network, otherwise nothing will happen. This can be done manually or via * your network, otherwise nothing will happen. This can be done manually or via
* our web API: https://my.zerotier.com/help/api * our web API: https://my.zerotier.com/help/api
@@ -143,12 +167,12 @@ void myZeroTierEventCallback(void *msgPtr)
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors * Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
* returned by these functions can be any of the following: * returned by these functions can be any of the following:
* *
* ZTS_ERR_OK 0 // No error * ZTS_ERR_OK // No error
* ZTS_ERR_SOCKET -1 // Socket error, see zts_errno * ZTS_ERR_SOCKET // Socket error, see zts_errno
* ZTS_ERR_SERVICE -2 // You probably did something at the wrong time * ZTS_ERR_SERVICE // You probably did something at the wrong time
* ZTS_ERR_ARG -3 // Invalid argument * ZTS_ERR_ARG // Invalid argument
* ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) * ZTS_ERR_NO_RESULT // No result (not necessarily an error)
* ZTS_ERR_GENERAL -5 // Consider filing a bug report * ZTS_ERR_GENERAL // Consider filing a bug report
* *
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc). * Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
* Errors returned by these functions can be the same as the above. With * Errors returned by these functions can be the same as the above. With
@@ -166,7 +190,7 @@ void myZeroTierEventCallback(void *msgPtr)
* are a few guidelines: * are a few guidelines:
* *
* If you are calling a zts_* function, use the appropriate ZTS_* constants: * If you are calling a zts_* function, use the appropriate ZTS_* constants:
* *
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT) * zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT) * zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
* *
@@ -178,7 +202,7 @@ void myZeroTierEventCallback(void *msgPtr)
* *
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 6) { if (argc != 6) {
printf("\nlibzt example client\n"); printf("\nlibzt example client\n");
@@ -208,7 +232,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
printf("Waiting for node to come online...\n"); printf("Waiting for node to come online...\n");
while (!nodeReady) { zts_delay_ms(50); } while (!myNode.online) { zts_delay_ms(50); }
printf("This node's identity is stored in %s\n", argv[1]); printf("This node's identity is stored in %s\n", argv[1]);
if((err = zts_join(nwid)) != ZTS_ERR_OK) { if((err = zts_join(nwid)) != ZTS_ERR_OK) {
@@ -217,7 +241,7 @@ int main(int argc, char **argv)
} }
printf("Joining network %llx\n", nwid); printf("Joining network %llx\n", nwid);
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n"); printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
while (!networkReady) { zts_delay_ms(50); } while (!myNode.joinedAtLeastOneNetwork) { zts_delay_ms(50); }
// Socket-like API example // Socket-like API example
@@ -243,7 +267,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
zts_delay_ms(250); zts_delay_ms(250);
} }
else { else {
printf("Connected.\n"); printf("Connected.\n");
break; break;

View File

@@ -12,7 +12,7 @@
* the location given in the first argument to zts_start(path, ...). If you accidentally * the location given in the first argument to zts_start(path, ...). If you accidentally
* duplicate the identity files and use them simultaneously in a different node instance * duplicate the identity files and use them simultaneously in a different node instance
* you will experience undefined behavior and it is likely nothing will work. * you will experience undefined behavior and it is likely nothing will work.
* *
* - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join * - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join
* your network, otherwise nothing will happen. This can be done manually or via * your network, otherwise nothing will happen. This can be done manually or via
* our web API: https://my.zerotier.com/help/api * our web API: https://my.zerotier.com/help/api
@@ -51,12 +51,12 @@
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors * Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
* returned by these functions can be any of the following: * returned by these functions can be any of the following:
* *
* ZTS_ERR_OK 0 // No error * ZTS_ERR_OK // No error
* ZTS_ERR_SOCKET -1 // Socket error, see zts_errno * ZTS_ERR_SOCKET // Socket error, see zts_errno
* ZTS_ERR_SERVICE -2 // You probably did something at the wrong time * ZTS_ERR_SERVICE // You probably did something at the wrong time
* ZTS_ERR_ARG -3 // Invalid argument * ZTS_ERR_ARG // Invalid argument
* ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) * ZTS_ERR_NO_RESULT // No result (not necessarily an error)
* ZTS_ERR_GENERAL -5 // Consider filing a bug report * ZTS_ERR_GENERAL // Consider filing a bug report
* *
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc). * Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
* Errors returned by these functions can be the same as the above. With * Errors returned by these functions can be the same as the above. With
@@ -74,7 +74,7 @@
* are a few guidelines: * are a few guidelines:
* *
* If you are calling a zts_* function, use the appropriate ZTS_* constants: * If you are calling a zts_* function, use the appropriate ZTS_* constants:
* *
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT) * zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT) * zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
* *
@@ -88,126 +88,45 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string>
#include "ZeroTierSockets.h" #include "ZeroTierSockets.h"
bool nodeReady = false; #include "winsock.h"
bool networkReady = false;
// Example callbacks struct Node
void myZeroTierEventCallback(void *msgPtr)
{ {
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr; Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
bool online;
bool joinedAtLeastOneNetwork;
uint64_t id;
// etc
} myNode;
// Node events void printNodeDetails(const char *msgStr, struct zts_node_details *d)
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) { {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address); printf("\n%s\n", msgStr);
nodeReady = true; printf("\t- id : %llx\n", d->address);
} printf("\t- version : %d.%d.%d\n", d->versionMajor, d->versionMinor, d->versionRev);
if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) { printf("\t- primaryPort : %d\n", d->primaryPort);
printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n"); printf("\t- secondaryPort : %d\n", d->secondaryPort);
nodeReady = false;
}
if (msg->eventCode == ZTS_EVENT_NODE_NORMAL_TERMINATION) {
printf("ZTS_EVENT_NODE_NORMAL_TERMINATION\n");
}
// Virtual network events
if (msg->eventCode == ZTS_EVENT_NETWORK_NOT_FOUND) {
printf("ZTS_EVENT_NETWORK_NOT_FOUND --- Are you sure %llx is a valid network?\n",
msg->network->nwid);
}
if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) {
printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid);
}
if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) {
printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n",
msg->network->nwid);
}
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) {
printf("ZTS_EVENT_NETWORK_READY_IP4 --- Network config received. IPv4 traffic can now be sent over network %llx\n",
msg->network->nwid);
networkReady = true;
}
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) {
printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n",
msg->network->nwid);
networkReady = true;
}
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
}
// Network stack events
if (msg->eventCode == ZTS_EVENT_NETIF_UP) {
printf("ZTS_EVENT_NETIF_UP --- network=%llx, mac=%llx, mtu=%d\n",
msg->netif->nwid,
msg->netif->mac,
msg->netif->mtu);
networkReady = true;
}
if (msg->eventCode == ZTS_EVENT_NETIF_DOWN) {
printf("ZTS_EVENT_NETIF_DOWN --- network=%llx, mac=%llx\n",
msg->netif->nwid,
msg->netif->mac);
networkReady = true;
}
// Address events
if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP4) {
char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP4 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr);
}
if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP6 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr);
}
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP4) {
char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_REMOVED_IP4 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid);
}
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_REMOVED_IP6 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid);
}
// Peer events
if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) {
printf("ZTS_EVENT_PEER_DIRECT --- node=%llx\n", msg->peer->address);
// A direct path is known for nodeId
}
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) {
printf("ZTS_EVENT_PEER_RELAY --- node=%llx\n", msg->peer->address);
// No direct path is known for nodeId
}
} }
void printPeerDetails(struct zts_peer_details *pd) void printPeerDetails(const char *msgStr, struct zts_peer_details *d)
{ {
printf("\npeer=%llx, latency=%d, version=%d.%d.%d, pathCount=%d\n", printf("\n%s\n", msgStr);
pd->address, printf("\t- peer : %llx\n", d->address);
pd->latency, printf("\t- role : %llx\n", d->role);
pd->versionMajor, printf("\t- latency : %llx\n", d->latency);
pd->versionMinor, printf("\t- pathCount : %llx\n", d->pathCount);
pd->versionRev, printf("\t- version : %d.%d.%d\n", d->versionMajor, d->versionMinor, d->versionRev);
pd->pathCount); printf("\t- paths:\n");
// Print all known paths for each peer // Print all known paths for each peer
for (unsigned int j=0; j<pd->pathCount; j++) { for (unsigned int j=0; j<d->pathCount; j++) {
char ipstr[ZTS_INET6_ADDRSTRLEN]; char ipstr[ZTS_INET6_ADDRSTRLEN];
int port = 0; int port = 0;
struct zts_sockaddr *sa = (struct zts_sockaddr *)&(pd->paths[j].address); struct zts_sockaddr *sa = (struct zts_sockaddr *)&(d->paths[j].address);
if (sa->sa_family == ZTS_AF_INET) { // TODO: Probably broken if (sa->sa_family == ZTS_AF_INET) { // TODO: Probably broken
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)sa; struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)sa;
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
@@ -217,51 +136,219 @@ void printPeerDetails(struct zts_peer_details *pd)
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)sa; struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)sa;
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
} }
printf("\tpath[%d]=%s, port=%d\n", j, ipstr, port); printf("\t - %15s : %6d\n", ipstr, port);
} }
printf("\n");
} }
void getSinglePeerDetails(uint64_t peerId) void printNetworkDetails(const char *msgStr, struct zts_network_details *d)
{ {
struct zts_peer_details pd; printf("\n%s\n", msgStr);
int err = zts_get_peer(&pd, peerId); printf("\t- nwid : %llx\n", d->nwid);
printf("\t- mac : %lx\n", d->mac);
printf("\t- name : %s\n", d->name);
printf("\t- type : %d\n", d->type);
/* MTU for the virtual network can be set via our web API */
printf("\t- mtu : %d\n", d->mtu);
printf("\t- dhcp : %d\n", d->dhcp);
printf("\t- bridge : %d\n", d->bridge);
printf("\t- broadcastEnabled : %d\n", d->broadcastEnabled);
printf("\t- portError : %d\n", d->portError);
printf("\t- netconfRevision : %d\n", d->netconfRevision);
printf("\t- routeCount : %d\n", d->routeCount);
printf("\t- multicastSubscriptionCount : %d\n", d->multicastSubscriptionCount);
if (err == ZTS_ERR_OK) { for (int i=0; i<d->multicastSubscriptionCount; i++) {
printf("(%d) call succeeded\n", err); printf("\t - mac=%llx, adi=%x\n", d->multicastSubscriptions[i].mac, d->multicastSubscriptions[i].adi);
printPeerDetails(&pd);
} if (err == ZTS_ERR_ARG) {
printf("(%d) invalid argument\n", err);
return;
} if (err == ZTS_ERR_SERVICE) {
printf("(%d) error: invalid API operation or service error\n", err);
return;
} if (err == ZTS_ERR_NO_RESULT) {
printf("(%d) error: object or result not found\n", err);
return;
} }
}
// Similar to "zerotier-cli listpeers" printf("\t- addresses:\n");
void getAllPeerDetails()
{ for (int i=0; i<d->assignedAddressCount; i++) {
struct zts_peer_details pd[128]; if (d->assignedAddresses[i].ss_family == ZTS_AF_INET) {
/* This number should be large enough to handle the char ipstr[ZTS_INET_ADDRSTRLEN];
expected number of peers. This call can also get struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(d->assignedAddresses[i]);
expensive for large numbers of peers. Consider using zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
get_peer(struct zts_peer_details *pds, uint64_t peerId) printf("\t - %s\n",ipstr);
instead */ }
unsigned int num = 128; if (d->assignedAddresses[i].ss_family == ZTS_AF_INET6) {
int err; char ipstr[ZTS_INET6_ADDRSTRLEN];
if ((err = zts_get_peers(pd, &num)) < 0) { struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(d->assignedAddresses[i]);
printf("error (%d)\n", err); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
return; printf("\t - %s\n",ipstr);
}
if (num) {
printf("num=%d\n", num);
for (unsigned int i=0; i<num; i++) {
printPeerDetails(&pd[i]);
} }
} }
printf("\t- routes:\n");
for (int i=0; i<d->routeCount; i++) {
if (d->routes[i].target.ss_family == ZTS_AF_INET) {
char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(d->routes[i].target);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("\t - target : %s\n",ipstr);
in4 = (struct zts_sockaddr_in*)&(d->routes[i].via);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("\t - via : %s\n",ipstr);
}
if (d->routes[i].target.ss_family == ZTS_AF_INET6) {
char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(d->routes[i].target);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("\t - target : %s\n",ipstr);
in6 = (struct zts_sockaddr_in6*)&(d->routes[i].via);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("\t - via : %s\n",ipstr);
}
printf("\t - flags : %d\n", d->routes[i].flags);
printf("\t - metric : %d\n", d->routes[i].metric);
}
}
void printNetifDetails(const char *msgStr, struct zts_netif_details *d)
{
printf("\n%s\n", msgStr);
printf("\t- nwid : %llx\n", d->nwid);
printf("\t- mac : %llx\n", d->mac);
printf("\t- mtu : %d\n", d->mtu);
}
/* Callback handler, you should return control from this function as quickly as you can
to ensure timely receipt of future events. You should not call libzt API functions from
this function unless it's something trivial like zts_inet_ntop() or similar that has
no state-change implications. */
void myZeroTierEventCallback(void *msgPtr)
{
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr;
printf("code=%d\n", msg->eventCode);
// Node events
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
printNodeDetails("nZTS_EVENT_NODE_ONLINE", msg->node);
myNode.id = msg->node->address;
myNode.online = true;
}
if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) {
printf("\nZTS_EVENT_NODE_OFFLINE --- Check your Internet connection, router, firewall, etc. What ports are you blocking?\n");
myNode.online = false;
}
if (msg->eventCode == ZTS_EVENT_NODE_NORMAL_TERMINATION) {
printf("\nZTS_EVENT_NODE_NORMAL_TERMINATION -- A call to zts_start() will restart ZeroTier.\n");
myNode.online = false;
}
// Virtual network events
if (msg->eventCode == ZTS_EVENT_NETWORK_NOT_FOUND) {
printf("\nZTS_EVENT_NETWORK_NOT_FOUND --- Are you sure %llx is a valid network?\n",
msg->network->nwid);
}
if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) {
printf("\nZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n",
msg->network->nwid);
}
if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) {
printf("\nZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n",
msg->network->nwid);
}
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) {
printNetworkDetails("ZTS_EVENT_NETWORK_READY_IP4 --- Network config received.", msg->network);
myNode.joinedAtLeastOneNetwork = true;
}
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) {
printNetworkDetails("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received.", msg->network);
myNode.joinedAtLeastOneNetwork = true;
}
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("\nZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
}
if (msg->eventCode == ZTS_EVENT_NETWORK_UPDATE) {
printNetworkDetails("ZTS_EVENT_NETWORK_UPDATE --- Network config received.", msg->network);
}
// Address events
if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP4) {
char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("\nZTS_EVENT_ADDR_ADDED_IP4 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr);
}
if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("\nZTS_EVENT_ADDR_ADDED_IP6 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr);
}
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP4) {
char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("\nZTS_EVENT_ADDR_REMOVED_IP4 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid);
}
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("\nZTS_EVENT_ADDR_REMOVED_IP6 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid);
}
// Peer events
if (msg->peer) {
if (msg->peer->role == ZTS_PEER_ROLE_PLANET) {
/* Safe to ignore, these are our roots. They orchestrate the P2P connection.
You might also see other unknown peers, these are our network controllers. */
return;
}
if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) {
printPeerDetails("ZTS_EVENT_PEER_DIRECT --- A direct path is known.", msg->peer);
}
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) {
printPeerDetails("ZTS_EVENT_PEER_RELAY --- No direct path known.", msg->peer);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DISCOVERED) {
printPeerDetails("ZTS_EVENT_PEER_PATH_DISCOVERED --- A new direct path was discovered.", msg->peer);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DEAD) {
printPeerDetails("ZTS_EVENT_PEER_PATH_DEAD --- A direct path has died.", msg->peer);
}
}
// Network stack (netif) events (used for debugging, can be ignored)
if (msg->eventCode == ZTS_EVENT_NETIF_UP) {
printNetifDetails("ZTS_EVENT_NETIF_UP --- No action required.", msg->netif);
}
if (msg->eventCode == ZTS_EVENT_NETIF_DOWN) {
printNetifDetails("ZTS_EVENT_NETIF_DOWN --- No action required.", msg->netif);
}
if (msg->eventCode == ZTS_EVENT_NETIF_REMOVED) {
printNetifDetails("ZTS_EVENT_NETIF_REMOVED --- No action required.", msg->netif);
}
if (msg->eventCode == ZTS_EVENT_NETIF_LINK_UP) {
printNetifDetails("ZTS_EVENT_NETIF_LINK_UP --- No action required.", msg->netif);
}
if (msg->eventCode == ZTS_EVENT_NETIF_LINK_DOWN) {
printNetifDetails("ZTS_EVENT_NETIF_LINK_DOWN --- No action required.", msg->netif);
}
// Network stack events (used for debugging, can be ignored)
if (msg->eventCode == ZTS_EVENT_STACK_UP) {
printf("\nZTS_EVENT_STACK_UP --- No action required.\n");
}
if (msg->eventCode == ZTS_EVENT_STACK_DOWN) {
printf("\nZTS_EVENT_STACK_DOWN --- No action required. An app restart is needed to use ZeroTier again.\n");
}
}
void get6PLANEAddressOfPeer(uint64_t peerId, uint64_t nwId)
{
char peerAddrStr[ZTS_INET6_ADDRSTRLEN] = {0};
struct zts_sockaddr_storage sixplane_addr;
zts_get_6plane_addr(&sixplane_addr, nwId, peerId);
struct zts_sockaddr_in6 *p6 = (struct zts_sockaddr_in6*)&sixplane_addr;
zts_inet_ntop(ZTS_AF_INET6, &(p6->sin6_addr), peerAddrStr, ZTS_INET6_ADDRSTRLEN);
printf("6PLANE address of peer is: %s\n", peerAddrStr);
} }
struct zts_stats_proto protoSpecificStats; struct zts_stats_proto protoSpecificStats;
@@ -283,35 +370,36 @@ void display_stack_stats()
printf("tcp.drop=%d\n", protoSpecificStats.drop); printf("tcp.drop=%d\n", protoSpecificStats.drop);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
fprintf(stderr, "AF_INET=%d, SOCK_STREAM=%d, IPPROTO_TCP=%d", AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (argc != 4) { if (argc != 4) {
printf("\nlibzt example server\n"); printf("\nlibzt example server\n");
printf("comprehensive <config_file_path> <nwid> <ztServicePort>\n"); printf("comprehensive <config_file_path> <nwid> <ztServicePort>\n");
exit(0); exit(0);
} }
std::string configPath = std::string(argv[1]);
uint64_t nwid = strtoull(argv[2],NULL,16); // Network ID to join uint64_t nwid = strtoull(argv[2],NULL,16); // Network ID to join
int ztServicePort = atoi(argv[3]); // Port ZT uses to send encrypted UDP packets to peers (try something like 9994) int ztServicePort = atoi(argv[3]); // Port ZT uses to send encrypted UDP packets to peers (try something like 9994)
// Bring up ZeroTier service and join network // Bring up ZeroTier service and join network
// Enable/Disable caching of network details in networks.d
// (read function documentation before disabling!)
// zts_allow_network_caching(0)
// Enable/Disable caching of peer details in peers.d
// (read function documentation before disabling!)
// zts_allow_network_caching(1)
int err = ZTS_ERR_OK; int err = ZTS_ERR_OK;
// Disable caching of network details in networks.d if((err = zts_start(configPath.c_str(), &myZeroTierEventCallback, ztServicePort)) != ZTS_ERR_OK) {
// (read function documentation before disabling!)
// zts_set_network_caching(false)
// Disable caching of peer details in peers.d
// (read function documentation before disabling!)
// zts_set_network_caching(false)
if((err = zts_start(argv[1], &myZeroTierEventCallback, ztServicePort)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err); printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1); exit(1);
} }
printf("Waiting for node to come online...\n"); printf("Waiting for node to come online...\n");
while (!nodeReady) { zts_delay_ms(50); } while (!myNode.online) { zts_delay_ms(50); }
printf("This node ID is %llx\n", zts_get_node_id());
printf("This node's identity is stored in %s\n", argv[1]); printf("This node's identity is stored in %s\n", argv[1]);
if((err = zts_join(nwid)) != ZTS_ERR_OK) { if((err = zts_join(nwid)) != ZTS_ERR_OK) {
@@ -320,35 +408,29 @@ int main(int argc, char **argv)
} }
printf("Joining network %llx\n", nwid); printf("Joining network %llx\n", nwid);
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n"); printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
while (!networkReady) { zts_delay_ms(50); } while (!myNode.joinedAtLeastOneNetwork) { zts_delay_ms(50); }
// Get multiple peer's details
getAllPeerDetails();
// Get a single peer's details
uint64_t peerId = 0xabcdef1234;
getSinglePeerDetails(peerId);
int status = -1;
// Get status of the node/service
status = zts_get_node_status();
printf("zts_get_node_status()=%d\n", status);
// Get status of a network
status = zts_get_network_status(nwid);
printf("zts_get_network_status()=%d\n", status);
// Idle and just show callback events, stack statistics, etc // Idle and just show callback events, stack statistics, etc
// Alternatively, this is where you could start making calls to the socket API
while (true) { /*
zts_delay_ms(1000); while(true) {
status = zts_get_node_status();
printf("zts_get_node_status()=%d\n", status);
display_stack_stats(); display_stack_stats();
zts_delay_ms(1000);
} }
*/
// Shut down service and stack threads int delay = 500000;
printf("This program will delay for %d seconds and then shut down.\n", (delay / 1000));
zts_delay_ms(delay);
//printf("Leaving network %llx\n", nwid);
//zts_leave(nwid);
//zts_delay_ms(3000); /* added for demo purposes so that events show up */
printf("Stopping ZeroTier\n");
zts_stop(); zts_stop();
zts_delay_ms(delay); /* added for demo purposes so that events show up */
printf("Stopping network stack\n");
zts_free();
zts_delay_ms(delay); /* added for demo purposes so that events show up */
return 0; return 0;
} }

View File

@@ -12,7 +12,7 @@
* the location given in the first argument to zts_start(path, ...). If you accidentally * the location given in the first argument to zts_start(path, ...). If you accidentally
* duplicate the identity files and use them simultaneously in a different node instance * duplicate the identity files and use them simultaneously in a different node instance
* you will experience undefined behavior and it is likely nothing will work. * you will experience undefined behavior and it is likely nothing will work.
* *
* - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join * - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join
* your network, otherwise nothing will happen. This can be done manually or via * your network, otherwise nothing will happen. This can be done manually or via
* our web API: https://my.zerotier.com/help/api * our web API: https://my.zerotier.com/help/api
@@ -51,12 +51,12 @@
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors * Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
* returned by these functions can be any of the following: * returned by these functions can be any of the following:
* *
* ZTS_ERR_OK 0 // No error * ZTS_ERR_OK // No error
* ZTS_ERR_SOCKET -1 // Socket error, see zts_errno * ZTS_ERR_SOCKET // Socket error, see zts_errno
* ZTS_ERR_SERVICE -2 // You probably did something at the wrong time * ZTS_ERR_SERVICE // You probably did something at the wrong time
* ZTS_ERR_ARG -3 // Invalid argument * ZTS_ERR_ARG // Invalid argument
* ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) * ZTS_ERR_NO_RESULT // No result (not necessarily an error)
* ZTS_ERR_GENERAL -5 // Consider filing a bug report * ZTS_ERR_GENERAL // Consider filing a bug report
* *
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc). * Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
* Errors returned by these functions can be the same as the above. With * Errors returned by these functions can be the same as the above. With
@@ -74,7 +74,7 @@
* are a few guidelines: * are a few guidelines:
* *
* If you are calling a zts_* function, use the appropriate ZTS_* constants: * If you are calling a zts_* function, use the appropriate ZTS_* constants:
* *
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT) * zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT) * zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
* *
@@ -91,25 +91,35 @@
#include "ZeroTierSockets.h" #include "ZeroTierSockets.h"
bool nodeReady = false; struct Node
bool networkReady = false; {
Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
bool online;
bool joinedAtLeastOneNetwork;
uint64_t id;
// etc
} myNode;
// Example callbacks /* Callback handler, you should return control from this function as quickly as you can
to ensure timely receipt of future events. You should not call libzt API functions from
this function unless it's something trivial like zts_inet_ntop() or similar that has
no state-change implications. */
void myZeroTierEventCallback(void *msgPtr) void myZeroTierEventCallback(void *msgPtr)
{ {
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr; struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr;
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) { if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address); printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address);
nodeReady = true; myNode.id = msg->node->address;
myNode.online = true;
} }
if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) { if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) {
printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n"); printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n");
nodeReady = false; myNode.online = false;
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) { if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) {
printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid);
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) { if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) {
printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n", printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n",
msg->network->nwid); msg->network->nwid);
@@ -117,7 +127,7 @@ void myZeroTierEventCallback(void *msgPtr)
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) { if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) {
printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n", printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n",
msg->network->nwid); msg->network->nwid);
networkReady = true; myNode.joinedAtLeastOneNetwork = true;
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) { if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
@@ -126,28 +136,42 @@ void myZeroTierEventCallback(void *msgPtr)
char ipstr[ZTS_INET_ADDRSTRLEN]; char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr); struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP4 --- Join %llx and ping me at %s\n", printf("ZTS_EVENT_ADDR_NEW_IP4 --- Join %llx and ping me at %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) { if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN]; char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr); struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP6 --- Join %llx and ping me at %s\n", printf("ZTS_EVENT_ADDR_NEW_IP6 --- Join %llx and ping me at %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
// Don't worry if you don't recognize a peer ID, it's most likely our infrastructure // Peer events
if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) { if (msg->peer) {
printf("ZTS_EVENT_PEER_DIRECT --- There is now a direct path to peer %llx\n", if (msg->peer->role == ZTS_PEER_ROLE_PLANET) {
msg->peer->address); /* Safe to ignore, these are our roots. They orchestrate the P2P connection.
} You might also see other unknown peers, these are our network controllers. */
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) { return;
printf("ZTS_EVENT_PEER_RELAY --- No direct path to peer %llx\n", }
msg->peer->address); if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) {
printf("ZTS_EVENT_PEER_DIRECT --- A direct path is known for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) {
printf("ZTS_EVENT_PEER_RELAY --- No direct path to node=%llx\n", msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DISCOVERED) {
printf("ZTS_EVENT_PEER_PATH_DISCOVERED --- A new direct path was discovered for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DEAD) {
printf("ZTS_EVENT_PEER_PATH_DEAD --- A direct path has died for node=%llx\n",
msg->peer->address);
}
} }
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 3) { if (argc != 3) {
printf("\nlibzt example\n"); printf("\nlibzt example\n");
@@ -155,7 +179,7 @@ int main(int argc, char **argv)
exit(0); exit(0);
} }
int ztServicePort = atoi(argv[2]); // Port ZT uses to send encrypted UDP packets to peers (try something like 9994) int ztServicePort = atoi(argv[2]); // Port ZT uses to send encrypted UDP packets to peers (try something like 9994)
int err = ZTS_ERR_OK; int err = ZTS_ERR_OK;
zts_allow_network_caching(false); zts_allow_network_caching(false);
@@ -164,7 +188,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
printf("Waiting for node to come online...\n"); printf("Waiting for node to come online...\n");
while (!nodeReady) { zts_delay_ms(50); } while (!myNode.online) { zts_delay_ms(50); }
printf("This node's identity is stored in %s\n", argv[1]); printf("This node's identity is stored in %s\n", argv[1]);
uint64_t nwid = 0x8056c2e21c000001; uint64_t nwid = 0x8056c2e21c000001;
@@ -174,7 +198,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
printf("Joining network %llx\n", nwid); printf("Joining network %llx\n", nwid);
while (!networkReady) { zts_delay_ms(50); } while (!myNode.joinedAtLeastOneNetwork) { zts_delay_ms(50); }
// Idle and just show callback events, stack statistics, etc // Idle and just show callback events, stack statistics, etc

View File

@@ -9,10 +9,19 @@
#include "ZeroTierSockets.h" #include "ZeroTierSockets.h"
bool nodeReady = false; struct Node
bool networkReady = false; {
Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
bool online;
bool joinedAtLeastOneNetwork;
uint64_t id;
// etc
} myNode;
// Example callbacks /* Callback handler, you should return control from this function as quickly as you can
to ensure timely receipt of future events. You should not call libzt API functions from
this function unless it's something trivial like zts_inet_ntop() or similar that has
no state-change implications. */
void myZeroTierEventCallback(void *msgPtr) void myZeroTierEventCallback(void *msgPtr)
{ {
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr; struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr;
@@ -20,11 +29,12 @@ void myZeroTierEventCallback(void *msgPtr)
// Node events // Node events
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) { if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address); printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address);
nodeReady = true; myNode.id = msg->node->address;
myNode.online = true;
} }
if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) { if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) {
printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n"); printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, firewall, etc. What ports are you blocking?\n");
nodeReady = false; myNode.online = false;
} }
if (msg->eventCode == ZTS_EVENT_NODE_NORMAL_TERMINATION) { if (msg->eventCode == ZTS_EVENT_NODE_NORMAL_TERMINATION) {
printf("ZTS_EVENT_NODE_NORMAL_TERMINATION\n"); printf("ZTS_EVENT_NODE_NORMAL_TERMINATION\n");
@@ -37,7 +47,7 @@ void myZeroTierEventCallback(void *msgPtr)
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) { if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) {
printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid);
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) { if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) {
printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n", printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n",
msg->network->nwid); msg->network->nwid);
@@ -45,12 +55,12 @@ void myZeroTierEventCallback(void *msgPtr)
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) { if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) {
printf("ZTS_EVENT_NETWORK_READY_IP4 --- Network config received. IPv4 traffic can now be sent over network %llx\n", printf("ZTS_EVENT_NETWORK_READY_IP4 --- Network config received. IPv4 traffic can now be sent over network %llx\n",
msg->network->nwid); msg->network->nwid);
networkReady = true; myNode.joinedAtLeastOneNetwork = true;
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) { if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) {
printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n", printf("ZTS_EVENT_NETWORK_READY_IP6 --- Network config received. IPv6 traffic can now be sent over network %llx\n",
msg->network->nwid); msg->network->nwid);
networkReady = true; myNode.joinedAtLeastOneNetwork = true;
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) { if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid); printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
@@ -61,38 +71,52 @@ void myZeroTierEventCallback(void *msgPtr)
char ipstr[ZTS_INET_ADDRSTRLEN]; char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr); struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP4 --- This node's virtual address on network %llx is %s\n", printf("ZTS_EVENT_ADDR_NEW_IP4 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) { if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN]; char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr); struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_NEW_IP6 --- This node's virtual address on network %llx is %s\n", printf("ZTS_EVENT_ADDR_NEW_IP6 --- This node's virtual address on network %llx is %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP4) { if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP4) {
char ipstr[ZTS_INET_ADDRSTRLEN]; char ipstr[ZTS_INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr); struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_REMOVED_IP4 --- The virtual address %s for this node on network %llx has been removed.\n", printf("ZTS_EVENT_ADDR_REMOVED_IP4 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid); ipstr, msg->addr->nwid);
} }
if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP6) { if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN]; char ipstr[ZTS_INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr); struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN); zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
printf("ZTS_EVENT_ADDR_REMOVED_IP6 --- The virtual address %s for this node on network %llx has been removed.\n", printf("ZTS_EVENT_ADDR_REMOVED_IP6 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg->addr->nwid); ipstr, msg->addr->nwid);
} }
// Peer events // Peer events
if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) { if (msg->peer) {
printf("ZTS_EVENT_PEER_DIRECT --- node=%llx\n", msg->peer->address); if (msg->peer->role == ZTS_PEER_ROLE_PLANET) {
// A direct path is known for nodeId /* Safe to ignore, these are our roots. They orchestrate the P2P connection.
} You might also see other unknown peers, these are our network controllers. */
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) { return;
printf("ZTS_EVENT_PEER_RELAY --- node=%llx\n", msg->peer->address); }
// No direct path is known for nodeId if (msg->eventCode == ZTS_EVENT_PEER_DIRECT) {
printf("ZTS_EVENT_PEER_DIRECT --- A direct path is known for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_RELAY) {
printf("ZTS_EVENT_PEER_RELAY --- No direct path to node=%llx\n", msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DISCOVERED) {
printf("ZTS_EVENT_PEER_PATH_DISCOVERED --- A new direct path was discovered for node=%llx\n",
msg->peer->address);
}
if (msg->eventCode == ZTS_EVENT_PEER_PATH_DEAD) {
printf("ZTS_EVENT_PEER_PATH_DEAD --- A direct path has died for node=%llx\n",
msg->peer->address);
}
} }
} }
@@ -104,7 +128,7 @@ void myZeroTierEventCallback(void *msgPtr)
* the location given in the first argument to zts_start(path, ...). If you accidentally * the location given in the first argument to zts_start(path, ...). If you accidentally
* duplicate the identity files and use them simultaneously in a different node instance * duplicate the identity files and use them simultaneously in a different node instance
* you will experience undefined behavior and it is likely nothing will work. * you will experience undefined behavior and it is likely nothing will work.
* *
* - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join * - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join
* your network, otherwise nothing will happen. This can be done manually or via * your network, otherwise nothing will happen. This can be done manually or via
* our web API: https://my.zerotier.com/help/api * our web API: https://my.zerotier.com/help/api
@@ -143,12 +167,12 @@ void myZeroTierEventCallback(void *msgPtr)
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors * Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
* returned by these functions can be any of the following: * returned by these functions can be any of the following:
* *
* ZTS_ERR_OK 0 // No error * ZTS_ERR_OK // No error
* ZTS_ERR_SOCKET -1 // Socket error, see zts_errno * ZTS_ERR_SOCKET // Socket error, see zts_errno
* ZTS_ERR_SERVICE -2 // You probably did something at the wrong time * ZTS_ERR_SERVICE // You probably did something at the wrong time
* ZTS_ERR_ARG -3 // Invalid argument * ZTS_ERR_ARG // Invalid argument
* ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) * ZTS_ERR_NO_RESULT // No result (not necessarily an error)
* ZTS_ERR_GENERAL -5 // Consider filing a bug report * ZTS_ERR_GENERAL // Consider filing a bug report
* *
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc). * Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
* Errors returned by these functions can be the same as the above. With * Errors returned by these functions can be the same as the above. With
@@ -166,7 +190,7 @@ void myZeroTierEventCallback(void *msgPtr)
* are a few guidelines: * are a few guidelines:
* *
* If you are calling a zts_* function, use the appropriate ZTS_* constants: * If you are calling a zts_* function, use the appropriate ZTS_* constants:
* *
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT) * zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT) * zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
* *
@@ -178,7 +202,7 @@ void myZeroTierEventCallback(void *msgPtr)
* *
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 5) { if (argc != 5) {
printf("\nlibzt example server\n"); printf("\nlibzt example server\n");
@@ -188,7 +212,7 @@ int main(int argc, char **argv)
uint64_t nwid = strtoull(argv[2],NULL,16); // Network ID to join uint64_t nwid = strtoull(argv[2],NULL,16); // Network ID to join
int serverBindPort = atoi(argv[3]); // Port the application should bind to int serverBindPort = atoi(argv[3]); // Port the application should bind to
int ztServicePort = atoi(argv[4]); // Port ZT uses to send encrypted UDP packets to peers (try something like 9994) int ztServicePort = atoi(argv[4]); // Port ZT uses to send encrypted UDP packets to peers (try something like 9994)
struct zts_sockaddr_in in4, acc_in4; struct zts_sockaddr_in in4, acc_in4;
in4.sin_port = zts_htons(serverBindPort); in4.sin_port = zts_htons(serverBindPort);
#if defined(_WIN32) #if defined(_WIN32)
@@ -208,7 +232,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
printf("Waiting for node to come online...\n"); printf("Waiting for node to come online...\n");
while (!nodeReady) { zts_delay_ms(50); } while (!myNode.online) { zts_delay_ms(50); }
printf("This node's identity is stored in %s\n", argv[1]); printf("This node's identity is stored in %s\n", argv[1]);
if((err = zts_join(nwid)) != ZTS_ERR_OK) { if((err = zts_join(nwid)) != ZTS_ERR_OK) {
@@ -217,7 +241,7 @@ int main(int argc, char **argv)
} }
printf("Joining network %llx\n", nwid); printf("Joining network %llx\n", nwid);
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n"); printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
while (!networkReady) { zts_delay_ms(50); } while (!myNode.joinedAtLeastOneNetwork) { zts_delay_ms(50); }
// Socket-like API example // Socket-like API example
@@ -237,7 +261,7 @@ int main(int argc, char **argv)
printf("Error placing socket in LISTENING state (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno); printf("Error placing socket in LISTENING state (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
exit(1); exit(1);
} }
int bytes=0; int bytes=0;
char recvBuf[128]; char recvBuf[128];
memset(recvBuf, 0, sizeof(recvBuf)); memset(recvBuf, 0, sizeof(recvBuf));

View File

@@ -60,12 +60,12 @@
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors * Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
* returned by these functions can be any of the following: * returned by these functions can be any of the following:
* *
* ZTS_ERR_OK 0 // No error * ZTS_ERR_OK // No error
* ZTS_ERR_SOCKET -1 // Socket error, see zts_errno * ZTS_ERR_SOCKET // Socket error, see zts_errno
* ZTS_ERR_SERVICE -2 // You probably did something at the wrong time * ZTS_ERR_SERVICE // You probably did something at the wrong time
* ZTS_ERR_ARG -3 // Invalid argument * ZTS_ERR_ARG // Invalid argument
* ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) * ZTS_ERR_NO_RESULT // No result (not necessarily an error)
* ZTS_ERR_GENERAL -5 // Consider filing a bug report * ZTS_ERR_GENERAL // Consider filing a bug report
* *
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc). * Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
* Errors returned by these functions can be the same as the above. With * Errors returned by these functions can be the same as the above. With
@@ -83,7 +83,7 @@
* are a few guidelines: * are a few guidelines:
* *
* If you are calling a zts_* function, use the appropriate ZTS_* constants: * If you are calling a zts_* function, use the appropriate ZTS_* constants:
* *
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT) * zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT) * zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
* *
@@ -119,7 +119,7 @@ void myZeroTierEventCallback(struct zts_callback_msg *msg)
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) { if (msg->eventCode == ZTS_EVENT_NETWORK_REQ_CONFIG) {
NSLog(@"ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid); NSLog(@"ZTS_EVENT_NETWORK_REQ_CONFIG --- Requesting config for network %llx, please wait a few seconds...\n", msg->network->nwid);
} }
if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) { if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) {
NSLog(@"ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n", NSLog(@"ZTS_EVENT_NETWORK_ACCESS_DENIED --- Access to virtual network %llx has been denied. Did you authorize the node yet?\n",
msg->network->nwid); msg->network->nwid);
@@ -134,17 +134,17 @@ void myZeroTierEventCallback(struct zts_callback_msg *msg)
} }
// Network stack events // Network stack events
if (msg->eventCode == ZTS_EVENT_NETIF_UP) { if (msg->eventCode == ZTS_EVENT_NETIF_UP) {
NSLog(@"ZTS_EVENT_NETIF_UP --- network=%llx, mac=%llx, mtu=%d\n", NSLog(@"ZTS_EVENT_NETIF_UP --- network=%llx, mac=%llx, mtu=%d\n",
msg->netif->nwid, msg->netif->nwid,
msg->netif->mac, msg->netif->mac,
msg->netif->mtu); msg->netif->mtu);
networkReady = true; networkReady = true;
} }
if (msg->eventCode == ZTS_EVENT_NETIF_DOWN) { if (msg->eventCode == ZTS_EVENT_NETIF_DOWN) {
NSLog(@"ZTS_EVENT_NETIF_DOWN --- network=%llx, mac=%llx\n", NSLog(@"ZTS_EVENT_NETIF_DOWN --- network=%llx, mac=%llx\n",
msg->netif->nwid, msg->netif->nwid,
msg->netif->mac); msg->netif->mac);
networkReady = true; networkReady = true;
} }
// Address events // Address events
@@ -152,7 +152,7 @@ void myZeroTierEventCallback(struct zts_callback_msg *msg)
char ipstr[INET6_ADDRSTRLEN]; char ipstr[INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr); struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg->addr->addr);
inet_ntop(AF_INET6, &(in6->sin6_addr), ipstr, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &(in6->sin6_addr), ipstr, INET6_ADDRSTRLEN);
NSLog(@"ZTS_EVENT_ADDR_NEW_IP6 --- Join %llx and ping me at %s\n", NSLog(@"ZTS_EVENT_ADDR_NEW_IP6 --- Join %llx and ping me at %s\n",
msg->addr->nwid, ipstr); msg->addr->nwid, ipstr);
} }
// Peer events // Peer events
@@ -192,7 +192,7 @@ be taken to avoid exposing vulnerable services or sharing unwanted files or othe
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 5) { if (argc != 5) {
NSLog(@"\nlibzt example\n"); NSLog(@"\nlibzt example\n");

2
examples/swift/Makefile Normal file
View File

@@ -0,0 +1,2 @@
all:
swiftc -g -lc++ -import-objc-header ../../include/ZeroTierSockets.h ../../lib/debug/macos-x86_64/zt.framework/zt main.swift -o main

View File

@@ -1,10 +1,5 @@
/** /**
* libzt Swift example * I'll order you a pizza if you can rewrite this in modern idomatic Swift
*
* swiftc -lc++ -import-objc-header ../../include/ZeroTierSockets.h -L. -lzt main.swift -o main;
* ./main
*
* TODO: This example is incomplete
*/ */
import Swift import Swift
@@ -56,12 +51,12 @@ import Foundation
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors * Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
* returned by these functions can be any of the following: * returned by these functions can be any of the following:
* *
* ZTS_ERR_OK 0 // No error * ZTS_ERR_OK // No error
* ZTS_ERR_SOCKET -1 // Socket error, see zts_errno * ZTS_ERR_SOCKET // Socket error, see zts_errno
* ZTS_ERR_SERVICE -2 // You probably did something at the wrong time * ZTS_ERR_SERVICE // You probably did something at the wrong time
* ZTS_ERR_ARG -3 // Invalid argument * ZTS_ERR_ARG // Invalid argument
* ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) * ZTS_ERR_NO_RESULT // No result (not necessarily an error)
* ZTS_ERR_GENERAL -5 // Consider filing a bug report * ZTS_ERR_GENERAL // Consider filing a bug report
* *
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc). * Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
* Errors returned by these functions can be the same as the above. With * Errors returned by these functions can be the same as the above. With
@@ -91,6 +86,119 @@ import Foundation
* *
*/ */
let printNodeDetails : @convention(c) (UnsafeMutableRawPointer?) -> Void =
{
(msgPtr) -> Void in
let msg = msgPtr?.bindMemory(to: zts_callback_msg.self, capacity: 1)
let d = msg?.pointee.node;
print(String(format: "\t- id : %llx", d!.pointee.address));
print(String(format: "\t- version : %d.%d.%d", d!.pointee.versionMajor, d!.pointee.versionMinor, d!.pointee.versionRev));
print(String(format: "\t- primaryPort : %d", d!.pointee.primaryPort));
print(String(format: "\t- secondaryPort : %d", d!.pointee.secondaryPort));
}
/*
func convertTupleToArray<Tuple, Value>(from tuple: Tuple) -> [Value] {
let tupleMirror = Mirror(reflecting: tuple)
func convert(child: Mirror.Child) -> Value? {
let valueMirror = Mirror(reflecting: child.value)
return child.value as? Value
}
return tupleMirror.children.flatMap(convert)
}
*/
let printNetworkDetails : @convention(c) (UnsafeMutableRawPointer?) -> Void =
{
(msgPtr) -> Void in
let msg = msgPtr?.bindMemory(to: zts_callback_msg.self, capacity: 1)
let d = msg?.pointee.network;
let name = ""; // String(d!.pointee.name);
print(String(format: "\t- nwid : %llx", d!.pointee.nwid));
print(String(format: "\t- mac : %lx", d!.pointee.mac));
print(String(format: "\t- name : %s", name));
print(String(format: "\t- type : %d", Int(d!.pointee.type.rawValue)));
/* MTU for the virtual network can be set via our web API */
print(String(format: "\t- mtu : %d", d!.pointee.mtu));
print(String(format: "\t- dhcp : %d", d!.pointee.dhcp));
print(String(format: "\t- bridge : %d", d!.pointee.bridge));
print(String(format: "\t- broadcastEnabled : %d", d!.pointee.broadcastEnabled));
print(String(format: "\t- portError : %d", d!.pointee.portError));
print(String(format: "\t- netconfRevision : %d", d!.pointee.netconfRevision));
print(String(format: "\t- routeCount : %d", d!.pointee.routeCount));
print(String(format: "\t- multicastSubscriptionCount : %d", d!.pointee.multicastSubscriptionCount));
/*
var addresses: [zts_sockaddr_storage] = convertTupleToArray(from: d!.pointee.assignedAddresses)
print("\t- addresses:\n");
for i in 0...d!.pointee.assignedAddressCount {
if (addresses[Int(i)].ss_family == ZTS_AF_INET) {
// Allocate a byte array that can hold the largest possible IPv4 human-readable string
var ipCharByteArray = Array<Int8>(repeating: 0, count: Int(ZTS_INET_ADDRSTRLEN))
// Cast unsafe pointer from zts_sockaddr_storage to zts_sockaddr_in
var addr:zts_sockaddr_in = withUnsafePointer(to: &(addresses[Int(i)])) {
$0.withMemoryRebound(to: zts_sockaddr_in.self, capacity: 1) {
$0.pointee
}
}
// Pass unsafe pointer (addr) to a ntop to convert into human-readable byte array
zts_inet_ntop(ZTS_AF_INET, &(addr.sin_addr), &ipCharByteArray, UInt32(ZTS_INET_ADDRSTRLEN))
//print(ipCharByteArray) // [49, 55, 50, 46, 50, 55, 46, 49, 49, 54, 46, 49, 54, 55, 0, 0]
// Somehow convery Int8 byte array to Swift String ???
//let ipString = String(bytes: ipStr, encoding: .utf8)
//print(ipString)
// Pass unsafe pointer (addr) to a ntop to convert into human-readable byte array
// convert to UInt8 byte array
let uintArray = ipCharByteArray.map { UInt8(bitPattern: $0) }
if let string = String(bytes: uintArray, encoding: .utf8) {
print("\t\t-", string)
}
}
if (addresses[Int(i)].ss_family == ZTS_AF_INET6) {
// ...
}
}
*/
/*
print("\t- routes:\n");
for i in 0...d!.pointee.routeCount {
// ...
}
*/
}
let printPeerDetails : @convention(c) (UnsafeMutableRawPointer?) -> Void =
{
(msgPtr) -> Void in
let msg = msgPtr?.bindMemory(to: zts_callback_msg.self, capacity: 1)
let d = msg?.pointee.peer;
print(String(format: "\t- peer : %llx", d!.pointee.address));
print(String(format: "\t- role : %d", Int(d!.pointee.role.rawValue)));
print(String(format: "\t- latency : %llx", d!.pointee.latency));
print(String(format: "\t- pathCount : %llx", d!.pointee.pathCount));
print(String(format: "\t- version : %d.%d.%d", d!.pointee.versionMajor, d!.pointee.versionMinor, d!.pointee.versionRev));
print(String(format: "\t- paths:\n"));
/*
for i in 0...d!.pointee.pathCount {
// ...
}
*/
}
let printNetifDetails : @convention(c) (UnsafeMutableRawPointer?) -> Void =
{
(msgPtr) -> Void in
let msg = msgPtr?.bindMemory(to: zts_callback_msg.self, capacity: 1)
let d = msg?.pointee.netif;
print(String(format: "\t- nwid : %llx", d!.pointee.nwid));
print(String(format: "\t- mac : %llx", d!.pointee.mac));
print(String(format: "\t- mtu : %d", d!.pointee.mtu));
}
var nodeReady:Bool = false var nodeReady:Bool = false
var networkReady:Bool = false var networkReady:Bool = false
@@ -99,16 +207,18 @@ let myZeroTierEventCallback : @convention(c) (UnsafeMutableRawPointer?) -> Void
(msgPtr) -> Void in (msgPtr) -> Void in
let msg = msgPtr?.bindMemory(to: zts_callback_msg.self, capacity: 1) let msg = msgPtr?.bindMemory(to: zts_callback_msg.self, capacity: 1)
var eventCode = msg!.pointee.eventCode let eventCode = msg!.pointee.eventCode
let node = msg?.pointee.node;
let network = msg?.pointee.network; let network = msg?.pointee.network;
let peer = msg?.pointee.peer;
switch Int32(eventCode)
{
case ZTS_EVENT_NODE_UP:
print("ZTS_EVENT_NODE_UP (you can ignore this)\n")
switch Int32(eventCode)
{
case ZTS_EVENT_NODE_ONLINE: case ZTS_EVENT_NODE_ONLINE:
let nodeId:UInt64 = node!.pointee.address print("ZTS_EVENT_NODE_ONLINE\n")
print(String(format: "ZTS_EVENT_NODE_ONLINE (%llx)", nodeId)) printNodeDetails(msg)
nodeReady = true; nodeReady = true;
case ZTS_EVENT_NODE_OFFLINE: case ZTS_EVENT_NODE_OFFLINE:
@@ -144,71 +254,68 @@ let myZeroTierEventCallback : @convention(c) (UnsafeMutableRawPointer?) -> Void
let networkId:UInt64 = network!.pointee.nwid let networkId:UInt64 = network!.pointee.nwid
print(String(format: "ZTS_EVENT_NETWORK_DOWN (%llx)", networkId)) print(String(format: "ZTS_EVENT_NETWORK_DOWN (%llx)", networkId))
/* case ZTS_EVENT_NETWORK_UPDATE:
// Network stack events print("ZTS_EVENT_NETWORK_UPDATE\n")
case ZTS_EVENT_NETIF_UP: printNetworkDetails(msg)
print("ZTS_EVENT_NETIF_UP --- network=%llx, mac=%llx, mtu=%d\n",
msg.netif->nwid,
msg.netif->mac,
msg.netif->mtu)
//networkReady = true;
case ZTS_EVENT_NETIF_DOWN:
print("ZTS_EVENT_NETIF_DOWN --- network=%llx, mac=%llx\n",
msg.netif->nwid,
msg.netif->mac)
//networkReady = true;
// Address events
case ZTS_EVENT_ADDR_ADDED_IP4: case ZTS_EVENT_ADDR_ADDED_IP4:
print("ZTS_EVENT_ADDR_ADDED_IP4") print("ZTS_EVENT_ADDR_ADDED_IP4\n")
/*
char ipstr[INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg.addr->addr);
inet_ntop(AF_INET, &(in4->sin_addr), ipstr, INET_ADDRSTRLEN);
print("ZTS_EVENT_ADDR_NEW_IP4 --- This node's virtual address on network %llx is %s\n",
msg.addr->nwid, ipstr)
*/
case ZTS_EVENT_ADDR_ADDED_IP6: case ZTS_EVENT_ADDR_ADDED_IP6:
print("ZTS_EVENT_ADDR_ADDED_IP6") print("ZTS_EVENT_ADDR_ADDED_IP6\n")
/*
char ipstr[INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg.addr->addr);
inet_ntop(AF_INET6, &(in6->sin6_addr), ipstr, INET6_ADDRSTRLEN);
print("ZTS_EVENT_ADDR_NEW_IP6 --- This node's virtual address on network %llx is %s\n",
msg.addr->nwid, ipstr)
*/
case ZTS_EVENT_ADDR_REMOVED_IP4: case ZTS_EVENT_ADDR_REMOVED_IP4:
print("ZTS_EVENT_ADDR_REMOVED_IP4") print("ZTS_EVENT_ADDR_REMOVED_IP4\n")
/*
char ipstr[INET_ADDRSTRLEN];
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)&(msg.addr->addr);
inet_ntop(AF_INET, &(in4->sin_addr), ipstr, INET_ADDRSTRLEN);
print("ZTS_EVENT_ADDR_REMOVED_IP4 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg.addr->nwid)
*/
case ZTS_EVENT_ADDR_REMOVED_IP6: case ZTS_EVENT_ADDR_REMOVED_IP6:
print("ZTS_EVENT_ADDR_REMOVED_IP6") print("ZTS_EVENT_ADDR_REMOVED_IP6\n")
/*
char ipstr[INET6_ADDRSTRLEN];
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)&(msg.addr->addr);
inet_ntop(AF_INET6, &(in6->sin6_addr), ipstr, INET6_ADDRSTRLEN);
print("ZTS_EVENT_ADDR_REMOVED_IP6 --- The virtual address %s for this node on network %llx has been removed.\n",
ipstr, msg.addr->nwid)
*/
// Peer events
case ZTS_EVENT_PEER_DIRECT: case ZTS_EVENT_PEER_DIRECT:
print("ZTS_EVENT_PEER_DIRECT --- node=%llx\n", msg.peer->address) let peerId:UInt64 = peer!.pointee.address
print(String(format: "ZTS_EVENT_PEER_DIRECT (%llx)", peerId))
printPeerDetails(msg)
case ZTS_EVENT_PEER_RELAY: case ZTS_EVENT_PEER_RELAY:
print("ZTS_EVENT_PEER_RELAY --- node=%llx\n", msg.peer->address) let peerId:UInt64 = peer!.pointee.address
print(String(format: "ZTS_EVENT_PEER_RELAY (%llx)", peerId))
printPeerDetails(msg)
case ZTS_EVENT_PEER_PATH_DISCOVERED:
let peerId:UInt64 = peer!.pointee.address
print(String(format: "ZTS_EVENT_PEER_PATH_DISCOVERED (%llx)", peerId))
printPeerDetails(msg)
case ZTS_EVENT_PEER_PATH_DEAD:
let peerId:UInt64 = peer!.pointee.address
print(String(format: "ZTS_EVENT_PEER_PATH_DEAD (%llx)", peerId))
printPeerDetails(msg)
*/ case ZTS_EVENT_NETIF_UP:
print("ZTS_EVENT_NETIF_UP\n")
case ZTS_EVENT_NETIF_DOWN:
print("ZTS_EVENT_NETIF_DOWN\n")
case ZTS_EVENT_NETIF_REMOVED:
print("ZTS_EVENT_NETIF_REMOVED\n")
case ZTS_EVENT_NETIF_LINK_UP:
print("ZTS_EVENT_NETIF_LINK_UP\n")
case ZTS_EVENT_NETIF_LINK_DOWN:
print("ZTS_EVENT_NETIF_LINK_DOWN\n")
case ZTS_EVENT_STACK_UP:
print("ZTS_EVENT_STACK_UP\n")
case ZTS_EVENT_STACK_DOWN:
print("ZTS_EVENT_STACK_DOWN\n")
default: default:
print("UNKNOWN_EVENT") print("UNKNOWN_EVENT: ", eventCode)
} }
} }
@@ -221,6 +328,26 @@ func main()
} }
print("Joining network") print("Joining network")
let nwId : UInt64 = 0x0123456789abcdef; // Specify your network ID here
zts_join(nwId);
// create address structure
let addr_str = "0.0.0.0"
let port = 8080
var in4 = zts_sockaddr_in(sin_len: UInt8(MemoryLayout<zts_sockaddr_in>.size),
sin_family: UInt8(ZTS_AF_INET),
sin_port: UInt16(port).bigEndian,
sin_addr: zts_in_addr(s_addr: 0),
sin_zero: (0,0,0,0,0,0,0,0))
zts_inet_pton(ZTS_AF_INET, addr_str, &(in4.sin_addr));
print("fd=", zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0));
// ...
while(true) {
sleep(1);
}
} }
main() main()