diff --git a/examples/cpp/earthtest.cpp b/examples/cpp/earthtest.cpp deleted file mode 100644 index df51df9..0000000 --- a/examples/cpp/earthtest.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include - -#include "libzt.h" - -int main(int argc, char **argv) -{ - uint64_t nwid = 0x8056c2e21c000001; - zts_startjoin(".", nwid); - fprintf(stderr, "%llx", (unsigned long long)zts_get_node_id()); - zts_leave(nwid); - zts_stop(); - return 0; -} \ No newline at end of file diff --git a/examples/cpp/ipv4simple/ipv4client.cpp b/examples/cpp/ipv4simple/ipv4client.cpp deleted file mode 100644 index 9d0100b..0000000 --- a/examples/cpp/ipv4simple/ipv4client.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "libzt.h" - -char *msg = (char*)"welcome to the machine"; - -int main(int argc, char **argv) -{ - if (argc != 5) { - printf("\nlibzt example client\n"); - printf("client [config_file_path] [nwid] [remote_addr] [remote_port]\n"); - exit(0); - } - std::string path = argv[1]; - std::string nwidstr = argv[2]; - std::string remote_addr = argv[3]; - int remote_port = atoi(argv[4]); - int r=0, w=0, err=0, sockfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in in4; - in4.sin_port = htons(remote_port); - in4.sin_addr.s_addr = inet_addr(remote_addr.c_str()); - in4.sin_family = AF_INET; - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = zts_connect(sockfd, (const struct sockaddr *)&in4, sizeof(in4))) < 0) { - printf("error connecting to remote host (%d)\n", err); - } - - printf("sending to server...\n"); - w = zts_write(sockfd, msg, strlen(msg)); - - printf("reading from server...\n"); - r = zts_read(sockfd, rbuf, strlen(msg)); - - printf("Sent : %s\n", msg); - printf("Received : %s\n", rbuf); - - err = zts_close(sockfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/ipv4simple/ipv4client_udp.cpp b/examples/cpp/ipv4simple/ipv4client_udp.cpp deleted file mode 100644 index 273c797..0000000 --- a/examples/cpp/ipv4simple/ipv4client_udp.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "libzt.h" - -char *msg = (char*)"welcome to the machine"; - -int main(int argc, char **argv) -{ - if (argc != 5) { - printf("\nlibzt example client\n"); - printf("client [config_file_path] [nwid] [remote_addr] [remote_port]\n"); - exit(0); - } - std::string path = argv[1]; - std::string nwidstr = argv[2]; - std::string remote_addr = argv[3]; - int remote_port = atoi(argv[4]); - int r=0, w=0, err=0, sockfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in in4; - in4.sin_port = htons(remote_port); - in4.sin_addr.s_addr = INADDR_ANY; - in4.sin_family = AF_INET; - - struct sockaddr_in remote4; - remote4.sin_port = htons(remote_port); - remote4.sin_addr.s_addr = inet_addr(remote_addr.c_str()); - remote4.sin_family = AF_INET; - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = zts_bind(sockfd, (struct sockaddr *)&in4, sizeof(struct sockaddr_in)) < 0)) { - printf("error binding to interface (%d)\n", err); - } - int flags = 0; - int len = strlen(msg); - - while(true) { - sleep(1); - if ((err = zts_sendto(sockfd, msg, len, flags, (const struct sockaddr *)&remote4, sizeof(remote4))) < 0) { - printf("error sending message to remote host (%d)\n", err); - } - printf("sent=%d\n", err); - } - /* - printf("reading from server...\n"); - r = zts_read(sockfd, rbuf, strlen(msg)); - - printf("Sent : %s\n", msg); - printf("Received : %s\n", rbuf); - */ - err = zts_close(sockfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/ipv4simple/ipv4server.cpp b/examples/cpp/ipv4simple/ipv4server.cpp deleted file mode 100644 index 260e9e4..0000000 --- a/examples/cpp/ipv4simple/ipv4server.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif -#include "libzt.h" - -int main(int argc, char **argv) -{ - if (argc != 4) { - printf("\nlibzt example server\n"); - printf("server [config_file_path] [nwid] [bind_port]\n"); - exit(0); - } - std::string path = argv[1]; - std::string nwidstr = argv[2]; - int bind_port = atoi(argv[3]); - int w=0, r=0, err=0, sockfd, accfd; - char rbuf[1000]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in in4, acc_in4; - in4.sin_port = htons(bind_port); - in4.sin_addr.s_addr = INADDR_ANY; - in4.sin_family = AF_INET; - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = zts_bind(sockfd, (struct sockaddr *)&in4, sizeof(struct sockaddr_in)) < 0)) { - printf("error binding to interface (%d)\n", err); - } - - if ((err = zts_listen(sockfd, 100)) < 0) { - printf("error placing socket in LISTENING state (%d)\n", err); - } - - socklen_t client_addrlen = sizeof(sockaddr_in); - if ((accfd = zts_accept(sockfd, (struct sockaddr *)&acc_in4, &client_addrlen)) < 0) { - printf("error accepting connection (%d)\n", err); - } - - socklen_t peer_addrlen = sizeof(struct sockaddr_storage); - zts_getpeername(accfd, (struct sockaddr*)&acc_in4, &peer_addrlen); - printf("accepted connection from %s : %d\n", inet_ntoa(acc_in4.sin_addr), ntohs(acc_in4.sin_port)); - - int tot = 0; - printf("reading from client...\n"); - while(true) { - memset(rbuf, 0, sizeof rbuf); - if (tot == 500000) - { - break; - } - r = zts_read(accfd, rbuf, sizeof rbuf); - printf("r=%d\n", r); - printf("Received : %s\n", rbuf); - tot+= r; - printf("tot=%d\n", tot); - } - printf("tot=%d\n", tot); - - printf("sending to client...\n"); - w = zts_write(accfd, rbuf, strlen(rbuf)); - printf("w=%d\n", r); - - printf("Received : %s\n", rbuf); - - err = zts_close(sockfd); - err = zts_close(accfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/ipv4simple/ipv4server_udp.cpp b/examples/cpp/ipv4simple/ipv4server_udp.cpp deleted file mode 100644 index 1a7f5eb..0000000 --- a/examples/cpp/ipv4simple/ipv4server_udp.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif -#include "libzt.h" - -int main(int argc, char **argv) -{ - if (argc != 4) { - printf("\nlibzt example server\n"); - printf("server [config_file_path] [nwid] [bind_port]\n"); - exit(0); - } - std::string path = argv[1]; - std::string nwidstr = argv[2]; - int bind_port = atoi(argv[3]); - int w=0, r=0, err=0, sockfd = 0, accfd = 0, flags = 0; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in in4, acc_in4; - in4.sin_port = htons(bind_port); - in4.sin_addr.s_addr = INADDR_ANY; - in4.sin_family = AF_INET; - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - if ((err = zts_bind(sockfd, (struct sockaddr *)&in4, sizeof(struct sockaddr_in)) < 0)) { - printf("error binding to interface (%d)\n", err); - } - -/* - socklen_t peer_addrlen = sizeof(struct sockaddr_storage); - zts_getpeername(accfd, (struct sockaddr*)&acc_in4, &peer_addrlen); - DEBUG_INFO("accepted connection from %s : %d", inet_ntoa(acc_in4.sin_addr), ntohs(acc_in4.sin_port)); -*/ - - printf("reading from client...\n"); - socklen_t addrlen = sizeof(acc_in4); - memset(&acc_in4, 0, sizeof acc_in4); - - while(true) { - memset(&rbuf, 0, sizeof rbuf); - r = zts_recvfrom(accfd, rbuf, sizeof(rbuf), flags, (struct sockaddr *)&acc_in4, &addrlen); - if (r >= 0) { - char *ip = inet_ntoa(acc_in4.sin_addr); - printf("Received : r=%d, %s -- from: %s : %d\n", r, rbuf, ip, ntohs(acc_in4.sin_port)); - } - } - -/* - printf("sending to client...\n"); - w = zts_write(accfd, rbuf, strlen(rbuf)); - -*/ - - err = zts_close(sockfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/ipv6adhoc/ipv6adhocclient.cpp b/examples/cpp/ipv6adhoc/ipv6adhocclient.cpp deleted file mode 100644 index ab1ee0e..0000000 --- a/examples/cpp/ipv6adhoc/ipv6adhocclient.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "libzt.h" - -char *msg = (char*)"welcome to the machine"; - -uint64_t generate_adhoc_nwid_from_port(int port) -{ - std::string padding; - if(port < 10) { - padding = "000"; - } else if(port < 100) { - padding = "00"; - } else if(port < 1000) { - padding = "0"; - } - // We will join ad-hoc network ffSSSSEEEE000000 - // Where SSSS = start port - // EEEE = end port - padding = padding + std::to_string(port); // SSSS - std::string nwidstr = "ff" + padding + padding + "000000"; // ff + SSSS + EEEE + 000000 - return strtoull(nwidstr.c_str(), NULL, 16); -} - -int main(int argc, char **argv) -{ - if (argc != 5) { - printf("\nlibzt example client\n"); - printf("client [config_file_path] [nwid] [remote_addr] [remote_port]\n"); - exit(0); - } - std::string path = argv[1]; - std::string nwidstr = argv[2]; - std::string remote_addr = argv[3]; - int remote_port = atoi(argv[4]); - int r=0, w=0, err=0, sockfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in6 in6; - in6.sin6_port = htons(remote_port); - inet_pton(AF_INET6, remote_addr.c_str(), &(in6.sin6_addr)); - in6.sin6_family = AF_INET6; - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = generate_adhoc_nwid_from_port(remote_port); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = zts_connect(sockfd, (const struct sockaddr *)&in6, sizeof(in6))) < 0) { - printf("error connecting to remote host (%d)\n", err); - } - - printf("sending to server...\n"); - w = zts_write(sockfd, msg, strlen(msg)); - - printf("reading from server...\n"); - r = zts_read(sockfd, rbuf, strlen(msg)); - - printf("Sent : %s\n", msg); - printf("Received : %s\n", rbuf); - - err = zts_close(sockfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/ipv6adhoc/ipv6adhocserver.cpp b/examples/cpp/ipv6adhoc/ipv6adhocserver.cpp deleted file mode 100644 index 512a568..0000000 --- a/examples/cpp/ipv6adhoc/ipv6adhocserver.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "libzt.h" - -uint64_t generate_adhoc_nwid_from_port(int port) -{ - std::string padding; - if(port < 10) { - padding = "000"; - } else if(port < 100) { - padding = "00"; - } else if(port < 1000) { - padding = "0"; - } - // We will join ad-hoc network ffSSSSEEEE000000 - // Where SSSS = start port - // EEEE = end port - padding = padding + std::to_string(port); // SSSS - std::string nwidstr = "ff" + padding + padding + "000000"; // ff + SSSS + EEEE + 000000 - return strtoull(nwidstr.c_str(), NULL, 16); -} - -int main(int argc, char **argv) -{ - if (argc != 4) { - printf("\nlibzt example server\n"); - printf("server [config_file_path] [bind_port]\n"); - exit(0); - } - std::string path = argv[1]; - int bind_port = atoi(argv[2]); - uint64_t nwid = generate_adhoc_nwid_from_port(bind_port); - int w=0, r=0, err=0, sockfd, accfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in6 in6, acc_in6; - in6.sin6_port = htons(bind_port); - in6.sin6_family = AF_INET6; - in6.sin6_addr = in6addr_any; - - fprintf(stderr, "nwid=%llx\n", (unsigned long long)nwid); - exit(-1); - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - nwid = generate_adhoc_nwid_from_port(bind_port); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = zts_bind(sockfd, (struct sockaddr *)&in6, sizeof(struct sockaddr_in6)) < 0)) { - printf("error binding to interface (%d)\n", err); - } - - if ((err = zts_listen(sockfd, 100)) < 0) { - printf("error placing socket in LISTENING state (%d)\n", err); - } - - socklen_t client_addrlen = sizeof(sockaddr_in6); - if ((accfd = zts_accept(sockfd, (struct sockaddr *)&acc_in6, &client_addrlen)) < 0) { - printf("error accepting connection (%d)\n", err); - } - - socklen_t peer_addrlen = sizeof(struct sockaddr_storage); - zts_getpeername(accfd, (struct sockaddr*)&acc_in6, &peer_addrlen); - //printf("accepted connection from %s : %d", inet_ntoa(acc_in6.sin6_addr), ntohs(acc_in6.sin6_port)); - - printf("reading from client...\n"); - r = zts_read(accfd, rbuf, sizeof rbuf); - - printf("sending to client...\n"); - w = zts_write(accfd, rbuf, strlen(rbuf)); - - printf("Received : %s\n", rbuf); - - err = zts_close(sockfd); - err = zts_close(accfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/ipv6simple/ipv6client.cpp b/examples/cpp/ipv6simple/ipv6client.cpp deleted file mode 100644 index 3bf3099..0000000 --- a/examples/cpp/ipv6simple/ipv6client.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "libzt.h" - -char *msg = (char*)"welcome to the machine"; - -int main(int argc, char **argv) -{ - if (argc != 5) { - printf("\nlibzt example client\n"); - printf("client [config_file_path] [nwid] [remote_addr] [remote_port]\n"); - exit(0); - } - std::string path = argv[1]; - std::string nwidstr = argv[2]; - std::string remote_addr = argv[3]; - int remote_port = atoi(argv[4]); - int r=0, w=0, err=0, sockfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in6 in6; - in6.sin6_port = htons(remote_port); - inet_pton(AF_INET6, remote_addr.c_str(), &(in6.sin6_addr)); - in6.sin6_family = AF_INET6; - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = zts_connect(sockfd, (const struct sockaddr *)&in6, sizeof(in6))) < 0) { - printf("error connecting to remote host (%d)\n", err); - } - - printf("sending to server...\n"); - w = zts_write(sockfd, msg, strlen(msg)); - - printf("reading from server...\n"); - r = zts_read(sockfd, rbuf, strlen(msg)); - - printf("Sent : %s\n", msg); - printf("Received : %s\n", rbuf); - - err = zts_close(sockfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/ipv6simple/ipv6server.cpp b/examples/cpp/ipv6simple/ipv6server.cpp deleted file mode 100644 index 7062d4f..0000000 --- a/examples/cpp/ipv6simple/ipv6server.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "libzt.h" - -int main(int argc, char **argv) -{ - if (argc != 4) { - printf("\nlibzt example server\n"); - printf("server [config_file_path] [nwid] [bind_port]\n"); - exit(0); - } - std::string path = argv[1]; - std::string nwidstr = argv[2]; - int bind_port = atoi(argv[3]); - int w=0, r=0, err=0, sockfd, accfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in6 in6, acc_in6; - in6.sin6_port = htons(bind_port); - in6.sin6_family = AF_INET6; - in6.sin6_addr = in6addr_any; - - // --- BEGIN EXAMPLE CODE - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = zts_bind(sockfd, (struct sockaddr *)&in6, sizeof(struct sockaddr_in6)) < 0)) { - printf("error binding to interface (%d)\n", err); - } - - if ((err = zts_listen(sockfd, 100)) < 0) { - printf("error placing socket in LISTENING state (%d)\n", err); - } - - socklen_t client_addrlen = sizeof(sockaddr_in6); - if ((accfd = zts_accept(sockfd, (struct sockaddr *)&acc_in6, &client_addrlen)) < 0) { - printf("error accepting connection (%d)\n", err); - } - - socklen_t peer_addrlen = sizeof(struct sockaddr_storage); - zts_getpeername(accfd, (struct sockaddr*)&acc_in6, &peer_addrlen); - //DEBUG_INFO("accepted connection from %s : %d", inet_ntoa(acc_in6.sin6_addr), ntohs(acc_in6.sin6_port)); - - printf("reading from client...\n"); - r = zts_read(accfd, rbuf, sizeof rbuf); - - printf("sending to client...\n"); - w = zts_write(accfd, rbuf, strlen(rbuf)); - - printf("Received : %s\n", rbuf); - - err = zts_close(sockfd); - err = zts_close(accfd); - - return err; -} \ No newline at end of file diff --git a/examples/cpp/sharedlib/ipv4client_shared.cpp b/examples/cpp/sharedlib/ipv4client_shared.cpp deleted file mode 100644 index 83a0782..0000000 --- a/examples/cpp/sharedlib/ipv4client_shared.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#if !defined(_MSC_VER) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libzt.h" - -// function pointers which will have values assigned once the dynamic library is loaded - -int (*_zts_set_service_port)(int portno); -int (*_zts_start)(const char *path, bool blocking); -int (*_zts_startjoin)(const char*, uint64_t); -void (*_zts_stop)(void); -int (*_zts_core_running)(void); -int (*_zts_stack_running)(void); -int (*_zts_ready)(void); -int (*_zts_join)(const uint64_t); -int (*_zts_leave)(const uint64_t); -void (*_zts_get_path)(char *homePath, const size_t len); -uint64_t (*_zts_get_node_id)(void); -int (*_zts_has_address)(const uint64_t); -int (*_zts_get_num_assigned_addresses)(const uint64_t nwid); -int (*_zts_get_address_at_index)(const uint64_t nwid, const int index, struct sockaddr_storage *addr); -int (*_zts_get_address)(const uint64_t nwid, struct sockaddr_storage *addr, const int address_family); -void (*_zts_get_6plane_addr)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); -void (*_zts_get_rfc4193_addr)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); -unsigned long (*_zts_get_peer_count)(void); -int (*_zts_get_peer_address)(char *peer, const uint64_t nodeId); -int (*_zts_socket)(int socket_family, int socket_type, int protocol); -int (*_zts_connect)(int fd, const struct sockaddr *addr, socklen_t addrlen); -int (*_zts_bind)(int fd, const struct sockaddr *addr, socklen_t addrlen); -int (*_zts_listen)(int fd, int backlog); -int (*_zts_accept)(int fd, struct sockaddr *addr, socklen_t *addrlen); -#if defined(__linux__) -int (*_zts_accept4)(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); -#endif -int (*_zts_setsockopt)(int fd, int level, int optname, const void *optval, socklen_t optlen); -int (*_zts_getsockopt)(int fd, int level, int optname, void *optval, socklen_t *optlen); -int (*_zts_getsockname)(int fd, struct sockaddr *addr, socklen_t *addrlen); -int (*_zts_getpeername)(int fd, struct sockaddr *addr, socklen_t *addrlen); -int (*_zts_gethostname)(char *name, size_t len); -int (*_zts_sethostname)(const char *name, size_t len); -struct hostent *(*_zts_gethostbyname)(const char *name); -int (*_zts_close)(int fd); -int(*_zts_fcntl)(int fd, int cmd, int flags); -int (*_zts_ioctl)(int fd, unsigned long request, void *argp); -ssize_t (*_zts_send)(int fd, const void *buf, size_t len, int flags); -ssize_t (*_zts_sendto)(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen); -ssize_t (*_zts_sendmsg)(int fd, const struct msghdr *msg, int flags); -ssize_t (*_zts_recv)(int fd, void *buf, size_t len, int flags); -ssize_t (*_zts_recvfrom)(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen); -ssize_t (*_zts_recvmsg)(int fd, struct msghdr *msg,int flags); -int (*_zts_read)(int fd, void *buf, size_t len); -int (*_zts_write)(int fd, const void *buf, size_t len); -int (*_zts_shutdown)(int fd, int how); -int (*_zts_add_dns_nameserver)(struct sockaddr *addr); -int (*_zts_del_dns_nameserver)(struct sockaddr *addr); - - -void load_library_symbols(char *library_path) -{ - void *libHandle = dlopen(library_path, RTLD_LAZY); - if (libHandle == NULL) { - DEBUG_ERROR("unable to load dynamic libs: %s", dlerror()); - exit(-1); - } - - // Load symbols from library (call these directly) - - _zts_set_service_port = (int(*)(int portno))dlsym(libHandle, "zts_set_service_port"); - _zts_start = (int(*)(const char *path, bool blocking))dlsym(libHandle, "zts_start"); - _zts_startjoin = (int(*)(const char*, uint64_t))dlsym(libHandle, "zts_startjoin"); - _zts_stop = (void(*)(void))dlsym(libHandle, "zts_stop"); - _zts_core_running = (int(*)(void))dlsym(libHandle, "zts_core_running"); - _zts_stack_running = (int(*)(void))dlsym(libHandle, "zts_stack_running"); - _zts_ready = (int(*)(void))dlsym(libHandle, "zts_ready"); - _zts_join = (int(*)(const uint64_t))dlsym(libHandle, "zts_join"); - _zts_leave = (int(*)(const uint64_t))dlsym(libHandle, "zts_leave"); - _zts_get_path = (void(*)(char *homePath, const size_t len))dlsym(libHandle, "zts_get_path"); - _zts_get_node_id = (uint64_t(*)(void))dlsym(libHandle, "zts_get_node_id"); - _zts_has_address = (int(*)(const uint64_t))dlsym(libHandle, "zts_has_address"); - _zts_get_num_assigned_addresses = (int(*)(const uint64_t nwid))dlsym(libHandle, "zts_get_num_assigned_addresses"); - _zts_get_address_at_index = (int(*)(const uint64_t nwid, const int index, struct sockaddr_storage *addr))dlsym(libHandle, "zts_get_address_at_index"); - _zts_get_address = (int(*)(const uint64_t nwid, struct sockaddr_storage *addr, const int address_family))dlsym(libHandle, "zts_get_address"); - _zts_get_6plane_addr = (void(*)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId))dlsym(libHandle, "zts_get_6plane_addr"); - _zts_get_rfc4193_addr = (void(*)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId))dlsym(libHandle, "zts_get_rfc4193_addr"); - _zts_get_peer_count = (unsigned long(*)(void))dlsym(libHandle, "zts_get_peer_count"); - _zts_get_peer_address = (int(*)(char *peer, const uint64_t nodeId))dlsym(libHandle, "zts_get_peer_address"); - _zts_socket = (int(*)(int socket_family, int socket_type, int protocol))dlsym(libHandle, "zts_socket"); - _zts_connect = (int(*)(int fd, const struct sockaddr *addr, socklen_t addrlen))dlsym(libHandle, "zts_connect"); - _zts_bind = (int(*)(int fd, const struct sockaddr *addr, socklen_t addrlen))dlsym(libHandle, "zts_bind"); - _zts_listen = (int(*)(int fd, int backlog))dlsym(libHandle, "zts_listen"); - _zts_accept = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_accept"); - #if defined(__linux__) - _zts_accept4 = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags))dlsym(libHandle, "zts_accept4"); - #endif - _zts_setsockopt = (int(*)(int fd, int level, int optname, const void *optval, socklen_t optlen))dlsym(libHandle, "zts_setsockopt"); - _zts_getsockopt = (int(*)(int fd, int level, int optname, void *optval, socklen_t *optlen))dlsym(libHandle, "zts_getsockopt"); - _zts_getsockname = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_getsockname"); - _zts_getpeername = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_getpeername"); - _zts_gethostname = (int(*)(char *name, size_t len))dlsym(libHandle, "zts_gethostname"); - _zts_sethostname = (int(*)(const char *name, size_t len))dlsym(libHandle, "zts_sethostname"); - _zts_gethostbyname = (struct hostent*(*)(const char *name))dlsym(libHandle, "zts_gethostbyname"); - _zts_close = (int(*)(int fd))dlsym(libHandle, "zts_close"); - _zts_fcntl = (int(*)(int fd, int cmd, int flags))dlsym(libHandle, "zts_fcntl"); - _zts_ioctl = (int(*)(int fd, unsigned long request, void *argp))dlsym(libHandle, "zts_ioctl"); - _zts_send = (ssize_t(*)(int fd, const void *buf, size_t len, int flags))dlsym(libHandle, "zts_send"); - _zts_sendto = (ssize_t(*)(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen))dlsym(libHandle, "zts_sendto"); - _zts_sendmsg = (ssize_t(*)(int fd, const struct msghdr *msg, int flags))dlsym(libHandle, "zts_sendmsg"); - _zts_recv = (ssize_t(*)(int fd, void *buf, size_t len, int flags))dlsym(libHandle, "zts_recv"); - _zts_recvfrom = (ssize_t(*)(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_recvfrom"); - _zts_recvmsg = (ssize_t(*)(int fd, struct msghdr *msg,int flags))dlsym(libHandle, "zts_recvmsg"); - _zts_read = (int(*)(int fd, void *buf, size_t len))dlsym(libHandle, "zts_read"); - _zts_write = (int(*)(int fd, const void *buf, size_t len))dlsym(libHandle, "zts_write"); - _zts_shutdown = (int(*)(int fd, int how))dlsym(libHandle, "zts_shutdown"); - _zts_add_dns_nameserver = (int(*)(struct sockaddr *addr))dlsym(libHandle, "zts_add_dns_nameserver"); -} - -char *msg = (char*)"welcome to the machine"; - -int main(int argc, char **argv) -{ - if (argc != 5) { - printf("\nlibzt example client\n"); - printf("client [config_file_path] [nwid] [remote_addr] [remote_port]\n"); - exit(0); - } - -#ifdef __linux__ - char *library_path = (char*)"./libzt.so"; -#endif -#ifdef __APPLE__ - char *library_path = (char*)"./libzt.dylib"; -#endif - load_library_symbols(library_path); - - std::string path = argv[1]; - std::string nwidstr = argv[2]; - std::string remote_addr = argv[3]; - int remote_port = atoi(argv[4]); - int r=0, w=0, err=0, sockfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in in4; - in4.sin_port = htons(remote_port); - in4.sin_addr.s_addr = inet_addr(remote_addr.c_str()); - in4.sin_family = AF_INET; - - // - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - _zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = _zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = _zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - - if ((err = _zts_connect(sockfd, (const struct sockaddr *)&in4, sizeof(in4))) < 0) { - printf("error connecting to remote host (%d)\n", err); - } - - printf("sending to server...\n"); - w = _zts_write(sockfd, msg, strlen(msg)); - - printf("reading from server...\n"); - r = _zts_read(sockfd, rbuf, strlen(msg)); - - printf("Sent : %s\n", msg); - printf("Received : %s\n", rbuf); - - err = _zts_close(sockfd); - - return err; -} - -#endif // _MSC_VER \ No newline at end of file diff --git a/examples/cpp/sharedlib/ipv4server_shared.cpp b/examples/cpp/sharedlib/ipv4server_shared.cpp deleted file mode 100644 index e5262cb..0000000 --- a/examples/cpp/sharedlib/ipv4server_shared.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#if !defined(_MSC_VER) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libzt.h" - -// function pointers which will have values assigned once the dynamic library is loaded - -int (*_zts_set_service_port)(int portno); -int (*_zts_start)(const char *path, bool blocking); -int (*_zts_startjoin)(const char*, uint64_t); -void (*_zts_stop)(void); -int (*_zts_core_running)(void); -int (*_zts_stack_running)(void); -int (*_zts_ready)(void); -int (*_zts_join)(const uint64_t); -int (*_zts_leave)(const uint64_t); -void (*_zts_get_path)(char *homePath, const size_t len); -uint64_t (*_zts_get_node_id)(void); -int (*_zts_has_address)(const uint64_t); -int (*_zts_get_num_assigned_addresses)(const uint64_t nwid); -int (*_zts_get_address_at_index)(const uint64_t nwid, const int index, struct sockaddr_storage *addr); -int (*_zts_get_address)(const uint64_t nwid, struct sockaddr_storage *addr, const int address_family); -void (*_zts_get_6plane_addr)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); -void (*_zts_get_rfc4193_addr)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); -unsigned long (*_zts_get_peer_count)(void); -int (*_zts_get_peer_address)(char *peer, const uint64_t nodeId); -int (*_zts_socket)(int socket_family, int socket_type, int protocol); -int (*_zts_connect)(int fd, const struct sockaddr *addr, socklen_t addrlen); -int (*_zts_bind)(int fd, const struct sockaddr *addr, socklen_t addrlen); -int (*_zts_listen)(int fd, int backlog); -int (*_zts_accept)(int fd, struct sockaddr *addr, socklen_t *addrlen); -#if defined(__linux__) -int (*_zts_accept4)(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); -#endif -int (*_zts_setsockopt)(int fd, int level, int optname, const void *optval, socklen_t optlen); -int (*_zts_getsockopt)(int fd, int level, int optname, void *optval, socklen_t *optlen); -int (*_zts_getsockname)(int fd, struct sockaddr *addr, socklen_t *addrlen); -int (*_zts_getpeername)(int fd, struct sockaddr *addr, socklen_t *addrlen); -int (*_zts_gethostname)(char *name, size_t len); -int (*_zts_sethostname)(const char *name, size_t len); -struct hostent *(*_zts_gethostbyname)(const char *name); -int (*_zts_close)(int fd); -int(*_zts_fcntl)(int fd, int cmd, int flags); -int (*_zts_ioctl)(int fd, unsigned long request, void *argp); -ssize_t (*_zts_send)(int fd, const void *buf, size_t len, int flags); -ssize_t (*_zts_sendto)(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen); -ssize_t (*_zts_sendmsg)(int fd, const struct msghdr *msg, int flags); -ssize_t (*_zts_recv)(int fd, void *buf, size_t len, int flags); -ssize_t (*_zts_recvfrom)(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen); -ssize_t (*_zts_recvmsg)(int fd, struct msghdr *msg,int flags); -int (*_zts_read)(int fd, void *buf, size_t len); -int (*_zts_write)(int fd, const void *buf, size_t len); -int (*_zts_shutdown)(int fd, int how); -int (*_zts_add_dns_nameserver)(struct sockaddr *addr); -int (*_zts_del_dns_nameserver)(struct sockaddr *addr); - - -void load_library_symbols(char *library_path) -{ - void *libHandle = dlopen(library_path, RTLD_LAZY); - if (libHandle == NULL) { - DEBUG_ERROR("unable to load dynamic libs: %s", dlerror()); - exit(-1); - } - - // Load symbols from library (call these directly) - - _zts_set_service_port = (int(*)(int portno))dlsym(libHandle, "zts_set_service_port"); - _zts_start = (int(*)(const char *path, bool blocking))dlsym(libHandle, "zts_start"); - _zts_startjoin = (int(*)(const char*, uint64_t))dlsym(libHandle, "zts_startjoin"); - _zts_stop = (void(*)(void))dlsym(libHandle, "zts_stop"); - _zts_core_running = (int(*)(void))dlsym(libHandle, "zts_core_running"); - _zts_stack_running = (int(*)(void))dlsym(libHandle, "zts_stack_running"); - _zts_ready = (int(*)(void))dlsym(libHandle, "zts_ready"); - _zts_join = (int(*)(const uint64_t))dlsym(libHandle, "zts_join"); - _zts_leave = (int(*)(const uint64_t))dlsym(libHandle, "zts_leave"); - _zts_get_path = (void(*)(char *homePath, const size_t len))dlsym(libHandle, "zts_get_path"); - _zts_get_node_id = (uint64_t(*)(void))dlsym(libHandle, "zts_get_node_id"); - _zts_has_address = (int(*)(const uint64_t))dlsym(libHandle, "zts_has_address"); - _zts_get_num_assigned_addresses = (int(*)(const uint64_t nwid))dlsym(libHandle, "zts_get_num_assigned_addresses"); - _zts_get_address_at_index = (int(*)(const uint64_t nwid, const int index, struct sockaddr_storage *addr))dlsym(libHandle, "zts_get_address_at_index"); - _zts_get_address = (int(*)(const uint64_t nwid, struct sockaddr_storage *addr, const int address_family))dlsym(libHandle, "zts_get_address"); - _zts_get_6plane_addr = (void(*)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId))dlsym(libHandle, "zts_get_6plane_addr"); - _zts_get_rfc4193_addr = (void(*)(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId))dlsym(libHandle, "zts_get_rfc4193_addr"); - _zts_get_peer_count = (unsigned long(*)(void))dlsym(libHandle, "zts_get_peer_count"); - _zts_get_peer_address = (int(*)(char *peer, const uint64_t nodeId))dlsym(libHandle, "zts_get_peer_address"); - _zts_socket = (int(*)(int socket_family, int socket_type, int protocol))dlsym(libHandle, "zts_socket"); - _zts_connect = (int(*)(int fd, const struct sockaddr *addr, socklen_t addrlen))dlsym(libHandle, "zts_connect"); - _zts_bind = (int(*)(int fd, const struct sockaddr *addr, socklen_t addrlen))dlsym(libHandle, "zts_bind"); - _zts_listen = (int(*)(int fd, int backlog))dlsym(libHandle, "zts_listen"); - _zts_accept = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_accept"); - #if defined(__linux__) - _zts_accept4 = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags))dlsym(libHandle, "zts_accept4"); - #endif - _zts_setsockopt = (int(*)(int fd, int level, int optname, const void *optval, socklen_t optlen))dlsym(libHandle, "zts_setsockopt"); - _zts_getsockopt = (int(*)(int fd, int level, int optname, void *optval, socklen_t *optlen))dlsym(libHandle, "zts_getsockopt"); - _zts_getsockname = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_getsockname"); - _zts_getpeername = (int(*)(int fd, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_getpeername"); - _zts_gethostname = (int(*)(char *name, size_t len))dlsym(libHandle, "zts_gethostname"); - _zts_sethostname = (int(*)(const char *name, size_t len))dlsym(libHandle, "zts_sethostname"); - _zts_gethostbyname = (struct hostent*(*)(const char *name))dlsym(libHandle, "zts_gethostbyname"); - _zts_close = (int(*)(int fd))dlsym(libHandle, "zts_close"); - _zts_fcntl = (int(*)(int fd, int cmd, int flags))dlsym(libHandle, "zts_fcntl"); - _zts_ioctl = (int(*)(int fd, unsigned long request, void *argp))dlsym(libHandle, "zts_ioctl"); - _zts_send = (ssize_t(*)(int fd, const void *buf, size_t len, int flags))dlsym(libHandle, "zts_send"); - _zts_sendto = (ssize_t(*)(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen))dlsym(libHandle, "zts_sendto"); - _zts_sendmsg = (ssize_t(*)(int fd, const struct msghdr *msg, int flags))dlsym(libHandle, "zts_sendmsg"); - _zts_recv = (ssize_t(*)(int fd, void *buf, size_t len, int flags))dlsym(libHandle, "zts_recv"); - _zts_recvfrom = (ssize_t(*)(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen))dlsym(libHandle, "zts_recvfrom"); - _zts_recvmsg = (ssize_t(*)(int fd, struct msghdr *msg,int flags))dlsym(libHandle, "zts_recvmsg"); - _zts_read = (int(*)(int fd, void *buf, size_t len))dlsym(libHandle, "zts_read"); - _zts_write = (int(*)(int fd, const void *buf, size_t len))dlsym(libHandle, "zts_write"); - _zts_shutdown = (int(*)(int fd, int how))dlsym(libHandle, "zts_shutdown"); - _zts_add_dns_nameserver = (int(*)(struct sockaddr *addr))dlsym(libHandle, "zts_add_dns_nameserver"); -} - -int main(int argc, char **argv) -{ - if (argc != 4) { - printf("\nlibzt example server\n"); - printf("server [config_file_path] [nwid] [bind_port]\n"); - exit(0); - } - -#ifdef __linux__ - char *library_path = (char*)"./libzt.so"; -#endif -#ifdef __APPLE__ - char *library_path = (char*)"./libzt.dylib"; -#endif - load_library_symbols(library_path); - - std::string path = argv[1]; - std::string nwidstr = argv[2]; - int bind_port = atoi(argv[3]); - int w=0, r=0, err=0, sockfd, accfd; - char rbuf[32]; - memset(rbuf, 0, sizeof rbuf); - - struct sockaddr_in in4, acc_in4; - in4.sin_port = htons(bind_port); - in4.sin_addr.s_addr = INADDR_ANY; - in4.sin_family = AF_INET; - - // - - printf("Waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - printf("nwid=%llx\n", (unsigned long long)nwid); - _zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = _zts_get_node_id(); - printf("I am %llx\n", (unsigned long long)nodeId); - - if ((sockfd = _zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) { - printf("error creating ZeroTier socket\n"); - } - if ((err = _zts_bind(sockfd, (struct sockaddr *)&in4, sizeof(struct sockaddr_in)) < 0)) { - printf("error binding to interface (%d)\n", err); - } - if ((err = _zts_listen(sockfd, 100)) < 0) { - printf("error placing socket in LISTENING state (%d)\n", err); - } - socklen_t client_addrlen = sizeof(sockaddr_in); - if ((accfd = _zts_accept(sockfd, (struct sockaddr *)&acc_in4, &client_addrlen)) < 0) { - printf("error accepting connection (%d)\n", err); - } - - socklen_t peer_addrlen = sizeof(struct sockaddr_storage); - _zts_getpeername(accfd, (struct sockaddr*)&acc_in4, &peer_addrlen); - DEBUG_INFO("accepted connection from %s : %d\n", inet_ntoa(acc_in4.sin_addr), ntohs(acc_in4.sin_port)); - - printf("reading from client...\n"); - r = _zts_read(accfd, rbuf, sizeof rbuf); - - printf("sending to client...\n"); - w = _zts_write(accfd, rbuf, strlen(rbuf)); - - printf("Received : %s\n", rbuf); - - err = _zts_close(sockfd); - err = _zts_close(accfd); - - return err; -} - -#endif // _MSC_VER diff --git a/test/example.cpp b/test/example.cpp deleted file mode 100644 index 11ff33c..0000000 --- a/test/example.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include -#include -#include -#include - -#include "ZeroTier.h" - -bool node_ready = false; -bool network_ready = false; - -// Example callbacks -void myZeroTierEventCallback(struct zts_callback_msg *msg) -{ - // - // Node events - // - if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) { - printf("ZTS_EVENT_NODE_ONLINE, node=%llx\n", msg->node->address); - node_ready = true; - // ZeroTier service is running and online - } - if (msg->eventCode == ZTS_EVENT_NODE_OFFLINE) { - printf("ZTS_EVENT_NODE_OFFLINE\n"); - node_ready = false; - // ZeroTier service is running and online - } - if (msg->eventCode == ZTS_EVENT_NODE_NORMAL_TERMINATION) { - printf("ZTS_EVENT_NODE_NORMAL_TERMINATION\n"); - // ZeroTier service has stopped - } - - // - // Virtual network events - // - if (msg->eventCode == ZTS_EVENT_NETWORK_NOT_FOUND) { - printf("ZTS_EVENT_NETWORK_NOT_FOUND --- network=%llx\n", msg->network->nwid); - // Is your nwid incorrect? - } - if (msg->eventCode == ZTS_EVENT_NETWORK_REQUESTING_CONFIG) { - printf("ZTS_EVENT_NETWORK_REQUESTING_CONFIG --- network=%llx\n", msg->network->nwid); - // Node is requesting network config details from controller, please wait - } - if (msg->eventCode == ZTS_EVENT_NETWORK_ACCESS_DENIED) { - printf("ZTS_EVENT_NETWORK_ACCESS_DENIED --- network=%llx\n", msg->network->nwid); - // This node is not authorized to join nwid - } - if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) { - printf("ZTS_EVENT_NETWORK_READY_IP4 --- network=%llx\n", msg->network->nwid); - network_ready = true; - // IPv4 traffic can now be processed for nwid - } - if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) { - printf("ZTS_EVENT_NETWORK_READY_IP6 --- network=%llx\n", msg->network->nwid); - network_ready = true; - } - if (msg->eventCode == ZTS_EVENT_NETWORK_DOWN) { - printf("ZTS_EVENT_NETWORK_DOWN --- network=%llx\n", msg->network->nwid); - // Can happen if another thread called zts_leave() - } - - // - // Network stack events - // - if (msg->eventCode == ZTS_EVENT_NETIF_UP) { - printf("ZTS_EVENT_NETIF_UP --- network=%llx, mac=%llx, mtu=%d\n", - msg->netif->nwid, - msg->netif->mac, - msg->netif->mtu); - network_ready = true; - } - if (msg->eventCode == ZTS_EVENT_NETIF_DOWN) { - printf("ZTS_EVENT_NETIF_DOWN --- network=%llx, mac=%llx\n", - msg->netif->nwid, - msg->netif->mac); - - network_ready = true; - } - - // - // Address events - // - if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP4) { - char ipstr[INET_ADDRSTRLEN]; - struct sockaddr_in *in4 = (struct sockaddr_in*)&(msg->addr->addr); - inet_ntop(AF_INET, &(in4->sin_addr), ipstr, INET_ADDRSTRLEN); - printf("ZTS_EVENT_ADDR_NEW_IP4 --- addr=%s (on network=%llx)\n", - ipstr, msg->addr->nwid); - } - if (msg->eventCode == ZTS_EVENT_ADDR_ADDED_IP6) { - char ipstr[INET6_ADDRSTRLEN]; - struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(msg->addr->addr); - inet_ntop(AF_INET6, &(in6->sin6_addr), ipstr, INET6_ADDRSTRLEN); - printf("ZTS_EVENT_ADDR_NEW_IP6 --- addr=%s (on network=%llx)\n", - ipstr, msg->addr->nwid); - } - if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP4) { - char ipstr[INET_ADDRSTRLEN]; - struct sockaddr_in *in4 = (struct sockaddr_in*)&(msg->addr->addr); - inet_ntop(AF_INET, &(in4->sin_addr), ipstr, INET_ADDRSTRLEN); - printf("ZTS_EVENT_ADDR_REMOVED_IP4 --- addr=%s (on network=%llx)\n", - ipstr, msg->addr->nwid); - } - if (msg->eventCode == ZTS_EVENT_ADDR_REMOVED_IP6) { - char ipstr[INET6_ADDRSTRLEN]; - struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(msg->addr->addr); - inet_ntop(AF_INET6, &(in6->sin6_addr), ipstr, INET6_ADDRSTRLEN); - printf("ZTS_EVENT_ADDR_REMOVED_IP6 --- addr=%s (on network=%llx)\n", - ipstr, msg->addr->nwid); - } - - // - // Peer events - // - if (msg->eventCode == ZTS_EVENT_PEER_P2P) { - printf("ZTS_EVENT_PEER_P2P --- node=%llx\n", msg->peer->address); - // A direct path is known for nodeId - } - if (msg->eventCode == ZTS_EVENT_PEER_RELAY) { - printf("ZTS_EVENT_PEER_RELAY --- node=%llx\n", msg->peer->address); - // No direct path is known for nodeId - } -} - -void printPeerDetails(struct zts_peer_details *pd) -{ - printf("\npeer=%llx, latency=%d, version=%d.%d.%d, pathCount=%d\n", - pd->address, - pd->latency, - pd->versionMajor, - pd->versionMinor, - pd->versionRev, - pd->pathCount); - // Print all known paths for each peer - for (int j=0; jpathCount; j++) { - char ipstr[INET6_ADDRSTRLEN]; - int port; - struct sockaddr *sa = (struct sockaddr *)&(pd->paths[j].address); - if (sa->sa_family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in*)sa; - inet_ntop(AF_INET, &(in4->sin_addr), ipstr, INET_ADDRSTRLEN); - port = ntohs(in4->sin_port); - } - if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *in6 = (struct sockaddr_in6*)sa; - inet_ntop(AF_INET6, &(in6->sin6_addr), ipstr, INET6_ADDRSTRLEN); - } - printf("\tpath[%d]=%s, port=%d\n", j, ipstr, port); - } -} - -void getSinglePeerDetails(uint64_t peerId) -{ - struct zts_peer_details pd; - int err = zts_get_peer(&pd, peerId); - - if (err == ZTS_ERR_OK) { - printf("(%d) call succeeded\n", err); - } if (err == ZTS_ERR_INVALID_ARG) { - printf("(%d) invalid argument\n", err); - return; - } if (err == ZTS_ERR_SERVICE) { - printf("(%d) error: service is unavailable\n", err); - return; - } if (err == ZTS_ERR_INVALID_OP) { - printf("(%d) error: invalid API operation\n", err); - return; - } if (err == ZTS_ERR_NO_RESULT) { - printf("(%d) error: object or result not found\n", err); - return; - } - if (err == 0) { // ZTS_ERR_OK - printPeerDetails(&pd); - } -} - -// Similar to "zerotier-cli listpeers" -void getAllPeerDetails() -{ - struct zts_peer_details pd[128]; - /* This number should be large enough to handle the - expected number of peers. This call can also get - expensive for large numbers of peers. Consider using - get_peer(struct zts_peer_details *pds, uint64_t peerId) - instead */ - int num = 128; - int err; - if ((err = zts_get_peers(pd, &num)) < 0) { - printf("error (%d)\n", err); - return; - } - if (num) { - printf("num=%d\n", num); - for (int i=0; i. - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libzt.h" - -#if defined(__SELFTEST__) -#include "Utils.hpp" -#endif - -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - - -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) - #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else - #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif - -void micro_sleep(unsigned long us) -{ - std::this_thread::sleep_for(std::chrono::microseconds(us)); -} - -#if defined(_WIN32) -#include -#include -#include -#include -#include -#include - -void sleep(unsigned long ms) -{ - Sleep(ms); -} - -struct timezone -{ - int tz_minuteswest; - int tz_dsttime; -}; - - -int gettimeofday(struct timeval *tv, struct timezone *tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; - - if (NULL != tv) - { - GetSystemTimeAsFileTime(&ft); - - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - - /*converting file time to unix epoch*/ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tmpres /= 10; /*convert into microseconds*/ - tv->tv_sec = (long)(tmpres / 1000000UL); - tv->tv_usec = (long)(tmpres % 1000000UL); - } - - if (NULL != tz) - { - if (!tzflag) - { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - - return 0; -} -#endif - - -#define EXIT_ON_FAIL false - -#define TEST_PASSED 1 -#define TEST_FAILED 0 - -#define ECHO_INTERVAL 1000000 // microseconds -#define SLAM_INTERVAL 500000 // microseconds - -#define ARTIFICIAL_SOCKET_LINGER 1 - -#define STR_SIZE 32 - -#define TEST_OP_N_BYTES 10 -#define TEST_OP_N_SECONDS 11 -#define TEST_OP_N_TIMES 12 - -#define TEST_MODE_CLIENT 20 -#define TEST_MODE_SERVER 21 - -#define TEST_TYPE_SIMPLE 30 -#define TEST_TYPE_SUSTAINED 31 -#define TEST_TYPE_PERF 32 -#define TEST_TYPE_PERF_TO_ECHO 33 - -#define MIN_PORT 5000 -#define MAX_PORT 50000 - -#define TCP_UNIT_TEST_SIG_4 struct sockaddr_in *addr, int op, int cnt, char *details, bool *passed -#define UDP_UNIT_TEST_SIG_4 struct sockaddr_in *local_addr, struct sockaddr_in *remote_addr, int op, int cnt, char *details, bool *passed - -#define TCP_UNIT_TEST_SIG_6 struct sockaddr_in6 *addr, int op, int cnt, char *details, bool *passed -#define UDP_UNIT_TEST_SIG_6 struct sockaddr_in6 *local_addr, struct sockaddr_in6 *remote_addr, int op, int cnt, char *details, bool *passed - -#define ECHOTEST_MODE_RX 333 -#define ECHOTEST_MODE_TX 666 - -#define MAX_RX_BUF_SZ 2048 -#define MAX_TX_BUF_SZ 2048 - -#define ONE_MEGABYTE 1024 * 1024 - -#define DETAILS_STR_LEN 128 - -// If running a self test, use libzt calls -#if defined(__SELFTEST__) -#define _SOCKET zts_socket -#define _BIND zts_bind -#define _LISTEN zts_listen -#define _ACCEPT zts_accept -#define _CONNECT zts_connect -#define _READ zts_read -#define _WRITE zts_write -#define _RECV zts_recv -#define _SEND zts_send -#define _RECVFROM zts_recvfrom -#define _SENDTO zts_sendto -#define _RECVMSG zts_recvmsg -#define _SENDMSG zts_sendmsg -#define _SETSOCKOPT zts_setsockopt -#define _GETSOCKOPT zts_getsockopt -#define _IOCTL zts_ioctl -#define _FCNTL zts_fcntl -#define _SELECT zts_select -#define _CLOSE zts_close -#define _GETPEERNAME zts_getpeername -#endif - -// If running a native instance to test against, use system calls -#if defined(__NATIVETEST__) -inline unsigned int gettid() -{ -#ifdef _WIN32 - return GetCurrentThreadId(); -#elif defined(__unix__) - return static_cast(::syscall(__NR_gettid)); -#elif defined(__APPLE__) - uint64_t tid64; - pthread_threadid_np(NULL, &tid64); - return static_cast(tid64); -#endif -} - -#define _SOCKET socket -#define _BIND bind -#define _LISTEN listen -#define _ACCEPT accept -#define _CONNECT connect -#define _RECV recvmsg -#define _SEND send -#define _RECVFROM recvfrom -#define _SENDTO sendto -#define _RECVMSG recvmsg -#define _SENDMSG sendmsg -#define _SETSOCKOPT setsockopt -#define _GETSOCKOPT getsockopt -#define _IOCTL ioctl -#define _FCNTL fcntl -#define _SELECT select - -#define _READ read -#define _WRITE write - -//#define _RECV recv -//#define _SEND send - -#if defined(_WIN32) -#define _CLOSE closesocket -#else -#define _CLOSE close -#endif - -#define _GETPEERNAME getpeername -#endif - -std::map testConf; - -/* Tests in this file: - - Basic RX/TX connect()/accept() Functionality: - - [ ?] slam - perform thousands of the same call per second - [ ] random - act like a monkey, press all the buttons - [OK] simple client ipv4 - connect, send one message and wait for an echo - [OK] simple server ipv4 - accept, read one message and echo it back - [OK] simple client ipv6 - connect, send one message and wait for an echo - [OK] simple server ipv6 - accept, read one message and echo it back - [OK] sustained client ipv4 - connect and rx/tx many messages, VERIFIES data integrity - [OK] sustained server ipv4 - accept and echo messages, VERIFIES data integrity - [OK] sustained client ipv6 - connect and rx/tx many messages, VERIFIES data integrity - [OK] sustained server ipv6 - accept and echo messages, VERIFIES data integrity - [OK] comprehensive client ipv4 - test all ipv4/6 client simple/sustained modes - [OK] comprehensive server ipv6 - test all ipv4/6 server simple/sustained modes - [ ?] SOCK_RAW (VL2) ipv4 - See test/layer2.cpp - [ ?] SOCK_RAW (VL2) ipv6 - See test/layer2.cpp - - Performance: - (See libzt.h, compile libzt with appropriate ZT_TCP_TX_BUF_SZ, ZT_TCP_RX_BUF_SZ, ZT_UDP_TX_BUF_SZ, and ZT_UDO_RX_BUF_SZ for your test) - - [OK] Throughput - Test maximum RX/TX speeds - [ ] Memory Usage - Test memory consumption profile - [ ] CPU Usage - Test processor usage - [ ] - - Correctness: - - [ ] Block/Non-block - Test that blocking and non-blocking behaviour is consistent - [ ] Release of resources - Test that all destructor methods/blocks function properly - [OK] Multi-network handling - Test internal Tap multiplexing works for multiple networks - [ ] Address handling - Test that addresses are copied/parsed/returned properly - -*/ - - - - - -/****************************************************************************/ -/* Helper Functions */ -/****************************************************************************/ - -/** Returns true on success, or false if there was an error */ -bool SetSocketBlockingEnabled(int fd, bool blocking) -{ - if (fd < 0) return false; -#ifdef _WIN32 - unsigned long mode = blocking ? 0 : 1; - return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? true : false; -#else - int flags = _FCNTL(fd, F_GETFL, 0); - if (flags == -1) return false; - flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); - return (_FCNTL(fd, F_SETFL, flags) == 0) ? true : false; -#endif -} - -void displayResults(int *results, int size) -{ - int success = 0, failure = 0; - for (int i=0; i get_now_ts()) { - sleep(1); - } -} -void wait_until_tplus_s(long int original_time, int tplus_s) -{ - int current_time_offset = (get_now_ts() - original_time) / 1000; - fprintf(stderr, "\n\n--- WAITING FOR T+%d --- (current: T+%d)\n\n", tplus_s, current_time_offset); - if (current_time_offset > tplus_s) { - DEBUG_ERROR("--- ABORTING TEST: Tests are out of sync and might not yield valid results. ---"); - //exit(0); - } - if (current_time_offset == tplus_s) { - DEBUG_ERROR("--- WARNING: Tests might be out of sync and might not yield valid results. ---"); - } - wait_until_tplus(original_time, tplus_s * 1000); -} - -int rand_in_range(int min, int max) -{ -#if defined(__SELFTEST__) - unsigned int seed; - ZeroTier::Utils::getSecureRandom((void*)&seed,sizeof(seed)); - srand(seed); -#else - srand((unsigned int)time(NULL)); -#endif - return min + rand() % static_cast(max - min + 1); -} - -void generate_random_data(void *buf, size_t n, int min, int max) -{ - char *b = (char*)buf; - for (size_t i=0; isin_addr.s_addr = inet_addr(ipstr.c_str()); - in4->sin_family = AF_INET; - in4->sin_port = htons(port); - } if (ipv == 6) { - struct sockaddr_in6 *in6 = (struct sockaddr_in6*)saddr; - inet_pton(AF_INET6, ipstr.c_str(), &(in6->sin6_addr)); - in6->sin6_flowinfo = 0; - in6->sin6_family = AF_INET6; - in6->sin6_port = htons(port); - } -} - -void RECORD_RESULTS(bool passed, char *details, std::vector *results) -{ - char *ok_str = (char*)"[ OK ]"; - char *fail_str = (char*)"[ FAIL ]"; - if (passed == TEST_PASSED) { - DEBUG_TEST("%s", ok_str); - results->push_back(std::string(ok_str) + " " + std::string(details)); - } else { - DEBUG_ERROR("%s", fail_str); - results->push_back(std::string(fail_str) + " " + std::string(details)); - } if (EXIT_ON_FAIL && !passed) { - fprintf(stderr, "%s\n", results->at(results->size()-1).c_str()); - exit(0); - } - memset(details, 0, DETAILS_STR_LEN); -} - -void wait_until_everyone_is_ready(struct sockaddr *local_addr, struct sockaddr *remote_addr, int start_port) -{ - /* try to connect to (and listen for) other selftest instances on the network. - When one is found, send some sort of synchronization message and allow test to - begin */ - int err; - bool connected = false; - int accepted_fd; - // listen socket setup - int listen_fd; - if ((listen_fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket"); - exit(0); - } if ((err = _BIND(listen_fd, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in)) < 0)) { - perror("bind"); - exit(0); - } if ((err = _LISTEN(listen_fd, 0)) < 0) { - perror("listen"); - exit(0); - } - SetSocketBlockingEnabled(listen_fd, true); - // connect socket setup - int conn_fd; - if ((conn_fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket"); - exit(0); - } - SetSocketBlockingEnabled(conn_fd, true); - while(connected == false) { - if ((err = _CONNECT(conn_fd, (const struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) { - if (errno == EISCONN) { - DEBUG_TEST("connected"); - connected = true; - } - } - else { - connected = true; - } - if (connected == false) { - struct sockaddr_in client; - socklen_t client_addrlen = sizeof(sockaddr_in); - if ((accepted_fd = _ACCEPT(listen_fd, (struct sockaddr *)&client, &client_addrlen)) < 0) { - //DEBUG_TEST("errno = %d", errno); - } - else { - DEBUG_TEST("connected"); - connected = true; - } - } - sleep(1); - } - _CLOSE(listen_fd); - _CLOSE(conn_fd); - _CLOSE(accepted_fd); -} - - -/****************************************************************************/ -/* POLL/_SELECT */ -/****************************************************************************/ - -void tcp_select_server(TCP_UNIT_TEST_SIG_4) -{ - std::string testname = "tcp_select_server"; - std::string msg = "tcp_select"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "accept connection, create poll/select loop, read and write strings back and forth\n"); - int w=0, r=0, fd, client_fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - perror("socket"); - *passed = false; - return; - } - if ((err = _BIND(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - if ((err = _LISTEN(fd, 100)) < 0) { - printf("error placing socket in _LISTENING state (%d)", err); - perror("listen"); - *passed = false; - return; - } - struct sockaddr_in client; - socklen_t client_addrlen = sizeof(sockaddr_in); - if ((client_fd = _ACCEPT(fd, (struct sockaddr *)&client, &client_addrlen)) < 0) { - perror("accept"); - *passed = false; - return; - } - - DEBUG_TEST("accepted connection fd=%d", client_fd); - - fd_set read_set, write_set; - memset(&read_set, 0, sizeof(read_set)); - memset(&write_set, 0, sizeof(write_set)); - - uint32_t msecs = 5; - struct timeval tv; - tv.tv_sec = msecs / 1000; - tv.tv_usec = (msecs % 1000) * 1000; - int ret = 0; - - FD_SET(client_fd, &read_set); - FD_SET(client_fd, &write_set); - - int tot = 1000, rx_num = 0, tx_num = 0; - - while(rx_num < tot && tx_num < tot) { - - FD_ZERO(&read_set); - FD_ZERO(&write_set); - - FD_SET(client_fd, &read_set); - FD_SET(client_fd, &write_set); - - ret = _SELECT(client_fd + 1, &read_set, &write_set, NULL, &tv); - - if (ret > 0) { - for (int fd_i=0; fd_i 0) { - DEBUG_TEST("socket activity"); - for (int fd_i=0; fd_i %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port)); - -#if defined(_WIN32) - w = _SEND(fd, msg.c_str(), len, 0); -#else - w = _WRITE(fd, msg.c_str(), len); -#endif -#if defined(_WIN32) - r = _RECV(fd, rbuf, len, 0); -#else - r = _READ(fd, rbuf, len); -#endif - DEBUG_TEST("Sent : %s", msg.c_str()); - DEBUG_TEST("Received : %s", rbuf); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - - - - - -void tcp_server_4(TCP_UNIT_TEST_SIG_4) -{ - std::string testname = "tcp_server_4"; - std::string msg = "tcp_cs_4"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "accept connection with IPv4 address, read string, write string, compare.\n"); - int w=0, r=0, fd, client_fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _BIND(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - if ((err = _LISTEN(fd, 100)) < 0) { - printf("error placing socket in _LISTENING state (%d)", err); - perror("listen"); - *passed = false; - return; - } - struct sockaddr_in client; - socklen_t client_addrlen = sizeof(sockaddr_in); - if ((client_fd = _ACCEPT(fd, (struct sockaddr *)&client, &client_addrlen)) < 0) { - perror("accept"); - *passed = false; - return; - } - DEBUG_TEST("accepted connection from %s, on port %d", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); - // TODO: Put this test in the general API section - struct sockaddr_storage peer_addr; - struct sockaddr_in *in4 = (struct sockaddr_in*)&peer_addr; - socklen_t peer_addrlen = sizeof(peer_addr); - - if ((err = _GETPEERNAME(client_fd, (struct sockaddr*)&peer_addr, &peer_addrlen)) < 0) { - perror("getpeername"); - *passed = false; - return; - } - DEBUG_TEST("getpeername() => %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port)); -#if defined(_WIN32) - r = _RECV(client_fd, rbuf, len, 0); -#else - r = _READ(client_fd, rbuf, len); -#endif - -#if defined(_WIN32) - w = _SEND(client_fd, rbuf, len, 0); -#else - w = _WRITE(client_fd, rbuf, len); -#endif - DEBUG_TEST("Received : %s, r=%d, w=%d", rbuf, r, w); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - err = _CLOSE(client_fd); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - - - - - -void tcp_client_6(TCP_UNIT_TEST_SIG_6) -{ - std::string testname = "tcp_client_6"; - std::string msg = "tcp_cs_6"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "connect to remote host with IPv6 address, write string, read string, compare.\n"); - int r, w, fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET6, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _CONNECT(fd, (const struct sockaddr *)addr, sizeof(*addr))) < 0) { - DEBUG_ERROR("error connecting to remote host (%d)", err); - perror("connect"); - *passed = false; - return; - } - // TODO: Put this test in the general API section - struct sockaddr_storage peer_addr; - struct sockaddr_in6 *p6 = (struct sockaddr_in6*)&peer_addr; - socklen_t peer_addrlen = sizeof(peer_addr); - if ((err = _GETPEERNAME(fd, (struct sockaddr*)&peer_addr, &peer_addrlen)) < 0) { - perror("getpeername"); - *passed = false; - return; - } - char peer_addrstr[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &(p6->sin6_addr), peer_addrstr, INET6_ADDRSTRLEN); - DEBUG_TEST("getpeername() => %s : %d", peer_addrstr, ntohs(p6->sin6_port)); - -#if defined(_WIN32) - w = _SEND(fd, msg.c_str(), len, 0); -#else - w = _WRITE(fd, msg.c_str(), len); -#endif -#if defined(_WIN32) - r = _RECV(fd, rbuf, len, 0); -#else - r = _READ(fd, rbuf, len); -#endif - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - DEBUG_TEST("Sent : %s", msg.c_str()); - DEBUG_TEST("Received : %s", rbuf); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - - - - -void tcp_server_6(TCP_UNIT_TEST_SIG_6) -{ - std::string testname = "tcp_server_6"; - std::string msg = "tcp_cs_6"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "accept connection with IPv6 address, read string, write string, compare.\n"); - int w=0, r=0, fd, client_fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET6, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _BIND(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in6)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - if ((err = _LISTEN(fd, 100)) < 0) { - DEBUG_ERROR("error placing socket in _LISTENING state (%d)", err); - perror("listen"); - *passed = false; - return; - } - struct sockaddr_in6 client; - socklen_t client_addrlen = sizeof(sockaddr_in6); - if ((client_fd = _ACCEPT(fd, (struct sockaddr *)&client, &client_addrlen)) < 0) { - perror("accept"); - *passed = false; - return; - } - char ipstr[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &client.sin6_addr, ipstr, sizeof ipstr); - DEBUG_TEST("accepted connection from %s, on port %d", ipstr, ntohs(client.sin6_port)); - // TODO: Put this test in the general API section - struct sockaddr_storage peer_addr; - struct sockaddr_in6 *p6 = (struct sockaddr_in6*)&peer_addr; - socklen_t peer_addrlen = sizeof(peer_addr); - if ((err = _GETPEERNAME(client_fd, (struct sockaddr*)&peer_addr, &peer_addrlen)) < 0) { - perror("getpeername"); - *passed = false; - return; - } - char peer_addrstr[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &(p6->sin6_addr), peer_addrstr, INET6_ADDRSTRLEN); - DEBUG_TEST("getpeername() => %s : %d", peer_addrstr, ntohs(p6->sin6_port)); -#if defined(_WIN32) - r = _RECV(client_fd, rbuf, sizeof rbuf, 0); -#else - r = _READ(client_fd, rbuf, sizeof rbuf); -#endif -#if defined(_WIN32) - w = _SEND(client_fd, rbuf, len, 0); -#else - w = _WRITE(client_fd, rbuf, len); -#endif - DEBUG_TEST("Received : %s", rbuf); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - err = _CLOSE(client_fd); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - - - - - -// UDP - -void udp_client_4(UDP_UNIT_TEST_SIG_4) -{ - std::string testname = "udp_client_4"; - std::string msg = "udp_cs_4"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "bind to interface with IPv4 address, send string until response is seen. compare.\n"); - int r, w, fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET, SOCK_DGRAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - SetSocketBlockingEnabled(fd, true); - DEBUG_TEST("sending UDP packets until I get a single response..."); - if ((err = _BIND(fd, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - struct sockaddr_storage saddr; - while (true) { - sleep(1); - // tx - if ((w = _SENDTO(fd, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) { - DEBUG_ERROR("error sending packet, err=%d", errno); - } - memset(rbuf, 0, sizeof(rbuf)); - int serverlen = sizeof(struct sockaddr_storage); - // rx - r = _RECVFROM(fd, rbuf, STR_SIZE, 0, (struct sockaddr *)&saddr, (socklen_t *)&serverlen); - if (r == (int)strlen(msg.c_str())) { - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - DEBUG_TEST("%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - DEBUG_TEST("Sent : %s", msg.c_str()); - DEBUG_TEST("Received : %s", rbuf); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); - return; - } - } -} - - - - - -void udp_server_4(UDP_UNIT_TEST_SIG_4) -{ - std::string testname = "udp_server_4"; - std::string msg = "udp_cs_4"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "bind to interface with IPv4 address, read single string, send many responses. compare.\n"); - int r, w, fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET, SOCK_DGRAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _BIND(fd, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - // rx - DEBUG_TEST("waiting for UDP packet..."); - struct sockaddr_storage saddr; - struct sockaddr_in *in4 = (struct sockaddr_in*)&saddr; - int serverlen = sizeof(saddr); - memset(&saddr, 0, sizeof(saddr)); - if ((r = _RECVFROM(fd, rbuf, STR_SIZE, 0, (struct sockaddr *)in4, (socklen_t *)&serverlen)) < 0) { - perror("recvfrom"); - *passed = false; - return; - } - char addrstr[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &(in4->sin_addr), addrstr, INET_ADDRSTRLEN); - // once we receive a UDP packet, spend 10 seconds sending responses in the hopes that the client will see - DEBUG_TEST("received DGRAM from %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port)); - DEBUG_TEST("sending DGRAM(s) to %s : %d", inet_ntoa(remote_addr->sin_addr), ntohs(remote_addr->sin_port)); - // tx - long int tx_ti = get_now_ts(); - while (true) { - sleep(1); - if ((w = _SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) { - DEBUG_ERROR("error sending packet, err=%d", errno); - } - if (get_now_ts() >= tx_ti + 10000) { - break; - } - } - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - DEBUG_TEST("%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - DEBUG_TEST("Sent : %s", msg.c_str()); - DEBUG_TEST("Received : %s", rbuf); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - - - -int zts_bind_test(int fd, const struct sockaddr *addr, socklen_t addrlen) -{ - // int err = -1; - DEBUG_EXTRA("fd=%d", fd); - DEBUG_INFO("addrp=%p", addr); - DEBUG_INFO("addrlen=%d", addrlen); - DEBUG_INFO("sa_family======%d", addr->sa_family); - struct sockaddr_storage ss; - memcpy(&ss, addr, addrlen); - DEBUG_INFO("ss->sa_family=%d", ss.ss_family); - //fix_addr_socket_family((struct sockaddr*)&ss); - //ss.ss_family=AF_INET6; - //DEBUG_INFO("ss->sa_family=%d", ss.ss_family); - //err = lwip_bind(fd, (struct sockaddr*)&ss, addrlen); - exit(0); -} - -void udp_client_6(UDP_UNIT_TEST_SIG_6) -{ - std::string testname = "udp_client_6"; - std::string msg = "udp_cs_6"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "bind to interface with IPv6 address, send string until response is seen. compare.\n"); - int r, w, fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - - if ((fd = _SOCKET(AF_INET6, SOCK_DGRAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - SetSocketBlockingEnabled(fd, true); - DEBUG_TEST("[1] binding and sending UDP packets until I get a single response..."); - if ((err = _BIND(fd, (struct sockaddr*)local_addr, sizeof(struct sockaddr_in6)) < 0)) { - DEBUG_ERROR("error binding to interface (err=%d, errno=%d)", err, errno); - perror("bind"); - *passed = false; - return; - } - // start sending UDP packets in the hopes that at least one will be picked up by the server - struct sockaddr_storage saddr; - while (true) { - // tx - if ((w = _SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) { - DEBUG_ERROR("error sending packet, err=%d", errno); - } - micro_sleep(100000); - memset(rbuf, 0, sizeof(rbuf)); - int serverlen = sizeof(struct sockaddr_storage); - // rx - r = _RECVFROM(fd, rbuf, len, 0, (struct sockaddr *)&saddr, (socklen_t *)&serverlen); - if (r == len) { - DEBUG_TEST("[2] complete"); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - DEBUG_TEST("%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - DEBUG_TEST("Sent : %s", msg.c_str()); - DEBUG_TEST("Received : %s", rbuf); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); - return; - } - } -} - - - -void udp_server_6(UDP_UNIT_TEST_SIG_6) -{ - std::string testname = "udp_server_6"; - std::string msg = "udp_cs_6"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "bind to interface with IPv6 address, read single string, send many responses. compare.\n"); - int r, w, fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - - if ((fd = _SOCKET(AF_INET6, SOCK_DGRAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _BIND(fd, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in6)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - // rx - DEBUG_TEST("[1/3] waiting for UDP packet to start test..."); - struct sockaddr_storage saddr; - struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&saddr; - int serverlen = sizeof(saddr); - memset(&saddr, 0, sizeof(saddr)); - if ((r = _RECVFROM(fd, rbuf, len, 0, (struct sockaddr *)&saddr, (socklen_t *)&serverlen)) < 0) { - perror("recvfrom"); - *passed = false; - return; - } - char addrstr[INET6_ADDRSTRLEN], remote_addrstr[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &(in6->sin6_addr), addrstr, INET6_ADDRSTRLEN); - inet_ntop(AF_INET6, &(remote_addr->sin6_addr), remote_addrstr, INET6_ADDRSTRLEN); - DEBUG_TEST("[2/3] received DGRAM from %s : %d", addrstr, ntohs(in6->sin6_port)); - DEBUG_TEST("[2/3] sending DGRAM(s) to %s : %d", remote_addrstr, ntohs(remote_addr->sin6_port)); - // once we receive a UDP packet, spend 10 seconds sending responses in the hopes that the client will see - // tx - long int tx_ti = get_now_ts(); - while (true) { - micro_sleep(100000); - //DEBUG_TEST("sending UDP packet"); - if ((w = _SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) { - DEBUG_ERROR("error sending packet, err=%d", errno); - } - if (get_now_ts() >= tx_ti + 10000) { - // DEBUG_TEST("[3/4] get_now_ts()-tx_ti=%d", get_now_ts()-tx_ti); - break; - } - } - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - DEBUG_TEST("[3/3] complete, %s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - sprintf(details, "%s, err=%d, r=%d, w=%d", testname.c_str(), err, r, w); - DEBUG_TEST("Sent : %s", msg.c_str()); - DEBUG_TEST("Received : %s", rbuf); - *passed = (w == len && r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - - - - - - -/****************************************************************************/ -/* SUSTAINED */ -/****************************************************************************/ - - - - - -void tcp_client_sustained_4(TCP_UNIT_TEST_SIG_4) -{ - std::string testname = "tcp_client_sustained_4"; - std::string msg = "tcp_sustained_4"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "connect to remote host with IPv4 address, exchange a sequence of packets, check order.\n"); - int n=0, w=0, r=0, fd, err; - char *rxbuf = (char*)malloc(cnt*sizeof(char)); - char *txbuf = (char*)malloc(cnt*sizeof(char)); - generate_random_data(txbuf, cnt, 0, 9); - - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _CONNECT(fd, (const struct sockaddr *)addr, sizeof(*addr))) < 0) { - DEBUG_ERROR("error connecting to remote host (%d)", err); - perror("connect"); - *passed = false; - return; - } - if (op == TEST_OP_N_BYTES) { - int wrem = cnt, rrem = cnt; - // TX - long int tx_ti = get_now_ts(); - while (wrem) { - int next_write = std::min(4096, wrem); -#if !defined(_WIN32) - signal(SIGPIPE, SIG_IGN); -#endif - DEBUG_TEST("writing..."); -#if defined(_WIN32) - n = _SEND(fd, &txbuf[w], next_write, 0); -#else - n = _WRITE(fd, &txbuf[w], next_write); -#endif - DEBUG_TEST("wrote=%d", n); - if (n > 0) { - w += n; - wrem -= n; - err = n; - DEBUG_TEST("wrote=%d, w=%d, wrem=%d", n, w, wrem); - } - } - long int tx_tf = get_now_ts(); - DEBUG_TEST("wrote=%d, reading next...", w); - // RX - long int rx_ti = 0; - while (rrem) { -#if defined(_WIN32) - n = _RECV(fd, &rxbuf[r], rrem, 0); -#else - n = _READ(fd, &rxbuf[r], rrem); -#endif - if (rx_ti == 0) { // wait for first message - rx_ti = get_now_ts(); - } - if (n > 0) { - r += n; - rrem -= n; - err = n; - } - } - long int rx_tf = get_now_ts(); - DEBUG_TEST("read=%d", r); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - // Compare RX and TX buffer and detect mismatches - bool match = true; - for (int i=0; i=0); - } - free(rxbuf); - free(txbuf); -} - - - - - -void tcp_client_sustained_6(TCP_UNIT_TEST_SIG_6) -{ - std::string testname = "tcp_client_sustained_6"; - std::string msg = "tcp_sustained_6"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "connect to remote host with IPv6 address, exchange a sequence of packets, check order.\n"); - int n=0, w=0, r=0, fd, err; - char *rxbuf = (char*)malloc(cnt*sizeof(char)); - char *txbuf = (char*)malloc(cnt*sizeof(char)); - generate_random_data(txbuf, cnt, 0, 9); - if ((fd = _SOCKET(AF_INET6, SOCK_STREAM, 0)) < 0){ - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _CONNECT(fd, (const struct sockaddr *)addr, sizeof(*addr))) < 0) { - DEBUG_ERROR("error connecting to remote host (%d)", err); - perror("connect"); - *passed = false; - return; - } - - if (op == TEST_OP_N_BYTES) { - int wrem = cnt, rrem = cnt; - // TX - long int tx_ti = get_now_ts(); - while (wrem) { - int next_write = std::min(4096, wrem); -#if defined(_WIN32) - n = _SEND(fd, &txbuf[w], next_write, 0); -#else - n = _WRITE(fd, &txbuf[w], next_write); -#endif - if (n > 0) { - w += n; - wrem -= n; - err = n; - } - } - long int tx_tf = get_now_ts(); - DEBUG_TEST("wrote=%d", w); - // RX - long int rx_ti = 0; - while (rrem) { -#if defined(_WIN32) - n = _RECV(fd, &rxbuf[r], rrem, 0); -#else - n = _READ(fd, &rxbuf[r], rrem); -#endif - if (rx_ti == 0) { // wait for first message - rx_ti = get_now_ts(); - } - if (n > 0) { - r += n; - rrem -= n; - err = n; - } - } - long int rx_tf = get_now_ts(); - DEBUG_TEST("read=%d", r); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - // Compare RX and TX buffer and detect mismatches - bool match = true; - for (int i=0; i=0); - } - free(rxbuf); - free(txbuf); -} - - - - - -void tcp_server_sustained_4(TCP_UNIT_TEST_SIG_4) -{ - std::string testname = "tcp_server_sustained_4"; - std::string msg = "tcp_sustained_4"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "accept connection from host with IPv4 address, exchange a sequence of packets, check order.\n"); - int n=0, w=0, r=0, fd, client_fd, err; - char *rxbuf = (char*)malloc(cnt*sizeof(char)); - memset(rxbuf, 0, cnt); - - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _BIND(fd, (struct sockaddr *)addr, (socklen_t)sizeof(*addr)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - if ((err = _LISTEN(fd, 1)) < 0) { - DEBUG_ERROR("error placing socket in _LISTENING state (%d)", err); - perror("listen"); - *passed = false; - return; - } - struct sockaddr_storage client; - struct sockaddr_in *in4 = (struct sockaddr_in*)&client; - socklen_t client_addrlen = sizeof(sockaddr_storage); - if ((client_fd = _ACCEPT(fd, (struct sockaddr *)in4, &client_addrlen)) < 0) { - fprintf(stderr,"error accepting connection (%d)\n", err); - perror("accept"); - } - DEBUG_TEST("accepted connection from %s, on port %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port)); - if (op == TEST_OP_N_BYTES) { - int wrem = cnt, rrem = cnt; - long int rx_ti = 0; - while (rrem) { -#if defined(_WIN32) - n = _RECV(client_fd, &rxbuf[r], rrem, 0); -#else - n = _READ(client_fd, &rxbuf[r], rrem); -#endif - if (n > 0) { - if (rx_ti == 0) { // wait for first message - rx_ti = get_now_ts(); - } - r += n; - rrem -= n; - err = n; - DEBUG_TEST("read=%d, r=%d, rrem=%d", n, r, rrem); - } - } - long int rx_tf = get_now_ts(); - DEBUG_TEST("read=%d, writing next...", r); - long int tx_ti = get_now_ts(); - while (wrem) { - int next_write = std::min(1024, wrem); -#if defined(_WIN32) - n = _SEND(client_fd, &rxbuf[w], next_write, 0); -#else - n = _WRITE(client_fd, &rxbuf[w], next_write); -#endif - if (n > 0) { - w += n; - wrem -= n; - err = n; - } - } - long int tx_tf = get_now_ts(); - DEBUG_TEST("wrote=%d", w); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - err = _CLOSE(client_fd); - // Compute time deltas and transfer rates - float tx_dt = (tx_tf - tx_ti) / (float)1000; - float rx_dt = (rx_tf - rx_ti) / (float)1000; - float tx_rate = (float)cnt / (float)tx_dt; - float rx_rate = (float)cnt / (float)rx_dt; - sprintf(details, "%s, n=%d, tx_dt=%.2f, rx_dt=%.2f, r=%d, w=%d, tx_rate=%.2f MB/s, rx_rate=%.2f MB/s", - testname.c_str(), cnt, tx_dt, rx_dt, r, w, (tx_rate / float(ONE_MEGABYTE) ), (rx_rate / float(ONE_MEGABYTE) )); - *passed = (r == cnt && w == cnt && err>=0); - } - free(rxbuf); -} - - - - - -void tcp_server_sustained_6(TCP_UNIT_TEST_SIG_6) -{ - std::string testname = "tcp_server_sustained_6"; - std::string msg = "tcp_sustained_6"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "accept connection from host with IPv6 address, exchange a sequence of packets, check order.\n"); - int n=0, w=0, r=0, fd, client_fd, err; - char *rxbuf = (char*)malloc(cnt*sizeof(char)); - memset(rxbuf, 0, cnt); - - if ((fd = _SOCKET(AF_INET6, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - if ((err = _BIND(fd, (struct sockaddr *)addr, (socklen_t)sizeof(struct sockaddr_in6)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - if ((err = _LISTEN(fd, 1)) < 0) { - DEBUG_ERROR("error placing socket in _LISTENING state (%d)", err); - perror("listen"); - *passed = false; - return; - } - struct sockaddr_in6 client; - socklen_t client_addrlen = sizeof(sockaddr_in6); - if ((client_fd = _ACCEPT(fd, (struct sockaddr *)&client, &client_addrlen)) < 0) { - fprintf(stderr,"error accepting connection (%d)\n", err); - perror("accept"); - *passed = false; - return; - } - char ipstr[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &client.sin6_addr, ipstr, sizeof ipstr); - DEBUG_TEST("accepted connection from %s, on port %d", ipstr, ntohs(client.sin6_port)); - - if (op == TEST_OP_N_BYTES) { - int wrem = cnt, rrem = cnt; - long int rx_ti = 0; - while (rrem) { -#if defined(_WIN32) - n = _RECV(client_fd, &rxbuf[r], rrem, 0); -#else - n = _READ(client_fd, &rxbuf[r], rrem); -#endif - if (n > 0) { - if (rx_ti == 0) { // wait for first message - rx_ti = get_now_ts(); - } - r += n; - rrem -= n; - err = n; - } - } - long int rx_tf = get_now_ts(); - DEBUG_TEST("read=%d", r); - long int tx_ti = get_now_ts(); - while (wrem) { - int next_write = std::min(1024, wrem); -#if defined(_WIN32) - n = _SEND(client_fd, &rxbuf[w], next_write, 0); -#else - n = _WRITE(client_fd, &rxbuf[w], next_write); -#endif - if (n > 0) { - w += n; - wrem -= n; - err = n; - } - } - long int tx_tf = get_now_ts(); - DEBUG_TEST("wrote=%d", w); - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - err = _CLOSE(client_fd); - // Compute time deltas and transfer rates - float tx_dt = (tx_tf - tx_ti) / (float)1000; - float rx_dt = (rx_tf - rx_ti) / (float)1000; - float tx_rate = (float)cnt / (float)tx_dt; - float rx_rate = (float)cnt / (float)rx_dt; - sprintf(details, "%s, n=%d, tx_dt=%.2f, rx_dt=%.2f, r=%d, w=%d, tx_rate=%.2f MB/s, rx_rate=%.2f MB/s", - testname.c_str(), cnt, tx_dt, rx_dt, r, w, (tx_rate / float(ONE_MEGABYTE) ), (rx_rate / float(ONE_MEGABYTE) )); - - *passed = (r == cnt && w == cnt && err>=0); - } - free(rxbuf); -} - - - - - -void udp_client_sustained_4(UDP_UNIT_TEST_SIG_4) -{ - std::string testname = "udp_client_sustained_4"; - std::string msg = "udp_sustained_4"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "bind to interface with IPv4 address, TX n-datagrams\n"); - int w, fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET, SOCK_DGRAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - SetSocketBlockingEnabled(fd, true); - DEBUG_TEST("sending UDP packets until I get a single response..."); - if ((err = _BIND(fd, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - int num_to_send = 10; - for (int i=0; isin_addr), addrstr, INET_ADDRSTRLEN); - // once we receive a UDP packet, spend 10 seconds sending responses in the hopes that the client will see - DEBUG_TEST("received DGRAM from %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port)); - DEBUG_TEST("sending DGRAM(s) to %s : %d", inet_ntoa(remote_addr->sin_addr), ntohs(remote_addr->sin_port)); - } - sleep(ARTIFICIAL_SOCKET_LINGER); - //err = _CLOSE(fd); - DEBUG_TEST("%s, n=%d, err=%d, r=%d", testname.c_str(), cnt, err, r); - sprintf(details, "%s, n=%d, err=%d, r=%d", testname.c_str(), cnt, err, r); - DEBUG_TEST("Received : %s", rbuf); - *passed = (r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - - - - - -void udp_client_sustained_6(UDP_UNIT_TEST_SIG_6) -{ - std::string testname = "udp_client_sustained_6"; - std::string msg = "udp_sustained_6"; - fprintf(stderr, "\n\n%s (ts=%lu)\n", testname.c_str(), get_now_ts()); - fprintf(stderr, "bind to interface with IPv6 address, TX n-datagrams\n"); - int w, fd, err, len = strlen(msg.c_str()); - char rbuf[STR_SIZE]; - memset(rbuf, 0, sizeof rbuf); - if ((fd = _SOCKET(AF_INET6, SOCK_DGRAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - exit(0); - perror("socket"); - *passed = false; - return; - } - SetSocketBlockingEnabled(fd, true); - DEBUG_TEST("sending UDP packets until I get a single response..."); - if ((err = _BIND(fd, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in6)) < 0)) { - DEBUG_ERROR("error binding to interface (%d)", err); - perror("bind"); - *passed = false; - return; - } - int num_to_send = 10; - for (int i=0; isin6_addr), addrstr, INET6_ADDRSTRLEN); - // once we receive a UDP packet, spend 10 seconds sending responses in the hopes that the client will see - //DEBUG_TEST("received DGRAM from %s : %d", inet_ntoa(in6->sin6_addr), ntohs(in6->sin6_port)); - //DEBUG_TEST("sending DGRAM(s) to %s : %d", inet_ntoa(remote_addr->sin6_addr), ntohs(remote_addr->sin6_port)); - } - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - DEBUG_TEST("%s, n=%d, err=%d, r=%d", testname.c_str(), cnt, err, r); - sprintf(details, "%s, n=%d, err=%d, r=%d", testname.c_str(), cnt, err, r); - DEBUG_TEST("Received : %s", rbuf); - *passed = (r == len && !err) && !strcmp(rbuf, msg.c_str()); -} - -/****************************************************************************/ -/* PERFORMANCE (between library instances) */ -/****************************************************************************/ - -// Maintain transfer for cnt OR cnt -void tcp_client_perf_4(TCP_UNIT_TEST_SIG_4) -{ - fprintf(stderr, "\n\n\ntcp_client_perf_4\n"); - /* - int w=0, fd, err; - int total_test_sz = cnt; - int arbitrary_chunk_sz_max = MAX_RX_BUF_SZ; - int arbitrary_chunk_sz_min = 512; - - char rbuf[arbitrary_chunk_sz_max]; - - for (int i=arbitrary_chunk_sz_min; (i*2) < arbitrary_chunk_sz_max; i*=2) { - - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) - DEBUG_ERROR("error creating ZeroTier socket"); - if ((err = _CONNECT(fd, (const struct sockaddr *)addr, sizeof(addr))) < 0) - DEBUG_ERROR("error connecting to remote host (%d)", err); - - DEBUG_TEST("[TX] Testing (%d) byte chunks: ", i); - - int chunk_sz = i; - long int start_time = get_now_ts(); - w = 0; - - // TX - while (w < total_test_sz) - w += _WRITE(fd, rbuf, chunk_sz); - - long int end_time = get_now_ts(); - float ts_delta = (end_time - start_time) / (float)1000; - float rate = (float)total_test_sz / (float)ts_delta; - sprintf(details, "tot=%d, dt=%.2f, rate=%.2f MB/s", w, ts_delta, (rate / float(ONE_MEGABYTE) )); - _CLOSE(fd); - } - *passed = (w == total_test_sz && !err) ? TEST_PASSED : TEST_FAILED; - */ -} - -// Maintain transfer for cnt OR cnt -void tcp_server_perf_4(TCP_UNIT_TEST_SIG_4) -{ - fprintf(stderr, "\n\n\ntcp_server_perf_4\n"); - /* - int r=0, fd, client_fd, err; - int total_test_sz = cnt; - int arbitrary_chunk_sz_max = MAX_RX_BUF_SZ; - int arbitrary_chunk_sz_min = 512; - - char rbuf[arbitrary_chunk_sz_max]; - - for (int i=arbitrary_chunk_sz_min; (i*2) < arbitrary_chunk_sz_max; i*=2) { - DEBUG_ERROR("TESTING chunk size = %d", i); - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) - DEBUG_ERROR("error creating ZeroTier socket"); - if ((err = _BIND(fd, (struct sockaddr *)addr, (socklen_t)sizeof(struct sockaddr_in)) < 0)) - DEBUG_ERROR("error binding to interface (%d)", err); - if ((err = _LISTEN(fd, 1)) < 0) - DEBUG_ERROR("error placing socket in _LISTENING state (%d)", err); - if ((client_fd = _ACCEPT(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr))) < 0) - DEBUG_ERROR("error accepting connection (%d)", err); - - DEBUG_TEST("[RX] Testing (%d) byte chunks: ", i); - - int chunk_sz = i; - long int start_time = get_now_ts(); - r = 0; - - // RX - while (r < total_test_sz) - r += _READ(client_fd, rbuf, chunk_sz); - - long int end_time = get_now_ts(); - - float ts_delta = (end_time - start_time) / (float)1000; - float rate = (float)total_test_sz / (float)ts_delta; - - sprintf(details, "tot=%d, dt=%.2f, rate=%.2f MB/s", r, ts_delta, (rate / float(ONE_MEGABYTE) )); - - _CLOSE(fd); - _CLOSE(client_fd); - } - *passed = (r == total_test_sz && !err) ? TEST_PASSED : TEST_FAILED; - */ -} - - - - - -/****************************************************************************/ -/* PERFORMANCE (between library and native) */ -/****************************************************************************/ - -void tcp_perf_tx_echo_4(TCP_UNIT_TEST_SIG_4) -{ - std::string msg = "tcp_perf_tx_echo_4"; - fprintf(stderr, "\n\n%s\n\n", msg.c_str()); - - int err = 0; - int tot = 0; - int w = 0; - int fd, mode; - - char pbuf[64]; // test parameter buffer - char tbuf[MAX_TX_BUF_SZ]; - - mode = ECHOTEST_MODE_TX; - - // connect to remote echotest host - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - return; - } - if ((err = _CONNECT(fd, (const struct sockaddr *)addr, sizeof(*addr))) < 0) { - DEBUG_ERROR("error connecting to remote host (%d)", err); - return; - } - - DEBUG_TEST("copying test parameters to buffer"); - memset(pbuf, 0, sizeof pbuf); - memcpy(pbuf, &mode, sizeof mode); - memcpy(pbuf + sizeof mode, &cnt, sizeof cnt); - - DEBUG_TEST("sending test parameters to echotest"); -#if defined(_WIN32) - if ((w = _SEND(fd, pbuf, sizeof pbuf, 0)) < 0) { -#else - if ((w = _WRITE(fd, pbuf, sizeof pbuf)) < 0) { -#endif - DEBUG_ERROR("error while sending test parameters to echotest (err=%d)", w); - return; - } - - // begin - DEBUG_TEST("beginning test, sending test byte stream..."); - while (tot < cnt) { -#if defined(_WIN32) - if ((w = _SEND(fd, tbuf, sizeof tbuf, 0)) < 0) { -#else - if ((w = _WRITE(fd, tbuf, sizeof tbuf)) < 0) { -#endif - DEBUG_ERROR("error while sending test byte stream to echotest (err=%d)", w); - return; - } - tot += w; - DEBUG_TEST("tot=%d, sent=%d", tot, w); - } - // read results - memset(pbuf, 0, sizeof pbuf); - DEBUG_TEST("reading test results from echotest"); -#if defined(_WIN32) - if ((w = _RECV(fd, pbuf, sizeof tbuf, 0)) < 0) { -#else - if ((w = _READ(fd, pbuf, sizeof tbuf)) < 0) { -#endif - DEBUG_ERROR("error while reading results from echotest (err=%d)", w); - return; - } - - DEBUG_TEST("reading test results"); - long int start_time = 0, end_time = 0; - memcpy(&start_time, pbuf, sizeof start_time); - memcpy(&end_time, pbuf + sizeof start_time, sizeof end_time); - - float ts_delta = (end_time - start_time) / (float)1000; - float rate = (float)tot / (float)ts_delta; - sprintf(details, "%s, tot=%d, dt=%.2f, rate=%.2f MB/s", msg.c_str(), tot, ts_delta, (rate / float(ONE_MEGABYTE) )); - - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - *passed = (tot == cnt && !err) ? TEST_PASSED : TEST_FAILED; -} - - -void tcp_perf_rx_echo_4(TCP_UNIT_TEST_SIG_4) -{ - std::string msg = "tcp_perf_rx_echo_4"; - fprintf(stderr, "\n\n%s\n\n", msg.c_str()); - - int err = 0; - int mode = 0; - int tot = 0; - int r = 0; - - char pbuf[64]; // test parameter buffer - char tbuf[MAX_TX_BUF_SZ]; - int fd; - - mode = ECHOTEST_MODE_RX; - - // connect to remote echotest host - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("error creating ZeroTier socket"); - return; - } - if ((err = _CONNECT(fd, (const struct sockaddr *)addr, sizeof(*addr))) < 0) { - DEBUG_ERROR("error connecting to remote host (%d)", err); - return; - } - - DEBUG_TEST("copying test parameters to buffer"); - memset(pbuf, 0, sizeof pbuf); - memcpy(pbuf, &mode, sizeof mode); - memcpy(pbuf + sizeof mode, &cnt, sizeof cnt); - - DEBUG_TEST("sending test parameters to echotest"); -#if defined(_WIN32) - if ((r = _SEND(fd, pbuf, sizeof pbuf, 0)) < 0) { -#else - if ((r = _WRITE(fd, pbuf, sizeof pbuf)) < 0) { -#endif - DEBUG_ERROR("error while sending test parameters to echotest (err=%d)", r); - return; - } - - // begin - DEBUG_TEST("beginning test, as soon as bytes are read we will start keeping time..."); -#if defined(_WIN32) - if ((r = _RECV(fd, tbuf, sizeof tbuf, 0)) < 0) { -#else - if ((r = _READ(fd, tbuf, sizeof tbuf)) < 0) { -#endif - DEBUG_ERROR("there was an error reading the test stream. aborting (err=%d, errno=%s)", r, strerror(errno)); - return; - } - - tot += r; - - long int start_time = get_now_ts(); - DEBUG_TEST("Received first set of bytes in test stream. now keeping time"); - - while (tot < cnt) { -#if defined(_WIN32) - if ((r = _RECV(fd, tbuf, sizeof tbuf, 0)) < 0) { -#else - if ((r = _READ(fd, tbuf, sizeof tbuf)) < 0) { -#endif - DEBUG_ERROR("there was an error reading the test stream. aborting (err=%d)", r); - return; - } - tot += r; - DEBUG_TEST("r=%d, tot=%d", r, tot); - } - long int end_time = get_now_ts(); - float ts_delta = (end_time - start_time) / (float)1000; - float rate = (float)tot / (float)ts_delta; - sprintf(details, "%s, tot=%d, dt=%.2f, rate=%.2f MB/s", msg.c_str(), tot, ts_delta, (rate / float(ONE_MEGABYTE) )); - - sleep(ARTIFICIAL_SOCKET_LINGER); - err = _CLOSE(fd); - *passed = (tot == cnt && !err) ? TEST_PASSED : TEST_FAILED; -} - -/****************************************************************************/ -/* OBSCURE API CALL TESTS */ -/****************************************************************************/ - -int obscure_api_test(bool *passed) -{ - int err = -1; - fprintf(stderr, "\n\nobscure API test\n\n"); - - /* - // --- - // getpeername() - int fd, client_fd; - - // after accept() - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) - DEBUG_ERROR("error creating ZeroTier socket"); - if ((err = _BIND(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) < 0)) - DEBUG_ERROR("error binding to interface (%d)", err); - if ((err = _LISTEN(fd, 100)) < 0) - printf("error placing socket in _LISTENING state (%d)", err); - // accept - struct sockaddr_in client; - socklen_t client_addrlen = sizeof(sockaddr_in); - if ((client_fd = accept(fd, (struct sockaddr *)&client, &client_addrlen)) < 0) - fprintf(stderr,"error accepting connection (%d)\n", err); - fprintf(stderr, "accepted connection from %s, on port %d", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); - // getpeername - struct sockaddr_storage peer_addr; - struct sockaddr_in *in4 = (struct sockaddr_in*)&peer_addr; - socklen_t peer_addrlen = sizeof(peer_addr); - _GETPEERNAME(fd, (struct sockaddr*)&peer_addr, &peer_addrlen); - DEBUG_TEST("getpeername() => %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port)); - // compate getpeername() result to address returned by accept() - - // after connect - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) - DEBUG_ERROR("error creating ZeroTier socket"); - if ((err = _CONNECT(fd, (const struct sockaddr *)addr, sizeof(*addr))) < 0) - DEBUG_ERROR("error connecting to remote host (%d)", err); - // TODO: Put this test in the general API section - struct sockaddr_storage peer_addr; - struct sockaddr_in *in4 = (struct sockaddr_in*)&peer_addr; - socklen_t peer_addrlen = sizeof(peer_addr); - _GETPEERNAME(fd, (struct sockaddr*)&peer_addr, &peer_addrlen); - DEBUG_TEST("getpeername() => %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port)); - // compare result of getpeername to remote address - - // TODO: write an ipv6 version of the above ^^^ - */ -/* -int levels[] = { - IPPROTO_TCP, - IPPROTO_UDP, - IPPROTO_IP - }; - int num_levels = sizeof(levels) / sizeof(int); - - int optnames[] = { - TCP_NODELAY, - SO_LINGER - }; - int num_optnames = sizeof(optnames) / sizeof(int); - - - for (int i=0; i 0) { // TODO: what should be expected for each platform? Should this mirror them? - optval = 0; - DEBUG_TEST("setting level=%d, optname=%d, optval=%d...", level, optname, optval); - if ((err = _SETSOCKOPT(fd, level, optname, (char *) &optval, (socklen_t)sizeof(int))) < 0) { - DEBUG_ERROR("error while setting on socket"); - *passed = false; - err = -1; - } - else { - DEBUG_TEST("success"); - *passed = true; - } - } else { - DEBUG_ERROR("the optval wasn't set correctly"); - *passed = false; - err = -1; - } - } - } - */ - return err; -} - -/****************************************************************************/ -/* SLAM API (multiple of each api call and/or plausible call sequence) */ -/****************************************************************************/ - -#if defined(__SELFTEST__) - -int ZT_control_semantics_test(bool *passed) -{ - // TODO: Each discrete operation should be tested in random order among every other discrete operation for a sustained period - - /* - std::vector *zts_get_network_routes(char *nwid); - int zts_get_id_from_file(const char *filepath, char *devID); - void *zts_start_service(void *thread_id); - void disableTaps(); - void zts_get_address(const char *nwid, struct sockaddr_storage *addr, const size_t addrlen); - int zts_has_address(const char *nwid); - void zts_get_6plane_addr(struct sockaddr_storage *addr, const char *nwid, const char *devID); - void zts_get_rfc4193_addr(struct sockaddr_storage *addr, const char *nwid, const char *devID); - void zts_join(const uin64_t nwid); - void zts_leave(const uint64_t nwid); - int zts_running(); - int zts_start(const char *path); - int zts_start(const char *path, const char *nwid); - void zts_stop(); - void zts_get_homepath(char *homePath, size_t len); - int zts_get_id(char *devID); - unsigned long zts_get_peer_count(); - int zts_get_peer_address(char *peer, const char *devID); - */ - - //int n_times = 5; - char *nwid = (char*)"17d709436c2c5367"; - char *path = (char*)"fake_path"; -/* - // Perform operations on ZeroTier before calling zts_start(). Doing this makes absolutely no sense but could happen - zts_stop(); - zts_join(nwid); - zts_leave(nwid); - - DEBUG_TEST("---\n"); - sleep(1); - - // Perform operations on ZeroTier immediately upon startup, try to catch it with its pants down - // Ideally, the service wrapper should perform necessary checks to prevent any sort of issue - zts_start(path); - zts_join(nwid); - zts_leave(nwid); - zts_stop(); - - DEBUG_TEST("---\n"); - sleep(1); -*/ - zts_start(path, false); - zts_join(strtoull(nwid,NULL,16)); - zts_leave(strtoull(nwid,NULL,16)); - zts_stop(); - - DEBUG_TEST("---\n"); - sleep(1); -/* - // start the ZeroTier service many times - for (int i=0; i used_ports; - - for (int j=0; j 0) { - if ((err = _CLOSE(sock)) < 0) { - std::cout << "error closing socket (errno = " << strerror(errno) << ")" << std::endl; - //return -1; - } - } - } - } - used_ports.clear(); - //if (zts_num_active_virt_sockets() == 0) - // std::cout << "TEST_PASSED [slam open, bind, listen, accept, close]" << std::endl; - //else - // std::cout << "TEST_FAILED [slam open, bind, listen, accept, close]" << std::endl; - } - - // TESTS: - // (1) _SOCKET() - // (2) connect() - // (3) close() - int num_times = 3;//zts_maxsockets(SOCK_STREAM); - std::cout << "socket/connect/close - " << num_times << " times" << std::endl; - for (int i=0;i<(SLAM_NUMBER*SLAM_REPEAT); i++) { results[i] = 0; } - if (true) - { - int port = 4545; - - // open, bind, listen, accept, close - for (int j=0; j *routes = zts_get_network_routes(nwid); - - for (int i=0; isize(); i++) { - struct sockaddr_in *target = (struct sockaddr_in*)&(routes->at(i).target); - struct sockaddr_in *via = (struct sockaddr_in*)&(routes->at(i).via); - char target_str[INET6_ADDRSTRLEN]; - memset(target_str, 0, INET6_ADDRSTRLEN); - inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)target)->sin_addr.s_addr, target_str, INET_ADDRSTRLEN); - char via_str[INET6_ADDRSTRLEN]; - memset(via_str, 0, INET6_ADDRSTRLEN); - inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)via)->sin_addr.s_addr, via_str, INET_ADDRSTRLEN); - DEBUG_TEST("", target_str, via_str, routes->at(i).flags); - } -} -*/ - -/****************************************************************************/ -/* RANDOMIZED API TEST */ -/****************************************************************************/ - -int random_api_test() -{ - // TEST_PASSED implies we didn't segfault or hang anywhere - - // variables which will be populated with random values - /* - int socket_family; - int socket_type; - int protocol; - int fd; - int len; - int addrlen; - int flags; - - struct sockaddr_storage; - struct sockaddr_in addr; - struct sockaddr_in6 addr6; - */ - - /* - int num_operations = 100; - char *opbuf = (char*)malloc(num_operations*sizeof(char)); - generate_random_data(opbuf, num_operations, 0, 9); - for (int i=0; ifd; - struct sockaddr_in *remote_addr = fdp->remote_addr; - //fprintf(stderr, "fd=%d\n", fd); - int w = 0; - for (int i=0; isin_port++; - } -} - -void bind_to_localhost_test(int port) -{ - fprintf(stderr, "\n\nbind_to_localhost_test\n\n"); - int fd, err = 0; - // ipv4, 0.0.0.0 - struct sockaddr_storage bind_addr; - DEBUG_TEST("binding to 0.0.0.0"); - str2addr("0.0.0.0", port, 4, (struct sockaddr *)&bind_addr); - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) > 0) { - if ((err = _BIND(fd, (struct sockaddr *)&bind_addr, sizeof(struct sockaddr_in))) == 0) { - micro_sleep(100000); - if ((err = _CLOSE(fd)) < 0) { - DEBUG_ERROR("error closing socket (%d)", err); - } - } - else{ - DEBUG_ERROR("error binding to interface (%d)", err); - } - } - else { - DEBUG_ERROR("error creating socket (%d)", err); - } - - port++; - - /* - // ipv4, 127.0.0.1 - DEBUG_TEST("binding to 127.0.0.1"); - str2addr("127.0.0.1", port, 4, (struct sockaddr *)&bind_addr); - if ((fd = _SOCKET(AF_INET, SOCK_STREAM, 0)) > 0) { - if ((err = _BIND(fd, (struct sockaddr *)&bind_addr, sizeof(struct sockaddr_in))) == 0) { - micro_sleep(100000); - if ((err = _CLOSE(fd)) < 0) { - DEBUG_ERROR("error closing socket (%d)", err); - } - } - else{ - DEBUG_ERROR("error binding to interface (%d)", err); - } - } - else { - DEBUG_ERROR("error creating socket", err); - } - - port++; - */ - - // ipv6, [::] - DEBUG_TEST("binding to [::]"); - str2addr("::", port, 6, (struct sockaddr *)&bind_addr); - if ((fd = _SOCKET(AF_INET6, SOCK_STREAM, 0)) > 0) { - if ((err = _BIND(fd, (struct sockaddr *)&bind_addr, sizeof(struct sockaddr_in))) == 0) { - micro_sleep(100000); - if ((err = _CLOSE(fd)) < 0) { - DEBUG_ERROR("error closing socket (%d)", err); - } - } - else{ - DEBUG_ERROR("error binding to interface (%d)", err); - } - } - else { - DEBUG_ERROR("error creating socket (%d)", err); - } -} - -#endif // __SELFTEST__ - -int trigger_address_sanitizer() -{ - // Deliberately create a bad read to trigger address sanitizer - /* - int stack_array[100]; - stack_array[1] = 0; - return stack_array[1 + 100]; // BOOM - */ - return 0; -} - -/****************************************************************************/ -/* main(), calls test_driver(...) */ -/****************************************************************************/ - -int main(int argc , char *argv[]) -{ -#if defined(__SELFTEST__) - if (argc == 4) { - DEBUG_TEST("generating id..."); - if (!strcmp(argv[1],"generate_id")) - { - DEBUG_TEST("generating ZeroTier identity for testing purposes..."); - if (strlen(argv[2]) <= 0) { - DEBUG_ERROR("invalid was given"); - exit(-1); - } - if (strlen(argv[3]) <= 0) { - DEBUG_ERROR("invalid pathname was given"); - exit(-1); - } - uint64_t nwid = strtoull(argv[2],NULL,16); - uint64_t nodeId = zts_get_node_id(); - - zts_start(argv[3], true); - zts_join(nwid); - sleep(2); - DEBUG_TEST("generated id: %llx", (unsigned long long)nodeId); - exit(0); - } - } - -#endif // __SELFTEST__ - - if (argc < 6) { - fprintf(stderr, "usage: selftest to \n"); - fprintf(stderr, "usage: selftest generate_id \n"); - fprintf(stderr, "e.g. : selftest 3 test/test.conf alice to bob\n"); - return 1; - } - int num_repeats = atoi(argv[1]); - std::string path = argv[2]; - std::string from = argv[3]; - std::string to = argv[5]; - std::string me = from; - std::vector results; - std::string remote_echo_ipv4, smode; - - std::string nwidstr, stype; - std::string ipstr, ipstr6, local_ipstr, local_ipstr6, remote_ipstr, remote_ipstr6; - - int err = 0; - int mode = 0; - int port = 0; - int op = 0; - int start_port = 0; - int cnt = 0; - int ipv; - // for timing - // how long we expect the specific test to take - int subtest_expected_duration; - // (T+X), when we plan to start this test - int subtest_start_time_offset = 0; - - char details[128]; - memset(&details, 0, sizeof details); - bool passed = 0; - struct sockaddr_storage local_addr; - struct sockaddr_storage remote_addr; - - // load config file - if (path.find(".conf") == std::string::npos) { - fprintf(stderr, "Possibly invalid conf file. Exiting...\n"); - exit(0); - } - loadTestConfigFile(path); - // get origin details - local_ipstr = testConf[me + ".ipv4"]; - local_ipstr6 = testConf[me + ".ipv6"]; - nwidstr = testConf[me + ".nwid"]; - path = testConf[me + ".path"]; - stype = testConf[me + ".test"]; - smode = testConf[me + ".mode"]; - start_port = atoi(testConf[me + ".port"].c_str()); - remote_echo_ipv4 = testConf[to + ".echo_ipv4"]; - remote_ipstr = testConf[to + ".ipv4"]; - remote_ipstr6 = testConf[to + ".ipv6"]; - - if (strcmp(smode.c_str(), "server") == 0) - mode = TEST_MODE_SERVER; - else - mode = TEST_MODE_CLIENT; - - fprintf(stderr, "\n\nORIGIN:\n\n"); - fprintf(stderr, "\tlocal_ipstr = %s\n", local_ipstr.c_str()); - fprintf(stderr, "\tlocal_ipstr6 = %s\n", local_ipstr6.c_str()); - fprintf(stderr, "\tstart_port = %d\n", start_port); - fprintf(stderr, "\tpath = %s\n", path.c_str()); - fprintf(stderr, "\tnwid = %s\n", nwidstr.c_str()); - fprintf(stderr, "\ttype = %s\n\n", stype.c_str()); - fprintf(stderr, "DESTINATION:\n\n"); - fprintf(stderr, "\tremote_ipstr = %s\n", remote_ipstr.c_str()); - fprintf(stderr, "\tremote_ipstr6 = %s\n", remote_ipstr6.c_str()); - fprintf(stderr, "\tremote_echo_ipv4 = %s\n", remote_echo_ipv4.c_str()); - -#if defined(__SELFTEST__) - if (me != "dummy") { // used for testing ZT service wrapper API (before, during, and after coming online) - // set start time here since we need to wait for both libzt instances to be online - DEBUG_TEST("app-thread, waiting for libzt to come online...\n"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - int portno = LIBZT_DEFAULT_PORT; - if (zts_set_service_port(portno) < 0) { - DEBUG_TEST("error, invalid zt service port number: %d", portno); - exit(0); - } - zts_startjoin(path.c_str(), nwid); - uint64_t nodeId = zts_get_node_id(); - DEBUG_TEST("I am %llx, %s", (unsigned long long)nodeId, me.c_str()); - if (mode == TEST_MODE_SERVER) { - DEBUG_TEST("Ready. You should start selftest program on second host now...\n\n"); - } - if (mode == TEST_MODE_CLIENT) { - DEBUG_TEST("Ready. Contacting selftest program on first host.\n\n"); - } - } - - // SYNCHRONIZE test start times between multiple instances of the selftest on the network - ipv = 4; - int negotiation_port = start_port + 1000; - port = negotiation_port; - str2addr(local_ipstr, port, ipv, (struct sockaddr *)&local_addr); - str2addr(remote_ipstr, port, ipv, (struct sockaddr *)&remote_addr); - wait_until_everyone_is_ready((struct sockaddr *)&local_addr, (struct sockaddr *)&remote_addr, start_port); - DEBUG_TEST("both instances of selftest have started. beginning tests..."); - - long int selftest_start_time = get_now_ts(); - subtest_expected_duration = 5; -#endif // __SELFTEST__ - -for (int i=0; i - -#ifdef _WIN32 -#include -#include -#include -#include -#else -#include -#include -#include -#endif - -#include - -bool node_ready = false; -bool network_ready = false; - -void myZeroTierEventCallback(struct zts_callback_msg *msg) -{ - switch (msg->eventCode) - { - case ZTS_EVENT_NODE_ONLINE: - printf("ZTS_EVENT_NODE_ONLINE, node=%llx\n", msg->node->address); - node_ready = true; - break; - case ZTS_EVENT_NODE_OFFLINE: - printf("ZTS_EVENT_NODE_OFFLINE\n"); - node_ready = false; - break; - case ZTS_EVENT_NETWORK_READY_IP4: - printf("ZTS_EVENT_NETWORK_READY_IP4 --- network=%llx\n", msg->network->nwid); - network_ready = true; - break; - case ZTS_EVENT_PEER_P2P: - printf("ZTS_EVENT_PEER_P2P --- node=%llx\n", msg->peer->address); - break; - case ZTS_EVENT_PEER_RELAY: - printf("ZTS_EVENT_PEER_RELAY --- node=%llx\n", msg->peer->address); - break; - // ... - default: - break; - } -} - -void delay(int n) -{ -#ifdef _WIN32 - Sleep(n * 1000); -#else - sleep(n); -#endif -} - -int main() -{ - char *str = "welcome to the machine"; - char *remoteIp = "11.7.7.223"; - int remotePort = 8082; - int fd, err = 0; - struct sockaddr_in addr; - addr.sin_family = ZTS_AF_INET; - addr.sin_addr.s_addr = inet_addr(remoteIp); - addr.sin_port = htons(remotePort); - - // Set up ZeroTier service and wai for callbacks - int port = 9994; - uint64_t nwid = 0x0123456789abcdef; - zts_start("path", &myZeroTierEventCallback, port); - printf("Waiting for node to come online...\n"); - while (!node_ready) { delay(1); } - printf("joining network...\n"); - zts_join(nwid); - printf("Joined virtual network. Requesting configuration...\n"); - while (!network_ready) { delay(1); } - - printf("I am %llx\n", zts_get_node_id()); - // Socket API example - if ((fd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) { - printf("error creating socket\n"); - } - if ((err = zts_connect(fd, (const struct sockaddr *)&addr, sizeof(addr))) < 0) { - printf("error connecting to remote host (%s)\n", remoteIp); - } - if ((err = zts_write(fd, str, strlen(str))) < 0) { - printf("error writing to socket\n"); - } - zts_close(fd); - zts_stop(); - return 0; -}