Format according to new ZeroTier standard

This commit is contained in:
Joseph Henry
2021-04-26 22:07:55 -07:00
parent 07b2a33447
commit a247552df1
23 changed files with 4991 additions and 4991 deletions

View File

@@ -35,62 +35,62 @@ be taken to avoid exposing vulnerable services or sharing unwanted files or othe
*/
int main(int argc, char** argv)
{
if (argc != 3) {
printf("\nUsage:\n");
printf("adhoc <adhocStartPort> <adhocEndPort>\n");
exit(0);
}
int err = ZTS_ERR_OK;
if (argc != 3) {
printf("\nUsage:\n");
printf("adhoc <adhocStartPort> <adhocEndPort>\n");
exit(0);
}
int err = ZTS_ERR_OK;
uint16_t adhocStartPort = atoi(argv[1]); // Start of port range your application will use
uint16_t adhocEndPort = atoi(argv[2]); // End of port range your application will use
long long int net_id = zts_net_compute_adhoc_id(adhocStartPort, adhocEndPort); // At least 64 bits
uint16_t adhocStartPort = atoi(argv[1]); // Start of port range your application will use
uint16_t adhocEndPort = atoi(argv[2]); // End of port range your application will use
long long int net_id = zts_net_compute_adhoc_id(adhocStartPort, adhocEndPort); // At least 64 bits
// Start node and get identity
// Start node and get identity
printf("Starting node...\n");
zts_node_start();
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
uint64_t node_id = zts_node_get_id();
printf("My public identity (node ID) is %llx\n", node_id);
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
uint16_t len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
printf("Starting node...\n");
zts_node_start();
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
uint64_t node_id = zts_node_get_id();
printf("My public identity (node ID) is %llx\n", node_id);
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
uint16_t len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
// Join the adhoc network
// Join the adhoc network
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
// Get address
// Get address
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
if ((err = zts_addr_compute_rfc4193_str(net_id, node_id, ipstr, ZTS_IP_MAX_STR_LEN)) != ZTS_ERR_OK) {
printf("Unable to compute address (error = %d). Exiting.\n", err);
exit(1);
}
printf("Join %llx from another machine and ping6 me at %s\n", net_id, ipstr);
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
if ((err = zts_addr_compute_rfc4193_str(net_id, node_id, ipstr, ZTS_IP_MAX_STR_LEN)) != ZTS_ERR_OK) {
printf("Unable to compute address (error = %d). Exiting.\n", err);
exit(1);
}
printf("Join %llx from another machine and ping6 me at %s\n", net_id, ipstr);
// Do network stuff!
// zts_socket, zts_connect, etc
// Do network stuff!
// zts_socket, zts_connect, etc
while (1) {
zts_util_delay(500); // Idle indefinitely
}
while (1) {
zts_util_delay(500); // Idle indefinitely
}
printf("Stopping node\n");
return zts_node_stop();
printf("Stopping node\n");
return zts_node_stop();
}

View File

@@ -12,97 +12,97 @@
void on_zts_event(void* msgPtr)
{
zts_event_msg_t* msg = (zts_event_msg_t*)msgPtr;
// Node events
if (msg->event_code == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->node_id);
}
if (msg->event_code == ZTS_EVENT_NODE_OFFLINE) {
printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, "
"firewall, etc. What ports are you blocking?\n");
}
// Virtual network events
if (msg->event_code == ZTS_EVENT_NETWORK_NOT_FOUND) {
printf("ZTS_EVENT_NETWORK_NOT_FOUND --- Are you sure %llx is a valid network?\n", msg->network->net_id);
}
if (msg->event_code == 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->net_id);
}
if (msg->event_code == 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->net_id);
}
// Address events
if (msg->event_code == ZTS_EVENT_ADDR_ADDED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN] = { 0 };
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 --- Join %llx and ping me at %s\n", msg->addr->net_id, ipstr);
}
zts_event_msg_t* msg = (zts_event_msg_t*)msgPtr;
// Node events
if (msg->event_code == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE --- This node's ID is %llx\n", msg->node->node_id);
}
if (msg->event_code == ZTS_EVENT_NODE_OFFLINE) {
printf("ZTS_EVENT_NODE_OFFLINE --- Check your physical Internet connection, router, "
"firewall, etc. What ports are you blocking?\n");
}
// Virtual network events
if (msg->event_code == ZTS_EVENT_NETWORK_NOT_FOUND) {
printf("ZTS_EVENT_NETWORK_NOT_FOUND --- Are you sure %llx is a valid network?\n", msg->network->net_id);
}
if (msg->event_code == 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->net_id);
}
if (msg->event_code == 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->net_id);
}
// Address events
if (msg->event_code == ZTS_EVENT_ADDR_ADDED_IP6) {
char ipstr[ZTS_INET6_ADDRSTRLEN] = { 0 };
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 --- Join %llx and ping me at %s\n", msg->addr->net_id, ipstr);
}
// To see more exhaustive examples look at test/selftest.c
// To see more exhaustive examples look at test/selftest.c
}
int main(int argc, char** argv)
{
if (argc != 2) {
printf("\nUsage:\n");
printf("pingable-node <net_id>\n");
exit(0);
}
long long int net_id = strtoull(argv[1], NULL, 16); // At least 64 bits
if (argc != 2) {
printf("\nUsage:\n");
printf("pingable-node <net_id>\n");
exit(0);
}
long long int net_id = strtoull(argv[1], NULL, 16); // At least 64 bits
zts_init_set_event_handler(&on_zts_event);
zts_init_set_event_handler(&on_zts_event);
printf("Starting node...\n");
zts_node_start();
printf("Starting node...\n");
zts_node_start();
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("My public identity (node ID) is %llx\n", zts_node_get_id());
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
uint16_t len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
printf("My public identity (node ID) is %llx\n", zts_node_get_id());
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
uint16_t len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Waiting for address assignment from network\n");
int err = 0;
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
printf("Waiting for address assignment from network\n");
int err = 0;
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Join %llx from another machine and ping me at %s\n", net_id, ipstr);
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Join %llx from another machine and ping me at %s\n", net_id, ipstr);
// Do network stuff!
// zts_socket, zts_connect, etc
// Do network stuff!
// zts_socket, zts_connect, etc
while (1) {
zts_util_delay(500); // Idle indefinitely
}
while (1) {
zts_util_delay(500); // Idle indefinitely
}
printf("Stopping node\n");
return zts_node_stop();
printf("Stopping node\n");
return zts_node_stop();
}

View File

