diff --git a/make-linux.mk b/make-linux.mk index 4ffafc4..912d0ec 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -221,15 +221,14 @@ endif linux_service_and_intercept: linux_intercept linux_sdk_service # Builds a single shared library which contains everything -ifeq ($(SDK_LWIP),1) -linux_shared_lib: $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_INTERCEPT -shared -o $(SHARED_LIB) $(OBJS) $(LWIP_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl -else -linux_shared_lib: $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_INTERCEPT -shared -o $(SHARED_LIB) $(OBJS) $(PICO_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl -endif - +linux_shared_lib: pico $(OBJS) + $(CXX) $(CXXFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_SERVICE -DSDK -DSDK_BUNDLED -DSDK_DEBUG -DSDK_PICOTCP -DSDK_IPV4 $(PICO_DRIVER_FILES) $(SDK_INTERCEPT_C_FILES) $(SDK_SERVICE_CPP_FILES) src/service.cpp -c + ar -rcs libzt.a picotcp.o proxy.o tap.o one.o OneService.o service.o sockets.o rpc.o intercept.o OneService.o $(OBJS) +# Builds zt-embedded tests +linux_shared_lib_tests: + $(CXX) -DSDK_SERVICE -DSDK -DSDK_BUNDLED -DSDK_DEBUG -DSDK_PICOTCP -DSDK_IPV4 $(CXXFLAGS) $(LDFLAGS) $(INCLUDES) -Isrc tests/api_test/zt_tcpserver4.c -o zt_tcpserver4.out -L. -lzt -ldl + $(CXX) -DSDK_SERVICE -DSDK -DSDK_BUNDLED -DSDK_DEBUG -DSDK_PICOTCP -DSDK_IPV4 -DSDK_DEBUG $(CXXFLAGS) $(LDFLAGS) $(INCLUDES) -Isrc tests/api_test/zt_tcpclient4.c -o zt_tcpclient4.out -L. -lzt -ldl # -------- ANDROID --------- # TODO: CHECK if ANDROID/GRADLE TOOLS are installed @@ -332,6 +331,9 @@ test_suite: tests lwip linux_service_and_intercept cp tests/cleanup.sh $(BUILD)/tests/cleanup.sh cp $(LWIP_LIB) $(BUILD)/tests/zerotier/$(LWIP_LIB_NAME) +shared_lib_tests: + mkdir -p $(BUILD)/tests; + -$(CC) $(CC_FLAGS) -Isrc tests/api_test/zt_tcpserver4.c -o $(BUILD)/tests/zt_tcpserver4.out $(BUILD)/libztlinux.so # ----- ADMINISTRATIVE ----- diff --git a/src/intercept.c b/src/intercept.c index c9c6ab1..f10f083 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -91,12 +91,14 @@ pthread_key_t thr_id_key; extern void load_symbols() { DEBUG_EXTRA(""); + #if defined(__linux__) realaccept4 = dlsym(RTLD_NEXT, "accept4"); #if !defined(__ANDROID__) realsyscall = dlsym(RTLD_NEXT, "syscall"); #endif #endif + realsetsockopt = (int(*)(SETSOCKOPT_SIG))dlsym(RTLD_NEXT, "setsockopt"); realgetsockopt = (int(*)(GETSOCKOPT_SIG))dlsym(RTLD_NEXT, "getsockopt"); realsocket = (int(*)(SOCKET_SIG))dlsym(RTLD_NEXT, "socket"); diff --git a/src/rpc.c b/src/rpc.c index 968c374..fc358f7 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -107,7 +107,7 @@ int get_retval(int rpc_sock) int load_symbols_rpc() { -#if defined(SDK_BUNDLED) || defined(__IOS__) || defined(__UNITY_3D__) +#if defined(__IOS__) || defined(__UNITY_3D__) realsocket = dlsym(RTLD_NEXT, "socket"); realconnect = dlsym(RTLD_NOW, "connect"); if(!realconnect || !realsocket) @@ -144,7 +144,7 @@ int rpc_join(char * sockname) #else if((conn_err = connect(sock, (struct sockaddr*)&addr, sizeof(addr))) != 0) { #endif - DEBUG_ERROR("error connecting to RPC socket. Re-attempting..."); + DEBUG_ERROR("error connecting to RPC socket (%s). Re-attempting...", sockname); usleep(100000); } else diff --git a/src/service.cpp b/src/service.cpp index 909431c..15a6adf 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -248,15 +248,10 @@ char *zts_get_homepath() { // ------------------------------------------------------------------------------ - // ------------------------------ -------------------------- + // ----------------------------------- Other ------------------------------------ // ------------------------------------------------------------------------------ // For use when symbols are used in Swift -// If we're using a bridging header for an Xcode project... -// This matters because the header/wrapper needs to define symbols -// for usage in Swift, but in order to maintain API naming consistency -// between build environments whilst also preventing duplicate symbols -// we need to check for this case void zts_start_service(const char *path) { @@ -426,6 +421,11 @@ void zts_start_service(const char *path) // Starts a ZeroTier service in the background void *zts_start_core_service(void *thread_id) { + + #if defined(SDK_BUNDLED) + homeDir = std::string((char*)thread_id); + #endif + #if defined(__ANDROID__) DEBUG_INFO("ZTSDK_BUILD_VERSION = %d", ZTSDK_BUILD_VERSION); #endif @@ -493,14 +493,13 @@ void *zts_start_core_service(void *thread_id) { return NULL; } - - //chdir(current_dir); // Return to previous current working directory (at the request of Unity3D) #if defined(__UNITY_3D__) DEBUG_INFO("starting service..."); #endif - + // Initialize RPC + // TODO: remove? if(rpcEnabled) { zts_init_rpc(localHomeDir.c_str(), rpcNWID.c_str()); } diff --git a/src/sockets.c b/src/sockets.c index ecb1459..32eb70f 100644 --- a/src/sockets.c +++ b/src/sockets.c @@ -53,6 +53,8 @@ #include #include +#include + #if defined(__linux__) #include #include @@ -62,7 +64,7 @@ #ifdef __cplusplus extern "C" { #endif - + #if defined(__linux__) #define SOCK_MAX (SOCK_PACKET + 1) #endif @@ -84,7 +86,9 @@ int (*realclose)(CLOSE_SIG); // ------------------------------------------------------------------------------ // ---------------------------------- zt_init_rpc ------------------------------- // ------------------------------------------------------------------------------ - + + int service_initialized = 0; + // Assembles (and/or) sets the RPC path for communication with the ZeroTier service void zts_init_rpc(const char *path, const char *nwid) { @@ -100,7 +104,7 @@ int (*realclose)(CLOSE_SIG); #if defined(SDK_BUNDLED) // Get the path/nwid from the user application // netpath = [path + "/nc_" + nwid] - char *fullpath = malloc(strlen(path)+strlen(nwid)+1+4); + char *fullpath = (char *)malloc(strlen(path)+strlen(nwid)+1+4); if(fullpath) { strcpy(fullpath, path); strcat(fullpath, "/nc_"); @@ -115,6 +119,20 @@ int (*realclose)(CLOSE_SIG); } #endif } + + // start the SDK service if this is bundled + #if defined(SDK_BUNDLED) + if(!service_initialized) { + //api_netpath = "/root/dev/ztest5/nc_565799d8f612388c"; + DEBUG_ATTN("api_netpath = %s", api_netpath); + pthread_t intercept_thread; + pthread_create(&intercept_thread, NULL, zts_start_core_service, (void *)(path)); + service_initialized = 1; + DEBUG_ATTN("waiting for service to come online"); + //while(!zts_service_is_running()) { } + sleep(10); + } + #endif } void get_api_netpath() { zts_init_rpc("",""); } @@ -226,7 +244,7 @@ int (*realclose)(CLOSE_SIG); errno = EMSGSIZE; // Message too large to send atomically via underlying protocol, don't send return -1; } - buf = malloc(tot_len); + buf = (char *)malloc(tot_len); if(tot_len != 0 && buf == NULL) { errno = ENOMEM; // Unable to allocate space for message return -1; @@ -236,7 +254,7 @@ int (*realclose)(CLOSE_SIG); memcpy(p, iov[i].iov_base, iov[i].iov_len); p += iov[i].iov_len; } - err = sendto(fd, buf, tot_len, flags, msg->msg_name, msg->msg_namelen); + //err = sendto(fd, buf, tot_len, flags, msg->msg_name, msg->msg_namelen); free(buf); return err; } @@ -315,12 +333,12 @@ int (*realclose)(CLOSE_SIG); for(int i = 0; i < msg->msg_iovlen; ++i) tot_len += iov[i].iov_len; - buf = malloc(tot_len); + buf = (char *)malloc(tot_len); if(tot_len != 0 && buf == NULL) { errno = ENOMEM; return -1; } - n = err = recvfrom(fd, buf, tot_len, flags, msg->msg_name, &msg->msg_namelen); + //n = err = recvfrom(fd, buf, tot_len, flags, msg->msg_name, &msg->msg_namelen); p = buf; // According to: http://pubs.opengroup.org/onlinepubs/009695399/functions/recvmsg.html @@ -446,7 +464,7 @@ int (*realclose)(CLOSE_SIG); #endif #ifdef DYNAMIC_LIB - int zts_socket(SOCKET_SIG) + int zt_socket(SOCKET_SIG) #else int zts_socket(SOCKET_SIG) #endif @@ -612,7 +630,6 @@ int (*realclose)(CLOSE_SIG); { get_api_netpath(); DEBUG_INFO("fd=%d", fd); - // FIXME: Find a better solution for this before production #if !defined(__UNITY_3D__) if(addr) addr->sa_family = AF_INET; diff --git a/src/stack_drivers/picotcp/picotcp.hpp b/src/stack_drivers/picotcp/picotcp.hpp index 2e33009..f212299 100644 --- a/src/stack_drivers/picotcp/picotcp.hpp +++ b/src/stack_drivers/picotcp/picotcp.hpp @@ -174,10 +174,13 @@ namespace ZeroTier { { #if defined(__ANDROID__) || defined(__UNITY_3D__) #define __STATIC_STACK__ -#elif defined(__linux__) +#elif defined(__linux__) && !defined(SDK_BUNDLED) #define __DYNAMIC_STACK__ // Dynamically load stack library _libref = dlmopen(LM_ID_NEWLM, path, RTLD_NOW); +#elif defined(__linux__) && defined(SDK_BUNDLED) // TODO: Determine why __STATIC_STACK__ won't work in SDK_BUNDLED mode + #define __DYNAMIC_STACK__ + _libref = dlmopen(LM_ID_NEWLM, path, RTLD_NOW); #elif defined(__APPLE__) #include "TargetConditionals.h" #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE diff --git a/src/tap.cpp b/src/tap.cpp index 41fcd8d..6c9a463 100644 --- a/src/tap.cpp +++ b/src/tap.cpp @@ -145,9 +145,10 @@ NetconEthernetTap::NetconEthernetTap( chmod(sockPath, 0777); // To make the RPC socket available to all users - DEBUG_INFO("tap initialized on: path=%s", sockPath); if (!_unixListenSocket) DEBUG_ERROR("unable to bind to: path=%s", sockPath); + else + DEBUG_INFO("tap initialized on: path=%s", sockPath); _thread = Thread::start(this); } diff --git a/tests/api_test/zt_tcpclient4.c b/tests/api_test/zt_tcpclient4.c new file mode 100644 index 0000000..0e8236a --- /dev/null +++ b/tests/api_test/zt_tcpclient4.c @@ -0,0 +1,67 @@ +// TCP Client test program + +#include +#include +#include +#include +#include + +#include +#include "sdk.h" + +int atoi(const char *str); +int close(int filedes); + +#define MSG_SZ 128 + +int main(int argc , char *argv[]) +{ + zts_init_rpc("/root/dev/ztest5","565799d8f612388c"); + + if(argc < 3) { + printf("usage: client \n"); + return 1; + } + + int sock, port = atoi(argv[2]); + struct sockaddr_in server; + char message[MSG_SZ] , server_reply[MSG_SZ]; + + sock = zts_socket(AF_INET , SOCK_STREAM , 0); + if (sock == -1) { + printf("could not create socket"); + } + server.sin_addr.s_addr = inet_addr(argv[1]); + server.sin_family = AF_INET; + server.sin_port = htons( port ); + + printf("connecting...\n"); + if (zts_connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { + perror("connect failed. Error"); + return 1; + } + printf("connected\n"); + + char *msg = "welcome to the machine!"; + + while(1) + { + // TX + if(send(sock, msg, strlen(msg), 0) < 0) { + printf("send failed"); + return 1; + } + else { + printf("TX: %s\n", msg); + printf("len = %ld\n", strlen(msg)); + + int bytes_read = read(sock, server_reply, MSG_SZ); + if(bytes_read < 0) + printf("\tRX: Nothing\n"); + else + printf("\tRX = (%d bytes): %s\n", bytes_read, server_reply); + } + } + close(sock); + return 0; +} diff --git a/tests/api_test/zt_tcpserver4.c b/tests/api_test/zt_tcpserver4.c index 295a9ea..a366ac9 100644 --- a/tests/api_test/zt_tcpserver4.c +++ b/tests/api_test/zt_tcpserver4.c @@ -4,12 +4,16 @@ #include #include #include -#include - +#include + +#include +#include "sdk.h" + int atoi(const char *str); int main(int argc , char *argv[]) -{ +{ + zts_init_rpc("/root/dev/ztest5","565799d8f612388c"); if(argc < 2) { printf("usage: tcp_server \n"); return 0; @@ -22,9 +26,9 @@ int main(int argc , char *argv[]) int comm_fd; struct sockaddr_in servaddr; - struct sockaddr_in client; + struct sockaddr_in client; - sock = socket(AF_INET, SOCK_STREAM, 0); + sock = zts_socket(AF_INET, SOCK_STREAM, 0); bzero( &servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; @@ -33,11 +37,11 @@ int main(int argc , char *argv[]) bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)); printf("listening\n"); - listen(sock , 3); + zts_listen(sock , 3); printf("waiting to accept\n"); c = sizeof(struct sockaddr_in); - client_sock = accept(sock, (struct sockaddr *)&client, (socklen_t*)&c); + client_sock = zts_accept(sock, (struct sockaddr *)&client, (socklen_t*)&c); if (client_sock < 0) { perror("accept failed"); return 0;