1st working version of node example

This commit is contained in:
heri16
2020-08-04 16:47:28 +08:00
parent 087d8a820c
commit 590ee0c655
5 changed files with 254 additions and 148 deletions

View File

@@ -11,6 +11,122 @@
#include "ZeroTierSockets.h"
#include "nbind/api.h"
struct Node
{
Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
bool online;
bool joinedAtLeastOneNetwork;
uint64_t id;
// etc
bool getOnline() { return online; }
bool getJoinedAtLeastOneNetwork() { return joinedAtLeastOneNetwork; }
uint64_t getId() { return id; }
} myNode;
/* 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;
// Node events
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address);
myNode.id = msg->node->address;
myNode.online = true;
}
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");
myNode.online = 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);
myNode.joinedAtLeastOneNetwork = 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);
myNode.joinedAtLeastOneNetwork = true;
}
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
}
// 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->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) {
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);
}
}
}
/**
*
* IDENTITIES and AUTHORIZATION:
@@ -98,17 +214,17 @@ public:
/**
* @brief Starts the ZeroTier service and notifies user application of events via callback
*
* @param path path directory where configuration files are stored
* @param callback User-specified callback for ZTS_EVENT_* events
* @param configPath path directory where configuration files are stored
* @param servicePort proit which ZeroTier service will listen on
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure
*/
static int start(const char *configFilePath, uint16_t servicePort)
static int start(const char *configPath, uint16_t servicePort)
{
// Bring up ZeroTier service
int err = ZTS_ERR_OK;
if((err = zts_start(configFilePath, &myZeroTierEventCallback, servicePort)) != ZTS_ERR_OK) {
if((err = zts_start(configPath, &myZeroTierEventCallback, servicePort)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d.\n", err);
return err;
}
@@ -158,6 +274,12 @@ public:
return zts_free();
}
/**
* @brief Join a network
*
* @param networkId A 16-digit hexadecimal virtual network ID
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
*/
static int join(const char *networkId)
{
// Join ZeroTier network
@@ -207,20 +329,25 @@ public:
return connect(ZTS_AF_INET6, ZTS_SOCK_RAW, protocol, remoteAddr, remotePort);
}
/**
* @brief Connect a socket to a remote host (sets zts_errno)
*
* @param socket_family Address family (ZTS_AF_INET, ZTS_AF_INET6)
* @param socket_type Type of socket (ZTS_SOCK_STREAM, ZTS_SOCK_DGRAM, ZTS_SOCK_RAW)
* @param protocol Protocols supported on this socket
* @param remoteAddr Remote Address to connect to
* @param remotePort Remote Port to connect to
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
*/
static int connect(const int socket_family, const int socket_type, const int protocol, const char *remoteAddr, const int remotePort)
{
const struct zts_sockaddr *addr;
zts_socklen_t addrlen;
if (socket_family == ZTS_AF_INET) {
struct zts_sockaddr_in in4 = sockaddr_in(remoteAddr, remotePort);
addr = (const struct zts_sockaddr *)&in4;
addrlen = sizeof(in4);
} else {
if (socket_family == ZTS_AF_INET6) {
printf("IPv6 NOT IMPLEMENTED.\n");
return -1;
}
struct zts_sockaddr_in in4 = sockaddr_in(remoteAddr, remotePort);
int fd;
if ((fd = zts_socket(socket_family, socket_type, protocol)) < 0) {
printf("Error creating ZeroTier socket (fd=%d, zts_errno=%d).\n", fd, zts_errno);
@@ -231,11 +358,11 @@ public:
int err = ZTS_ERR_OK;
for (;;) {
printf("Connecting to remote host...\n");
if ((err = zts_connect(fd, addr, addrlen)) < 0) {
if ((err = zts_connect(fd, (const struct zts_sockaddr *)&in4, sizeof(in4))) < 0) {
printf("Error connecting to remote host (fd=%d, ret=%d, zts_errno=%d). Trying again.\n",
fd, err, zts_errno);
zts_close(fd);
printf("Creating socket...\n");
// printf("Creating socket...\n");
if ((fd = zts_socket(socket_family, socket_type, protocol)) < 0) {
printf("Error creating ZeroTier socket (fd=%d, zts_errno=%d).\n", fd, zts_errno);
return -1;
@@ -248,9 +375,36 @@ public:
}
}
// Set non-blocking mode
fcntl(fd, ZTS_F_SETFL, ZTS_O_NONBLOCK);
return fd;
}
static int fcntlSetBlocking(int fd, bool isBlocking)
{
int flags = fcntl(fd, ZTS_F_GETFL, 0);
if (isBlocking) {
flags &= ~ZTS_O_NONBLOCK;
} else {
flags &= ZTS_O_NONBLOCK;
}
return fcntl(fd, ZTS_F_SETFL, flags);
}
/**
* @brief Issue file control commands on a socket
*
* @param fd File descriptor
* @param cmd
* @param flags
* @return
*/
static int fcntl(int fd, int cmd, int flags)
{
return zts_fcntl(fd, cmd, flags);
}
static ssize_t read(int fd, nbind::Buffer buf)
{
return zts_read(fd, buf.data(), buf.length());
@@ -289,136 +443,36 @@ public:
return in4;
}
private:
static struct Node
{
Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
bool online;
bool joinedAtLeastOneNetwork;
uint64_t id;
// etc
} myNode;
/* 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. */
static void myZeroTierEventCallback(void *msgPtr)
{
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr;
// Node events
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->address);
myNode.id = msg->node->address;
myNode.online = true;
}
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");
myNode.online = 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);
myNode.joinedAtLeastOneNetwork = 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);
myNode.joinedAtLeastOneNetwork = true;
}
if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) {
printf("ZTS_EVENT_NETWORK_DOWN --- %llx\n", msg->network->nwid);
}
// 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->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) {
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);
}
}
}
static Node getMyNode() { return myNode; }
};
#include "nbind/nbind.h"
NBIND_CLASS(ZeroTier) {
method(start);
method(join);
method(connectStream);
method(connectDgram);
method(connectRaw);
method(connectStream6);
method(connectDgram6);
method(connectRaw6);
method(connect);
method(read);
method(write);
method(recv);
method(send);
method(restart);
method(stop);
method(free);
NBIND_CLASS(Node) {
getter(getOnline);
getter(getJoinedAtLeastOneNetwork);
getter(getId);
}
NBIND_CLASS(ZeroTier) {
method(start);
method(join);
method(connectStream);
method(connectDgram);
method(connectRaw);
method(connectStream6);
method(connectDgram6);
method(connectRaw6);
method(connect);
method(read);
method(write);
method(recv);
method(send);
method(fcntlSetBlocking);
method(fcntl);
method(close);
method(restart);
method(stop);
method(free);
method(getMyNode);
}