From 362f6769b290514fa921729998b2f783ebb1d554 Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Mon, 25 Feb 2019 14:52:19 -0800 Subject: [PATCH] Bug fix for callbacks, minor netif driver tweak, minor Makefile tweak --- CMakeLists.txt | 83 +++++++++++++++++++++++----------------------- Makefile | 10 +++--- src/Controls.cpp | 31 ++++++++++++++++- src/VirtualTap.cpp | 21 ++++++++++-- src/lwipDriver.cpp | 45 ++++++++++--------------- src/lwipDriver.hpp | 7 ++-- 6 files changed, 117 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cc2809..bfd3c7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,26 +66,6 @@ else () set (DYNAMIC_LIB_OUTPUT_NAME ${PROJECT_NAME}) endif () -# ----------------------------------------------------------------------------- -# | FLAGS | -# ----------------------------------------------------------------------------- - -set (SILENCE "-Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-missing-field-initializers") -set (LIBZT_FLAGS "-D_USING_LWIP_DEFINITIONS_=1 -DZT_SDK") -set (ZTCORE_FLAGS "-DZT_USE_MINIUPNPC=1 -DZT_SOFTWARE_UPDATE_DEFAULT=0") - -if (BUILDING_WIN) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc -DNOMINMAX") -else () - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBZT_FLAGS} -fstack-protector") - set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${LIBZT_FLAGS} -DLWIP_DEBUG=1 -DLIBZT_DEBUG=1") - set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${LIBZT_FLAGS} -fstack-protector") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SILENCE} ${LIBZT_FLAGS} -O3 -Wall -Wextra -std=c++11") - set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${SILENCE} ${LIBZT_FLAGS} -std=c++11 -DLWIP_DEBUG=1 -DLIBZT_DEBUG=1") - set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${SILENCE} ${LIBZT_FLAGS} -O3 -std=c++11") -endif () - # ----------------------------------------------------------------------------- # | PLATFORM/FEATURE AND IDE DETECTION | # ----------------------------------------------------------------------------- @@ -121,6 +101,32 @@ if (BUILDING_WIN32 OR BUILDING_WIN64 OR MSVC) set (BUILDING_WIN TRUE) endif () +# ----------------------------------------------------------------------------- +# | FLAGS | +# ----------------------------------------------------------------------------- + +set (SILENCE "-Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-missing-field-initializers") +set (LIBZT_FLAGS "-D_USING_LWIP_DEFINITIONS_=1 -DZT_SDK") +set (ZTCORE_FLAGS "-DZT_USE_MINIUPNPC=1 -DZT_SOFTWARE_UPDATE_DEFAULT=0") + +if (BUILDING_WIN) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc -DNOMINMAX") +else () + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBZT_FLAGS} -fstack-protector") + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${LIBZT_FLAGS} -DLWIP_DEBUG=1 -DLIBZT_DEBUG=1") + set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${LIBZT_FLAGS} -fstack-protector") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SILENCE} ${LIBZT_FLAGS} -O3 -Wall -Wextra -std=c++11") + set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${SILENCE} ${LIBZT_FLAGS} -std=c++11 -DLWIP_DEBUG=1 -DLIBZT_DEBUG=1") + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${SILENCE} ${LIBZT_FLAGS} -O3 -std=c++11") +endif () + +if (BUILDING_LINUX AND NOT BUILDING_ANDROID) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lpthread") +endif () + + + # ----------------------------------------------------------------------------- # | JNI | # ----------------------------------------------------------------------------- @@ -324,27 +330,22 @@ endif () # ----------------------------------------------------------------------------- if (SHOULD_BUILD_TESTS) - add_executable (example ${PROJ_DIR}/test/example.cpp) - target_link_libraries(example zt) - add_executable (selftest ${PROJ_DIR}/test/selftest.cpp) - target_link_libraries(selftest zt) - set_target_properties (selftest PROPERTIES COMPILE_FLAGS "${SILENCE} -D__SELFTEST__") + # Minimal functional example + #add_executable (example ${PROJ_DIR}/test/example.cpp) + #target_link_libraries(example zt) - # Simple client/server example using ZeroTier sockets - add_executable (client ${PROJ_DIR}/test/client.cpp) - target_link_libraries(client zt) - set_target_properties (client PROPERTIES COMPILE_FLAGS "${SILENCE} -D__SELFTEST__") - add_executable (server ${PROJ_DIR}/test/server.cpp) - target_link_libraries(server zt) - set_target_properties (server PROPERTIES COMPILE_FLAGS "${SILENCE} -D__SELFTEST__") + # API test + #add_executable (apitest ${PROJ_DIR}/test/apitest.cpp) + #target_link_libraries(apitest zt) - # Native client/server - add_executable (client_native ${PROJ_DIR}/test/client.cpp) - target_link_libraries(client_native zt) - set_target_properties (client_native PROPERTIES COMPILE_FLAGS "${SILENCE}") - set_target_properties (client_native PROPERTIES OUTPUT_NAME client_native) - add_executable (server_native ${PROJ_DIR}/test/server.cpp) - target_link_libraries(server_native zt) - set_target_properties (server_native PROPERTIES COMPILE_FLAGS "${SILENCE}") - set_target_properties (server_native PROPERTIES OUTPUT_NAME server_native) + # Selftest + #add_executable (selftest ${PROJ_DIR}/test/selftest.cpp) + #target_link_libraries(selftest zt) + #set_target_properties (selftest PROPERTIES COMPILE_FLAGS "-D__SELFTEST__") + + # client/server performance test + #add_executable (client ${PROJ_DIR}/test/client.cpp) + #target_link_libraries(client zt) + #add_executable (server ${PROJ_DIR}/test/server.cpp) + #target_link_libraries(server zt) endif () \ No newline at end of file diff --git a/Makefile b/Makefile index 1ad6a85..6e51b8a 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ CLEAN_SCRIPT := ./ports/clean.sh PACKAGE_SCRIPT := ./ports/package.sh endif -CONCURRENT_BUILD_JOBS=2 +CONCURRENT_BUILD_JOBS=#-j 2 # Patch submodules patch: @@ -43,19 +43,21 @@ patch: .PHONY: clean clean: - rm -rf bin staging generated dist + -rm -rf bin staging generated dist + -find ports -name ".externalNativeBuild" -exec rm -r "{}" \; all: debug release release: -mkdir generated cmake -H. -Bgenerated/release -DCMAKE_BUILD_TYPE=Release - cmake --build generated/release -j $(CONCURRENT_BUILD_JOBS) + cmake --build generated/release $(CONCURRENT_BUILD_JOBS) + debug: -mkdir generated cmake -H. -Bgenerated/debug -DCMAKE_BUILD_TYPE=Debug - cmake --build generated/debug -j $(CONCURRENT_BUILD_JOBS) + cmake --build generated/debug $(CONCURRENT_BUILD_JOBS) # dist: # Build and package everything diff --git a/src/Controls.cpp b/src/Controls.cpp index 30eeebf..6718080 100644 --- a/src/Controls.cpp +++ b/src/Controls.cpp @@ -165,23 +165,52 @@ void freeEvent(struct zts_callback_msg *msg) void _process_callback_event_helper(struct zts_callback_msg *msg) { #ifdef SDK_JNI +/* Old style callback messages are simply a uint64_t with a network/peer/node +if of some sort and an associated message code id. This is deprecated and here +only for legacy reasons. */ +#if 1 + if(_userCallbackMethodRef) { + JNIEnv *env; + jint rs = jvm->AttachCurrentThread(&env, NULL); + assert (rs == JNI_OK); + uint64_t arg = 0; + uint64_t id = 0; + if (NODE_EVENT_TYPE(msg->eventCode)) { + DEBUG_INFO("NODE_EVENT_TYPE(%d)", msg->eventCode); + id = msg->node ? msg->node->address : 0; + } + if (NETWORK_EVENT_TYPE(msg->eventCode)) { + DEBUG_INFO("NETWORK_EVENT_TYPE(%d)", msg->eventCode); + id = msg->network ? msg->network->nwid : 0; + } + if (PEER_EVENT_TYPE(msg->eventCode)) { + DEBUG_INFO("PEER_EVENT_TYPE(%d)", msg->eventCode); + id = msg->peer ? msg->peer->address : 0; + } + env->CallVoidMethod(objRef, _userCallbackMethodRef, id, msg->eventCode); + freeEvent(msg); + } +#else if(_userCallbackMethodRef) { JNIEnv *env; jint rs = jvm->AttachCurrentThread(&env, NULL); assert (rs == JNI_OK); uint64_t arg = 0; if (NODE_EVENT_TYPE(msg->eventCode)) { + DEBUG_INFO("NODE_EVENT_TYPE(%d)", msg->eventCode); arg = msg->node->address; } if (NETWORK_EVENT_TYPE(msg->eventCode)) { + DEBUG_INFO("NETWORK_EVENT_TYPE(%d)", msg->eventCode); arg = msg->network->nwid; } if (PEER_EVENT_TYPE(msg->eventCode)) { + DEBUG_INFO("PEER_EVENT_TYPE(%d)", msg->eventCode); arg = msg->peer->address; } env->CallVoidMethod(objRef, _userCallbackMethodRef, arg, msg->eventCode); freeEvent(msg); - } +#endif #else if (_userEventCallbackFunc) { _userEventCallbackFunc(msg); diff --git a/src/VirtualTap.cpp b/src/VirtualTap.cpp index 70364fe..aa85611 100644 --- a/src/VirtualTap.cpp +++ b/src/VirtualTap.cpp @@ -92,7 +92,8 @@ VirtualTap::~VirtualTap() _run = false; ::write(_shutdownSignalPipe[1],"\0",1); _phy.whack(); - lwip_dispose_of_netif(this); + lwip_remove_netif(netif); + netif = NULL; Thread::join(_thread); ::close(_shutdownSignalPipe[0]); ::close(_shutdownSignalPipe[1]); @@ -137,8 +138,24 @@ bool VirtualTap::hasIpv6Addr() bool VirtualTap::addIp(const InetAddress &ip) { - char ipbuf[INET6_ADDRSTRLEN]; + //char ipbuf[128]; + //ip.toString(ipbuf); + //DEBUG_INFO("addr=%s", ipbuf); + + /* Limit address assignments to one per type. + This limitation can be removed if some changes + are made in the netif driver. */ + if (ip.isV4() && hasIpv4Addr()) { + return false; + } + if (ip.isV6() && hasIpv6Addr()) { + return false; + } + Mutex::Lock _l(_ips_m); + if (_ips.size() >= ZT_MAX_ZT_ASSIGNED_ADDRESSES) { + return false; + } if (std::find(_ips.begin(),_ips.end(),ip) == _ips.end()) { lwip_init_interface((void*)this, this->_mac, ip); // TODO: Add ZTS_EVENT_ADDR_NEW ? diff --git a/src/lwipDriver.cpp b/src/lwipDriver.cpp index 0181d8b..104780a 100644 --- a/src/lwipDriver.cpp +++ b/src/lwipDriver.cpp @@ -58,9 +58,6 @@ extern void postEvent(uint64_t eventCode, void *arg); extern void postEvent(uint64_t eventCode); -#include "concurrentqueue.h" -moodycamel::ConcurrentQueue rx_queue; - #if defined(_WIN32) #include #endif @@ -70,6 +67,10 @@ moodycamel::ConcurrentQueue rx_queue; */ #define ZTS_MAC_ADDRSTRLEN 18 +#ifndef htonll +#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#endif + namespace ZeroTier { bool _has_exited = false; @@ -167,15 +168,6 @@ void lwip_driver_shutdown() _run_lwip_tcpip = false; // Wait until the main lwIP thread has exited while (!_has_exited) { lwip_sleep(LWIP_GUARDED_BUF_CHECK_INTERVAL); } - // After we're certain the stack isn't processing anymore traffic, - // start dequeing from the RX queue. This queue should be rejecting - // new frames at this point. - struct zts_sorted_packet *sp; - for (int i = 0; i < ZTS_LWIP_MAX_RX_QUEUE_LEN; i++) { - if (rx_queue.try_dequeue(sp)) { - delete sp; - } - } /* if (tcpip_shutdown() == ERR_OK) { sys_timeouts_free(); @@ -183,18 +175,14 @@ void lwip_driver_shutdown() */ } -void lwip_dispose_of_netif(void *tapref) +void lwip_remove_netif(void *netif) { - VirtualTap *vtap = (VirtualTap*)tapref; - if (vtap->netif) { - LOCK_TCPIP_CORE(); - netif_remove((struct netif*)(vtap->netif)); - netif_set_down((struct netif*)(vtap->netif)); - netif_set_link_down((struct netif*)(vtap->netif)); - UNLOCK_TCPIP_CORE(); - delete vtap->netif; - vtap->netif = NULL; - } + struct netif *n = (struct netif*)netif; + LOCK_TCPIP_CORE(); + netif_remove(n); + netif_set_down(n); + netif_set_link_down(n); + UNLOCK_TCPIP_CORE(); } err_t lwip_eth_tx(struct netif *n, struct pbuf *p) @@ -299,6 +287,7 @@ void lwip_eth_rx(VirtualTap *tap, const MAC &from, const MAC &to, unsigned int e } } +/* static void print_netif_info(struct netif *n) { DEBUG_INFO("n=%p, %c%c, %d, o=%p, o6=%p, mc=%x:%x:%x:%x:%x:%x, hwln=%d, st=%p, flgs=%d\n", n, @@ -318,6 +307,7 @@ static void print_netif_info(struct netif *n) { n->flags ); } +*/ bool lwip_is_netif_up(void *n) { @@ -388,7 +378,7 @@ void lwip_set_callbacks(struct netif *n) #endif } -static void lwip_prepare_netif_status_msg(struct netif *n) +static struct zts_netif_details *lwip_prepare_netif_status_msg(struct netif *n) { VirtualTap *tap = (VirtualTap*)(n->state); struct zts_netif_details *ifd = new zts_netif_details; @@ -398,8 +388,8 @@ static void lwip_prepare_netif_status_msg(struct netif *n) ifd->mtu = n->mtu; // MAC memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len); - ifd->mac = lwip_htonl(ifd->mac) >> 16; - postEvent(ZTS_EVENT_NETIF_UP, (void*)ifd); + ifd->mac = htonll(ifd->mac) >> 16; + return ifd; } static err_t netif_init(struct netif *n) @@ -421,7 +411,6 @@ static err_t netif_init(struct netif *n) n->hwaddr_len = sizeof(n->hwaddr); VirtualTap *tap = (VirtualTap*)(n->state); tap->_mac.copyTo(n->hwaddr, n->hwaddr_len); - lwip_prepare_netif_status_msg(n); return ERR_OK; } @@ -447,6 +436,7 @@ void lwip_init_interface(void *tapref, const MAC &mac, const InetAddress &ip) netmask.addr = *((u32_t *)ip.netmask().rawIpData()); LOCK_TCPIP_CORE(); netif_add(n, &ipaddr, &netmask, &gw, tapref, netif_init, tcpip_input); + postEvent(ZTS_EVENT_NETIF_UP, (void*)lwip_prepare_netif_status_msg(n)); UNLOCK_TCPIP_CORE(); /* snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x", @@ -468,6 +458,7 @@ void lwip_init_interface(void *tapref, const MAC &mac, const InetAddress &ip) netif_ip6_addr_set_state(n, 0, IP6_ADDR_TENTATIVE); netif_ip6_addr_set_state(n, 1, IP6_ADDR_TENTATIVE); n->output_ip6 = ethip6_output; + postEvent(ZTS_EVENT_NETIF_UP, (void*)lwip_prepare_netif_status_msg(n)); UNLOCK_TCPIP_CORE(); /* snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x", diff --git a/src/lwipDriver.hpp b/src/lwipDriver.hpp index 8e24e05..11b54cd 100644 --- a/src/lwipDriver.hpp +++ b/src/lwipDriver.hpp @@ -101,14 +101,11 @@ void lwip_driver_init(); void lwip_driver_shutdown(); /** - * @brief Bring down and delete all interfaces belonging to the given virtual tap + * @brief Requests that a netif be brought down and removed. * - * @usage This is to be called when the application desires to stop all traffic processing in the - * stack. Unlike lwip_driver_shutdown(), the application can easily resume traffic processing - * by re-adding a virtual tap (and associated lwip netifs) * @return */ -void lwip_dispose_of_netif(void *tapref); +void lwip_remove_netif(void *netif); /** * @brief Initialize and start the DNS client