Format according to new ZeroTier standard
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
364
src/Central.cpp
364
src/Central.cpp
@@ -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
|
||||
|
||||
684
src/Controls.cpp
684
src/Controls.cpp
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
300
src/Events.cpp
300
src/Events.cpp
@@ -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
|
||||
|
||||
146
src/Events.hpp
146
src/Events.hpp
@@ -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
|
||||
|
||||
2608
src/NodeService.cpp
2608
src/NodeService.cpp
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
996
src/Sockets.cpp
996
src/Sockets.cpp
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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, ðhdr, 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, ðhdr, 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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user