From bda82e3e1e12e3aa00717b62f6a5aa5da1d2adab Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Thu, 25 Aug 2016 11:12:13 -0700 Subject: [PATCH] OSX app framework build fix, slight re-organization of SDK_Service --- .../project.pbxproj | 2 + src/SDK.h | 18 +- src/SDK_Service.cpp | 251 +++++++++--------- 3 files changed, 141 insertions(+), 130 deletions(-) diff --git a/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj b/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj index 17fe263..3369801 100644 --- a/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj +++ b/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 7C0252A51D62945B005D5FD8 /* SDK_Service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CAA03DE1D628E88003F9B1A /* SDK_Service.cpp */; }; + 7C6F654E1D6F6BA1004F6CDF /* SDK_Service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CAA03DE1D628E88003F9B1A /* SDK_Service.cpp */; }; 7CAA03DF1D628E88003F9B1A /* SDK_Service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CAA03DE1D628E88003F9B1A /* SDK_Service.cpp */; }; 7CC003261D1216E3003E68DC /* ZeroTierSDK_iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CC003251D1216E3003E68DC /* ZeroTierSDK_iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7CC003501D12178D003E68DC /* SDK_Debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC003421D12178D003E68DC /* SDK_Debug.c */; }; @@ -1112,6 +1113,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7C6F654E1D6F6BA1004F6CDF /* SDK_Service.cpp in Sources */, 7CC004D21D131F76003E68DC /* ip_addr.c in Sources */, 7CC004D01D131E37003E68DC /* lz4.c in Sources */, 7CC004D11D131E37003E68DC /* http_parser.c in Sources */, diff --git a/src/SDK.h b/src/SDK.h index d8262d5..8649912 100644 --- a/src/SDK.h +++ b/src/SDK.h @@ -37,13 +37,14 @@ #include #endif +#include "SDK_LocalBuild.h" + #ifdef __cplusplus extern "C" { #endif #define INTERCEPT_ENABLED 111 #define INTERCEPT_DISABLED 222 -#define TEMP_MTU 2800 extern void load_symbols(); extern void zt_init_rpc(const char *path, const char *nwid); @@ -90,16 +91,22 @@ int zts_start_proxy_server(const char *homepath, const char * nwid, struct socka int zts_stop_proxy_server(const char *nwid); int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage *addr); // ZT Service Controls +void *zts_start_service(void *thread_id); +void zts_stop_service(); +bool zts_is_running(); void zts_join_network(const char * nwid); void zts_leave_network(const char * nwid); -bool zts_is_running(); void zts_get_addresses(const char * nwid, char * addrstr); int zts_get_device_id(); -void zts_stop_service(); bool zts_is_relayed(); char *zts_get_homepath(); + // ZT Intercept/RPC Controls +// TODO: Remove any? void set_intercept_status(int mode); /* TODO: Rethink this */ +void init_service(int key, const char * path); +void init_service_and_rpc(int key, const char * path, const char * nwid); +void init_intercept(int key); int zts_socket(SOCKET_SIG); int zts_connect(CONNECT_SIG); @@ -172,11 +179,6 @@ ssize_t zts_recvmsg(RECVMSG_SIG); JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1getsockopt(JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jint optval, jint optlen); JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1getsockname(JNIEnv *env, jobject thisObj, jint fd, jobject ztaddr); JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1getpeername(JNIEnv *env, jobject thisObj, jint fd, jobject ztaddr); -#else - void * zt_start_service(void *thread_id); - void init_service(int key, const char * path); - void init_service_and_rpc(int key, const char * path, const char * nwid); - void init_intercept(int key); #endif diff --git a/src/SDK_Service.cpp b/src/SDK_Service.cpp index c85bc63..214fe83 100644 --- a/src/SDK_Service.cpp +++ b/src/SDK_Service.cpp @@ -49,6 +49,7 @@ #include "SDK_EthernetTap.hpp" #include "SDK.h" #include "SDK_Debug.h" +#include "SDK_LocalBuild.h" std::string service_path; pthread_t intercept_thread; @@ -68,6 +69,8 @@ bool rpcEnabled; extern "C" { #endif +// Prototypes +void *zts_start_service(void *thread_id); void zt_init_rpc(const char * path, const char * nwid); void dwr(int level, const char *fmt, ... ); @@ -197,6 +200,28 @@ char *zts_get_homepath() { // Android JNI wrapper // JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME #if defined(__ANDROID__) + // Starts a new service instance + /* NOTE: Since on Android devices the sdcard is formatted as fat32, we can't use just any + location to set up the RPC unix domain socket. Rather we must use the application's specific + data directory given by getApplicationContext().getFilesDir() */ + JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1start_1service(JNIEnv *env, jobject thisObj, jstring path) { + if(path) + homeDir = env->GetStringUTFChars(path, NULL); + zts_start_service(NULL); + } + // Shuts down ZeroTier service and SOCKS5 Proxy server + JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1stop_1service(JNIEnv *env, jobject thisObj) { + if(zt1Service) + zts_stop_service(); + // TODO: Also terminate SOCKS5 Proxy + // zts_stop_proxy_server(); + } + // Returns whether the ZeroTier service is running + JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1running(JNIEnv *env, jobject thisObj) { + if(zt1Service) + return zts_is_running(); + return false; + } // Join a network JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1join_1network(JNIEnv *env, jobject thisObj, jstring nwid) { const char *nwidstr; @@ -213,19 +238,6 @@ char *zts_get_homepath() { zts_leave_network(nwidstr); } } - // Returns whether the ZeroTier service is running - JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1running(JNIEnv *env, jobject thisObj) { - if(zt1Service) - return zts_is_running(); - return false; - } - // Shuts down ZeroTier service and SOCKS5 Proxy server - JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1stop_1service(JNIEnv *env, jobject thisObj) { - if(zt1Service) - zts_stop_service(); - // TODO: Also terminate SOCKS5 Proxy - // zts_stop_proxy_server(); - } // FIXME: Re-implemented to make it play nicer with the C-linkage required for Xcode integrations // Now only returns first assigned address per network. Shouldn't normally be a problem JNIEXPORT jobject JNICALL Java_ZeroTier_SDK_zt_1get_1addresses(JNIEnv *env, jobject thisObj, jstring nwid) { @@ -309,7 +321,7 @@ char *zts_get_homepath() { pthread_key_create(&thr_id_key, NULL); intercept_thread_id = (int*)malloc(sizeof(int)); *intercept_thread_id = key; - pthread_create(&intercept_thread, NULL, zt_start_service, (void *)(intercept_thread_id)); + pthread_create(&intercept_thread, NULL, zts_start_service, (void *)(intercept_thread_id)); } void init_service_and_rpc(int key, const char * path, const char * nwid) { rpcEnabled = true; @@ -328,130 +340,125 @@ char *zts_get_homepath() { } #endif -/* - * Starts a new service instance - */ -#if defined(__ANDROID__) - /* NOTE: Since on Android devices the sdcard is formatted as fat32, we can't use just any - location to set up the RPC unix domain socket. Rather we must use the application's specific - data directory given by getApplicationContext().getFilesDir() */ - JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1start_1service(JNIEnv *env, jobject thisObj, jstring path) { - if(path) - homeDir = env->GetStringUTFChars(path, NULL); -#else - void *zt_start_service(void *thread_id) { -#endif + +// Starts a ZeroTier service in the background +void *zts_start_service(void *thread_id) { + + //#ifdef ZTSDK_BUILD_VERSION + dwr(MSG_DEBUG, "ZTSDK_BUILD_VERSION = %d", ZTSDK_BUILD_VERSION); + LOGV("ZTSDK_BUILD_VERSION = %d", ZTSDK_BUILD_VERSION); + //#endif #if defined(SDK_BUNDLED) && !defined(__ANDROID__) set_intercept_status(INTERCEPT_DISABLED); // Ignore network calls from ZT service #endif - #if defined(__UNITY_3D__) - int MAX_DIR_SZ = 256; - char current_dir[MAX_DIR_SZ]; - getcwd(current_dir, MAX_DIR_SZ); - chdir(service_path.c_str()); - homeDir = current_dir; // homeDir shall be current_dir - #endif + #if defined(__UNITY_3D__) + int MAX_DIR_SZ = 256; + char current_dir[MAX_DIR_SZ]; + getcwd(current_dir, MAX_DIR_SZ); + chdir(service_path.c_str()); + homeDir = current_dir; // homeDir shall be current_dir + #endif - #if defined(__APPLE__) - #include "TargetConditionals.h" - #if TARGET_IPHONE_SIMULATOR - // homeDir = "dont/run/this/in/the/simulator/it/wont/work"; - #elif TARGET_OS_IPHONE - localHomeDir = "ZeroTier/One"; - std::string del = givenHomeDir.length() && givenHomeDir[givenHomeDir.length()-1]!='/' ? "/" : ""; - homeDir = givenHomeDir + del + localHomeDir; - #endif + #if defined(__APPLE__) + #include "TargetConditionals.h" + #if TARGET_IPHONE_SIMULATOR + // homeDir = "dont/run/this/in/the/simulator/it/wont/work"; + #elif TARGET_OS_IPHONE + localHomeDir = "ZeroTier/One"; + std::string del = givenHomeDir.length() && givenHomeDir[givenHomeDir.length()-1]!='/' ? "/" : ""; + homeDir = givenHomeDir + del + localHomeDir; #endif + #endif - #if defined(__APPLE__) && !defined(__IOS__) - homeDir = givenHomeDir; - localHomeDir = givenHomeDir; // Used for RPC and *can* differ from homeDir on some platforms - #endif + #if defined(__APPLE__) && !defined(__IOS__) + homeDir = givenHomeDir; + localHomeDir = givenHomeDir; // Used for RPC and *can* differ from homeDir on some platforms + #endif - dwr(MSG_DEBUG, "homeDir = %s", givenHomeDir.c_str()); - // Where network .conf files will be stored - netDir = homeDir + "/networks.d"; - zt1Service = (ZeroTier::OneService *)0; - - // Construct path for network config and supporting service files - if (homeDir.length()) { - dwr(MSG_DEBUG, "start_service(): constructing path...\n"); - std::vector hpsp(ZeroTier::Utils::split(homeDir.c_str(),ZT_PATH_SEPARATOR_S,"","")); - std::string ptmp; - if (homeDir[0] == ZT_PATH_SEPARATOR) + dwr(MSG_DEBUG, "homeDir = %s", givenHomeDir.c_str()); + // Where network .conf files will be stored + netDir = homeDir + "/networks.d"; + zt1Service = (ZeroTier::OneService *)0; + + // Construct path for network config and supporting service files + if (homeDir.length()) { + dwr(MSG_DEBUG, "start_service(): constructing path...\n"); + std::vector hpsp(ZeroTier::Utils::split(homeDir.c_str(),ZT_PATH_SEPARATOR_S,"","")); + std::string ptmp; + if (homeDir[0] == ZT_PATH_SEPARATOR) + ptmp.push_back(ZT_PATH_SEPARATOR); + for(std::vector::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) { + if (ptmp.length() > 0) ptmp.push_back(ZT_PATH_SEPARATOR); - for(std::vector::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) { - if (ptmp.length() > 0) - ptmp.push_back(ZT_PATH_SEPARATOR); - ptmp.append(*pi); - if ((*pi != ".")&&(*pi != "..")) { - if (!ZeroTier::OSUtils::mkdir(ptmp)) { - dwr(MSG_ERROR, "startOneService(): home path does not exist, and could not create\n"); - } + ptmp.append(*pi); + if ((*pi != ".")&&(*pi != "..")) { + if (!ZeroTier::OSUtils::mkdir(ptmp)) { + dwr(MSG_ERROR, "startOneService(): home path does not exist, and could not create\n"); } } } - else { - fprintf(stderr, "start_service(): homeDir is empty, could not construct path\n"); - return NULL; - } - - #if defined(__IOS__) - // Go to the app's data directory so we can shorten the sun_path we bind to - int MAX_DIR_SZ = 256; - char current_dir[MAX_DIR_SZ]; - getcwd(current_dir, MAX_DIR_SZ); - std::string targetDir = homeDir + "/../../"; - chdir(targetDir.c_str()); - homeDir = localHomeDir; - #endif - - //chdir(current_dir); // Return to previous current working directory (at the request of Unity3D) - #if defined(__UNITY_3D__) - Debug("Starting service...\n"); - #endif - - // Initialize RPC - if(rpcEnabled) { - zt_init_rpc(localHomeDir.c_str(), rpcNWID.c_str()); - } - - // Generate random port for new service instance - unsigned int randp = 0; - ZeroTier::Utils::getSecureRandom(&randp,sizeof(randp)); - int servicePort = 9000 + (randp % 1000); - - for(;;) { - zt1Service = ZeroTier::OneService::newInstance(homeDir.c_str(),servicePort); - switch(zt1Service->run()) { - case ZeroTier::OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done - case ZeroTier::OneService::ONE_NORMAL_TERMINATION: - break; - case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: - fprintf(stderr,"start_service(): fatal error: %s",zt1Service->fatalErrorMessage().c_str()); - break; - case ZeroTier::OneService::ONE_IDENTITY_COLLISION: { - delete zt1Service; - zt1Service = (ZeroTier::OneService *)0; - std::string oldid; - ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid); - if (oldid.length()) { - ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid); - ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str()); - ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str()); - } - } - continue; // restart! - } - break; // terminate loop -- normally we don't keep restarting - } - delete zt1Service; - zt1Service = (ZeroTier::OneService *)0; + } + else { + fprintf(stderr, "start_service(): homeDir is empty, could not construct path\n"); return NULL; } + #if defined(__IOS__) + // Go to the app's data directory so we can shorten the sun_path we bind to + int MAX_DIR_SZ = 256; + char current_dir[MAX_DIR_SZ]; + getcwd(current_dir, MAX_DIR_SZ); + std::string targetDir = homeDir + "/../../"; + chdir(targetDir.c_str()); + homeDir = localHomeDir; + #endif + + //chdir(current_dir); // Return to previous current working directory (at the request of Unity3D) + #if defined(__UNITY_3D__) + Debug("Starting service...\n"); + #endif + + // Initialize RPC + if(rpcEnabled) { + zt_init_rpc(localHomeDir.c_str(), rpcNWID.c_str()); + } + + // Generate random port for new service instance + unsigned int randp = 0; + ZeroTier::Utils::getSecureRandom(&randp,sizeof(randp)); + int servicePort = 9000 + (randp % 1000); + + for(;;) { + zt1Service = ZeroTier::OneService::newInstance(homeDir.c_str(),servicePort); + switch(zt1Service->run()) { + case ZeroTier::OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done + case ZeroTier::OneService::ONE_NORMAL_TERMINATION: + break; + case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: + fprintf(stderr,"start_service(): fatal error: %s",zt1Service->fatalErrorMessage().c_str()); + break; + case ZeroTier::OneService::ONE_IDENTITY_COLLISION: { + delete zt1Service; + zt1Service = (ZeroTier::OneService *)0; + std::string oldid; + ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid); + if (oldid.length()) { + ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid); + ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str()); + ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str()); + } + } + continue; // restart! + } + break; // terminate loop -- normally we don't keep restarting + } + delete zt1Service; + zt1Service = (ZeroTier::OneService *)0; + return NULL; +} + #ifdef __cplusplus } #endif