@@ -12,94 +12,94 @@
int main(int argc, char** argv)
{
if (argc != 5) {
printf("\nlibzt example client\n");
printf("client <id_storage_path> <net_id> <remote_addr> <remote_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* remote_addr = argv[3];
int remote_port = atoi(argv[4]);
int err = ZTS_ERR_OK;
if (argc != 5) {
printf("\nlibzt example client\n");
printf("client <id_storage_path> <net_id> <remote_addr> <remote_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* remote_addr = argv[3];
int remote_port = atoi(argv[4]);
int err = ZTS_ERR_OK;
// Initialize node
// Initialize node
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
// Start node
// Start node
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Public identity (node ID) is %llx\n", (long long int)zts_node_get_id());
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Public identity (node ID) is %llx\n", (long long int)zts_node_get_id());
// Join network
// Join network
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
// Get assigned address (of the family type we care about)
// Get assigned address (of the family type we care about)
int family = zts_util_get_ip_family(remote_addr);
int family = zts_util_get_ip_family(remote_addr);
printf("Waiting for address assignment from network\n");
while (! (err = zts_addr_is_assigned(net_id, family))) {
zts_util_delay(50);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, family, ipstr, ZTS_IP_MAX_STR_LEN);
printf("IP address on network %llx is %s\n", net_id, ipstr);
printf("Waiting for address assignment from network\n");
while (! (err = zts_addr_is_assigned(net_id, family))) {
zts_util_delay(50);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, family, ipstr, ZTS_IP_MAX_STR_LEN);
printf("IP address on network %llx is %s\n", net_id, ipstr);
// BEGIN Socket Stuff
// BEGIN Socket Stuff
char* msgStr = (char*)"Welcome to the machine";
int bytes = 0, fd;
char recvBuf[128] = { 0 };
memset(recvBuf, 0, sizeof(recvBuf));
char* msgStr = (char*)"Welcome to the machine";
int bytes = 0, fd;
char recvBuf[128] = { 0 };
memset(recvBuf, 0, sizeof(recvBuf));
// Connect to remote host
// Connect to remote host
// Can also use traditional: zts_socket(), zts_connect(), etc
// Can also use traditional: zts_socket(), zts_connect(), etc
printf("Attempting to connect...\n");
while ((fd = zts_simple_tcp_client(remote_addr, remote_port)) < 0) {
printf("Re-attempting to connect...\n");
}
printf("Attempting to connect...\n");
while ((fd = zts_simple_tcp_client(remote_addr, remote_port)) < 0) {
printf("Re-attempting to connect...\n");
}
// Data I/O
// Data I/O
printf("Sending message string to server...\n");
if ((bytes = zts_write(fd, msgStr, strlen(msgStr))) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Sent %d bytes: %s\n", bytes, msgStr);
printf("Reading message string from server...\n");
if ((bytes = zts_read(fd, recvBuf, sizeof(recvBuf))) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Read %d bytes: %s\n", bytes, recvBuf);
printf("Sending message string to server...\n");
if ((bytes = zts_write(fd, msgStr, strlen(msgStr))) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Sent %d bytes: %s\n", bytes, msgStr);
printf("Reading message string from server...\n");
if ((bytes = zts_read(fd, recvBuf, sizeof(recvBuf))) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Read %d bytes: %s\n", bytes, recvBuf);
// Close
// Close
zts_close(fd);
return zts_node_stop();
zts_close(fd);
return zts_node_stop();
}

View File

@@ -12,108 +12,108 @@
void print_peer_details(const char* msg, zts_peer_info_t* d)
{
printf(" %s\n", msg);
printf("\t- peer : %llx\n", d->address);
printf("\t- role : %d\n", d->role);
printf("\t- latency : %d\n", d->latency);
printf("\t- version : %d.%d.%d\n", d->ver_major, d->ver_minor, d->ver_rev);
printf("\t- path_count : %d\n", d->path_count);
printf("\t- paths:\n");
printf(" %s\n", msg);
printf("\t- peer : %llx\n", d->address);
printf("\t- role : %d\n", d->role);
printf("\t- latency : %d\n", d->latency);
printf("\t- version : %d.%d.%d\n", d->ver_major, d->ver_minor, d->ver_rev);
printf("\t- path_count : %d\n", d->path_count);
printf("\t- paths:\n");
// Print all known paths for each peer
for (unsigned int j = 0; j < d->path_count; j++) {
char ipstr[ZTS_INET6_ADDRSTRLEN] = { 0 };
int port = 0;
struct zts_sockaddr* sa = (struct zts_sockaddr*)&(d->paths[j].address);
if (sa->sa_family == ZTS_AF_INET) {
struct zts_sockaddr_in* in4 = (struct zts_sockaddr_in*)sa;
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
port = ntohs(in4->sin_port);
}
if (sa->sa_family == ZTS_AF_INET6) {
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)sa;
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
}
printf("\t - %15s : %6d\n", ipstr, port);
}
printf("\n\n");
// Print all known paths for each peer
for (unsigned int j = 0; j < d->path_count; j++) {
char ipstr[ZTS_INET6_ADDRSTRLEN] = { 0 };
int port = 0;
struct zts_sockaddr* sa = (struct zts_sockaddr*)&(d->paths[j].address);
if (sa->sa_family == ZTS_AF_INET) {
struct zts_sockaddr_in* in4 = (struct zts_sockaddr_in*)sa;
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), ipstr, ZTS_INET_ADDRSTRLEN);
port = ntohs(in4->sin_port);
}
if (sa->sa_family == ZTS_AF_INET6) {
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)sa;
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), ipstr, ZTS_INET6_ADDRSTRLEN);
}
printf("\t - %15s : %6d\n", ipstr, port);
}
printf("\n\n");
}
void on_zts_event(void* msgPtr)
{
zts_event_msg_t* msg = (zts_event_msg_t*)msgPtr;
printf("event_code = %d\n", msg->event_code);
zts_event_msg_t* msg = (zts_event_msg_t*)msgPtr;
printf("event_code = %d\n", msg->event_code);
if (msg->peer) {
if (msg->peer->role != ZTS_PEER_ROLE_PLANET) {
return; // Don't print controllers and ordinary nodes.
}
}
if (msg->event_code == ZTS_EVENT_PEER_DIRECT) {
print_peer_details("ZTS_EVENT_PEER_DIRECT", msg->peer);
}
if (msg->event_code == ZTS_EVENT_PEER_RELAY) {
print_peer_details("ZTS_EVENT_PEER_RELAY", msg->peer);
}
if (msg->peer) {
if (msg->peer->role != ZTS_PEER_ROLE_PLANET) {
return; // Don't print controllers and ordinary nodes.
}
}
if (msg->event_code == ZTS_EVENT_PEER_DIRECT) {
print_peer_details("ZTS_EVENT_PEER_DIRECT", msg->peer);
}
if (msg->event_code == ZTS_EVENT_PEER_RELAY) {
print_peer_details("ZTS_EVENT_PEER_RELAY", msg->peer);
}
}
int main()
{
// World generation
// World generation
// Buffers that will be filled after generating the world
char world_data_out[4096] = { 0 }; // (binary) Your new world definition
unsigned int world_len = 0;
unsigned int prev_key_len = 0;
unsigned int curr_key_len = 0;
char prev_key[4096] = { 0 }; // (binary) (optional) For updating a world
char curr_key[4096] = { 0 }; // (binary) You should save this
// Buffers that will be filled after generating the world
char world_data_out[4096] = { 0 }; // (binary) Your new world definition
unsigned int world_len = 0;
unsigned int prev_key_len = 0;
unsigned int curr_key_len = 0;
char prev_key[4096] = { 0 }; // (binary) (optional) For updating a world
char curr_key[4096] = { 0 }; // (binary) You should save this
// Arbitrary World ID
uint64_t id = 149604618;
// Arbitrary World ID
uint64_t id = 149604618;
// Timestamp indicating when this world was generated
uint64_t ts = 1567191349589ULL;
// Timestamp indicating when this world was generated
uint64_t ts = 1567191349589ULL;
// struct containing public keys and stable IP endpoints for roots
zts_world_t world = { 0 };
// struct containing public keys and stable IP endpoints for roots
zts_world_t world = { 0 };
world.public_id_str[0] =
"992fcf1db7:0:"
"206ed59350b31916f749a1f85dffb3a8787dcbf83b8c6e9448d4e3ea0e3369301be716c3609344a9d1533850fb4460c5"
"0af43322bcfc8e13d3301a1f1003ceb6";
world.endpoint_ip_str[0][0] = "195.181.173.159/9993";
world.endpoint_ip_str[0][1] = "2a02:6ea0:c024::/9993";
world.public_id_str[0] =
"992fcf1db7:0:"
"206ed59350b31916f749a1f85dffb3a8787dcbf83b8c6e9448d4e3ea0e3369301be716c3609344a9d1533850fb4460c5"
"0af43322bcfc8e13d3301a1f1003ceb6";
world.endpoint_ip_str[0][0] = "195.181.173.159/9993";
world.endpoint_ip_str[0][1] = "2a02:6ea0:c024::/9993";
// Generate world
// Generate world
zts_util_world_new(&world_data_out, &world_len, &prev_key, &prev_key_len, &curr_key, &curr_key_len, id, ts, &world);
zts_util_world_new(&world_data_out, &world_len, &prev_key, &prev_key_len, &curr_key, &curr_key_len, id, ts, &world);
printf("world_data_out= ");
for (int i = 0; i < world_len; i++) {
if (i > 0) {
printf(",");
}
printf("0x%.2x", (unsigned char)world_data_out[i]);
}
printf("\n");
printf("world_len = %d\n", world_len);
printf("prev_key_len = %d\n", prev_key_len);
printf("curr_key_len = %d\n", curr_key_len);
printf("world_data_out= ");
for (int i = 0; i < world_len; i++) {
if (i > 0) {
printf(",");
}
printf("0x%.2x", (unsigned char)world_data_out[i]);
}
printf("\n");
printf("world_len = %d\n", world_len);
printf("prev_key_len = %d\n", prev_key_len);
printf("curr_key_len = %d\n", curr_key_len);
// Now, initialize node and use newly-generated world definition
// Now, initialize node and use newly-generated world definition
zts_init_set_world(&world_data_out, world_len);
zts_init_set_event_handler(&on_zts_event);
zts_init_from_storage(".");
zts_init_set_world(&world_data_out, world_len);
zts_init_set_event_handler(&on_zts_event);
zts_init_from_storage(".");
// Start node
// Start node
zts_node_start();
zts_node_start();
while (1) {
zts_util_delay(500);
}
while (1) {
zts_util_delay(500);
}
return zts_node_stop();
return zts_node_stop();
}

View File

@@ -12,85 +12,85 @@
int main(int argc, char** argv)
{
if (argc != 5) {
printf("\nlibzt example client\n");
printf("client <id_storage_path> <net_id> <remote_addr> <remote_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* remote_addr = argv[3];
int remote_port = atoi(argv[4]);
int err = ZTS_ERR_OK;
if (argc != 5) {
printf("\nlibzt example client\n");
printf("client <id_storage_path> <net_id> <remote_addr> <remote_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* remote_addr = argv[3];
int remote_port = atoi(argv[4]);
int err = ZTS_ERR_OK;
// Initialize node
// Initialize node
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
// Start node
// Start node
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Public identity (node ID) is %llx\n", (long long int)zts_node_get_id());
printf("Public identity (node ID) is %llx\n", (long long int)zts_node_get_id());
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
// Sockets
// Sockets
char* msgStr = (char*)"Welcome to the machine";
int bytes = 0, fd;
char recvBuf[128] = { 0 };
memset(recvBuf, 0, sizeof(recvBuf));
char* msgStr = (char*)"Welcome to the machine";
int bytes = 0, fd;
char recvBuf[128] = { 0 };
memset(recvBuf, 0, sizeof(recvBuf));
// Create socket
// Create socket
if ((fd = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0)) < 0) {
printf("Error (fd=%d, zts_errno=%d). Exiting.\n", fd, zts_errno);
exit(1);
}
if ((fd = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0)) < 0) {
printf("Error (fd=%d, zts_errno=%d). Exiting.\n", fd, zts_errno);
exit(1);
}
// Connect
// Connect
// Can also use:
// zts_connect(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen);
while (zts_simple_connect(fd, remote_addr, remote_port, 0) != ZTS_ERR_OK) {
printf("Attempting to connect...\n");
}
// Can also use:
// zts_connect(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen);
while (zts_simple_connect(fd, remote_addr, remote_port, 0) != ZTS_ERR_OK) {
printf("Attempting to connect...\n");
}
// Data I/O
// Data I/O
// Wait random intervals to send a message to the server
// The non-blocking aspect of this example is server-side
while (1) {
if ((bytes = zts_send(fd, msgStr, strlen(msgStr), 0)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("zts_send()=%d\n", bytes);
zts_util_delay((rand() % 100) * 50);
}
// Wait random intervals to send a message to the server
// The non-blocking aspect of this example is server-side
while (1) {
if ((bytes = zts_send(fd, msgStr, strlen(msgStr), 0)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("zts_send()=%d\n", bytes);
zts_util_delay((rand() % 100) * 50);
}
zts_close(fd);
return zts_node_stop();
zts_close(fd);
return zts_node_stop();
}

View File

@@ -12,158 +12,158 @@
int main(int argc, char** argv)
{
if (argc != 5) {
printf("\nlibzt example server\n");
printf("server <id_storage_path> <net_id> <local_addr> <local_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* local_addr = argv[3];
int local_port = atoi(argv[4]);
int fd, accfd;
int err = ZTS_ERR_OK;
if (argc != 5) {
printf("\nlibzt example server\n");
printf("server <id_storage_path> <net_id> <local_addr> <local_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* local_addr = argv[3];
int local_port = atoi(argv[4]);
int fd, accfd;
int err = ZTS_ERR_OK;
// Initialize node
// Initialize node
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
// Start node
// Start node
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Public identity (node ID) is %llx\n", zts_node_get_id());
printf("Public identity (node ID) is %llx\n", zts_node_get_id());
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Waiting for address assignment from network\n");
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
printf("Waiting for address assignment from network\n");
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Assigned IP address: %s\n", ipstr);
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Assigned IP address: %s\n", ipstr);
// Sockets
// Sockets
printf("Creating socket...\n");
if ((fd = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
exit(1);
}
printf("Binding...\n");
// Can also use:
// zts_bind(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
if ((err = zts_simple_bind(fd, local_addr, local_port) < 0)) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
exit(1);
}
printf("Listening...\n");
int backlog = 100;
if ((err = zts_listen(fd, backlog)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
exit(1);
}
printf("Creating socket...\n");
if ((fd = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
exit(1);
}
printf("Binding...\n");
// Can also use:
// zts_bind(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
if ((err = zts_simple_bind(fd, local_addr, local_port) < 0)) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
exit(1);
}
printf("Listening...\n");
int backlog = 100;
if ((err = zts_listen(fd, backlog)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
exit(1);
}
int bytes = 0;
char recvBuf[128] = { 0 };
int bytes = 0;
char recvBuf[128] = { 0 };
while (1) {
// Accept
// Can also use
// zts_accept(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
while (1) {
// Accept
// Can also use
// zts_accept(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
char ipstr[ZTS_INET6_ADDRSTRLEN] = { 0 };
int port = 0;
printf("Accepting on listening socket...\n");
if ((accfd = zts_simple_accept(fd, ipstr, ZTS_INET6_ADDRSTRLEN, &port)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
}
printf("Accepted connection from %s:%d\n", ipstr, port);
}
char ipstr[ZTS_INET6_ADDRSTRLEN] = { 0 };
int port = 0;
printf("Accepting on listening socket...\n");
if ((accfd = zts_simple_accept(fd, ipstr, ZTS_INET6_ADDRSTRLEN, &port)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, err, zts_errno);
}
printf("Accepted connection from %s:%d\n", ipstr, port);
}
// Data I/O
// Data I/O
// Technique 1: ZTS_O_NONBLOCK
if (0) {
zts_fcntl(fd, ZTS_F_SETFL, ZTS_O_NONBLOCK);
zts_fcntl(accfd, ZTS_F_SETFL, ZTS_O_NONBLOCK);
while (1) {
bytes = zts_recv(accfd, recvBuf, sizeof(recvBuf), 0);
printf("zts_recv(%d, ...)=%d\n", accfd, bytes);
zts_util_delay(100);
}
}
// Technique 1: ZTS_O_NONBLOCK
if (0) {
zts_fcntl(fd, ZTS_F_SETFL, ZTS_O_NONBLOCK);
zts_fcntl(accfd, ZTS_F_SETFL, ZTS_O_NONBLOCK);
while (1) {
bytes = zts_recv(accfd, recvBuf, sizeof(recvBuf), 0);
printf("zts_recv(%d, ...)=%d\n", accfd, bytes);
zts_util_delay(100);
}
}
// Technique 2: zts_select
if (0) {
struct zts_timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 50000;
int result = 0;
zts_fd_set active_fd_set, read_fd_set;
ZTS_FD_ZERO(&active_fd_set);
ZTS_FD_SET(accfd, &active_fd_set);
while (1) {
read_fd_set = active_fd_set;
if ((result = zts_select(ZTS_FD_SETSIZE, &read_fd_set, NULL, NULL, &tv) < 0)) {
// perror ("select");
exit(1);
}
for (int i = 0; i < ZTS_FD_SETSIZE; i++) {
if (ZTS_FD_ISSET(i, &read_fd_set)) {
bytes = zts_recv(accfd, recvBuf, sizeof(recvBuf), 0);
printf("zts_recv(%d, ...)=%d\n", i, bytes);
}
// ZTS_FD_CLR(i, &active_fd_set);
}
}
}
// Technique 2: zts_select
if (0) {
struct zts_timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 50000;
int result = 0;
zts_fd_set active_fd_set, read_fd_set;
ZTS_FD_ZERO(&active_fd_set);
ZTS_FD_SET(accfd, &active_fd_set);
while (1) {
read_fd_set = active_fd_set;
if ((result = zts_select(ZTS_FD_SETSIZE, &read_fd_set, NULL, NULL, &tv) < 0)) {
// perror ("select");
exit(1);
}
for (int i = 0; i < ZTS_FD_SETSIZE; i++) {
if (ZTS_FD_ISSET(i, &read_fd_set)) {
bytes = zts_recv(accfd, recvBuf, sizeof(recvBuf), 0);
printf("zts_recv(%d, ...)=%d\n", i, bytes);
}
// ZTS_FD_CLR(i, &active_fd_set);
}
}
}
// Technique 3: zts_poll
if (1) {
int numfds = 0;
struct zts_pollfd poll_set[16];
memset(poll_set, '\0', sizeof(poll_set));
poll_set[0].fd = accfd;
poll_set[0].events = ZTS_POLLIN;
numfds++;
int result = 0;
int timeout_ms = 50;
while (1) {
result = zts_poll(poll_set, numfds, timeout_ms);
printf("zts_poll()=%d\n", result);
for (int i = 0; i < numfds; i++) {
if (poll_set[i].revents & ZTS_POLLIN) {
bytes = zts_recv(poll_set[i].fd, recvBuf, sizeof(recvBuf), 0);
printf("zts_recv(%d, ...)=%d\n", i, bytes);
}
}
}
}
// Technique 3: zts_poll
if (1) {
int numfds = 0;
struct zts_pollfd poll_set[16];
memset(poll_set, '\0', sizeof(poll_set));
poll_set[0].fd = accfd;
poll_set[0].events = ZTS_POLLIN;
numfds++;
int result = 0;
int timeout_ms = 50;
while (1) {
result = zts_poll(poll_set, numfds, timeout_ms);
printf("zts_poll()=%d\n", result);
for (int i = 0; i < numfds; i++) {
if (poll_set[i].revents & ZTS_POLLIN) {
bytes = zts_recv(poll_set[i].fd, recvBuf, sizeof(recvBuf), 0);
printf("zts_recv(%d, ...)=%d\n", i, bytes);
}
}
}
}
err = zts_close(fd);
return zts_node_stop();
err = zts_close(fd);
return zts_node_stop();
}

View File

@@ -18,92 +18,92 @@ char cache_data[ZTS_STORE_DATA_LEN];
void on_zts_event(void* msgPtr)
{
zts_event_msg_t* msg = (zts_event_msg_t*)msgPtr;
int len = msg->len; // Length of message (or structure)
zts_event_msg_t* msg = (zts_event_msg_t*)msgPtr;
int len = msg->len; // Length of message (or structure)
if (msg->event_code == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE\n");
}
if (msg->event_code == ZTS_EVENT_NODE_ONLINE) {
printf("ZTS_EVENT_NODE_ONLINE\n");
}
// Copy data to a buffer that you have allocated or write it to storage.
// The data pointed to by msg->cache will be invalid after this function
// returns.
// Copy data to a buffer that you have allocated or write it to storage.
// The data pointed to by msg->cache will be invalid after this function
// returns.
memset(cache_data, 0, ZTS_STORE_DATA_LEN);
memset(cache_data, 0, ZTS_STORE_DATA_LEN);
if (msg->event_code == ZTS_EVENT_STORE_IDENTITY_PUBLIC) {
printf("ZTS_EVENT_STORE_IDENTITY_PUBLIC (len=%d)\n", msg->len);
printf("identity.public = [ %.*s ]\n", len, msg->cache);
memcpy(cache_data, msg->cache, len);
}
if (msg->event_code == ZTS_EVENT_STORE_IDENTITY_SECRET) {
printf("ZTS_EVENT_STORE_IDENTITY_SECRET (len=%d)\n", msg->len);
printf("identity.secret = [ %.*s ]\n", len, msg->cache);
memcpy(cache_data, msg->cache, len);
// Same data can be retrieved via: zts_node_get_id_pair()
}
if (msg->event_code == ZTS_EVENT_STORE_PLANET) {
printf("ZTS_EVENT_STORE_PLANET (len=%d)\n", msg->len);
// Binary data
memcpy(cache_data, msg->cache, len);
}
if (msg->event_code == ZTS_EVENT_STORE_PEER) {
printf("ZTS_EVENT_STORE_PEER (len=%d)\n", msg->len);
// Binary data
memcpy(cache_data, msg->cache, len);
}
if (msg->event_code == ZTS_EVENT_STORE_NETWORK) {
printf("ZTS_EVENT_STORE_NETWORK (len=%d)\n", msg->len);
// Binary data
memcpy(cache_data, msg->cache, len);
}
if (msg->event_code == ZTS_EVENT_STORE_IDENTITY_PUBLIC) {
printf("ZTS_EVENT_STORE_IDENTITY_PUBLIC (len=%d)\n", msg->len);
printf("identity.public = [ %.*s ]\n", len, msg->cache);
memcpy(cache_data, msg->cache, len);
}
if (msg->event_code == ZTS_EVENT_STORE_IDENTITY_SECRET) {
printf("ZTS_EVENT_STORE_IDENTITY_SECRET (len=%d)\n", msg->len);
printf("identity.secret = [ %.*s ]\n", len, msg->cache);
memcpy(cache_data, msg->cache, len);
// Same data can be retrieved via: zts_node_get_id_pair()
}
if (msg->event_code == ZTS_EVENT_STORE_PLANET) {
printf("ZTS_EVENT_STORE_PLANET (len=%d)\n", msg->len);
// Binary data
memcpy(cache_data, msg->cache, len);
}
if (msg->event_code == ZTS_EVENT_STORE_PEER) {
printf("ZTS_EVENT_STORE_PEER (len=%d)\n", msg->len);
// Binary data
memcpy(cache_data, msg->cache, len);
}
if (msg->event_code == ZTS_EVENT_STORE_NETWORK) {
printf("ZTS_EVENT_STORE_NETWORK (len=%d)\n", msg->len);
// Binary data
memcpy(cache_data, msg->cache, len);
}
}
int main(int argc, char** argv)
{
int err = ZTS_ERR_OK;
int err = ZTS_ERR_OK;
// Initialize node
// Initialize node
zts_init_set_event_handler(&on_zts_event);
zts_init_set_event_handler(&on_zts_event);
// Start node
// Start node
printf("Starting node...\n");
int generate_new_id = 1;
if (generate_new_id) {
// OPTION A
// Generate new automatically ID if no prior init called
zts_node_start();
}
else {
// OPTION B
// Copy your key here
char identity[ZTS_ID_STR_BUF_LEN] = { 0 };
int len = ZTS_ID_STR_BUF_LEN;
printf("Starting node...\n");
int generate_new_id = 1;
if (generate_new_id) {
// OPTION A
// Generate new automatically ID if no prior init called
zts_node_start();
}
else {
// OPTION B
// Copy your key here
char identity[ZTS_ID_STR_BUF_LEN] = { 0 };
int len = ZTS_ID_STR_BUF_LEN;
// Generate key (optional):
// int key_len;
// zts_id_new(identity, &key_len);
// Generate key (optional):
// int key_len;
// zts_id_new(identity, &key_len);
// Load pre-existing identity from buffer
zts_init_from_memory(identity, len);
zts_node_start();
}
// Load pre-existing identity from buffer
zts_init_from_memory(identity, len);
zts_node_start();
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
// Do network stuff!
// zts_socket, zts_connect, etc
// Do network stuff!
// zts_socket, zts_connect, etc
printf("Node %llx is now online. Idling.\n", zts_node_get_id());
while (1) {
zts_util_delay(500); // Idle indefinitely
}
printf("Node %llx is now online. Idling.\n", zts_node_get_id());
while (1) {
zts_util_delay(500); // Idle indefinitely
}
printf("Stopping node\n");
return zts_node_stop();
printf("Stopping node\n");
return zts_node_stop();
}

View File

@@ -11,57 +11,57 @@
int main(int argc, char** argv)
{
if (argc != 2) {
printf("\nUsage:\n");
printf("pingable-node <net_id>\n");
exit(0);
}
long long int net_id = strtoull(argv[1], NULL, 16); // At least 64 bits
if (argc != 2) {
printf("\nUsage:\n");
printf("pingable-node <net_id>\n");
exit(0);
}
long long int net_id = strtoull(argv[1], NULL, 16); // At least 64 bits
printf("Starting node...\n");
zts_node_start();
printf("Starting node...\n");
zts_node_start();
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("My public identity (node ID) is %llx\n", (long long int)zts_node_get_id());
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
unsigned int len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
printf("My public identity (node ID) is %llx\n", (long long int)zts_node_get_id());
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
unsigned int len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Waiting for address assignment from network\n");
int err = 0;
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
printf("Waiting for address assignment from network\n");
int err = 0;
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Join %llx from another machine and ping me at %s\n", net_id, ipstr);
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Join %llx from another machine and ping me at %s\n", net_id, ipstr);
// Do network stuff!
// zts_socket, zts_connect, etc
// Do network stuff!
// zts_socket, zts_connect, etc
while (1) {
zts_util_delay(500); // Idle indefinitely
}
while (1) {
zts_util_delay(500); // Idle indefinitely
}
printf("Stopping node\n");
return zts_node_stop();
printf("Stopping node\n");
return zts_node_stop();
}

View File

@@ -12,99 +12,99 @@
int main(int argc, char** argv)
{
if (argc != 5) {
printf("\nlibzt example server\n");
printf("server <id_storage_path> <net_id> <local_addr> <local_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* local_addr = argv[3];
int local_port = atoi(argv[4]);
int fd, accfd;
int err = ZTS_ERR_OK;
if (argc != 5) {
printf("\nlibzt example server\n");
printf("server <id_storage_path> <net_id> <local_addr> <local_port>\n");
exit(0);
}
char* storage_path = argv[1];
long long int net_id = strtoull(argv[2], NULL, 16); // At least 64 bits
char* local_addr = argv[3];
int local_port = atoi(argv[4]);
int fd, accfd;
int err = ZTS_ERR_OK;
// Initialize node
// Initialize node
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
if ((err = zts_init_from_storage(storage_path)) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
// Start node
// Start node
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Public identity (node ID) is %llx\n", zts_node_get_id());
if ((err = zts_node_start()) != ZTS_ERR_OK) {
printf("Unable to start service, error = %d. Exiting.\n", err);
exit(1);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Public identity (node ID) is %llx\n", zts_node_get_id());
// Join network
// Join network
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Don't forget to authorize this device in my.zerotier.com or the web API!\n");
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
// Get assigned address (of the family type we care about)
// Get assigned address (of the family type we care about)
int family = zts_util_get_ip_family(local_addr);
int family = zts_util_get_ip_family(local_addr);
printf("Waiting for address assignment from network\n");
while (! (err = zts_addr_is_assigned(net_id, family))) {
zts_util_delay(50);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, family, ipstr, ZTS_IP_MAX_STR_LEN);
printf("IP address on network %llx is %s\n", net_id, ipstr);
printf("Waiting for address assignment from network\n");
while (! (err = zts_addr_is_assigned(net_id, family))) {
zts_util_delay(50);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, family, ipstr, ZTS_IP_MAX_STR_LEN);
printf("IP address on network %llx is %s\n", net_id, ipstr);
// BEGIN Socket Stuff
// BEGIN Socket Stuff
// Accept incoming connection
// Accept incoming connection
// Can also use traditional: zts_socket(), zts_bind(), zts_listen(), zts_accept(), etc.
// Can also use traditional: zts_socket(), zts_bind(), zts_listen(), zts_accept(), etc.
char remote_addr[ZTS_INET6_ADDRSTRLEN] = { 0 };
int remote_port = 0;
int len = ZTS_INET6_ADDRSTRLEN;
if ((accfd = zts_simple_tcp_server(local_addr, local_port, remote_addr, len, &remote_port)) < 0) {
printf("Error (fd=%d, zts_errno=%d). Exiting.\n", accfd, zts_errno);
exit(1);
}
printf("Accepted connection from %s:%d\n", remote_addr, remote_port);
char remote_addr[ZTS_INET6_ADDRSTRLEN] = { 0 };
int remote_port = 0;
int len = ZTS_INET6_ADDRSTRLEN;
if ((accfd = zts_simple_tcp_server(local_addr, local_port, remote_addr, len, &remote_port)) < 0) {
printf("Error (fd=%d, zts_errno=%d). Exiting.\n", accfd, zts_errno);
exit(1);
}
printf("Accepted connection from %s:%d\n", remote_addr, remote_port);
// Data I/O
// Data I/O
int bytes = 0;
char recvBuf[128] = { 0 };
int bytes = 0;
char recvBuf[128] = { 0 };
printf("Reading message string from client...\n");
if ((bytes = zts_read(accfd, recvBuf, sizeof(recvBuf))) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Read %d bytes: %s\n", bytes, recvBuf);
printf("Sending message string to client...\n");
if ((bytes = zts_write(accfd, recvBuf, bytes)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Sent %d bytes: %s\n", bytes, recvBuf);
printf("Reading message string from client...\n");
if ((bytes = zts_read(accfd, recvBuf, sizeof(recvBuf))) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Read %d bytes: %s\n", bytes, recvBuf);
printf("Sending message string to client...\n");
if ((bytes = zts_write(accfd, recvBuf, bytes)) < 0) {
printf("Error (fd=%d, ret=%d, zts_errno=%d). Exiting.\n", fd, bytes, zts_errno);
exit(1);
}
printf("Sent %d bytes: %s\n", bytes, recvBuf);
// Close
// Close
printf("Closing connection socket\n");
err = zts_close(accfd);
err = zts_close(fd);
return zts_node_stop();
printf("Closing connection socket\n");
err = zts_close(accfd);
err = zts_close(fd);
return zts_node_stop();
}

View File

@@ -12,119 +12,119 @@
int main(int argc, char** argv)
{
if (argc != 2) {
printf("\nUsage:\n");
printf("pingable-node <net_id>\n");
exit(0);
}
long long int net_id = strtoull(argv[1], NULL, 16); // At least 64 bits
if (argc != 2) {
printf("\nUsage:\n");
printf("pingable-node <net_id>\n");
exit(0);
}
long long int net_id = strtoull(argv[1], NULL, 16); // At least 64 bits
printf("Starting node...\n");
zts_node_start();
printf("Starting node...\n");
zts_node_start();
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("Waiting for node to come online\n");
while (! zts_node_is_online()) {
zts_util_delay(50);
}
printf("My public identity (node ID) is %llx\n", zts_node_get_id());
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
uint16_t len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
printf("My public identity (node ID) is %llx\n", zts_node_get_id());
char keypair[ZTS_ID_STR_BUF_LEN] = { 0 };
uint16_t len = ZTS_ID_STR_BUF_LEN;
if (zts_node_get_id_pair(keypair, &len) != ZTS_ERR_OK) {
printf("Error getting identity keypair. Exiting.\n");
}
printf("Identity [public/secret pair] = %s\n", keypair);
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Joining network %llx\n", net_id);
if (zts_net_join(net_id) != ZTS_ERR_OK) {
printf("Unable to join network. Exiting.\n");
exit(1);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Waiting for join to complete\n");
while (! zts_net_transport_is_ready(net_id)) {
zts_util_delay(50);
}
printf("Waiting for address assignment from network\n");
int err = 0;
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
printf("Waiting for address assignment from network\n");
int err = 0;
while (! (err = zts_addr_is_assigned(net_id, ZTS_AF_INET))) {
zts_util_delay(500);
}
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Join %llx from another machine and ping me at %s\n", net_id, ipstr);
char ipstr[ZTS_IP_MAX_STR_LEN] = { 0 };
zts_addr_get_str(net_id, ZTS_AF_INET, ipstr, ZTS_IP_MAX_STR_LEN);
printf("Join %llx from another machine and ping me at %s\n", net_id, ipstr);
// Do network stuff!
// zts_socket, zts_connect, etc
// Do network stuff!
// zts_socket, zts_connect, etc
// Show protocol statistics
// Show protocol statistics
zts_stats_counter_t s = { 0 };
zts_stats_counter_t s = { 0 };
while (1) {
zts_util_delay(1000);
if ((err = zts_stats_get_all(&s)) == ZTS_ERR_NO_RESULT) {
printf("no results\n");
continue;
}
printf("\n\n");
while (1) {
zts_util_delay(1000);
if ((err = zts_stats_get_all(&s)) == ZTS_ERR_NO_RESULT) {
printf("no results\n");
continue;
}
printf("\n\n");
printf(
" link_tx=%9d, link_rx=%9d, link_drop=%9d, link_err=%9d\n",
s.link_tx,
s.link_rx,
s.link_drop,
s.link_err);
printf(
"etharp_tx=%9d, etharp_rx=%9d, etharp_drop=%9d, etharp_err=%9d\n",
s.etharp_tx,
s.etharp_rx,
s.etharp_drop,
s.etharp_err);
printf(
" ip4_tx=%9d, ip4_rx=%9d, ip4_drop=%9d, ip4_err=%9d\n",
s.ip4_tx,
s.ip4_rx,
s.ip4_drop,
s.ip4_err);
printf(
" ip6_tx=%9d, ip6_rx=%9d, ip6_drop=%9d, ip6_err=%9d\n",
s.ip6_tx,
s.ip6_rx,
s.ip6_drop,
s.ip6_err);
printf(
" icmp4_tx=%9d, icmp4_rx=%9d, icmp4_drop=%9d, icmp4_err=%9d\n",
s.icmp4_tx,
s.icmp4_rx,
s.icmp4_drop,
s.icmp4_err);
printf(
" icmp6_tx=%9d, icmp6_rx=%9d, icmp6_drop=%9d, icmp6_err=%9d\n",
s.icmp6_tx,
s.icmp6_rx,
s.icmp6_drop,
s.icmp6_err);
printf(
" udp_tx=%9d, udp_rx=%9d, udp_drop=%9d, udp_err=%9d\n",
s.udp_tx,
s.udp_rx,
s.udp_drop,
s.udp_err);
printf(
" tcp_tx=%9d, tcp_rx=%9d, tcp_drop=%9d, tcp_err=%9d\n",
s.tcp_tx,
s.tcp_rx,
s.tcp_drop,
s.tcp_err);
printf(
" nd6_tx=%9d, nd6_rx=%9d, nd6_drop=%9d, nd6_err=%9d\n",
s.nd6_tx,
s.nd6_rx,
s.nd6_drop,
s.nd6_err);
}
return zts_node_stop();
printf(
" link_tx=%9d, link_rx=%9d, link_drop=%9d, link_err=%9d\n",
s.link_tx,
s.link_rx,
s.link_drop,
s.link_err);
printf(
"etharp_tx=%9d, etharp_rx=%9d, etharp_drop=%9d, etharp_err=%9d\n",
s.etharp_tx,
s.etharp_rx,
s.etharp_drop,
s.etharp_err);
printf(
" ip4_tx=%9d, ip4_rx=%9d, ip4_drop=%9d, ip4_err=%9d\n",
s.ip4_tx,
s.ip4_rx,
s.ip4_drop,
s.ip4_err);
printf(
" ip6_tx=%9d, ip6_rx=%9d, ip6_drop=%9d, ip6_err=%9d\n",
s.ip6_tx,
s.ip6_rx,
s.ip6_drop,
s.ip6_err);
printf(
" icmp4_tx=%9d, icmp4_rx=%9d, icmp4_drop=%9d, icmp4_err=%9d\n",
s.icmp4_tx,
s.icmp4_rx,
s.icmp4_drop,
s.icmp4_err);
printf(
" icmp6_tx=%9d, icmp6_rx=%9d, icmp6_drop=%9d, icmp6_err=%9d\n",
s.icmp6_tx,
s.icmp6_rx,
s.icmp6_drop,
s.icmp6_err);
printf(
" udp_tx=%9d, udp_rx=%9d, udp_drop=%9d, udp_err=%9d\n",
s.udp_tx,
s.udp_rx,
s.udp_drop,
s.udp_err);
printf(
" tcp_tx=%9d, tcp_rx=%9d, tcp_drop=%9d, tcp_err=%9d\n",
s.tcp_tx,
s.tcp_rx,
s.tcp_drop,
s.tcp_err);
printf(
" nd6_tx=%9d, nd6_rx=%9d, nd6_drop=%9d, nd6_err=%9d\n",
s.nd6_tx,
s.nd6_rx,
s.nd6_drop,
s.nd6_err);
}
return zts_node_stop();
}

File diff suppressed because it is too large Load Diff

View File

@@ -47,80 +47,80 @@ extern "C" {
size_t on_data(void* buffer, size_t size, size_t nmemb, void* userp)
{
DEBUG_INFO("buf=%p,size=%zu,nmemb=%zu,userp=%p", buffer, size, nmemb, userp);
int byte_count = (size * nmemb);
if (_resp_buf_offset + byte_count >= _resp_buf_len) {
DEBUG_INFO("Out of buffer space. Cannot store response from server");
return 0; // Signal to libcurl that our buffer is full (triggers a
// write error.)
}
memcpy(_resp_buf + _resp_buf_offset, buffer, byte_count);
_resp_buf_offset += byte_count;
return byte_count;
DEBUG_INFO("buf=%p,size=%zu,nmemb=%zu,userp=%p", buffer, size, nmemb, userp);
int byte_count = (size * nmemb);
if (_resp_buf_offset + byte_count >= _resp_buf_len) {
DEBUG_INFO("Out of buffer space. Cannot store response from server");
return 0; // Signal to libcurl that our buffer is full (triggers a
// write error.)
}
memcpy(_resp_buf + _resp_buf_offset, buffer, byte_count);
_resp_buf_offset += byte_count;
return byte_count;
}
int zts_central_set_access_mode(int8_t modes)
{
if (! (modes & ZTS_CENTRAL_READ) && ! (modes & ZTS_CENTRAL_WRITE)) {
return ZTS_ERR_ARG;
}
_access_modes = modes;
return ZTS_ERR_OK;
if (! (modes & ZTS_CENTRAL_READ) && ! (modes & ZTS_CENTRAL_WRITE)) {
return ZTS_ERR_ARG;
}
_access_modes = modes;
return ZTS_ERR_OK;
}
int zts_central_set_verbose(int8_t is_verbose)
{
if (is_verbose != 1 && is_verbose != 0) {
return ZTS_ERR_ARG;
}
_bIsVerbose = is_verbose;
return ZTS_ERR_OK;
if (is_verbose != 1 && is_verbose != 0) {
return ZTS_ERR_ARG;
}
_bIsVerbose = is_verbose;
return ZTS_ERR_OK;
}
void zts_central_clear_resp_buf()
{
Mutex::Lock _l(_responseBuffer_m);
memset(_resp_buf, 0, _resp_buf_len);
_resp_buf_offset = 0;
Mutex::Lock _l(_responseBuffer_m);
memset(_resp_buf, 0, _resp_buf_len);
_resp_buf_offset = 0;
}
int zts_central_init(const char* url_str, const char* token_str, char* resp_buf, uint32_t resp_buf_len)
{
_access_modes = ZTS_CENTRAL_READ; // Default read-only
_bIsVerbose = 0; // Default disable libcurl verbose output
Mutex::Lock _l(_responseBuffer_m);
if (resp_buf_len == 0) {
return ZTS_ERR_ARG;
}
_resp_buf = resp_buf;
_resp_buf_len = resp_buf_len;
_resp_buf_offset = 0;
// Initialize all curl internal submodules
curl_global_init(CURL_GLOBAL_ALL);
_access_modes = ZTS_CENTRAL_READ; // Default read-only
_bIsVerbose = 0; // Default disable libcurl verbose output
Mutex::Lock _l(_responseBuffer_m);
if (resp_buf_len == 0) {
return ZTS_ERR_ARG;
}
_resp_buf = resp_buf;
_resp_buf_len = resp_buf_len;
_resp_buf_offset = 0;
// Initialize all curl internal submodules
curl_global_init(CURL_GLOBAL_ALL);
int url_len = strlen(url_str);
if (url_len < 3 || url_len > ZTS_CENRTAL_MAX_URL_LEN) {
return ZTS_ERR_ARG;
}
else {
memset(api_url, 0, ZTS_CENRTAL_MAX_URL_LEN);
strncpy(api_url, url_str, url_len);
}
int token_len = strlen(token_str);
if (token_len != ZTS_CENTRAL_TOKEN_LEN) {
return ZTS_ERR_ARG;
}
else {
memset(api_token, 0, ZTS_CENTRAL_TOKEN_LEN);
strncpy(api_token, token_str, token_len);
}
_bInit = true;
return ZTS_ERR_OK;
int url_len = strlen(url_str);
if (url_len < 3 || url_len > ZTS_CENRTAL_MAX_URL_LEN) {
return ZTS_ERR_ARG;
}
else {
memset(api_url, 0, ZTS_CENRTAL_MAX_URL_LEN);
strncpy(api_url, url_str, url_len);
}
int token_len = strlen(token_str);
if (token_len != ZTS_CENTRAL_TOKEN_LEN) {
return ZTS_ERR_ARG;
}
else {
memset(api_token, 0, ZTS_CENTRAL_TOKEN_LEN);
strncpy(api_token, token_str, token_len);
}
_bInit = true;
return ZTS_ERR_OK;
}
void zts_central_cleanup()
{
curl_global_cleanup();
curl_global_cleanup();
}
int central_req(
@@ -131,183 +131,183 @@ int central_req(
int* response_code,
char* post_data)
{
int err = ZTS_ERR_OK;
if (! _bInit) {
DEBUG_INFO("Error: Central API must be initialized first. Call "
"zts_central_init()");
return ZTS_ERR_SERVICE;
}
if (request_type == ZTS_HTTP_GET && ! (_access_modes & ZTS_CENTRAL_READ)) {
DEBUG_INFO("Error: Incorrect access mode. Need (ZTS_CENTRAL_READ) permission");
return ZTS_ERR_SERVICE;
}
if (request_type == ZTS_HTTP_POST && ! (_access_modes & ZTS_CENTRAL_WRITE)) {
DEBUG_INFO("Error: Incorrect access mode. Need (ZTS_CENTRAL_WRITE) "
"permission");
return ZTS_ERR_SERVICE;
}
zts_central_clear_resp_buf();
int central_strlen = strlen(central_str);
int api_route_strlen = strlen(api_route_str);
int token_strlen = strlen(token_str);
int url_len = central_strlen + api_route_strlen;
if (token_strlen > ZTS_CENTRAL_TOKEN_LEN) {
return ZTS_ERR_ARG;
}
if (url_len > ZTS_CENRTAL_MAX_URL_LEN) {
return ZTS_ERR_ARG;
}
char req_url[ZTS_CENRTAL_MAX_URL_LEN] = { 0 };
strncpy(req_url, central_str, ZTS_CENRTAL_MAX_URL_LEN);
strncat(req_url, api_route_str, ZTS_CENRTAL_MAX_URL_LEN);
int err = ZTS_ERR_OK;
if (! _bInit) {
DEBUG_INFO("Error: Central API must be initialized first. Call "
"zts_central_init()");
return ZTS_ERR_SERVICE;
}
if (request_type == ZTS_HTTP_GET && ! (_access_modes & ZTS_CENTRAL_READ)) {
DEBUG_INFO("Error: Incorrect access mode. Need (ZTS_CENTRAL_READ) permission");
return ZTS_ERR_SERVICE;
}
if (request_type == ZTS_HTTP_POST && ! (_access_modes & ZTS_CENTRAL_WRITE)) {
DEBUG_INFO("Error: Incorrect access mode. Need (ZTS_CENTRAL_WRITE) "
"permission");
return ZTS_ERR_SERVICE;
}
zts_central_clear_resp_buf();
int central_strlen = strlen(central_str);
int api_route_strlen = strlen(api_route_str);
int token_strlen = strlen(token_str);
int url_len = central_strlen + api_route_strlen;
if (token_strlen > ZTS_CENTRAL_TOKEN_LEN) {
return ZTS_ERR_ARG;
}
if (url_len > ZTS_CENRTAL_MAX_URL_LEN) {
return ZTS_ERR_ARG;
}
char req_url[ZTS_CENRTAL_MAX_URL_LEN] = { 0 };
strncpy(req_url, central_str, ZTS_CENRTAL_MAX_URL_LEN);
strncat(req_url, api_route_str, ZTS_CENRTAL_MAX_URL_LEN);
CURL* curl;
CURLcode res;
curl = curl_easy_init();
if (! curl) {
return ZTS_ERR_GENERAL;
}
CURL* curl;
CURLcode res;
curl = curl_easy_init();
if (! curl) {
return ZTS_ERR_GENERAL;
}
struct curl_slist* hs = NULL;
char auth_str[ZTS_CENTRAL_TOKEN_LEN + 32] = { 0 }; // + Authorization: Bearer
if (token_strlen == ZTS_CENTRAL_TOKEN_LEN) {
OSUtils::ztsnprintf(auth_str, ZTS_CENTRAL_TOKEN_LEN + 32, "Authorization: Bearer %s", token_str);
}
struct curl_slist* hs = NULL;
char auth_str[ZTS_CENTRAL_TOKEN_LEN + 32] = { 0 }; // + Authorization: Bearer
if (token_strlen == ZTS_CENTRAL_TOKEN_LEN) {
OSUtils::ztsnprintf(auth_str, ZTS_CENTRAL_TOKEN_LEN + 32, "Authorization: Bearer %s", token_str);
}
hs = curl_slist_append(hs, auth_str);
hs = curl_slist_append(hs, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);
curl_easy_setopt(curl, CURLOPT_URL, req_url);
// example.com is redirected, so we tell libcurl to follow redirection
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
if (_bIsVerbose) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
}
// Tell curl to use our write function
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_data);
hs = curl_slist_append(hs, auth_str);
hs = curl_slist_append(hs, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);
curl_easy_setopt(curl, CURLOPT_URL, req_url);
// example.com is redirected, so we tell libcurl to follow redirection
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
if (_bIsVerbose) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
}
// Tell curl to use our write function
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_data);
if (request_type == ZTS_HTTP_GET) {
// Nothing
DEBUG_INFO("Request (GET) = %s", api_route_str);
}
if (request_type == ZTS_HTTP_POST) {
DEBUG_INFO("Request (POST) = %s", api_route_str);
if (post_data) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
}
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
}
if (request_type == ZTS_HTTP_DELETE) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
}
// curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); // Consider 400-500
// series code as failures
// Perform request
res = curl_easy_perform(curl);
if (res == CURLE_OK) {
// char* url;
double elapsed_time = 0.0;
long hrc = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &hrc);
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed_time);
DEBUG_INFO("Req. took %f second(s). HTTP code (%ld)", elapsed_time, hrc);
*response_code = hrc;
// curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
}
else {
DEBUG_INFO("%s", curl_easy_strerror(res));
err = ZTS_ERR_SERVICE;
}
curl_easy_cleanup(curl);
return err;
if (request_type == ZTS_HTTP_GET) {
// Nothing
DEBUG_INFO("Request (GET) = %s", api_route_str);
}
if (request_type == ZTS_HTTP_POST) {
DEBUG_INFO("Request (POST) = %s", api_route_str);
if (post_data) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
}
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
}
if (request_type == ZTS_HTTP_DELETE) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
}
// curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); // Consider 400-500
// series code as failures
// Perform request
res = curl_easy_perform(curl);
if (res == CURLE_OK) {
// char* url;
double elapsed_time = 0.0;
long hrc = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &hrc);
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed_time);
DEBUG_INFO("Req. took %f second(s). HTTP code (%ld)", elapsed_time, hrc);
*response_code = hrc;
// curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
}
else {
DEBUG_INFO("%s", curl_easy_strerror(res));
err = ZTS_ERR_SERVICE;
}
curl_easy_cleanup(curl);
return err;
}
int zts_central_get_last_resp_buf(char* dest_buffer, int dest_buf_len)
{
if (dest_buf_len <= _resp_buf_offset) {
return ZTS_ERR_ARG;
}
int sz = dest_buf_len < _resp_buf_len ? dest_buf_len : _resp_buf_len;
memcpy(dest_buffer, _resp_buf, sz);
return ZTS_ERR_OK;
if (dest_buf_len <= _resp_buf_offset) {
return ZTS_ERR_ARG;
}
int sz = dest_buf_len < _resp_buf_len ? dest_buf_len : _resp_buf_len;
memcpy(dest_buffer, _resp_buf, sz);
return ZTS_ERR_OK;
}
int zts_central_status_get(int* resp_code)
{
return central_req(ZTS_HTTP_GET, api_url, (char*)"/api/status", api_token, resp_code, NULL);
return central_req(ZTS_HTTP_GET, api_url, (char*)"/api/status", api_token, resp_code, NULL);
}
int zts_central_self_get(int* resp_code)
{
return central_req(ZTS_HTTP_GET, api_url, (char*)"/api/self", api_token, resp_code, NULL);
return central_req(ZTS_HTTP_GET, api_url, (char*)"/api/self", api_token, resp_code, NULL);
}
int zts_central_net_get(int* resp_code, uint64_t net_id)
{
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx", net_id);
return central_req(ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx", net_id);
return central_req(ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
}
int zts_central_net_update(int* resp_code, uint64_t net_id)
{
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx", net_id);
return central_req(ZTS_HTTP_POST, api_url, req, api_token, resp_code, NULL);
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx", net_id);
return central_req(ZTS_HTTP_POST, api_url, req, api_token, resp_code, NULL);
}
int zts_central_net_delete(int* resp_code, uint64_t net_id)
{
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx", net_id);
return central_req(ZTS_HTTP_DELETE, api_url, req, api_token, resp_code, NULL);
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx", net_id);
return central_req(ZTS_HTTP_DELETE, api_url, req, api_token, resp_code, NULL);
}
int zts_central_net_get_all(int* resp_code)
{
return central_req(ZTS_HTTP_GET, api_url, (char*)"/api/network", api_token, resp_code, NULL);
return central_req(ZTS_HTTP_GET, api_url, (char*)"/api/network", api_token, resp_code, NULL);
}
int zts_central_member_get(int* resp_code, uint64_t net_id, uint64_t node_id)
{
if (net_id == 0 || node_id == 0) {
return ZTS_ERR_ARG;
}
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx/member/%llx", net_id, node_id);
return central_req(ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
if (net_id == 0 || node_id == 0) {
return ZTS_ERR_ARG;
}
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx/member/%llx", net_id, node_id);
return central_req(ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
}
int zts_central_member_update(int* resp_code, uint64_t net_id, uint64_t node_id, char* post_data)
{
if (net_id == 0 || node_id == 0 || post_data == NULL) {
return ZTS_ERR_ARG;
}
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx/member/%llx", net_id, node_id);
return central_req(ZTS_HTTP_POST, api_url, req, api_token, resp_code, post_data);
if (net_id == 0 || node_id == 0 || post_data == NULL) {
return ZTS_ERR_ARG;
}
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx/member/%llx", net_id, node_id);
return central_req(ZTS_HTTP_POST, api_url, req, api_token, resp_code, post_data);
}
int zts_central_node_auth(int* resp_code, uint64_t net_id, uint64_t node_id, uint8_t is_authed)
{
if (is_authed != 0 && is_authed != 1) {
return ZTS_ERR_ARG;
}
char config_data[REQ_LEN] = { 0 };
if (is_authed == ZTS_CENTRAL_NODE_AUTH_TRUE) {
OSUtils::ztsnprintf(config_data, REQ_LEN, "{\"config\": {\"authorized\": true} }");
}
if (is_authed == ZTS_CENTRAL_NODE_AUTH_FALSE) {
OSUtils::ztsnprintf(config_data, REQ_LEN, "{\"config\": {\"authorized\": false} }");
}
return zts_central_member_update(resp_code, net_id, node_id, config_data);
if (is_authed != 0 && is_authed != 1) {
return ZTS_ERR_ARG;
}
char config_data[REQ_LEN] = { 0 };
if (is_authed == ZTS_CENTRAL_NODE_AUTH_TRUE) {
OSUtils::ztsnprintf(config_data, REQ_LEN, "{\"config\": {\"authorized\": true} }");
}
if (is_authed == ZTS_CENTRAL_NODE_AUTH_FALSE) {
OSUtils::ztsnprintf(config_data, REQ_LEN, "{\"config\": {\"authorized\": false} }");
}
return zts_central_member_update(resp_code, net_id, node_id, config_data);
}
int zts_central_net_get_members(int* resp_code, uint64_t net_id)
{
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx/member", net_id);
return central_req(ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
char req[REQ_LEN] = { 0 };
OSUtils::ztsnprintf(req, REQ_LEN, "/api/network/%llx/member", net_id);
return central_req(ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
}
#ifdef __cplusplus

View File

@@ -69,20 +69,20 @@ Mutex service_m;
*/
int init_subsystems()
{
if (! zts_events) {
zts_events = new Events();
}
if (zts_events->getState(ZTS_STATE_FREE_CALLED)) {
return ZTS_ERR_SERVICE;
}
if (! zts_events) {
zts_events = new Events();
}
if (zts_events->getState(ZTS_STATE_FREE_CALLED)) {
return ZTS_ERR_SERVICE;
}
#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
_install_signal_handlers();
_install_signal_handlers();
#endif // ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
if (! zts_service) {
zts_service = new NodeService();
zts_service->setUserEventSystem(zts_events);
}
return ZTS_ERR_OK;
if (! zts_service) {
zts_service = new NodeService();
zts_service->setUserEventSystem(zts_events);
}
return ZTS_ERR_OK;
}
#ifdef __cplusplus
@@ -91,15 +91,15 @@ extern "C" {
int zts_init_from_storage(const char* path)
{
ACQUIRE_SERVICE_OFFLINE();
zts_service->setHomePath(path);
return ZTS_ERR_OK;
ACQUIRE_SERVICE_OFFLINE();
zts_service->setHomePath(path);
return ZTS_ERR_OK;
}
int zts_init_from_memory(const char* keypair, unsigned int len)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->setIdentity(keypair, len);
ACQUIRE_SERVICE_OFFLINE();
return zts_service->setIdentity(keypair, len);
}
#ifdef ZTS_ENABLE_PYTHON
@@ -112,154 +112,154 @@ int zts_init_set_event_handler(PythonDirectorCallbackClass* callback)
int zts_init_set_event_handler(void (*callback)(void*))
#endif
{
ACQUIRE_SERVICE_OFFLINE();
if (! callback) {
return ZTS_ERR_ARG;
}
_userEventCallback = callback;
zts_service->enableEvents();
return ZTS_ERR_OK;
ACQUIRE_SERVICE_OFFLINE();
if (! callback) {
return ZTS_ERR_ARG;
}
_userEventCallback = callback;
zts_service->enableEvents();
return ZTS_ERR_OK;
}
int zts_init_blacklist_if(const char* prefix, unsigned int len)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->addInterfacePrefixToBlacklist(prefix, len);
ACQUIRE_SERVICE_OFFLINE();
return zts_service->addInterfacePrefixToBlacklist(prefix, len);
}
int zts_init_set_world(const void* world_data, unsigned int len)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->setWorld(world_data, len);
ACQUIRE_SERVICE_OFFLINE();
return zts_service->setWorld(world_data, len);
}
int zts_init_set_port(unsigned short port)
{
ACQUIRE_SERVICE_OFFLINE();
zts_service->setPrimaryPort(port);
return ZTS_ERR_OK;
ACQUIRE_SERVICE_OFFLINE();
zts_service->setPrimaryPort(port);
return ZTS_ERR_OK;
}
int zts_init_allow_peer_cache(unsigned int allowed)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowPeerCaching(allowed);
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowPeerCaching(allowed);
}
int zts_init_allow_net_cache(unsigned int allowed)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowNetworkCaching(allowed);
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowNetworkCaching(allowed);
}
int zts_init_allow_world_cache(unsigned int allowed)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowWorldCaching(allowed);
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowWorldCaching(allowed);
}
int zts_init_allow_id_cache(unsigned int allowed)
{
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowIdentityCaching(allowed);
ACQUIRE_SERVICE_OFFLINE();
return zts_service->allowIdentityCaching(allowed);
}
int zts_addr_compute_6plane(const uint64_t net_id, const uint64_t node_id, struct zts_sockaddr_storage* addr)
{
if (! addr || ! net_id || ! node_id) {
return ZTS_ERR_ARG;
}
InetAddress _6planeAddr = InetAddress::makeIpv66plane(net_id, node_id);
struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
memcpy(in6->sin6_addr.s6_addr, _6planeAddr.rawIpData(), sizeof(struct in6_addr));
return ZTS_ERR_OK;
if (! addr || ! net_id || ! node_id) {
return ZTS_ERR_ARG;
}
InetAddress _6planeAddr = InetAddress::makeIpv66plane(net_id, node_id);
struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
memcpy(in6->sin6_addr.s6_addr, _6planeAddr.rawIpData(), sizeof(struct in6_addr));
return ZTS_ERR_OK;
}
int zts_addr_compute_rfc4193(const uint64_t net_id, const uint64_t node_id, struct zts_sockaddr_storage* addr)
{
if (! addr || ! net_id || ! node_id) {
return ZTS_ERR_ARG;
}
InetAddress _rfc4193Addr = InetAddress::makeIpv6rfc4193(net_id, node_id);
struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
memcpy(in6->sin6_addr.s6_addr, _rfc4193Addr.rawIpData(), sizeof(struct in6_addr));
return ZTS_ERR_OK;
if (! addr || ! net_id || ! node_id) {
return ZTS_ERR_ARG;
}
InetAddress _rfc4193Addr = InetAddress::makeIpv6rfc4193(net_id, node_id);
struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
memcpy(in6->sin6_addr.s6_addr, _rfc4193Addr.rawIpData(), sizeof(struct in6_addr));
return ZTS_ERR_OK;
}
int zts_addr_compute_rfc4193_str(uint64_t net_id, uint64_t node_id, char* dst, unsigned int len)
{
if (! net_id || ! node_id || ! dst || len != ZTS_IP_MAX_STR_LEN) {
return ZTS_ERR_ARG;
}
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_compute_rfc4193(net_id, node_id, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)&ss;
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), dst, ZTS_IP_MAX_STR_LEN);
return ZTS_ERR_OK;
if (! net_id || ! node_id || ! dst || len != ZTS_IP_MAX_STR_LEN) {
return ZTS_ERR_ARG;
}
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_compute_rfc4193(net_id, node_id, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)&ss;
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), dst, ZTS_IP_MAX_STR_LEN);
return ZTS_ERR_OK;
}
int zts_addr_compute_6plane_str(uint64_t net_id, uint64_t node_id, char* dst, unsigned int len)
{
if (! net_id || ! node_id || ! dst || len != ZTS_IP_MAX_STR_LEN) {
return ZTS_ERR_ARG;
}
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_compute_6plane(net_id, node_id, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)&ss;
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), dst, ZTS_IP_MAX_STR_LEN);
return ZTS_ERR_OK;
if (! net_id || ! node_id || ! dst || len != ZTS_IP_MAX_STR_LEN) {
return ZTS_ERR_ARG;
}
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_compute_6plane(net_id, node_id, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)&ss;
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), dst, ZTS_IP_MAX_STR_LEN);
return ZTS_ERR_OK;
}
uint64_t zts_net_compute_adhoc_id(uint16_t start_port, uint16_t end_port)
{
char net_id_str[ZTS_INET6_ADDRSTRLEN] = { 0 };
OSUtils::ztsnprintf(net_id_str, ZTS_INET6_ADDRSTRLEN, "ff%04x%04x000000", start_port, end_port);
return strtoull(net_id_str, NULL, 16);
char net_id_str[ZTS_INET6_ADDRSTRLEN] = { 0 };
OSUtils::ztsnprintf(net_id_str, ZTS_INET6_ADDRSTRLEN, "ff%04x%04x000000", start_port, end_port);
return strtoull(net_id_str, NULL, 16);
}
int zts_id_new(char* key, unsigned int* dst_len)
{
if (key == NULL || *dst_len != ZT_IDENTITY_STRING_BUFFER_LENGTH) {
return ZTS_ERR_ARG;
}
Identity id;
id.generate();
char idtmp[1024] = { 0 };
std::string idser = id.toString(true, idtmp);
unsigned int key_pair_len = idser.length();
if (key_pair_len > *dst_len) {
return ZTS_ERR_ARG;
}
memcpy(key, idser.c_str(), key_pair_len);
*dst_len = key_pair_len;
return ZTS_ERR_OK;
if (key == NULL || *dst_len != ZT_IDENTITY_STRING_BUFFER_LENGTH) {
return ZTS_ERR_ARG;
}
Identity id;
id.generate();
char idtmp[1024] = { 0 };
std::string idser = id.toString(true, idtmp);
unsigned int key_pair_len = idser.length();
if (key_pair_len > *dst_len) {
return ZTS_ERR_ARG;
}
memcpy(key, idser.c_str(), key_pair_len);
*dst_len = key_pair_len;
return ZTS_ERR_OK;
}
int zts_id_pair_is_valid(const char* key, unsigned int len)
{
if (key == NULL || len != ZT_IDENTITY_STRING_BUFFER_LENGTH) {
return false;
}
Identity id;
if ((strlen(key) > 32) && (key[10] == ':')) {
if (id.fromString(key)) {
return id.locallyValidate();
}
}
return false;
if (key == NULL || len != ZT_IDENTITY_STRING_BUFFER_LENGTH) {
return false;
}
Identity id;
if ((strlen(key) > 32) && (key[10] == ':')) {
if (id.fromString(key)) {
return id.locallyValidate();
}
}
return false;
}
int zts_node_get_id_pair(char* key, unsigned int* dst_len)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->getIdentity(key, dst_len);
return *dst_len > 0 ? ZTS_ERR_OK : ZTS_ERR_GENERAL;
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->getIdentity(key, dst_len);
return *dst_len > 0 ? ZTS_ERR_OK : ZTS_ERR_GENERAL;
}
#if defined(__WINDOWS__)
@@ -269,95 +269,95 @@ void* cbRun(void* arg)
#endif
{
#if defined(__APPLE__)
pthread_setname_np(ZTS_EVENT_CALLBACK_THREAD_NAME);
pthread_setname_np(ZTS_EVENT_CALLBACK_THREAD_NAME);
#endif
zts_events->run();
zts_events->run();
#if ZTS_ENABLE_JAVA
_java_detach_from_thread();
// pthread_exit(0);
_java_detach_from_thread();
// pthread_exit(0);
#endif
return NULL;
return NULL;
}
int zts_addr_is_assigned(uint64_t net_id, unsigned int family)
{
ACQUIRE_SERVICE(0);
return zts_service->addrIsAssigned(net_id, family);
ACQUIRE_SERVICE(0);
return zts_service->addrIsAssigned(net_id, family);
}
int zts_addr_get(uint64_t net_id, unsigned int family, struct zts_sockaddr_storage* addr)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getFirstAssignedAddr(net_id, family, addr);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getFirstAssignedAddr(net_id, family, addr);
}
int zts_addr_get_str(uint64_t net_id, unsigned int family, char* dst, unsigned int len)
{
// No service lock required since zts_addr_get will lock it
if (net_id == 0) {
return ZTS_ERR_ARG;
}
if (len < ZTS_INET6_ADDRSTRLEN) {
return ZTS_ERR_ARG;
}
// No service lock required since zts_addr_get will lock it
if (net_id == 0) {
return ZTS_ERR_ARG;
}
if (len < ZTS_INET6_ADDRSTRLEN) {
return ZTS_ERR_ARG;
}
if (family == ZTS_AF_INET) {
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_get(net_id, family, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in* in4 = (struct zts_sockaddr_in*)&ss;
zts_inet_ntop(family, &(in4->sin_addr), dst, ZTS_INET6_ADDRSTRLEN);
}
if (family == ZTS_AF_INET6) {
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_get(net_id, family, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)&ss;
zts_inet_ntop(family, &(in6->sin6_addr), dst, ZTS_INET6_ADDRSTRLEN);
}
return ZTS_ERR_OK;
if (family == ZTS_AF_INET) {
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_get(net_id, family, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in* in4 = (struct zts_sockaddr_in*)&ss;
zts_inet_ntop(family, &(in4->sin_addr), dst, ZTS_INET6_ADDRSTRLEN);
}
if (family == ZTS_AF_INET6) {
struct zts_sockaddr_storage ss;
int err = ZTS_ERR_OK;
if ((err = zts_addr_get(net_id, family, &ss)) != ZTS_ERR_OK) {
return err;
}
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)&ss;
zts_inet_ntop(family, &(in6->sin6_addr), dst, ZTS_INET6_ADDRSTRLEN);
}
return ZTS_ERR_OK;
}
int zts_addr_get_all(uint64_t net_id, struct zts_sockaddr_storage* addr, unsigned int* count)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getAllAssignedAddr(net_id, addr, count);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getAllAssignedAddr(net_id, addr, count);
}
int zts_core_lock_obtain()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->obtainLock();
return ZTS_ERR_OK;
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->obtainLock();
return ZTS_ERR_OK;
}
int zts_core_lock_release()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->releaseLock();
return ZTS_ERR_OK;
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->releaseLock();
return ZTS_ERR_OK;
}
int zts_core_query_addr_count(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->addressCount(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->addressCount(net_id);
}
int zts_core_query_addr(uint64_t net_id, unsigned int idx, char* addr, unsigned int len)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getAddrAtIdx(net_id, idx, addr, len);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getAddrAtIdx(net_id, idx, addr, len);
}
int zts_core_query_route_count(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->routeCount(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->routeCount(net_id);
}
int zts_core_query_route(
@@ -369,110 +369,110 @@ int zts_core_query_route(
uint16_t* flags,
uint16_t* metric)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getRouteAtIdx(net_id, idx, target, via, len, flags, metric);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getRouteAtIdx(net_id, idx, target, via, len, flags, metric);
}
int zts_core_query_path_count(uint64_t peer_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->pathCount(peer_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->pathCount(peer_id);
}
int zts_core_query_path(uint64_t peer_id, unsigned int idx, char* path, unsigned int len)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getPathAtIdx(peer_id, idx, path, len);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getPathAtIdx(peer_id, idx, path, len);
}
int zts_core_query_mc_count(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->multicastSubCount(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->multicastSubCount(net_id);
}
int zts_core_query_mc(uint64_t net_id, unsigned int idx, uint64_t* mac, uint32_t* adi)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getMulticastSubAtIdx(net_id, idx, mac, adi);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getMulticastSubAtIdx(net_id, idx, mac, adi);
}
int zts_net_join(const uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->join(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->join(net_id);
}
int zts_net_leave(const uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->leave(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->leave(net_id);
}
int zts_net_transport_is_ready(const uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->networkIsReady(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->networkIsReady(net_id);
}
uint64_t zts_net_get_mac(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getMACAddress(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getMACAddress(net_id);
}
ZTS_API int ZTCALL zts_net_get_mac_str(uint64_t net_id, char* dst, unsigned int len)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
if (! dst || len < ZTS_MAC_ADDRSTRLEN) {
return ZTS_ERR_ARG;
}
uint64_t mac = zts_service->getMACAddress(net_id);
OSUtils::ztsnprintf(
dst,
ZTS_MAC_ADDRSTRLEN,
"%x:%x:%x:%x:%x:%x",
(mac >> 48) & 0xFF,
(mac >> 32) & 0xFF,
(mac >> 24) & 0xFF,
(mac >> 16) & 0xFF,
(mac >> 8) & 0xFF,
(mac >> 0) & 0xFF);
return ZTS_ERR_OK;
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
if (! dst || len < ZTS_MAC_ADDRSTRLEN) {
return ZTS_ERR_ARG;
}
uint64_t mac = zts_service->getMACAddress(net_id);
OSUtils::ztsnprintf(
dst,
ZTS_MAC_ADDRSTRLEN,
"%x:%x:%x:%x:%x:%x",
(mac >> 48) & 0xFF,
(mac >> 32) & 0xFF,
(mac >> 24) & 0xFF,
(mac >> 16) & 0xFF,
(mac >> 8) & 0xFF,
(mac >> 0) & 0xFF);
return ZTS_ERR_OK;
}
int zts_net_get_broadcast(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkBroadcast(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkBroadcast(net_id);
}
int zts_net_get_mtu(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkMTU(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkMTU(net_id);
}
int zts_net_get_name(uint64_t net_id, char* dst, unsigned int len)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkName(net_id, dst, len);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkName(net_id, dst, len);
}
int zts_net_get_status(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkStatus(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkStatus(net_id);
}
int zts_net_get_type(uint64_t net_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkType(net_id);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNetworkType(net_id);
}
int zts_route_is_assigned(uint64_t net_id, unsigned int family)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->networkHasRoute(net_id, family);
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->networkHasRoute(net_id, family);
}
// Start a ZeroTier NodeService background thread
@@ -483,211 +483,211 @@ void* _runNodeService(void* arg)
#endif
{
#if defined(__APPLE__)
pthread_setname_np(ZTS_SERVICE_THREAD_NAME);
pthread_setname_np(ZTS_SERVICE_THREAD_NAME);
#endif
try {
zts_service->run();
// Begin shutdown
service_m.lock();
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
delete zts_service;
zts_service = (NodeService*)0;
service_m.unlock();
events_m.lock();
zts_util_delay(ZTS_CALLBACK_PROCESSING_INTERVAL * 2);
if (zts_events) {
zts_events->disable();
delete zts_events;
zts_events = (Events*)0;
}
events_m.unlock();
}
catch (...) {
}
try {
zts_service->run();
// Begin shutdown
service_m.lock();
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
delete zts_service;
zts_service = (NodeService*)0;
service_m.unlock();
events_m.lock();
zts_util_delay(ZTS_CALLBACK_PROCESSING_INTERVAL * 2);
if (zts_events) {
zts_events->disable();
delete zts_events;
zts_events = (Events*)0;
}
events_m.unlock();
}
catch (...) {
}
#ifndef __WINDOWS__
pthread_exit(0);
pthread_exit(0);
#endif
return NULL;
return NULL;
}
int zts_node_start()
{
ACQUIRE_SERVICE_OFFLINE();
// Start TCP/IP stack
_lwip_driver_init();
// Start callback thread
int res = ZTS_ERR_OK;
if (zts_events->hasCallback()) {
ACQUIRE_SERVICE_OFFLINE();
// Start TCP/IP stack
_lwip_driver_init();
// Start callback thread
int res = ZTS_ERR_OK;
if (zts_events->hasCallback()) {
#if defined(__WINDOWS__)
HANDLE callbackThread = CreateThread(NULL, 0, cbRun, NULL, 0, NULL);
// TODO: Check success
HANDLE callbackThread = CreateThread(NULL, 0, cbRun, NULL, 0, NULL);
// TODO: Check success
#else
pthread_t cbThread;
if ((res = pthread_create(&cbThread, NULL, cbRun, NULL)) != 0) {}
pthread_t cbThread;
if ((res = pthread_create(&cbThread, NULL, cbRun, NULL)) != 0) {}
#endif
#if defined(__linux__)
pthread_setname_np(cbThread, ZTS_EVENT_CALLBACK_THREAD_NAME);
pthread_setname_np(cbThread, ZTS_EVENT_CALLBACK_THREAD_NAME);
#endif
if (res != ZTS_ERR_OK) {
zts_events->clrState(ZTS_STATE_CALLBACKS_RUNNING);
zts_events->clrCallback();
}
zts_events->setState(ZTS_STATE_CALLBACKS_RUNNING);
}
// Start ZeroTier service
if (res != ZTS_ERR_OK) {
zts_events->clrState(ZTS_STATE_CALLBACKS_RUNNING);
zts_events->clrCallback();
}
zts_events->setState(ZTS_STATE_CALLBACKS_RUNNING);
}
// Start ZeroTier service
#if defined(__WINDOWS__)
WSAStartup(MAKEWORD(2, 2), &wsaData);
HANDLE serviceThread = CreateThread(NULL, 0, _runNodeService, (void*)NULL, 0, NULL);
// TODO: Check success
WSAStartup(MAKEWORD(2, 2), &wsaData);
HANDLE serviceThread = CreateThread(NULL, 0, _runNodeService, (void*)NULL, 0, NULL);
// TODO: Check success
#else
pthread_t service_thread;
if ((res = pthread_create(&service_thread, NULL, _runNodeService, (void*)NULL)) != 0) {}
pthread_t service_thread;
if ((res = pthread_create(&service_thread, NULL, _runNodeService, (void*)NULL)) != 0) {}
#endif
#if defined(__linux__)
pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME);
pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME);
#endif
if (res != ZTS_ERR_OK) {
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
}
zts_events->setState(ZTS_STATE_NODE_RUNNING);
return ZTS_ERR_OK;
if (res != ZTS_ERR_OK) {
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
}
zts_events->setState(ZTS_STATE_NODE_RUNNING);
return ZTS_ERR_OK;
}
int zts_node_is_online()
{
ACQUIRE_SERVICE(0);
return zts_service->nodeIsOnline();
ACQUIRE_SERVICE(0);
return zts_service->nodeIsOnline();
}
uint64_t zts_node_get_id()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNodeId();
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getNodeId();
}
int zts_node_get_port()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getPrimaryPort();
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
return zts_service->getPrimaryPort();
}
int zts_node_stop()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
#if defined(__WINDOWS__)
WSACleanup();
WSACleanup();
#endif
return ZTS_ERR_OK;
return ZTS_ERR_OK;
}
int zts_node_free()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_events->setState(ZTS_STATE_FREE_CALLED);
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_events->setState(ZTS_STATE_FREE_CALLED);
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
#if defined(__WINDOWS__)
WSACleanup();
WSACleanup();
#endif
_lwip_driver_shutdown();
return ZTS_ERR_OK;
_lwip_driver_shutdown();
return ZTS_ERR_OK;
}
int zts_moon_orbit(uint64_t moon_world_id, uint64_t moon_seed)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->orbit(NULL, moon_world_id, moon_seed);
return ZTS_ERR_OK;
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->orbit(NULL, moon_world_id, moon_seed);
return ZTS_ERR_OK;
}
int zts_moon_deorbit(uint64_t moon_world_id)
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->deorbit(NULL, moon_world_id);
return ZTS_ERR_OK;
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_service->deorbit(NULL, moon_world_id);
return ZTS_ERR_OK;
}
int zts_stats_get_all(zts_stats_counter_t* dst)
{
if (! dst) {
return ZTS_ERR_ARG;
}
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! dst) {
return ZTS_ERR_ARG;
}
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
#if LWIP_STATS
extern struct stats_ lwip_stats;
extern struct stats_ lwip_stats;
#define lws lwip_stats
/* Here we summarize lwIP's statistics for simplicity at the expense of specificity */
/* Here we summarize lwIP's statistics for simplicity at the expense of specificity */
// link
dst->link_tx = lws.link.xmit;
dst->link_rx = lws.link.recv;
dst->link_drop = lws.link.drop;
dst->link_err = lws.link.chkerr + lws.link.lenerr + lws.link.memerr + lws.link.rterr + lws.link.proterr
+ lws.link.opterr + lws.link.err;
// etharp
dst->etharp_tx = lws.etharp.xmit;
dst->etharp_rx = lws.etharp.recv;
dst->etharp_drop = lws.etharp.drop;
dst->etharp_err = lws.etharp.chkerr + lws.etharp.lenerr + lws.etharp.memerr + lws.etharp.rterr + lws.etharp.proterr
+ lws.etharp.opterr + lws.etharp.err;
// ip4
dst->ip4_tx = lws.ip.xmit;
dst->ip4_rx = lws.ip.recv;
dst->ip4_drop = lws.ip.drop;
dst->ip4_err = lws.ip.chkerr + lws.ip.lenerr + lws.ip.memerr + lws.ip.rterr + lws.ip.proterr + lws.ip.opterr
+ lws.ip.err + lws.ip_frag.chkerr + lws.ip_frag.lenerr + lws.ip_frag.memerr + lws.ip_frag.rterr
+ lws.ip_frag.proterr + lws.ip_frag.opterr + lws.ip_frag.err;
// ip6
dst->ip6_tx = lws.ip6.xmit;
dst->ip6_rx = lws.ip6.recv;
dst->ip6_drop = lws.ip6.drop;
dst->ip6_err = lws.ip6.chkerr + lws.ip6.lenerr + lws.ip6.memerr + lws.ip6.rterr + lws.ip6.proterr + lws.ip6.opterr
+ lws.ip6.err + lws.ip6_frag.chkerr + lws.ip6_frag.lenerr + lws.ip6_frag.memerr + lws.ip6_frag.rterr
+ lws.ip6_frag.proterr + lws.ip6_frag.opterr + lws.ip6_frag.err;
// link
dst->link_tx = lws.link.xmit;
dst->link_rx = lws.link.recv;
dst->link_drop = lws.link.drop;
dst->link_err = lws.link.chkerr + lws.link.lenerr + lws.link.memerr + lws.link.rterr + lws.link.proterr
+ lws.link.opterr + lws.link.err;
// etharp
dst->etharp_tx = lws.etharp.xmit;
dst->etharp_rx = lws.etharp.recv;
dst->etharp_drop = lws.etharp.drop;
dst->etharp_err = lws.etharp.chkerr + lws.etharp.lenerr + lws.etharp.memerr + lws.etharp.rterr + lws.etharp.proterr
+ lws.etharp.opterr + lws.etharp.err;
// ip4
dst->ip4_tx = lws.ip.xmit;
dst->ip4_rx = lws.ip.recv;
dst->ip4_drop = lws.ip.drop;
dst->ip4_err = lws.ip.chkerr + lws.ip.lenerr + lws.ip.memerr + lws.ip.rterr + lws.ip.proterr + lws.ip.opterr
+ lws.ip.err + lws.ip_frag.chkerr + lws.ip_frag.lenerr + lws.ip_frag.memerr + lws.ip_frag.rterr
+ lws.ip_frag.proterr + lws.ip_frag.opterr + lws.ip_frag.err;
// ip6
dst->ip6_tx = lws.ip6.xmit;
dst->ip6_rx = lws.ip6.recv;
dst->ip6_drop = lws.ip6.drop;
dst->ip6_err = lws.ip6.chkerr + lws.ip6.lenerr + lws.ip6.memerr + lws.ip6.rterr + lws.ip6.proterr + lws.ip6.opterr
+ lws.ip6.err + lws.ip6_frag.chkerr + lws.ip6_frag.lenerr + lws.ip6_frag.memerr + lws.ip6_frag.rterr
+ lws.ip6_frag.proterr + lws.ip6_frag.opterr + lws.ip6_frag.err;
// icmp4
dst->icmp4_tx = lws.icmp.xmit;
dst->icmp4_rx = lws.icmp.recv;
dst->icmp4_drop = lws.icmp.drop;
dst->icmp4_err = lws.icmp.chkerr + lws.icmp.lenerr + lws.icmp.memerr + lws.icmp.rterr + lws.icmp.proterr
+ lws.icmp.opterr + lws.icmp.err;
// icmp6
dst->icmp6_tx = lws.icmp6.xmit;
dst->icmp6_rx = lws.icmp6.recv;
dst->icmp6_drop = lws.icmp6.drop;
dst->icmp6_err = lws.icmp6.chkerr + lws.icmp6.lenerr + lws.icmp6.memerr + lws.icmp6.rterr + lws.icmp6.proterr
+ lws.icmp6.opterr + lws.icmp6.err;
// udp
dst->udp_tx = lws.udp.xmit;
dst->udp_rx = lws.udp.recv;
dst->udp_drop = lws.udp.drop;
dst->udp_err = lws.udp.chkerr + lws.udp.lenerr + lws.udp.memerr + lws.udp.rterr + lws.udp.proterr + lws.udp.opterr
+ lws.udp.err;
// tcp
dst->tcp_tx = lws.tcp.xmit;
dst->tcp_rx = lws.tcp.recv;
dst->tcp_drop = lws.tcp.drop;
dst->tcp_err = lws.tcp.chkerr + lws.tcp.lenerr + lws.tcp.memerr + lws.tcp.rterr + lws.tcp.proterr + lws.tcp.opterr
+ lws.tcp.err;
// nd6
dst->nd6_tx = lws.nd6.xmit;
dst->nd6_rx = lws.nd6.recv;
dst->nd6_drop = lws.nd6.drop;
dst->nd6_err = lws.nd6.chkerr + lws.nd6.lenerr + lws.nd6.memerr + lws.nd6.rterr + lws.nd6.proterr + lws.nd6.opterr
+ lws.nd6.err;
// icmp4
dst->icmp4_tx = lws.icmp.xmit;
dst->icmp4_rx = lws.icmp.recv;
dst->icmp4_drop = lws.icmp.drop;
dst->icmp4_err = lws.icmp.chkerr + lws.icmp.lenerr + lws.icmp.memerr + lws.icmp.rterr + lws.icmp.proterr
+ lws.icmp.opterr + lws.icmp.err;
// icmp6
dst->icmp6_tx = lws.icmp6.xmit;
dst->icmp6_rx = lws.icmp6.recv;
dst->icmp6_drop = lws.icmp6.drop;
dst->icmp6_err = lws.icmp6.chkerr + lws.icmp6.lenerr + lws.icmp6.memerr + lws.icmp6.rterr + lws.icmp6.proterr
+ lws.icmp6.opterr + lws.icmp6.err;
// udp
dst->udp_tx = lws.udp.xmit;
dst->udp_rx = lws.udp.recv;
dst->udp_drop = lws.udp.drop;
dst->udp_err = lws.udp.chkerr + lws.udp.lenerr + lws.udp.memerr + lws.udp.rterr + lws.udp.proterr + lws.udp.opterr
+ lws.udp.err;
// tcp
dst->tcp_tx = lws.tcp.xmit;
dst->tcp_rx = lws.tcp.recv;
dst->tcp_drop = lws.tcp.drop;
dst->tcp_err = lws.tcp.chkerr + lws.tcp.lenerr + lws.tcp.memerr + lws.tcp.rterr + lws.tcp.proterr + lws.tcp.opterr
+ lws.tcp.err;
// nd6
dst->nd6_tx = lws.nd6.xmit;
dst->nd6_rx = lws.nd6.recv;
dst->nd6_drop = lws.nd6.drop;
dst->nd6_err = lws.nd6.chkerr + lws.nd6.lenerr + lws.nd6.memerr + lws.nd6.rterr + lws.nd6.proterr + lws.nd6.opterr
+ lws.nd6.err;
// TODO: Add mem and sys stats
// TODO: Add mem and sys stats
return ZTS_ERR_OK;
return ZTS_ERR_OK;
#else
return ZTS_ERR_NO_RESULT;
return ZTS_ERR_NO_RESULT;
#endif
#undef lws
}

