-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Expand C API and simplify NodeService
- Loading branch information
1 parent
565b56d
commit 4335069
Showing
30 changed files
with
7,495 additions
and
5,265 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/** | ||
* libzt C API example | ||
* | ||
* Pingable node joined to controller-less adhoc network with a 6PLANE addressing scheme | ||
*/ | ||
|
||
#include "ZeroTierSockets.h" | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
/* | ||
Ad-hoc Network: | ||
ffSSSSEEEE000000 | ||
| | | | | ||
| | | Reserved for future use, must be 0 | ||
| | End of port range (hex) | ||
| Start of port range (hex) | ||
Reserved ZeroTier address prefix indicating a controller-less network. | ||
Ad-hoc networks are public (no access control) networks that have no network controller. Instead | ||
their configuration and other credentials are generated locally. Ad-hoc networks permit only IPv6 | ||
UDP and TCP unicast traffic (no multicast or broadcast) using 6plane format NDP-emulated IPv6 | ||
addresses. In addition an ad-hoc network ID encodes an IP port range. UDP packets and TCP SYN | ||
(connection open) packets are only allowed to destination ports within the encoded range. | ||
For example ff00160016000000 is an ad-hoc network allowing only SSH, while ff0000ffff000000 is an | ||
ad-hoc network allowing any UDP or TCP port. | ||
Keep in mind that these networks are public and anyone in the entire world can join them. Care must | ||
be taken to avoid exposing vulnerable services or sharing unwanted files or other resources. | ||
*/ | ||
int main(int argc, char** argv) | ||
{ | ||
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 | ||
uint64_t net_id = zts_net_compute_adhoc_id(adhocStartPort, adhocEndPort); | ||
|
||
// 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); | ||
|
||
// 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_count() < 1) { | ||
zts_util_delay(50); | ||
} | ||
|
||
// 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); | ||
|
||
// Do network stuff! | ||
// zts_socket, zts_connect, etc | ||
|
||
while (1) { | ||
zts_util_delay(500); // Idle indefinitely | ||
} | ||
|
||
printf("Stopping node\n"); | ||
return zts_node_stop(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/** | ||
* libzt C API example | ||
* | ||
* Pingable node that demonstrates basic usage of the callback API. To see | ||
* more exhaustive examples look at test/selftest.c | ||
*/ | ||
|
||
#include "ZeroTierSockets.h" | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
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); | ||
} | ||
|
||
// 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); | ||
} | ||
uint64_t net_id = strtoull(argv[1], NULL, 16); | ||
|
||
zts_init_set_event_handler(&on_zts_event); | ||
|
||
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("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("Waiting for join to complete\n"); | ||
while (zts_net_count() < 1) { | ||
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); | ||
} | ||
|
||
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 | ||
|
||
while (1) { | ||
zts_util_delay(500); // Idle indefinitely | ||
} | ||
|
||
printf("Stopping node\n"); | ||
return zts_node_stop(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include "ZeroTierSockets.h" | ||
|
||
#include <iomanip> | ||
#include <iostream> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <string> | ||
|
||
// For optional JSON parsing | ||
#include "../ext/ZeroTierOne/ext/json/json.hpp" | ||
|
||
void process_response(char* response, int http_resp_code) | ||
{ | ||
if (http_resp_code == 0) { | ||
// Request failed at library level, do nothing. There would be no HTTP code at this point. | ||
return; | ||
} | ||
printf("Raw response string (%d) = %s\n", http_resp_code, response); | ||
// Parse into navigable JSON object | ||
if (http_resp_code < 200 || http_resp_code >= 300) { | ||
return; | ||
} | ||
nlohmann::json res = nlohmann::json::parse(response); | ||
if (! res.is_object()) { | ||
fprintf(stderr, "Unable to parse (root element is not a JSON object)"); | ||
} | ||
// Pretty print JSON blob | ||
std::cout << std::setw(4) << res << std::endl; | ||
} | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
if (argc != 3) { | ||
printf("\nlibzt example central API client\n"); | ||
printf("centralapi <central_url> <api_token>\n"); | ||
exit(0); | ||
} | ||
char* central_url = argv[1]; // API endpoint | ||
char* api_token = argv[2]; // User token (generate at my.zerotier.com) | ||
|
||
/** | ||
* This example demonstrates how to use the ZeroTier Central API to: | ||
* | ||
* - Get the status of our hosted service (or your own) | ||
* - Create a network | ||
* - Get the full configuration of a network | ||
* - Authorize/Deauthorize nodes on a network | ||
* | ||
* This example does not start a node (though you can if you wish.) This portion of the | ||
* libzt API is merely a wrapper around our web API endpoint (https://my.zerotier.com/help/api). | ||
* The HTTP requests are done via libcurl. This API is thread-safe but not multi-threaded. | ||
* | ||
* Error Codes: | ||
* -2 : [ZTS_ERR_SERVICE] The API may not have been initialized properly | ||
* -3 : [ZTS_ERR_ARG] Invalid argument | ||
* [100-500] : Standard HTTP error codes | ||
* | ||
* Usage example: centralapi https://my.zerotier.com e7no7nVRFItge7no7cVR5Ibge7no8nV1 | ||
* | ||
*/ | ||
|
||
int err = ZTS_ERR_OK; | ||
// Buffer to store server response as JSON string blobs | ||
char rbuf[ZTS_CENTRAL_RESP_BUF_DEFAULT_SZ] = { 0 }; | ||
|
||
// Provide URL to Central API server and user API token generated at https://my.zerotier.com | ||
printf("Initializing Central API client...\n"); | ||
if ((err = zts_central_init(central_url, api_token, rbuf, ZTS_CENTRAL_RESP_BUF_DEFAULT_SZ)) | ||
!= ZTS_ERR_OK) { | ||
fprintf(stderr, "Error while initializing client's Central API parameters\n"); | ||
return 0; | ||
} | ||
|
||
zts_central_set_verbose(false); // (optional) Turn on reporting from libcurl | ||
zts_central_set_access_mode(ZTS_CENTRAL_READ /*| ZTS_CENTRAL_WRITE*/); | ||
|
||
int http_res_code = 0; | ||
|
||
// Get hosted service status | ||
printf("Requesting Central API server status (/api/status):\n"); | ||
if ((err = zts_central_status_get(&http_res_code)) != ZTS_ERR_OK) { | ||
fprintf(stderr, "Error (%d) making the request.\n", err); | ||
} | ||
else { | ||
process_response(rbuf, http_res_code); | ||
} | ||
// Get network config | ||
int64_t nwid = 0x1234567890abcdef; | ||
printf("Requesting network config: /api/network/%llx\n", nwid); | ||
if ((err = zts_central_net_get(&http_res_code, nwid)) != ZTS_ERR_OK) { | ||
fprintf(stderr, "Error (%d) making the request.\n", err); | ||
} | ||
else { | ||
process_response(rbuf, http_res_code); | ||
} | ||
// Authorize a node on a network | ||
int64_t nodeid = 0x9934343434; | ||
printf("Authorizing: /api/network/%llx/member/%llx\n", nwid, nodeid); | ||
if ((err = zts_central_node_auth(&http_res_code, nwid, nodeid, ZTS_CENTRAL_NODE_AUTH_TRUE)) | ||
!= ZTS_ERR_OK) { | ||
fprintf(stderr, "Error (%d) making the request.\n", err); | ||
} | ||
else { | ||
process_response(rbuf, http_res_code); | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.