diff --git a/CMakeLists.txt b/CMakeLists.txt index add188e..0ab3cdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.0) +cmake_minimum_required (VERSION 3.10) project (zt) # ----------------------------------------------------------------------------- @@ -133,8 +133,8 @@ set (DEBUG_OPTIMIZATION "-O3") set (RELEASE_OPTIMIZATION "-O3") if (BUILDING_WIN) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc -DNOMINMAX") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -idirafter ${PROJECT_SOURCE_DIR}/include/mingw-fixes") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX -idirafter ${PROJECT_SOURCE_DIR}/include/mingw-fixes") else () set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \ @@ -235,7 +235,8 @@ file (GLOB ztcoreSrcGlob file (GLOB libnatpmpSrcGlob ${ZTO_SRC_DIR}/ext/libnatpmp/natpmp.c - ${ZTO_SRC_DIR}/ext/libnatpmp/getgateway.c) + ${ZTO_SRC_DIR}/ext/libnatpmp/getgateway.c + ${ZTO_SRC_DIR}/ext/libnatpmp/wingettimeofday.c) file (GLOB libminiupnpcSrcGlob ${ZTO_SRC_DIR}/ext/miniupnpc/connecthostport.c @@ -430,7 +431,7 @@ add_library (${STATIC_LIB_NAME} STATIC $ $ $ $ -$ ${libztSrcGlob}) +$) set_target_properties (${STATIC_LIB_NAME} PROPERTIES OUTPUT_NAME zt LIBRARY_OUTPUT_DIRECTORY ${INTERMEDIATE_LIBRARY_OUTPUT_PATH}) @@ -500,21 +501,3 @@ if (SHOULD_BUILD_TESTS) #add_executable (simple ${PROJ_DIR}/test/simple.cpp) #target_link_libraries(simple ${STATIC_LIB_NAME}) endif () - -# ----------------------------------------------------------------------------- -# | INSTALL | -# ----------------------------------------------------------------------------- - -set (PUBLIC_ZT_HEADERS - ${PROJECT_SOURCE_DIR}/include/ZeroTier.h - ${PROJECT_SOURCE_DIR}/include/ZeroTierConstants.h) - -set_target_properties(${STATIC_LIB_NAME} PROPERTIES PUBLIC_HEADER "${PUBLIC_ZT_HEADERS}") -install (TARGETS ${STATIC_LIB_NAME} - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - PUBLIC_HEADER DESTINATION include -) -install (TARGETS ${DYNAMIC_LIB_NAME} - LIBRARY DESTINATION lib -) diff --git a/include/ZeroTier.h b/include/ZeroTier.h index a60849b..b15c30d 100644 --- a/include/ZeroTier.h +++ b/include/ZeroTier.h @@ -37,7 +37,8 @@ #include -#ifdef _WIN32 +//#ifdef _WIN32 +#if 0 #ifdef ADD_EXPORTS #define ZT_SOCKET_API __declspec(dllexport) #else @@ -71,6 +72,8 @@ typedef int socklen_t; #include #include #include +#else +#include #endif #if defined(_MSC_VER) @@ -92,7 +95,7 @@ typedef uint16_t zts_in_port_t; typedef uint8_t zts_sa_family_t; struct zts_in_addr { - zts_in_addr_t s_addr; + zts_in_addr_t zts_s_addr; }; struct zts_in6_addr { diff --git a/include/mingw-fixes/IPHlpApi.h b/include/mingw-fixes/IPHlpApi.h new file mode 100644 index 0000000..4d08efd --- /dev/null +++ b/include/mingw-fixes/IPHlpApi.h @@ -0,0 +1 @@ +#include diff --git a/include/mingw-fixes/Ifdef.h b/include/mingw-fixes/Ifdef.h new file mode 100644 index 0000000..5283a4a --- /dev/null +++ b/include/mingw-fixes/Ifdef.h @@ -0,0 +1 @@ +#include diff --git a/include/mingw-fixes/ShlObj.h b/include/mingw-fixes/ShlObj.h new file mode 100644 index 0000000..5b17afa --- /dev/null +++ b/include/mingw-fixes/ShlObj.h @@ -0,0 +1 @@ +#include diff --git a/include/mingw-fixes/Shlwapi.h b/include/mingw-fixes/Shlwapi.h new file mode 100644 index 0000000..89b9b63 --- /dev/null +++ b/include/mingw-fixes/Shlwapi.h @@ -0,0 +1 @@ +#include diff --git a/include/mingw-fixes/WS2tcpip.h b/include/mingw-fixes/WS2tcpip.h new file mode 100644 index 0000000..8fc8783 --- /dev/null +++ b/include/mingw-fixes/WS2tcpip.h @@ -0,0 +1 @@ +#include diff --git a/include/mingw-fixes/WinSock2.h b/include/mingw-fixes/WinSock2.h new file mode 100644 index 0000000..29f4ce7 --- /dev/null +++ b/include/mingw-fixes/WinSock2.h @@ -0,0 +1 @@ +#include diff --git a/include/mingw-fixes/Windows.h b/include/mingw-fixes/Windows.h new file mode 100644 index 0000000..776a87c --- /dev/null +++ b/include/mingw-fixes/Windows.h @@ -0,0 +1 @@ +#include diff --git a/src/Controls.cpp b/src/Controls.cpp index c2b8152..d74ef45 100644 --- a/src/Controls.cpp +++ b/src/Controls.cpp @@ -34,6 +34,8 @@ #include #endif +#include + #include "Node.hpp" #include "ZeroTierOne.h" #include "OSUtils.hpp" @@ -94,8 +96,8 @@ bool _run_lwip_tcpip = false; //bool _startupError = false; -pthread_t service_thread; -pthread_t callback_thread; +std::thread service_thread; +std::thread callback_thread; // Global reference to ZeroTier service OneService *service; @@ -283,22 +285,22 @@ void _api_sleep(int interval_ms) int _change_nice(int increment) { +#ifndef _WIN32 if (increment == 0) { return 0; } int priority = getpriority(PRIO_PROCESS, 0); return setpriority(PRIO_PROCESS, 0, priority+increment); +#else + return 0; +#endif } ////////////////////////////////////////////////////////////////////////////// // Callback thread // ////////////////////////////////////////////////////////////////////////////// -#if defined(_WIN32) -DWORD WINAPI _zts_run_callbacks(LPVOID thread_id) -#else -void *_zts_run_callbacks(void *thread_id) -#endif +void _zts_run_callbacks() { _change_nice(CALLBACK_THREAD_NICENESS); #if defined(__APPLE__) @@ -329,12 +331,8 @@ void *_zts_run_callbacks(void *thread_id) ////////////////////////////////////////////////////////////////////////////// // Starts a ZeroTier service in the background -#if defined(_WIN32) -DWORD WINAPI _zts_run_service(LPVOID arg) -#else -void *_zts_run_service(void *arg) -#endif -{ +void _zts_run_service() +{ #if defined(__APPLE__) pthread_setname_np(ZTS_SERVICE_THREAD_NAME); #endif @@ -406,7 +404,6 @@ void *_zts_run_service(void *arg) // TODO: Find a more elegant solution _api_sleep(ZTS_CALLBACK_PROCESSING_INTERVAL*2); _run_callbacks = false; - pthread_exit(0); } #ifdef __cplusplus @@ -564,19 +561,15 @@ int zts_start( #if defined(_WIN32) // Initialize WinSock. Used in Phy for loopback pipe WSAStartup(MAKEWORD(2, 2), &wsaData); - HANDLE serviceThread = CreateThread(NULL, 0, _zts_run_service, (void*)params, 0, NULL); - HANDLE callbackThread = CreateThread(NULL, 0, _zts_run_callbacks, NULL, 0, NULL); #endif - if ((err = pthread_create(&service_thread, NULL, _zts_run_service, NULL)) != 0) { - retval = err; - } - if ((err = pthread_create(&callback_thread, NULL, _zts_run_callbacks, NULL)) != 0) { - retval = err; - } + service_thread = std::thread(_zts_run_service); + callback_thread = std::thread(_zts_run_callbacks); #if defined(__linux__) - pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME); - pthread_setname_np(callback_thread, ZTS_EVENT_CALLBACK_THREAD_NAME); + pthread_setname_np(service_thread.native_handle(), ZTS_SERVICE_THREAD_NAME); + pthread_setname_np(callback_thread.native_handle(), ZTS_EVENT_CALLBACK_THREAD_NAME); #endif + service_thread.detach(); + callback_thread.detach(); if (retval != ZTS_ERR_OK) { _run_callbacks = false; diff --git a/src/Controls.hpp b/src/Controls.hpp index 4b3870e..4a4d4df 100644 --- a/src/Controls.hpp +++ b/src/Controls.hpp @@ -77,11 +77,7 @@ extern "C" { * @param * @return */ -#if defined(_WIN32) -DWORD WINAPI _zts_run_service(LPVOID thread_id); -#else -void *_zts_run_service(void *thread_id); -#endif +void _zts_run_service(); /** * @brief [Should not be called from user application] This function must be surrounded by diff --git a/src/Service.cpp b/src/Service.cpp index ebf8277..492c907 100644 --- a/src/Service.cpp +++ b/src/Service.cpp @@ -384,6 +384,7 @@ public: } if (_trialBind(_primaryPort)) { _ports[0] = _primaryPort; + break; } else { _primaryPort = 0; } diff --git a/src/VirtualTap.cpp b/src/VirtualTap.cpp index a0dd2cb..2563542 100644 --- a/src/VirtualTap.cpp +++ b/src/VirtualTap.cpp @@ -74,12 +74,12 @@ VirtualTap::VirtualTap( _mtu(mtu), _nwid(nwid), _unixListenSocket((PhySocket *)0), - _phy(this,false,true) + _phy(this,false,true), + shutdownSignal(false) { memset(vtap_full_name, 0, sizeof(vtap_full_name)); snprintf(vtap_full_name, sizeof(vtap_full_name), "libzt%llx", (unsigned long long)_nwid); _dev = vtap_full_name; - ::pipe(_shutdownSignalPipe); // Start virtual tap thread and stack I/O loops _thread = Thread::start(this); } @@ -90,13 +90,15 @@ VirtualTap::~VirtualTap() nd->nwid = _nwid; postEvent(ZTS_EVENT_NETWORK_DOWN, (void*)nd); _run = false; - ::write(_shutdownSignalPipe[1],"\0",1); + { + std::unique_lock lock(shutdownSignalMutex); + shutdownSignal = true; + shutdownSignalConditionTrue.notify_all(); + } _phy.whack(); lwip_remove_netif(netif); netif = NULL; Thread::join(_thread); - ::close(_shutdownSignalPipe[0]); - ::close(_shutdownSignalPipe[1]); } void VirtualTap::lastConfigUpdate(uint64_t lastConfigUpdateTime) @@ -245,6 +247,11 @@ void VirtualTap::scanMulticastGroups(std::vector &added, std::vector newGroups; Mutex::Lock _l(_multicastGroups_m); // TODO: get multicast subscriptions + + // Hardcoded MAC for IPv6 multicast address + // ff0e:a8a9:b611:58ce:0412:fd73:3786:6fb7 + newGroups.push_back(MulticastGroup(MAC(0x33, 0x33, 0x37, 0x86, 0x6f, 0xb7), 0)); + std::vector allIps(ips()); for (std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); @@ -271,33 +278,31 @@ void VirtualTap::setMtu(unsigned int mtu) void VirtualTap::threadMain() throw() { - fd_set readfds,nullfds; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; - FD_ZERO(&readfds); - FD_ZERO(&nullfds); - int nfds = (int)std::max(_shutdownSignalPipe[0],0) + 1; #if defined(__linux__) pthread_setname_np(pthread_self(), vtap_full_name); #endif #if defined(__APPLE__) pthread_setname_np(vtap_full_name); #endif - while (true) { - FD_SET(_shutdownSignalPipe[0],&readfds); - select(nfds,&readfds,&nullfds,&nullfds,&tv); - // writes to shutdown pipe terminate thread - if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) { - break; - } + { + std::unique_lock lock(shutdownSignalMutex); + while (true) { + if(shutdownSignal) + break; + shutdownSignalConditionTrue.wait(lock); + if(shutdownSignal) + break; #if defined(_WIN32) - Sleep(ZTS_TAP_THREAD_POLLING_INTERVAL); + Sleep(ZTS_TAP_THREAD_POLLING_INTERVAL); #else - struct timespec sleepValue = {0}; - sleepValue.tv_nsec = ZTS_TAP_THREAD_POLLING_INTERVAL * 500000; - nanosleep(&sleepValue, NULL); + struct timespec sleepValue = {0}; + sleepValue.tv_nsec = ZTS_TAP_THREAD_POLLING_INTERVAL * 500000; + nanosleep(&sleepValue, NULL); #endif + } } } diff --git a/src/VirtualTap.hpp b/src/VirtualTap.hpp index 1f45469..202023e 100644 --- a/src/VirtualTap.hpp +++ b/src/VirtualTap.hpp @@ -37,6 +37,8 @@ extern int errno; #endif +#include + #include "Phy.hpp" #include "Thread.hpp" #include "InetAddress.hpp" @@ -214,7 +216,9 @@ public: Thread _thread; - int _shutdownSignalPipe[2]; + bool shutdownSignal; + std::mutex shutdownSignalMutex; + std::condition_variable shutdownSignalConditionTrue; std::string _dev; // path to Unix domain socket diff --git a/src/lwipopts.h b/src/lwipopts.h index 1d6b390..006d824 100644 --- a/src/lwipopts.h +++ b/src/lwipopts.h @@ -54,12 +54,13 @@ #if __ANDROID__ #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 0 #endif -#if __ANDROID__ -#define LWIP_PROVIDE_ERRNO 1 -#define SOCKLEN_T_DEFINED -#elif !defined(_MSC_VER) -#define LWIP_PROVIDE_ERRNO 1 -#endif +// #if __ANDROID__ +// #define LWIP_PROVIDE_ERRNO 1 +// #define SOCKLEN_T_DEFINED +// #elif !defined(_MSC_VER) +// #define LWIP_PROVIDE_ERRNO 1 +// #endif +#define LWIP_ERRNO_STDINCLUDE 1 // Sockets #define LWIP_SOCKET 1 #define LWIP_COMPAT_SOCKETS 0 @@ -118,7 +119,7 @@ // tcpip #define TCPIP_MBOX_SIZE 0 #define LWIP_TCPIP_CORE_LOCKING 1 -#define LWIP_TCPIP_CORE_LOCKING_INPUT 1 +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 // netconn #define LWIP_NETCONN_FULLDUPLEX 0 // netif @@ -968,14 +969,14 @@ happening sooner than they should. * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) */ #if !defined LWIP_BROADCAST_PING || defined __DOXYGEN__ -#define LWIP_BROADCAST_PING 0 +#define LWIP_BROADCAST_PING 1 #endif /** * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) */ #if !defined LWIP_MULTICAST_PING || defined __DOXYGEN__ -#define LWIP_MULTICAST_PING 0 +#define LWIP_MULTICAST_PING 1 #endif /** * @} @@ -1174,7 +1175,7 @@ happening sooner than they should. * LWIP_IGMP==1: Turn on IGMP module. */ #if !defined LWIP_IGMP || defined __DOXYGEN__ -#define LWIP_IGMP 0 +#define LWIP_IGMP 1 #endif #if !LWIP_IPV4 #undef LWIP_IGMP @@ -3176,7 +3177,7 @@ happening sooner than they should. * @see debugging_levels */ #if !defined LWIP_DBG_MIN_LEVEL || defined __DOXYGEN__ -#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_SEVERE #endif /**