View File

@@ -62,20 +62,20 @@
#if defined(LIBZT_DEBUG)
#if defined(__ANDROID__)
#define DEBUG_INFO(fmt, args...) \
((void)__android_log_print( \
ANDROID_LOG_VERBOSE, \
ZT_LOG_TAG, \
"%17s:%5d:%20s: " fmt "\n", \
ZT_FILENAME, \
__LINE__, \
__FUNCTION__, \
##args))
((void)__android_log_print( \
ANDROID_LOG_VERBOSE, \
ZT_LOG_TAG, \
"%17s:%5d:%20s: " fmt "\n", \
ZT_FILENAME, \
__LINE__, \
__FUNCTION__, \
##args))
#elif defined(_WIN32)
#define DEBUG_INFO(fmt, ...) \
fprintf(stderr, ZT_WHT "%17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
fprintf(stderr, ZT_WHT "%17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define DEBUG_INFO(fmt, args...) \
fprintf(stderr, ZT_WHT "%17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
fprintf(stderr, ZT_WHT "%17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
#else // !LIBZT_DEBUG
#if defined(_WIN32)

View File

@@ -75,218 +75,218 @@ moodycamel::ConcurrentQueue<zts_event_msg_t*> _callbackMsgQueue;
void Events::run()
{
while (getState(ZTS_STATE_CALLBACKS_RUNNING) || _callbackMsgQueue.size_approx() > 0) {
zts_event_msg_t* msg;
size_t sz = _callbackMsgQueue.size_approx();
for (size_t j = 0; j < sz; j++) {
if (_callbackMsgQueue.try_dequeue(msg)) {
events_m.lock();
sendToUser(msg);
events_m.unlock();
}
}
zts_util_delay(ZTS_CALLBACK_PROCESSING_INTERVAL);
}
while (getState(ZTS_STATE_CALLBACKS_RUNNING) || _callbackMsgQueue.size_approx() > 0) {
zts_event_msg_t* msg;
size_t sz = _callbackMsgQueue.size_approx();
for (size_t j = 0; j < sz; j++) {
if (_callbackMsgQueue.try_dequeue(msg)) {
events_m.lock();
sendToUser(msg);
events_m.unlock();
}
}
zts_util_delay(ZTS_CALLBACK_PROCESSING_INTERVAL);
}
}
void Events::enqueue(unsigned int event_code, const void* arg, int len)
{
if (! _enabled) {
return;
}
zts_event_msg_t* msg = new zts_event_msg_t();
msg->event_code = event_code;
if (! _enabled) {
return;
}
zts_event_msg_t* msg = new zts_event_msg_t();
msg->event_code = event_code;
if (ZTS_NODE_EVENT(event_code)) {
msg->node = (zts_node_info_t*)arg;
msg->len = sizeof(zts_node_info_t);
}
if (ZTS_NETWORK_EVENT(event_code)) {
msg->network = (zts_net_info_t*)arg;
msg->len = sizeof(zts_net_info_t);
}
if (ZTS_STACK_EVENT(event_code)) {
/* nothing to convey to user */
}
if (ZTS_NETIF_EVENT(event_code)) {
msg->netif = (zts_netif_info_t*)arg;
msg->len = sizeof(zts_netif_info_t);
}
if (ZTS_ROUTE_EVENT(event_code)) {
msg->route = (zts_route_info_t*)arg;
msg->len = sizeof(zts_route_info_t);
}
if (ZTS_PEER_EVENT(event_code)) {
msg->peer = (zts_peer_info_t*)arg;
msg->len = sizeof(zts_peer_info_t);
}
if (ZTS_ADDR_EVENT(event_code)) {
msg->addr = (zts_addr_info_t*)arg;
msg->len = sizeof(zts_addr_info_t);
}
if (ZTS_STORE_EVENT(event_code)) {
msg->cache = (void*)arg;
msg->len = len;
}
if (msg && _callbackMsgQueue.size_approx() > 1024) {
/* Rate-limit number of events. This value should only grow if the
user application isn't returning from the event handler in a timely manner.
For most applications it should hover around 1 to 2 */
destroy(msg);
}
else {
_callbackMsgQueue.enqueue(msg);
}
if (ZTS_NODE_EVENT(event_code)) {
msg->node = (zts_node_info_t*)arg;
msg->len = sizeof(zts_node_info_t);
}
if (ZTS_NETWORK_EVENT(event_code)) {
msg->network = (zts_net_info_t*)arg;
msg->len = sizeof(zts_net_info_t);
}
if (ZTS_STACK_EVENT(event_code)) {
/* nothing to convey to user */
}
if (ZTS_NETIF_EVENT(event_code)) {
msg->netif = (zts_netif_info_t*)arg;
msg->len = sizeof(zts_netif_info_t);
}
if (ZTS_ROUTE_EVENT(event_code)) {
msg->route = (zts_route_info_t*)arg;
msg->len = sizeof(zts_route_info_t);
}
if (ZTS_PEER_EVENT(event_code)) {
msg->peer = (zts_peer_info_t*)arg;
msg->len = sizeof(zts_peer_info_t);
}
if (ZTS_ADDR_EVENT(event_code)) {
msg->addr = (zts_addr_info_t*)arg;
msg->len = sizeof(zts_addr_info_t);
}
if (ZTS_STORE_EVENT(event_code)) {
msg->cache = (void*)arg;
msg->len = len;
}
if (msg && _callbackMsgQueue.size_approx() > 1024) {
/* Rate-limit number of events. This value should only grow if the
user application isn't returning from the event handler in a timely manner.
For most applications it should hover around 1 to 2 */
destroy(msg);
}
else {
_callbackMsgQueue.enqueue(msg);
}
}
void Events::destroy(zts_event_msg_t* msg)
{
if (! msg) {
return;
}
if (msg->node) {
delete msg->node;
}
if (msg->network) {
delete msg->network;
}
if (msg->netif) {
delete msg->netif;
}
if (msg->route) {
delete msg->route;
}
if (msg->peer) {
delete msg->peer;
}
if (msg->addr) {
delete msg->addr;
}
delete msg;
msg = NULL;
if (! msg) {
return;
}
if (msg->node) {
delete msg->node;
}
if (msg->network) {
delete msg->network;
}
if (msg->netif) {
delete msg->netif;
}
if (msg->route) {
delete msg->route;
}
if (msg->peer) {
delete msg->peer;
}
if (msg->addr) {
delete msg->addr;
}
delete msg;
msg = NULL;
}
void Events::sendToUser(zts_event_msg_t* msg)
{
bool bShouldStopCallbackThread = (msg->event_code == ZTS_EVENT_STACK_DOWN);
bool bShouldStopCallbackThread = (msg->event_code == ZTS_EVENT_STACK_DOWN);
#ifdef ZTS_ENABLE_PYTHON
PyGILState_STATE state = PyGILState_Ensure();
_userEventCallback->on_zerotier_event(msg);
PyGILState_Release(state);
PyGILState_STATE state = PyGILState_Ensure();
_userEventCallback->on_zerotier_event(msg);
PyGILState_Release(state);
#endif
#ifdef ZTS_ENABLE_JAVA
if (_userCallbackMethodRef) {
JNIEnv* env;
if (_userCallbackMethodRef) {
JNIEnv* env;
#if defined(__ANDROID__)
jint rs = jvm->AttachCurrentThread(&env, NULL);
jint rs = jvm->AttachCurrentThread(&env, NULL);
#else
jint rs = jvm->AttachCurrentThread((void**)&env, NULL);
jint rs = jvm->AttachCurrentThread((void**)&env, NULL);
#endif
uint64_t arg = 0;
uint64_t id = 0;
if (ZTS_NODE_EVENT(msg->event_code)) {
id = msg->node ? msg->node->address : 0;
}
if (ZTS_NETWORK_EVENT(msg->event_code)) {
id = msg->network ? msg->network->nwid : 0;
}
if (ZTS_PEER_EVENT(msg->event_code)) {
id = msg->peer ? msg->peer->address : 0;
}
env->CallVoidMethod(objRef, _userCallbackMethodRef, id, msg->event_code);
}
uint64_t arg = 0;
uint64_t id = 0;
if (ZTS_NODE_EVENT(msg->event_code)) {
id = msg->node ? msg->node->address : 0;
}
if (ZTS_NETWORK_EVENT(msg->event_code)) {
id = msg->network ? msg->network->nwid : 0;
}
if (ZTS_PEER_EVENT(msg->event_code)) {
id = msg->peer ? msg->peer->address : 0;
}
env->CallVoidMethod(objRef, _userCallbackMethodRef, id, msg->event_code);
}
#endif // ZTS_ENABLE_JAVA
#ifdef ZTS_ENABLE_PINVOKE
if (_userEventCallback) {
_userEventCallback(msg);
}
if (_userEventCallback) {
_userEventCallback(msg);
}
#endif
#ifdef ZTS_C_API_ONLY
if (_userEventCallback) {
_userEventCallback(msg);
}
if (_userEventCallback) {
_userEventCallback(msg);
}
#endif
destroy(msg);
if (bShouldStopCallbackThread) {
/* Ensure last possible callback ZTS_EVENT_STACK_DOWN is
delivered before callback thread is finally stopped. */
clrState(ZTS_STATE_CALLBACKS_RUNNING);
}
destroy(msg);
if (bShouldStopCallbackThread) {
/* Ensure last possible callback ZTS_EVENT_STACK_DOWN is
delivered before callback thread is finally stopped. */
clrState(ZTS_STATE_CALLBACKS_RUNNING);
}
}
bool Events::hasCallback()
{
events_m.lock();
bool retval = false;
events_m.lock();
bool retval = false;
#ifdef ZTS_ENABLE_JAVA
retval = (jvm && objRef && _userCallbackMethodRef);
retval = (jvm && objRef && _userCallbackMethodRef);
#else
retval = _userEventCallback;
retval = _userEventCallback;
#endif
events_m.unlock();
return retval;
events_m.unlock();
return retval;
}
void Events::clrCallback()
{
events_m.lock();
events_m.lock();
#ifdef ZTS_ENABLE_JAVA
objRef = NULL;
_userCallbackMethodRef = NULL;
objRef = NULL;
_userCallbackMethodRef = NULL;
#else
_userEventCallback = NULL;
_userEventCallback = NULL;
#endif
events_m.unlock();
events_m.unlock();
}
int Events::canPerformServiceOperation()
{
return zts_service && zts_service->isRunning() && ! getState(ZTS_STATE_FREE_CALLED);
return zts_service && zts_service->isRunning() && ! getState(ZTS_STATE_FREE_CALLED);
}
void Events::setState(uint8_t newFlags)
{
if ((newFlags ^ service_state) & ZTS_STATE_NET_SERVICE_RUNNING) {
return; // No effect. Not allowed to set this flag manually
}
SET_FLAGS(newFlags);
if (GET_FLAGS(ZTS_STATE_NODE_RUNNING) && GET_FLAGS(ZTS_STATE_STACK_RUNNING)
&& ! (GET_FLAGS(ZTS_STATE_FREE_CALLED))) {
SET_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
else {
CLR_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
if ((newFlags ^ service_state) & ZTS_STATE_NET_SERVICE_RUNNING) {
return; // No effect. Not allowed to set this flag manually
}
SET_FLAGS(newFlags);
if (GET_FLAGS(ZTS_STATE_NODE_RUNNING) && GET_FLAGS(ZTS_STATE_STACK_RUNNING)
&& ! (GET_FLAGS(ZTS_STATE_FREE_CALLED))) {
SET_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
else {
CLR_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
}
void Events::clrState(uint8_t newFlags)
{
if (newFlags & ZTS_STATE_NET_SERVICE_RUNNING) {
return; // No effect. Not allowed to set this flag manually
}
CLR_FLAGS(newFlags);
if (GET_FLAGS(ZTS_STATE_NODE_RUNNING) && GET_FLAGS(ZTS_STATE_STACK_RUNNING)
&& ! (GET_FLAGS(ZTS_STATE_FREE_CALLED))) {
SET_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
else {
CLR_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
if (newFlags & ZTS_STATE_NET_SERVICE_RUNNING) {
return; // No effect. Not allowed to set this flag manually
}
CLR_FLAGS(newFlags);
if (GET_FLAGS(ZTS_STATE_NODE_RUNNING) && GET_FLAGS(ZTS_STATE_STACK_RUNNING)
&& ! (GET_FLAGS(ZTS_STATE_FREE_CALLED))) {
SET_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
else {
CLR_FLAGS(ZTS_STATE_NET_SERVICE_RUNNING);
}
}
bool Events::getState(uint8_t testFlags)
{
return testFlags & service_state;
return testFlags & service_state;
}
void Events::enable()
{
_enabled = true;
_enabled = true;
}
void Events::disable()
{
_enabled = false;
_enabled = false;
}
} // namespace ZeroTier

View File

@@ -34,33 +34,33 @@
// Lock service and check that it is running
#define ACQUIRE_SERVICE(x) \
Mutex::Lock _ls(service_m); \
if (! zts_service || ! zts_service->isRunning()) { \
return x; \
}
Mutex::Lock _ls(service_m); \
if (! zts_service || ! zts_service->isRunning()) { \
return x; \
}
// Lock service and check that it is not currently running
#define ACQUIRE_SERVICE_OFFLINE() \
Mutex::Lock _ls(service_m); \
if (zts_service && zts_service->isRunning()) { \
return ZTS_ERR_SERVICE; \
} \
if (! zts_service) { \
init_subsystems(); \
}
Mutex::Lock _ls(service_m); \
if (zts_service && zts_service->isRunning()) { \
return ZTS_ERR_SERVICE; \
} \
if (! zts_service) { \
init_subsystems(); \
}
// Unlock service
#define RELEASE_SERVICE() service_m.unlock();
// Lock service, ensure node is online
#define ACQUIRE_ONLINE_NODE() \
ACQUIRE_SERVICE() if (! zts_service->nodeIsOnline()) \
{ \
return ZTS_ERR_SERVICE; \
}
ACQUIRE_SERVICE() if (! zts_service->nodeIsOnline()) \
{ \
return ZTS_ERR_SERVICE; \
}
// Lock event callback
#define ACQUIRE_EVENTS() \
Mutex::Lock _lc(events_m); \
if (! zts_events) { \
return ZTS_ERR_SERVICE; \
}
Mutex::Lock _lc(events_m); \
if (! zts_events) { \
return ZTS_ERR_SERVICE; \
}
namespace ZeroTier {
@@ -83,8 +83,8 @@ extern int last_state_check;
inline int transport_ok()
{
last_state_check = service_state & ZTS_STATE_NET_SERVICE_RUNNING;
return last_state_check;
last_state_check = service_state & ZTS_STATE_NET_SERVICE_RUNNING;
return last_state_check;
}
/**
@@ -93,72 +93,72 @@ inline int transport_ok()
#define ZTS_CALLBACK_PROCESSING_INTERVAL 25
class Events {
bool _enabled;
bool _enabled;
public:
Events() : _enabled(false)
{
}
Events() : _enabled(false)
{
}
/**
* Perform one iteration of callback processing
*/
void run();
/**
* Perform one iteration of callback processing
*/
void run();
/**
* Enable callback event processing
*/
void enable();
/**
* Enable callback event processing
*/
void enable();
/**
* Disable callback event processing
*/
void disable();
/**
* Disable callback event processing
*/
void disable();
/**
* Enqueue an event to be sent to the user application
*/
void enqueue(unsigned int event_code, const void* arg, int len = 0);
/**
* Enqueue an event to be sent to the user application
*/
void enqueue(unsigned int event_code, const void* arg, int len = 0);
/**
* Send callback message to user application
*/
void sendToUser(zts_event_msg_t* msg);
/**
* Send callback message to user application
*/
void sendToUser(zts_event_msg_t* msg);
/**
* Free memory occupied by callback structures
*/
void destroy(zts_event_msg_t* msg);
/**
* Free memory occupied by callback structures
*/
void destroy(zts_event_msg_t* msg);
/**
* Return whether a callback method has been set
*/
bool hasCallback();
/**
* Return whether a callback method has been set
*/
bool hasCallback();
/**
* Clear pointer reference to user-provided callback function
*/
void clrCallback();
/**
* Clear pointer reference to user-provided callback function
*/
void clrCallback();
/**
* Return whether service operation can be performed at this time
*/
int canPerformServiceOperation();
/**
* Return whether service operation can be performed at this time
*/
int canPerformServiceOperation();
/**
* Set internal state flags
*/
void setState(uint8_t newFlags);
/**
* Set internal state flags
*/
void setState(uint8_t newFlags);
/**
* Clear internal state flags
*/
void clrState(uint8_t newFlags);
/**
* Clear internal state flags
*/
void clrState(uint8_t newFlags);
/**
* Get internal state flags
*/
bool getState(uint8_t testFlags);
/**
* Get internal state flags
*/
bool getState(uint8_t testFlags);
};
} // namespace ZeroTier

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -38,43 +38,43 @@
void _signal_handler(int signal)
{
/*
switch(signal)
{
case SIGINT:
fprintf(stderr, "SIGINT\n");
break;
case SIGABRT:
fprintf(stderr, "SIGABRT\n");
break;
case SIGILL:
fprintf(stderr, "SIGILL\n");
break;
case SIGSEGV:
fprintf(stderr, "SIGSEGV\n");
break;
case SIGFPE:
fprintf(stderr, "SIGFPE\n");
break;
case SIGTERM:
default:
fprintf(stderr, "SIGTERM\n");
break;
}
*/
exit(signal);
/*
switch(signal)
{
case SIGINT:
fprintf(stderr, "SIGINT\n");
break;
case SIGABRT:
fprintf(stderr, "SIGABRT\n");
break;
case SIGILL:
fprintf(stderr, "SIGILL\n");
break;
case SIGSEGV:
fprintf(stderr, "SIGSEGV\n");
break;
case SIGFPE:
fprintf(stderr, "SIGFPE\n");
break;
case SIGTERM:
default:
fprintf(stderr, "SIGTERM\n");
break;
}
*/
exit(signal);
}
void _install_signal_handlers()
{
signal(SIGINT, &_signal_handler);
/*
signal(SIGABRT, &_signal_handler);
signal(SIGFPE, &_signal_handler);
signal(SIGILL, &_signal_handler);
signal(SIGSEGV, &_signal_handler);
signal(SIGTERM, &_signal_handler);
*/
signal(SIGINT, &_signal_handler);
/*
signal(SIGABRT, &_signal_handler);
signal(SIGFPE, &_signal_handler);
signal(SIGILL, &_signal_handler);
signal(SIGSEGV, &_signal_handler);
signal(SIGTERM, &_signal_handler);
*/
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -46,32 +46,32 @@ extern "C" {
int zts_util_get_ip_family(const char* ipstr)
{
if (! ipstr) {
return ZTS_ERR_ARG;
}
int family = -1;
struct zts_sockaddr_in sa4;
if (zts_inet_pton(ZTS_AF_INET, ipstr, &(sa4.sin_addr)) == 1) {
family = ZTS_AF_INET;
}
struct zts_sockaddr_in6 sa6;
if (zts_inet_pton(ZTS_AF_INET6, ipstr, &(sa6.sin6_addr)) == 1) {
family = ZTS_AF_INET6;
}
return family;
if (! ipstr) {
return ZTS_ERR_ARG;
}
int family = -1;
struct zts_sockaddr_in sa4;
if (zts_inet_pton(ZTS_AF_INET, ipstr, &(sa4.sin_addr)) == 1) {
family = ZTS_AF_INET;
}
struct zts_sockaddr_in6 sa6;
if (zts_inet_pton(ZTS_AF_INET6, ipstr, &(sa6.sin6_addr)) == 1) {
family = ZTS_AF_INET6;
}
return family;
}
void zts_util_delay(unsigned long milliseconds)
{
#ifdef __WINDOWS__
Sleep(milliseconds);
Sleep(milliseconds);
#elif _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
#else
usleep(milliseconds * 1000);
usleep(milliseconds * 1000);
#endif
}
@@ -86,97 +86,97 @@ int zts_util_world_new(
uint64_t ts,
zts_world_t* world_spec)
{
if (! world_spec || ! prev_key || ! curr_key || ! prev_key_len || ! curr_key_len) {
return ZTS_ERR_ARG;
}
// Generate signing keys
std::string previous, current;
if ((! OSUtils::readFile("previous.c25519", previous)) || (! OSUtils::readFile("current.c25519", current))) {
C25519::Pair np(C25519::generate());
previous = std::string();
previous.append((const char*)np.pub.data, ZT_C25519_PUBLIC_KEY_LEN);
previous.append((const char*)np.priv.data, ZT_C25519_PRIVATE_KEY_LEN);
current = previous;
}
if ((previous.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))
|| (current.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))) {
// Previous.c25519 or current.c25519 empty or invalid
return ZTS_ERR_ARG;
}
C25519::Pair previousKP;
memcpy(previousKP.pub.data, previous.data(), ZT_C25519_PUBLIC_KEY_LEN);
memcpy(previousKP.priv.data, previous.data() + ZT_C25519_PUBLIC_KEY_LEN, ZT_C25519_PRIVATE_KEY_LEN);
C25519::Pair currentKP;
memcpy(currentKP.pub.data, current.data(), ZT_C25519_PUBLIC_KEY_LEN);
memcpy(currentKP.priv.data, current.data() + ZT_C25519_PUBLIC_KEY_LEN, ZT_C25519_PRIVATE_KEY_LEN);
if (! world_spec || ! prev_key || ! curr_key || ! prev_key_len || ! curr_key_len) {
return ZTS_ERR_ARG;
}
// Generate signing keys
std::string previous, current;
if ((! OSUtils::readFile("previous.c25519", previous)) || (! OSUtils::readFile("current.c25519", current))) {
C25519::Pair np(C25519::generate());
previous = std::string();
previous.append((const char*)np.pub.data, ZT_C25519_PUBLIC_KEY_LEN);
previous.append((const char*)np.priv.data, ZT_C25519_PRIVATE_KEY_LEN);
current = previous;
}
if ((previous.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))
|| (current.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))) {
// Previous.c25519 or current.c25519 empty or invalid
return ZTS_ERR_ARG;
}
C25519::Pair previousKP;
memcpy(previousKP.pub.data, previous.data(), ZT_C25519_PUBLIC_KEY_LEN);
memcpy(previousKP.priv.data, previous.data() + ZT_C25519_PUBLIC_KEY_LEN, ZT_C25519_PRIVATE_KEY_LEN);
C25519::Pair currentKP;
memcpy(currentKP.pub.data, current.data(), ZT_C25519_PUBLIC_KEY_LEN);
memcpy(currentKP.priv.data, current.data() + ZT_C25519_PUBLIC_KEY_LEN, ZT_C25519_PRIVATE_KEY_LEN);
// Set up world definition
std::vector<World::Root> roots;
for (int i = 0; i < ZTS_MAX_NUM_ROOTS; i++) {
if (! world_spec->public_id_str[i]) {
break;
}
if (strlen(world_spec->public_id_str[i])) {
// printf("id = %s\n", world_spec->public_id_str[i]);
roots.push_back(World::Root());
roots.back().identity = Identity(world_spec->public_id_str[i]);
for (int j = 0; j < ZTS_MAX_ENDPOINTS_PER_ROOT; j++) {
if (! world_spec->endpoint_ip_str[i][j]) {
break;
}
if (strlen(world_spec->endpoint_ip_str[i][j])) {
roots.back().stableEndpoints.push_back(InetAddress(world_spec->endpoint_ip_str[i][j]));
// printf(" ep = %s\n", world_spec->endpoint_ip_str[i][j]);
}
}
}
}
// Set up world definition
std::vector<World::Root> roots;
for (int i = 0; i < ZTS_MAX_NUM_ROOTS; i++) {
if (! world_spec->public_id_str[i]) {
break;
}
if (strlen(world_spec->public_id_str[i])) {
// printf("id = %s\n", world_spec->public_id_str[i]);
roots.push_back(World::Root());
roots.back().identity = Identity(world_spec->public_id_str[i]);
for (int j = 0; j < ZTS_MAX_ENDPOINTS_PER_ROOT; j++) {
if (! world_spec->endpoint_ip_str[i][j]) {
break;
}
if (strlen(world_spec->endpoint_ip_str[i][j])) {
roots.back().stableEndpoints.push_back(InetAddress(world_spec->endpoint_ip_str[i][j]));
// printf(" ep = %s\n", world_spec->endpoint_ip_str[i][j]);
}
}
}
}
// Generate
World nw = World::make(World::TYPE_PLANET, id, ts, currentKP.pub, roots, previousKP);
// Test
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> outtmp;
nw.serialize(outtmp, false);
World testw;
testw.deserialize(outtmp, 0);
if (testw != nw) {
// Serialization test failed
return ZTS_ERR_GENERAL;
}
// Write output
memcpy(world_out, (char*)outtmp.data(), outtmp.size());
*world_len = outtmp.size();
memcpy(prev_key, previous.data(), previous.length());
*prev_key_len = ZT_C25519_PRIVATE_KEY_LEN + ZT_C25519_PUBLIC_KEY_LEN;
memcpy(curr_key, current.data(), current.length());
*curr_key_len = ZT_C25519_PRIVATE_KEY_LEN + ZT_C25519_PUBLIC_KEY_LEN;
return ZTS_ERR_OK;
// Generate
World nw = World::make(World::TYPE_PLANET, id, ts, currentKP.pub, roots, previousKP);
// Test
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> outtmp;
nw.serialize(outtmp, false);
World testw;
testw.deserialize(outtmp, 0);
if (testw != nw) {
// Serialization test failed
return ZTS_ERR_GENERAL;
}
// Write output
memcpy(world_out, (char*)outtmp.data(), outtmp.size());
*world_len = outtmp.size();
memcpy(prev_key, previous.data(), previous.length());
*prev_key_len = ZT_C25519_PRIVATE_KEY_LEN + ZT_C25519_PUBLIC_KEY_LEN;
memcpy(curr_key, current.data(), current.length());
*curr_key_len = ZT_C25519_PRIVATE_KEY_LEN + ZT_C25519_PUBLIC_KEY_LEN;
return ZTS_ERR_OK;
}
void native_ss_to_zts_ss(struct zts_sockaddr_storage* ss_out, const struct sockaddr_storage* ss_in)
{
if (ss_in->ss_family == AF_INET) {
struct sockaddr_in* s_in4 = (struct sockaddr_in*)ss_in;
struct zts_sockaddr_in* d_in4 = (struct zts_sockaddr_in*)ss_out;
if (ss_in->ss_family == AF_INET) {
struct sockaddr_in* s_in4 = (struct sockaddr_in*)ss_in;
struct zts_sockaddr_in* d_in4 = (struct zts_sockaddr_in*)ss_out;
#ifndef __WINDOWS__
d_in4->sin_len = 0; // s_in4->sin_len;
d_in4->sin_len = 0; // s_in4->sin_len;
#endif
d_in4->sin_family = ZTS_AF_INET;
d_in4->sin_port = s_in4->sin_port;
memcpy(&(d_in4->sin_addr), &(s_in4->sin_addr), sizeof(s_in4->sin_addr));
}
if (ss_in->ss_family == AF_INET6) {
struct sockaddr_in6* s_in6 = (struct sockaddr_in6*)ss_in;
struct zts_sockaddr_in6* d_in6 = (struct zts_sockaddr_in6*)ss_out;
d_in4->sin_family = ZTS_AF_INET;
d_in4->sin_port = s_in4->sin_port;
memcpy(&(d_in4->sin_addr), &(s_in4->sin_addr), sizeof(s_in4->sin_addr));
}
if (ss_in->ss_family == AF_INET6) {
struct sockaddr_in6* s_in6 = (struct sockaddr_in6*)ss_in;
struct zts_sockaddr_in6* d_in6 = (struct zts_sockaddr_in6*)ss_out;
#ifndef __WINDOWS__
d_in6->sin6_len = 0; // s_in6->sin6_len;
d_in6->sin6_len = 0; // s_in6->sin6_len;
#endif
d_in6->sin6_family = ZTS_AF_INET6;
d_in6->sin6_port = s_in6->sin6_port;
d_in6->sin6_flowinfo = s_in6->sin6_flowinfo;
memcpy(&(d_in6->sin6_addr), &(s_in6->sin6_addr), sizeof(s_in6->sin6_addr));
d_in6->sin6_scope_id = s_in6->sin6_scope_id;
}
d_in6->sin6_family = ZTS_AF_INET6;
d_in6->sin6_port = s_in6->sin6_port;
d_in6->sin6_flowinfo = s_in6->sin6_flowinfo;
memcpy(&(d_in6->sin6_addr), &(s_in6->sin6_addr), sizeof(s_in6->sin6_addr));
d_in6->sin6_scope_id = s_in6->sin6_scope_id;
}
}
#ifdef __cplusplus

View File

@@ -84,191 +84,191 @@ VirtualTap::VirtualTap(
, _unixListenSocket((PhySocket*)0)
, _phy(this, false, true)
{
OSUtils::ztsnprintf(vtap_full_name, VTAP_NAME_LEN, "libzt-vtap-%llx", _net_id);
OSUtils::ztsnprintf(vtap_full_name, VTAP_NAME_LEN, "libzt-vtap-%llx", _net_id);
#ifndef __WINDOWS__
::pipe(_shutdownSignalPipe);
::pipe(_shutdownSignalPipe);
#endif
// Start virtual tap thread and stack I/O loops
_thread = Thread::start(this);
// Start virtual tap thread and stack I/O loops
_thread = Thread::start(this);
}
VirtualTap::~VirtualTap()
{
_run = false;
_run = false;
#ifndef __WINDOWS__
::write(_shutdownSignalPipe[1], "\0", 1);
::write(_shutdownSignalPipe[1], "\0", 1);
#endif
_phy.whack();
_lwip_remove_netif(netif4);
netif4 = NULL;
_lwip_remove_netif(netif6);
netif6 = NULL;
Thread::join(_thread);
_phy.whack();
_lwip_remove_netif(netif4);
netif4 = NULL;
_lwip_remove_netif(netif6);
netif6 = NULL;
Thread::join(_thread);
#ifndef __WINDOWS__
::close(_shutdownSignalPipe[0]);
::close(_shutdownSignalPipe[1]);
::close(_shutdownSignalPipe[0]);
::close(_shutdownSignalPipe[1]);
#endif
}
void VirtualTap::lastConfigUpdate(uint64_t lastConfigUpdateTime)
{
_lastConfigUpdateTime = lastConfigUpdateTime;
_lastConfigUpdateTime = lastConfigUpdateTime;
}
void VirtualTap::setEnabled(bool en)
{
_enabled = en;
_enabled = en;
}
bool VirtualTap::enabled() const
{
return _enabled;
return _enabled;
}
void VirtualTap::setUserEventSystem(Events* events)
{
_events = events;
_events = events;
}
bool VirtualTap::hasIpv4Addr()
{
Mutex::Lock _l(_ips_m);
std::vector<InetAddress>::iterator it(_ips.begin());
while (it != _ips.end()) {
if ((*it).isV4()) {
return true;
}
++it;
}
return false;
Mutex::Lock _l(_ips_m);
std::vector<InetAddress>::iterator it(_ips.begin());
while (it != _ips.end()) {
if ((*it).isV4()) {
return true;
}
++it;
}
return false;
}
bool VirtualTap::hasIpv6Addr()
{
Mutex::Lock _l(_ips_m);
std::vector<InetAddress>::iterator it(_ips.begin());
while (it != _ips.end()) {
if ((*it).isV6()) {
return true;
}
++it;
}
return false;
Mutex::Lock _l(_ips_m);
std::vector<InetAddress>::iterator it(_ips.begin());
while (it != _ips.end()) {
if ((*it).isV6()) {
return true;
}
++it;
}
return false;
}
bool VirtualTap::addIp(const InetAddress& ip)
{
// TODO: Rewrite to allow for more addresses
char ipbuf[128] = { 0 };
/* Limit address assignments to one per type.
This limitation can be removed if some changes
are made in the netif driver. */
if (ip.isV4() && hasIpv4Addr()) {
ip.toString(ipbuf);
// DEBUG_INFO("failed to add IP (%s), only one per type per netif
// allowed\n", ipbuf);
return false;
}
if (ip.isV6() && hasIpv6Addr()) {
ip.toString(ipbuf);
// DEBUG_INFO("failed to add IP (%s), only one per type per netif
// allowed\n", ipbuf);
return false;
}
// TODO: Rewrite to allow for more addresses
char ipbuf[128] = { 0 };
/* Limit address assignments to one per type.
This limitation can be removed if some changes
are made in the netif driver. */
if (ip.isV4() && hasIpv4Addr()) {
ip.toString(ipbuf);
// DEBUG_INFO("failed to add IP (%s), only one per type per netif
// allowed\n", ipbuf);
return false;
}
if (ip.isV6() && hasIpv6Addr()) {
ip.toString(ipbuf);
// DEBUG_INFO("failed to add IP (%s), only one per type per netif
// allowed\n", ipbuf);
return false;
}
Mutex::Lock _l(_ips_m);
if (_ips.size() >= ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
return false;
}
if (std::find(_ips.begin(), _ips.end(), ip) == _ips.end()) {
_lwip_init_interface((void*)this, ip);
_ips.push_back(ip);
std::sort(_ips.begin(), _ips.end());
}
return true;
Mutex::Lock _l(_ips_m);
if (_ips.size() >= ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
return false;
}
if (std::find(_ips.begin(), _ips.end(), ip) == _ips.end()) {
_lwip_init_interface((void*)this, ip);
_ips.push_back(ip);
std::sort(_ips.begin(), _ips.end());
}
return true;
}
bool VirtualTap::removeIp(const InetAddress& ip)
{
Mutex::Lock _l(_ips_m);
if (std::find(_ips.begin(), _ips.end(), ip) != _ips.end()) {
std::vector<InetAddress>::iterator i(std::find(_ips.begin(), _ips.end(), ip));
_lwip_remove_address_from_netif((void*)this, ip);
_ips.erase(i);
}
return true;
Mutex::Lock _l(_ips_m);
if (std::find(_ips.begin(), _ips.end(), ip) != _ips.end()) {
std::vector<InetAddress>::iterator i(std::find(_ips.begin(), _ips.end(), ip));
_lwip_remove_address_from_netif((void*)this, ip);
_ips.erase(i);
}
return true;
}
std::vector<InetAddress> VirtualTap::ips() const
{
Mutex::Lock _l(_ips_m);
return _ips;
Mutex::Lock _l(_ips_m);
return _ips;
}
void VirtualTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len)
{
if (len && _enabled) {
_lwip_eth_rx(this, from, to, etherType, data, len);
}
if (len && _enabled) {
_lwip_eth_rx(this, from, to, etherType, data, len);
}
}
void VirtualTap::scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed)
{
std::vector<MulticastGroup> newGroups;
Mutex::Lock _l(_multicastGroups_m);
// TODO: get multicast subscriptions
std::vector<InetAddress> allIps(ips());
for (std::vector<InetAddress>::iterator ip(allIps.begin()); ip != allIps.end(); ++ip)
newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip));
std::vector<MulticastGroup> newGroups;
Mutex::Lock _l(_multicastGroups_m);
// TODO: get multicast subscriptions
std::vector<InetAddress> allIps(ips());
for (std::vector<InetAddress>::iterator ip(allIps.begin()); ip != allIps.end(); ++ip)
newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip));
std::sort(newGroups.begin(), newGroups.end());
std::sort(newGroups.begin(), newGroups.end());
for (std::vector<MulticastGroup>::iterator m(newGroups.begin()); m != newGroups.end(); ++m) {
if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m))
added.push_back(*m);
}
for (std::vector<MulticastGroup>::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) {
if (! std::binary_search(newGroups.begin(), newGroups.end(), *m))
removed.push_back(*m);
}
_multicastGroups.swap(newGroups);
for (std::vector<MulticastGroup>::iterator m(newGroups.begin()); m != newGroups.end(); ++m) {
if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m))
added.push_back(*m);
}
for (std::vector<MulticastGroup>::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) {
if (! std::binary_search(newGroups.begin(), newGroups.end(), *m))
removed.push_back(*m);
}
_multicastGroups.swap(newGroups);
}
void VirtualTap::setMtu(unsigned int mtu)
{
_mtu = mtu;
_mtu = mtu;
}
void VirtualTap::threadMain() throw()
{
fd_set readfds, nullfds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_ZERO(&nullfds);
int nfds = (int)std::max(_shutdownSignalPipe[0], 0) + 1;
fd_set readfds, nullfds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_ZERO(&nullfds);
int nfds = (int)std::max(_shutdownSignalPipe[0], 0) + 1;
#if defined(__linux__)
pthread_setname_np(pthread_self(), vtap_full_name);
pthread_setname_np(pthread_self(), vtap_full_name);
#endif
#if defined(__APPLE__)
pthread_setname_np(vtap_full_name);
pthread_setname_np(vtap_full_name);
#endif
while (true) {
FD_SET(_shutdownSignalPipe[0], &readfds);
select(nfds, &readfds, &nullfds, &nullfds, &tv);
// writes to shutdown pipe terminate thread
if (FD_ISSET(_shutdownSignalPipe[0], &readfds)) {
break;
}
while (true) {
FD_SET(_shutdownSignalPipe[0], &readfds);
select(nfds, &readfds, &nullfds, &nullfds, &tv);
// writes to shutdown pipe terminate thread
if (FD_ISSET(_shutdownSignalPipe[0], &readfds)) {
break;
}
#if defined(__WINDOWS__)
Sleep(ZTS_TAP_THREAD_POLLING_INTERVAL);
Sleep(ZTS_TAP_THREAD_POLLING_INTERVAL);
#else
struct timespec sleepValue = { 0 };
sleepValue.tv_nsec = ZTS_TAP_THREAD_POLLING_INTERVAL * 500000;
nanosleep(&sleepValue, NULL);
struct timespec sleepValue = { 0 };
sleepValue.tv_nsec = ZTS_TAP_THREAD_POLLING_INTERVAL * 500000;
nanosleep(&sleepValue, NULL);
#endif
}
}
}
void VirtualTap::phyOnDatagram(
@@ -279,7 +279,7 @@ void VirtualTap::phyOnDatagram(
void* data,
unsigned long len)
{
// Intentionally empty
// Intentionally empty
}
void VirtualTap::phyOnTcpConnect(PhySocket* sock, void** uptr, bool success)
@@ -327,118 +327,118 @@ Mutex stackLock;
// Callback for when the TCPIP thread has been successfully started
static void _tcpip_init_done(void* arg)
{
sys_sem_t* sem;
sem = (sys_sem_t*)arg;
zts_events->setState(ZTS_STATE_STACK_RUNNING);
_has_started = true;
zts_events->enqueue(ZTS_EVENT_STACK_UP, NULL);
sys_sem_signal(sem);
sys_sem_t* sem;
sem = (sys_sem_t*)arg;
zts_events->setState(ZTS_STATE_STACK_RUNNING);
_has_started = true;
zts_events->enqueue(ZTS_EVENT_STACK_UP, NULL);
sys_sem_signal(sem);
}
static void _main_lwip_driver_loop(void* arg)
{
#if defined(__linux__)
pthread_setname_np(pthread_self(), ZTS_LWIP_THREAD_NAME);
pthread_setname_np(pthread_self(), ZTS_LWIP_THREAD_NAME);
#endif
#if defined(__APPLE__)
pthread_setname_np(ZTS_LWIP_THREAD_NAME);
pthread_setname_np(ZTS_LWIP_THREAD_NAME);
#endif
sys_sem_t sem;
LWIP_UNUSED_ARG(arg);
if (sys_sem_new(&sem, 0) != ERR_OK) {
// DEBUG_ERROR("failed to create semaphore");
}
tcpip_init(_tcpip_init_done, &sem);
sys_sem_wait(&sem);
// Main loop
while (zts_events->getState(ZTS_STATE_STACK_RUNNING)) {
zts_util_delay(LWIP_DRIVER_LOOP_INTERVAL);
}
_has_exited = true;
zts_events->enqueue(ZTS_EVENT_STACK_DOWN, NULL);
sys_sem_t sem;
LWIP_UNUSED_ARG(arg);
if (sys_sem_new(&sem, 0) != ERR_OK) {
// DEBUG_ERROR("failed to create semaphore");
}
tcpip_init(_tcpip_init_done, &sem);
sys_sem_wait(&sem);
// Main loop
while (zts_events->getState(ZTS_STATE_STACK_RUNNING)) {
zts_util_delay(LWIP_DRIVER_LOOP_INTERVAL);
}
_has_exited = true;
zts_events->enqueue(ZTS_EVENT_STACK_DOWN, NULL);
}
bool _lwip_is_up()
{
Mutex::Lock _l(stackLock);
return zts_events->getState(ZTS_STATE_STACK_RUNNING);
Mutex::Lock _l(stackLock);
return zts_events->getState(ZTS_STATE_STACK_RUNNING);
}
void _lwip_driver_init()
{
if (_lwip_is_up()) {
return;
}
if (_has_exited) {
return;
}
Mutex::Lock _l(stackLock);
if (_lwip_is_up()) {
return;
}
if (_has_exited) {
return;
}
Mutex::Lock _l(stackLock);
#if defined(__WINDOWS__)
sys_init(); // Required for win32 init of critical sections
sys_init(); // Required for win32 init of critical sections
#endif
sys_thread_new(ZTS_LWIP_THREAD_NAME, _main_lwip_driver_loop, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
sys_thread_new(ZTS_LWIP_THREAD_NAME, _main_lwip_driver_loop, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
}
void _lwip_driver_shutdown()
{
if (_has_exited) {
return;
}
Mutex::Lock _l(stackLock);
// Set flag to stop sending frames into the core
zts_events->clrState(ZTS_STATE_STACK_RUNNING);
// Wait until the main lwIP thread has exited
if (_has_started) {
while (! _has_exited) {
zts_util_delay(LWIP_DRIVER_LOOP_INTERVAL);
}
}
if (_has_exited) {
return;
}
Mutex::Lock _l(stackLock);
// Set flag to stop sending frames into the core
zts_events->clrState(ZTS_STATE_STACK_RUNNING);
// Wait until the main lwIP thread has exited
if (_has_started) {
while (! _has_exited) {
zts_util_delay(LWIP_DRIVER_LOOP_INTERVAL);
}
}
}
void _lwip_remove_netif(void* netif)
{
if (! netif) {
return;
}
struct netif* n = (struct netif*)netif;
LOCK_TCPIP_CORE();
netif_remove(n);
netif_set_down(n);
netif_set_link_down(n);
UNLOCK_TCPIP_CORE();
if (! netif) {
return;
}
struct netif* n = (struct netif*)netif;
LOCK_TCPIP_CORE();
netif_remove(n);
netif_set_down(n);
netif_set_link_down(n);
UNLOCK_TCPIP_CORE();
}
err_t _lwip_eth_tx(struct netif* n, struct pbuf* p)
{
if (! n) {
return ERR_IF;
}
struct pbuf* q;
char buf[ZT_MAX_MTU + 32] = { 0 };
char* bufptr;
int totalLength = 0;
if (! n) {
return ERR_IF;
}
struct pbuf* q;
char buf[ZT_MAX_MTU + 32] = { 0 };
char* bufptr;
int totalLength = 0;
VirtualTap* tap = (VirtualTap*)n->state;
bufptr = buf;
for (q = p; q != NULL; q = q->next) {
memcpy(bufptr, q->payload, q->len);
bufptr += q->len;
totalLength += q->len;
}
struct eth_hdr* ethhdr;
ethhdr = (struct eth_hdr*)buf;
VirtualTap* tap = (VirtualTap*)n->state;
bufptr = buf;
for (q = p; q != NULL; q = q->next) {
memcpy(bufptr, q->payload, q->len);
bufptr += q->len;
totalLength += q->len;
}
struct eth_hdr* ethhdr;
ethhdr = (struct eth_hdr*)buf;
MAC src_mac;
MAC dest_mac;
src_mac.setTo(ethhdr->src.addr, 6);
dest_mac.setTo(ethhdr->dest.addr, 6);
MAC src_mac;
MAC dest_mac;
src_mac.setTo(ethhdr->src.addr, 6);
dest_mac.setTo(ethhdr->dest.addr, 6);
char* data = buf + sizeof(struct eth_hdr);
int len = totalLength - sizeof(struct eth_hdr);
int proto = Utils::ntoh((uint16_t)ethhdr->type);
tap->_handler(tap->_arg, NULL, tap->_net_id, src_mac, dest_mac, proto, 0, data, len);
char* data = buf + sizeof(struct eth_hdr);
int len = totalLength - sizeof(struct eth_hdr);
int proto = Utils::ntoh((uint16_t)ethhdr->type);
tap->_handler(tap->_arg, NULL, tap->_net_id, src_mac, dest_mac, proto, 0, data, len);
return ERR_OK;
return ERR_OK;
}
void _lwip_eth_rx(
@@ -450,213 +450,213 @@ void _lwip_eth_rx(
unsigned int len)
{
#ifdef LWIP_STATS
stats_display();
stats_display();
#endif
if (! zts_events->getState(ZTS_STATE_STACK_RUNNING)) {
return;
}
struct pbuf *p, *q;
struct eth_hdr ethhdr;
from.copyTo(ethhdr.src.addr, 6);
to.copyTo(ethhdr.dest.addr, 6);
ethhdr.type = Utils::hton((uint16_t)etherType);
if (! zts_events->getState(ZTS_STATE_STACK_RUNNING)) {
return;
}
struct pbuf *p, *q;
struct eth_hdr ethhdr;
from.copyTo(ethhdr.src.addr, 6);
to.copyTo(ethhdr.dest.addr, 6);
ethhdr.type = Utils::hton((uint16_t)etherType);
p = pbuf_alloc(PBUF_RAW, (uint16_t)len + sizeof(struct eth_hdr), PBUF_RAM);
if (! p) {
// DEBUG_ERROR("dropped packet: unable to allocate memory for
// pbuf");
return;
}
// First pbuf gets Ethernet header at start
q = p;
if (q->len < sizeof(ethhdr)) {
pbuf_free(p);
p = NULL;
// DEBUG_ERROR("dropped packet: first pbuf smaller than Ethernet
// header");
return;
}
// Copy frame data into pbuf
const char* dataptr = reinterpret_cast<const char*>(data);
memcpy(q->payload, &ethhdr, sizeof(ethhdr));
int remainingPayloadSpace = q->len - sizeof(ethhdr);
memcpy((char*)q->payload + sizeof(ethhdr), dataptr, remainingPayloadSpace);
dataptr += remainingPayloadSpace;
// Remaining pbufs (if any) get rest of data
while ((q = q->next)) {
memcpy(q->payload, dataptr, q->len);
dataptr += q->len;
}
// Feed packet into stack
int err;
p = pbuf_alloc(PBUF_RAW, (uint16_t)len + sizeof(struct eth_hdr), PBUF_RAM);
if (! p) {
// DEBUG_ERROR("dropped packet: unable to allocate memory for
// pbuf");
return;
}
// First pbuf gets Ethernet header at start
q = p;
if (q->len < sizeof(ethhdr)) {
pbuf_free(p);
p = NULL;
// DEBUG_ERROR("dropped packet: first pbuf smaller than Ethernet
// header");
return;
}
// Copy frame data into pbuf
const char* dataptr = reinterpret_cast<const char*>(data);
memcpy(q->payload, &ethhdr, sizeof(ethhdr));
int remainingPayloadSpace = q->len - sizeof(ethhdr);
memcpy((char*)q->payload + sizeof(ethhdr), dataptr, remainingPayloadSpace);
dataptr += remainingPayloadSpace;
// Remaining pbufs (if any) get rest of data
while ((q = q->next)) {
memcpy(q->payload, dataptr, q->len);
dataptr += q->len;
}
// Feed packet into stack
int err;
if (Utils::ntoh(ethhdr.type) == 0x800 || Utils::ntoh(ethhdr.type) == 0x806) {
if (tap->netif4) {
if ((err = ((struct netif*)tap->netif4)->input(p, (struct netif*)tap->netif4)) != ERR_OK) {
// DEBUG_ERROR("packet input error (%d)", err);
pbuf_free(p);
}
}
}
if (Utils::ntoh(ethhdr.type) == 0x86DD) {
if (tap->netif6) {
if ((err = ((struct netif*)tap->netif6)->input(p, (struct netif*)tap->netif6)) != ERR_OK) {
// DEBUG_ERROR("packet input error (%d)", err);
pbuf_free(p);
}
}
}
if (Utils::ntoh(ethhdr.type) == 0x800 || Utils::ntoh(ethhdr.type) == 0x806) {
if (tap->netif4) {
if ((err = ((struct netif*)tap->netif4)->input(p, (struct netif*)tap->netif4)) != ERR_OK) {
// DEBUG_ERROR("packet input error (%d)", err);
pbuf_free(p);
}
}
}
if (Utils::ntoh(ethhdr.type) == 0x86DD) {
if (tap->netif6) {
if ((err = ((struct netif*)tap->netif6)->input(p, (struct netif*)tap->netif6)) != ERR_OK) {
// DEBUG_ERROR("packet input error (%d)", err);
pbuf_free(p);
}
}
}
}
bool _lwip_is_netif_up(void* n)
{
if (! n) {
return false;
}
LOCK_TCPIP_CORE();
bool result = netif_is_up((struct netif*)n);
UNLOCK_TCPIP_CORE();
return result;
if (! n) {
return false;
}
LOCK_TCPIP_CORE();
bool result = netif_is_up((struct netif*)n);
UNLOCK_TCPIP_CORE();
return result;
}
static err_t _netif_init4(struct netif* n)
{
if (! n || ! n->state) {
return ERR_IF;
}
// Called from core, no need to lock
VirtualTap* tap = (VirtualTap*)(n->state);
n->hwaddr_len = 6;
n->name[0] = '4';
n->name[1] = 'a' + netifCount;
n->linkoutput = _lwip_eth_tx;
n->output = etharp_output;
n->mtu = std::min(LWIP_MTU, (int)tap->_mtu);
n->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6
| NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
n->hwaddr_len = sizeof(n->hwaddr);
tap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
return ERR_OK;
if (! n || ! n->state) {
return ERR_IF;
}
// Called from core, no need to lock
VirtualTap* tap = (VirtualTap*)(n->state);
n->hwaddr_len = 6;
n->name[0] = '4';
n->name[1] = 'a' + netifCount;
n->linkoutput = _lwip_eth_tx;
n->output = etharp_output;
n->mtu = std::min(LWIP_MTU, (int)tap->_mtu);
n->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6
| NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
n->hwaddr_len = sizeof(n->hwaddr);
tap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
return ERR_OK;
}
static err_t _netif_init6(struct netif* n)
{
if (! n || ! n->state) {
return ERR_IF;
}
n->hwaddr_len = sizeof(n->hwaddr);
VirtualTap* tap = (VirtualTap*)(n->state);
tap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
// Called from core, no need to lock
n->hwaddr_len = 6;
n->name[0] = '6';
n->name[1] = 'a' + netifCount;
n->linkoutput = _lwip_eth_tx;
n->output_ip6 = ethip6_output;
n->mtu = std::min(LWIP_MTU, (int)tap->_mtu);
n->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6
| NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
return ERR_OK;
if (! n || ! n->state) {
return ERR_IF;
}
n->hwaddr_len = sizeof(n->hwaddr);
VirtualTap* tap = (VirtualTap*)(n->state);
tap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
// Called from core, no need to lock
n->hwaddr_len = 6;
n->name[0] = '6';
n->name[1] = 'a' + netifCount;
n->linkoutput = _lwip_eth_tx;
n->output_ip6 = ethip6_output;
n->mtu = std::min(LWIP_MTU, (int)tap->_mtu);
n->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6
| NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
return ERR_OK;
}
void _lwip_init_interface(void* tapref, const InetAddress& ip)
{
char macbuf[ZTS_MAC_ADDRSTRLEN] = { 0 };
char macbuf[ZTS_MAC_ADDRSTRLEN] = { 0 };
VirtualTap* vtap = (VirtualTap*)tapref;
struct netif* n = NULL;
bool isNewNetif = false;
VirtualTap* vtap = (VirtualTap*)tapref;
struct netif* n = NULL;
bool isNewNetif = false;
if (ip.isV4()) {
if (vtap->netif4) {
n = (struct netif*)vtap->netif4;
}
else {
n = new struct netif;
isNewNetif = true;
netifCount++;
}
if (ip.isV4()) {
if (vtap->netif4) {
n = (struct netif*)vtap->netif4;
}
else {
n = new struct netif;
isNewNetif = true;
netifCount++;
}
static ip4_addr_t ip4, netmask, gw;
IP4_ADDR(&gw, 127, 0, 0, 1);
ip4.addr = *((u32_t*)ip.rawIpData());
netmask.addr = *((u32_t*)ip.netmask().rawIpData());
LOCK_TCPIP_CORE();
netif_add(n, &ip4, &netmask, &gw, (void*)vtap, _netif_init4, tcpip_input);
vtap->netif4 = (void*)n;
UNLOCK_TCPIP_CORE();
snprintf(
macbuf,
ZTS_MAC_ADDRSTRLEN,
"%02x:%02x:%02x:%02x:%02x:%02x",
n->hwaddr[0],
n->hwaddr[1],
n->hwaddr[2],
n->hwaddr[3],
n->hwaddr[4],
n->hwaddr[5]);
}
if (ip.isV6()) {
if (vtap->netif6) {
n = (struct netif*)vtap->netif6;
}
else {
n = new struct netif;
isNewNetif = true;
netifCount++;
}
static ip6_addr_t ip6;
memcpy(&(ip6.addr), ip.rawIpData(), sizeof(ip6.addr));
LOCK_TCPIP_CORE();
if (isNewNetif) {
vtap->netif6 = (void*)n;
netif_add(n, NULL, NULL, NULL, (void*)vtap, _netif_init6, ethernet_input);
n->ip6_autoconfig_enabled = 1;
vtap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
netif_create_ip6_linklocal_address(n, 1);
netif_set_link_up(n);
netif_set_up(n);
netif_set_default(n);
}
netif_add_ip6_address(n, &ip6, NULL);
n->output_ip6 = ethip6_output;
UNLOCK_TCPIP_CORE();
snprintf(
macbuf,
ZTS_MAC_ADDRSTRLEN,
"%02x:%02x:%02x:%02x:%02x:%02x",
n->hwaddr[0],
n->hwaddr[1],
n->hwaddr[2],
n->hwaddr[3],
n->hwaddr[4],
n->hwaddr[5]);
}
static ip4_addr_t ip4, netmask, gw;
IP4_ADDR(&gw, 127, 0, 0, 1);
ip4.addr = *((u32_t*)ip.rawIpData());
netmask.addr = *((u32_t*)ip.netmask().rawIpData());
LOCK_TCPIP_CORE();
netif_add(n, &ip4, &netmask, &gw, (void*)vtap, _netif_init4, tcpip_input);
vtap->netif4 = (void*)n;
UNLOCK_TCPIP_CORE();
snprintf(
macbuf,
ZTS_MAC_ADDRSTRLEN,
"%02x:%02x:%02x:%02x:%02x:%02x",
n->hwaddr[0],
n->hwaddr[1],
n->hwaddr[2],
n->hwaddr[3],
n->hwaddr[4],
n->hwaddr[5]);
}
if (ip.isV6()) {
if (vtap->netif6) {
n = (struct netif*)vtap->netif6;
}
else {
n = new struct netif;
isNewNetif = true;
netifCount++;
}
static ip6_addr_t ip6;
memcpy(&(ip6.addr), ip.rawIpData(), sizeof(ip6.addr));
LOCK_TCPIP_CORE();
if (isNewNetif) {
vtap->netif6 = (void*)n;
netif_add(n, NULL, NULL, NULL, (void*)vtap, _netif_init6, ethernet_input);
n->ip6_autoconfig_enabled = 1;
vtap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
netif_create_ip6_linklocal_address(n, 1);
netif_set_link_up(n);
netif_set_up(n);
netif_set_default(n);
}
netif_add_ip6_address(n, &ip6, NULL);
n->output_ip6 = ethip6_output;
UNLOCK_TCPIP_CORE();
snprintf(
macbuf,
ZTS_MAC_ADDRSTRLEN,
"%02x:%02x:%02x:%02x:%02x:%02x",
n->hwaddr[0],
n->hwaddr[1],
n->hwaddr[2],
n->hwaddr[3],
n->hwaddr[4],
n->hwaddr[5]);
}
}
void _lwip_remove_address_from_netif(void* tapref, const InetAddress& ip)
{
if (! tapref) {
return;
}
VirtualTap* vtap = (VirtualTap*)tapref;
struct netif* n = NULL;
/* When true multi-homing is implemented this will need to
be a bit more sophisticated */
if (ip.isV4()) {
if (vtap->netif4) {
n = (struct netif*)vtap->netif4;
}
}
if (ip.isV6()) {
if (vtap->netif6) {
n = (struct netif*)vtap->netif6;
}
}
if (! n) {
return;
}
_lwip_remove_netif(n);
if (! tapref) {
return;
}
VirtualTap* vtap = (VirtualTap*)tapref;
struct netif* n = NULL;
/* When true multi-homing is implemented this will need to
be a bit more sophisticated */
if (ip.isV4()) {
if (vtap->netif4) {
n = (struct netif*)vtap->netif4;
}
}
if (ip.isV6()) {
if (vtap->netif6) {
n = (struct netif*)vtap->netif6;
}
}
if (! n) {
return;
}
_lwip_remove_netif(n);
}
} // namespace ZeroTier

View File

@@ -42,153 +42,153 @@ struct InetAddress;
* then be destroyed upon leaving the network.
*/
class VirtualTap {
friend class Phy<VirtualTap*>;
friend class Phy<VirtualTap*>;
public:
VirtualTap(
const char* homePath,
const MAC& mac,
unsigned int mtu,
unsigned int metric,
uint64_t net_id,
void (*handler)(
void*,
void*,
uint64_t,
const MAC&,
const MAC&,
unsigned int,
unsigned int,
const void*,
unsigned int),
void* arg);
VirtualTap(
const char* homePath,
const MAC& mac,
unsigned int mtu,
unsigned int metric,
uint64_t net_id,
void (*handler)(
void*,
void*,
uint64_t,
const MAC&,
const MAC&,
unsigned int,
unsigned int,
const void*,
unsigned int),
void* arg);
~VirtualTap();
~VirtualTap();
void setEnabled(bool en);
bool enabled() const;
void setEnabled(bool en);
bool enabled() const;
/**
* System to ingest events from this class and emit them to the user
*/
Events* _events;
/**
* System to ingest events from this class and emit them to the user
*/
Events* _events;
/**
* Mutex for protecting IP address container for this tap.
*/
Mutex _ips_m; // Public because we want it accessible by the driver
// layer
/**
* Mutex for protecting IP address container for this tap.
*/
Mutex _ips_m; // Public because we want it accessible by the driver
// layer
void setUserEventSystem(Events* events);
void setUserEventSystem(Events* events);
/**
* Return whether this tap has been assigned an IPv4 address.
*/
bool hasIpv4Addr();
/**
* Return whether this tap has been assigned an IPv4 address.
*/
bool hasIpv4Addr();
/**
* Return whether this tap has been assigned an IPv6 address.
*/
bool hasIpv6Addr();
/**
* Return whether this tap has been assigned an IPv6 address.
*/
bool hasIpv6Addr();
/**
* Adds an address to the user-space stack interface associated with
* this VirtualTap
* - Starts VirtualTap main thread ONLY if successful
*/
bool addIp(const InetAddress& ip);
/**
* Adds an address to the user-space stack interface associated with
* this VirtualTap
* - Starts VirtualTap main thread ONLY if successful
*/
bool addIp(const InetAddress& ip);
/**
* Removes an address from the user-space stack interface associated
* with this VirtualTap
*/
bool removeIp(const InetAddress& ip);
/**
* Removes an address from the user-space stack interface associated
* with this VirtualTap
*/
bool removeIp(const InetAddress& ip);
/**
* Presents data to the user-space stack
*/
void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len);
/**
* Presents data to the user-space stack
*/
void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len);
/**
* Scan multicast groups
*/
void scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed);
/**
* Scan multicast groups
*/
void scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed);
/**
* Set MTU
*/
void setMtu(unsigned int mtu);
/**
* Set MTU
*/
void setMtu(unsigned int mtu);
/**
* Calls main network stack loops
*/
void threadMain() throw();
/**
* Calls main network stack loops
*/
void threadMain() throw();
/**
* For moving data onto the ZeroTier virtual wire
*/
void (*_handler)(
void*,
void*,
uint64_t,
const MAC&,
const MAC&,
unsigned int,
unsigned int,
const void*,
unsigned int);
/**
* For moving data onto the ZeroTier virtual wire
*/
void (*_handler)(
void*,
void*,
uint64_t,
const MAC&,
const MAC&,
unsigned int,
unsigned int,
const void*,
unsigned int);
void* netif4 = NULL;
void* netif6 = NULL;
void* netif4 = NULL;
void* netif6 = NULL;
// The last time that this virtual tap received a network config update
// from the core
uint64_t _lastConfigUpdateTime = 0;
// The last time that this virtual tap received a network config update
// from the core
uint64_t _lastConfigUpdateTime = 0;
void lastConfigUpdate(uint64_t lastConfigUpdateTime);
void lastConfigUpdate(uint64_t lastConfigUpdateTime);
int _networkStatus = 0;
int _networkStatus = 0;
char vtap_full_name[VTAP_NAME_LEN] = { 0 };
char vtap_full_name[VTAP_NAME_LEN] = { 0 };
std::vector<InetAddress> ips() const;
std::vector<InetAddress> _ips;
std::vector<InetAddress> ips() const;
std::vector<InetAddress> _ips;
std::string _homePath;
void* _arg;
volatile bool _initialized;
volatile bool _enabled;
volatile bool _run;
MAC _mac;
unsigned int _mtu;
uint64_t _net_id;
PhySocket* _unixListenSocket;
Phy<VirtualTap*> _phy;
std::string _homePath;
void* _arg;
volatile bool _initialized;
volatile bool _enabled;
volatile bool _run;
MAC _mac;
unsigned int _mtu;
uint64_t _net_id;
PhySocket* _unixListenSocket;
Phy<VirtualTap*> _phy;
Thread _thread;
Thread _thread;
int _shutdownSignalPipe[2] = { 0 };
int _shutdownSignalPipe[2] = { 0 };
std::vector<MulticastGroup> _multicastGroups;
Mutex _multicastGroups_m;
std::vector<MulticastGroup> _multicastGroups;
Mutex _multicastGroups_m;
//----------------------------------------------------------------------------//
// Not used in this implementation //
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// Not used in this implementation //
//----------------------------------------------------------------------------//
void phyOnDatagram(
PhySocket* sock,
void** uptr,
const struct sockaddr* local_address,
const struct sockaddr* from,
void* data,
unsigned long len);
void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success);
void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from);
void phyOnTcpClose(PhySocket* sock, void** uptr);
void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len);
void phyOnTcpWritable(PhySocket* sock, void** uptr);
void phyOnUnixClose(PhySocket* sock, void** uptr);
void phyOnDatagram(
PhySocket* sock,
void** uptr,
const struct sockaddr* local_address,
const struct sockaddr* from,
void* data,
unsigned long len);
void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success);
void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from);
void phyOnTcpClose(PhySocket* sock, void** uptr);
void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len);
void phyOnTcpWritable(PhySocket* sock, void** uptr);
void phyOnUnixClose(PhySocket* sock, void** uptr);
};
/**