From 2fdcf025e1d179ba2e1faf86e75efb7b5dc8de75 Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Wed, 6 Feb 2019 22:00:39 -0800 Subject: [PATCH] Re-work of thread model --- CMakeLists.txt | 399 +- Jenkinsfile | 44 - Makefile | 98 +- README.md | 9 +- examples/android/ExampleAndroidApp/.project | 17 + .../org.eclipse.buildship.core.prefs | 2 + .../android/ExampleAndroidApp/app/.classpath | 6 + .../android/ExampleAndroidApp/app/.project | 23 + .../org.eclipse.buildship.core.prefs | 2 + .../ExampleAndroidApp/app/build.gradle | 10 + .../app/libs/libzt-android-debug.aar | Bin 0 -> 861495 bytes .../example/exampleandroidapp/HTTPWorker.java | 79 + .../exampleandroidapp/MainActivity.java | 499 +- .../MyZeroTierEventListener.java | 82 + .../app/src/main/res/layout/activity_main.xml | 8 + .../ExampleWindowsCSharpApp.sln | 25 - .../ExampleWindowsCSharpApp/App.config | 6 - .../ExampleWindowsCSharpApp.csproj | 54 - .../ExampleWindowsCSharpApp/Program.cs | 118 - .../Properties/AssemblyInfo.cs | 36 - .../ExampleWindowsCSharpApp/libzt.cs | 184 - examples/java/ExampleApp.java | 280 - examples/java/README.md | 8 - examples/java/com/zerotier/libzt/ZTFDSet.java | 54 - .../com/zerotier/libzt/ZTSocketAddress.java | 92 - .../java/com/zerotier/libzt/ZeroTier.java | 82 - examples/layer2/layer2.cpp | 194 - examples/scala/ExampleApp.scala | 36 - examples/scala/Makefile | 18 - examples/scala/README.md | 14 - examples/scala/libzt.scala | 76 - .../ExampleSwiftApp.xcodeproj/project.pbxproj | 374 - .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcschemes/xcschememanagement.plist | 14 - .../ExampleSwiftApp/AppDelegate.swift | 46 - .../AppIcon.appiconset/Contents.json | 98 - .../Assets.xcassets/Contents.json | 6 - .../Base.lproj/LaunchScreen.storyboard | 25 - .../Base.lproj/Main.storyboard | 24 - .../ExampleSwiftApp/Example.swift | 73 - .../ExampleSwiftApp-Bridging-Header.h | 71 - .../ExampleSwiftApp/Info.plist | 45 - .../ExampleSwiftApp/ViewController.swift | 28 - .../ExampleSwiftApp/wrapper.cpp | 20 - .../ExampleSwiftApp/wrapper.hpp | 14 - examples/ztproxy/ztproxy.cpp | 406 -- examples/ztproxy/ztproxy.hpp | 132 - ext/ZeroTierOne.patch | 26 - ext/concurrentqueue/LICENSE.md | 61 + ext/concurrentqueue/concurrentqueue.h | 3635 ++++++++++ ext/lwip-contrib.patch | 32 - ext/lwipopts.h | 2 - include/Constants.hpp | 346 - include/Defs.hpp | 215 - include/RingBuffer.h | 97 - include/ServiceControls.hpp | 393 -- include/libzt.h | 527 +- packages/PyPI/bdist.bat | 7 - packages/README.md | 25 - packages/android/.gitignore | 10 - packages/android/.project | 17 + packages/android/app/.gitignore | 1 - packages/android/app/build.gradle | 42 - packages/android/app/proguard-rules.pro | 21 - .../zerotier/ExampleInstrumentedTest.java | 26 - .../android/app/src/main/AndroidManifest.xml | 25 - .../android/app/src/main/java/ZTFDSet.java | 54 - .../app/src/main/java/ZTSocketAddress.java | 92 - .../android/app/src/main/java/ZeroTier.java | 82 - .../com/example/zerotier/MainActivity.java | 75 - .../drawable-v24/ic_launcher_foreground.xml | 34 - .../res/drawable/ic_launcher_background.xml | 170 - .../app/src/main/res/layout/activity_main.xml | 19 - .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3056 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 5024 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2096 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 2858 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4569 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 7098 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 6464 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10676 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 9250 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 15523 -> 0 bytes .../app/src/main/res/values/colors.xml | 6 - .../app/src/main/res/values/strings.xml | 3 - .../app/src/main/res/values/styles.xml | 11 - .../com/example/zerotier/ExampleUnitTest.java | 17 - packages/android/build.gradle | 27 - packages/android/gradle.properties | 13 - .../android/gradle/wrapper/gradle-wrapper.jar | Bin 54708 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - packages/android/gradlew | 172 - packages/android/gradlew.bat | 84 - packages/android/settings.gradle | 1 - packages/clean.bat | 4 - packages/clean.sh | 7 - packages/dist.bat | 88 - packages/dist.sh | 184 - packages/java/com/zerotier/libzt/ZTFDSet.java | 54 - .../com/zerotier/libzt/ZTSocketAddress.java | 92 - .../java/com/zerotier/libzt/ZeroTier.java | 82 - packages/module.modulemap | 6 - packages/package.sh | 43 - packages/pypi/LICENSE.txt | 674 -- packages/pypi/MANIFEST.in | 12 - packages/pypi/Makefile | 20 - packages/pypi/README.md | 67 - packages/pypi/README.rst | 8 - packages/pypi/libzt.i | 136 - packages/pypi/libzt.py | 380 -- packages/pypi/libzt/.gitignore | 4 - packages/pypi/libzt_wrap.cxx | 6003 ----------------- packages/pypi/setup.cfg | 2 - packages/pypi/setup.py | 113 - packages/pypi/test.py | 23 - src/Controls.cpp | 760 +++ src/Controls.hpp | 91 + {include => src}/Debug.hpp | 0 src/Intercept.cpp | 0 src/Intercept.hpp | 0 src/Options.h | 59 + src/RingBuffer.cpp | 143 - src/Service.cpp | 1230 ++++ src/Service.hpp | 203 + src/ServiceControls.cpp | 1177 ---- src/{libzt.cpp => Sockets.cpp} | 139 +- src/VirtualTap.cpp | 90 +- {include => src}/VirtualTap.hpp | 2 +- src/{lwIP.cpp => lwipDriver.cpp} | 85 +- include/lwIP.h => src/lwipDriver.hpp | 6 +- src/lwipRawDriver.cpp | 0 src/lwipRawDriver.hpp | 0 {include => src}/lwipopts.h | 4 +- test/create_test_identities.sh | 11 - test/echotest.cpp | 288 - 138 files changed, 7567 insertions(+), 15053 deletions(-) delete mode 100644 Jenkinsfile create mode 100644 examples/android/ExampleAndroidApp/.project create mode 100644 examples/android/ExampleAndroidApp/.settings/org.eclipse.buildship.core.prefs create mode 100644 examples/android/ExampleAndroidApp/app/.classpath create mode 100644 examples/android/ExampleAndroidApp/app/.project create mode 100644 examples/android/ExampleAndroidApp/app/.settings/org.eclipse.buildship.core.prefs create mode 100644 examples/android/ExampleAndroidApp/app/libs/libzt-android-debug.aar create mode 100644 examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/HTTPWorker.java create mode 100644 examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MyZeroTierEventListener.java delete mode 100644 examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.sln delete mode 100644 examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/App.config delete mode 100644 examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.csproj delete mode 100644 examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs delete mode 100644 examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Properties/AssemblyInfo.cs delete mode 100644 examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs delete mode 100644 examples/java/ExampleApp.java delete mode 100644 examples/java/README.md delete mode 100644 examples/java/com/zerotier/libzt/ZTFDSet.java delete mode 100644 examples/java/com/zerotier/libzt/ZTSocketAddress.java delete mode 100644 examples/java/com/zerotier/libzt/ZeroTier.java delete mode 100644 examples/layer2/layer2.cpp delete mode 100644 examples/scala/ExampleApp.scala delete mode 100644 examples/scala/Makefile delete mode 100644 examples/scala/README.md delete mode 100644 examples/scala/libzt.scala delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.pbxproj delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/xcuserdata/joseph.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/AppDelegate.swift delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/Contents.json delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/LaunchScreen.storyboard delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/Main.storyboard delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/Example.swift delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/Info.plist delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/ViewController.swift delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.cpp delete mode 100644 examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.hpp delete mode 100644 examples/ztproxy/ztproxy.cpp delete mode 100644 examples/ztproxy/ztproxy.hpp create mode 100644 ext/concurrentqueue/LICENSE.md create mode 100644 ext/concurrentqueue/concurrentqueue.h delete mode 100644 ext/lwip-contrib.patch delete mode 100644 ext/lwipopts.h delete mode 100644 include/Constants.hpp delete mode 100644 include/Defs.hpp delete mode 100644 include/RingBuffer.h delete mode 100644 include/ServiceControls.hpp delete mode 100644 packages/PyPI/bdist.bat delete mode 100644 packages/README.md delete mode 100644 packages/android/.gitignore create mode 100644 packages/android/.project delete mode 100644 packages/android/app/.gitignore delete mode 100644 packages/android/app/build.gradle delete mode 100644 packages/android/app/proguard-rules.pro delete mode 100644 packages/android/app/src/androidTest/java/com/example/zerotier/ExampleInstrumentedTest.java delete mode 100644 packages/android/app/src/main/AndroidManifest.xml delete mode 100644 packages/android/app/src/main/java/ZTFDSet.java delete mode 100644 packages/android/app/src/main/java/ZTSocketAddress.java delete mode 100644 packages/android/app/src/main/java/ZeroTier.java delete mode 100644 packages/android/app/src/main/java/com/example/zerotier/MainActivity.java delete mode 100644 packages/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml delete mode 100644 packages/android/app/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 packages/android/app/src/main/res/layout/activity_main.xml delete mode 100644 packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 packages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 packages/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png delete mode 100644 packages/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 packages/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png delete mode 100644 packages/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 packages/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png delete mode 100644 packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 packages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 packages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png delete mode 100644 packages/android/app/src/main/res/values/colors.xml delete mode 100644 packages/android/app/src/main/res/values/strings.xml delete mode 100644 packages/android/app/src/main/res/values/styles.xml delete mode 100644 packages/android/app/src/test/java/com/example/zerotier/ExampleUnitTest.java delete mode 100644 packages/android/build.gradle delete mode 100644 packages/android/gradle.properties delete mode 100644 packages/android/gradle/wrapper/gradle-wrapper.jar delete mode 100644 packages/android/gradle/wrapper/gradle-wrapper.properties delete mode 100755 packages/android/gradlew delete mode 100644 packages/android/gradlew.bat delete mode 100644 packages/android/settings.gradle delete mode 100644 packages/clean.bat delete mode 100755 packages/clean.sh delete mode 100644 packages/dist.bat delete mode 100755 packages/dist.sh delete mode 100644 packages/java/com/zerotier/libzt/ZTFDSet.java delete mode 100644 packages/java/com/zerotier/libzt/ZTSocketAddress.java delete mode 100644 packages/java/com/zerotier/libzt/ZeroTier.java delete mode 100644 packages/module.modulemap delete mode 100755 packages/package.sh delete mode 100644 packages/pypi/LICENSE.txt delete mode 100644 packages/pypi/MANIFEST.in delete mode 100644 packages/pypi/Makefile delete mode 100644 packages/pypi/README.md delete mode 100644 packages/pypi/README.rst delete mode 100644 packages/pypi/libzt.i delete mode 100644 packages/pypi/libzt.py delete mode 100644 packages/pypi/libzt/.gitignore delete mode 100644 packages/pypi/libzt_wrap.cxx delete mode 100644 packages/pypi/setup.cfg delete mode 100644 packages/pypi/setup.py delete mode 100644 packages/pypi/test.py create mode 100644 src/Controls.cpp create mode 100644 src/Controls.hpp rename {include => src}/Debug.hpp (100%) create mode 100644 src/Intercept.cpp create mode 100644 src/Intercept.hpp create mode 100644 src/Options.h delete mode 100644 src/RingBuffer.cpp create mode 100644 src/Service.cpp create mode 100644 src/Service.hpp delete mode 100644 src/ServiceControls.cpp rename src/{libzt.cpp => Sockets.cpp} (82%) rename {include => src}/VirtualTap.hpp (99%) rename src/{lwIP.cpp => lwipDriver.cpp} (88%) rename include/lwIP.h => src/lwipDriver.hpp (98%) create mode 100644 src/lwipRawDriver.cpp create mode 100644 src/lwipRawDriver.hpp rename {include => src}/lwipopts.h (99%) delete mode 100755 test/create_test_identities.sh delete mode 100644 test/echotest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ba2824..1e0a733 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,29 +28,63 @@ cmake_minimum_required (VERSION 3.0) project (zt) set (CMAKE_VERBOSE_MAKEFILE ON) -set (CMAKE_SUPPRESS_REGENERATION true) -set (PROJ_DIR ${PROJECT_SOURCE_DIR}) -set (CMAKE_BINARY_DIR ${PROJECT_SOURCE_DIR}/bin) -set (EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) -set (LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) -set (INCLUDE_PATH ${PROJ_DIR}/include) - -# ----------------------------------------------------------------------------- -# | BUILD CONFIG | -# ----------------------------------------------------------------------------- - -# Default build type: Release - -# Release - Optimization and no debug info -# Debug - No optimization, debug info -# RelWithDebInfo - Release optimizations and debug info -# MinSizeRel - Similar to Release but with optimizations to minimize size +# Library and executable output paths if (NOT CMAKE_BUILD_TYPE) - set (CMAKE_BUILD_TYPE Release) + message( FATAL_ERROR "Must specify CMAKE_BUILD_TYPE, CMake will exit." ) endif () -set (SILENCE "-Wno-unused-parameter -Wno-unused-variable -Wno-missing-field-initializers") +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set (CMAKE_BINARY_DIR ${PROJECT_SOURCE_DIR}/bin/debug) +endif() +if (CMAKE_BUILD_TYPE STREQUAL "Release") + set (CMAKE_BINARY_DIR ${PROJECT_SOURCE_DIR}/bin/release) +endif() + +set (EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) +set (LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) +set (INTERMEDIATE_LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib/intermediate) + +# ----------------------------------------------------------------------------- +# | LIBRARY NAMES | +# ----------------------------------------------------------------------------- + +if (IN_XCODE) + set (XCODE_FRAMEWORK_NAME ${PROJECT_NAME}) +endif () + +if (BUILDING_WIN) + # Possibly a CMake limitation? -- Can't share target output names + set (STATIC_LIB_NAME ${PROJECT_NAME}-static) + set (STATIC_LIB_OUTPUT_NAME ${PROJECT_NAME}-static) + set (DYNAMIC_LIB_NAME ${PROJECT_NAME}-shared) + set (DYNAMIC_LIB_OUTPUT_NAME ${PROJECT_NAME}-shared) +else () + set (STATIC_LIB_NAME ${PROJECT_NAME}-static) + set (STATIC_LIB_OUTPUT_NAME ${PROJECT_NAME}) + set (DYNAMIC_LIB_NAME ${PROJECT_NAME}-shared) + 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 | @@ -77,6 +111,9 @@ if (${CMAKE_GENERATOR} STREQUAL "Xcode") #set_target_properties (${STATIC_LIB_NAME} PROPERTIES XCODE_ATTRIBUTE_MY_BUILD_ONLY_ACTIVE_ARCH YES) #set_target_properties (${STATIC_LIB_NAME} PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "${MY_BUILD_ONLY_ACTIVE_ARCH}) endif () +if (BUILDING_WIN32 OR BUILDING_WIN64 OR MSVC) + set (BUILDING_WIN TRUE) +endif () if (NOT BUILDING_ANDROID AND NOT IN_XCODE AND NOT BUILD_TESTS EQUAL 0) set(SHOULD_BUILD_TESTS TRUE) endif () @@ -128,9 +165,41 @@ if ((BUILDING_ANDROID OR JNI) AND JNI_FOUND) endif () # ----------------------------------------------------------------------------- -# | LWIP PORT | +# | SOURCE FILE GLOBS | # ----------------------------------------------------------------------------- +set (PROJ_DIR ${PROJECT_SOURCE_DIR}) +set (LWIP_SRC_DIR "${PROJ_DIR}/ext/lwip/src") +set (ZTO_SRC_DIR "${PROJ_DIR}/ext/ZeroTierOne") +set (LIBZT_SRC_DIR "${PROJ_DIR}/src") + +file (GLOB zerotiercoreSrcGlob + ${ZTO_SRC_DIR}/node/*.cpp + ${ZTO_SRC_DIR}/osdep/OSUtils.cpp + ${ZTO_SRC_DIR}/osdep/PortMapper.cpp + ${ZTO_SRC_DIR}/osdep/ManagedRoute.cpp) + +file (GLOB libnatpmpSrcGlob + ${ZTO_SRC_DIR}/ext/libnatpmp/natpmp.c + ${ZTO_SRC_DIR}/ext/libnatpmp/getgateway.c) + +file (GLOB libminiupnpcSrcGlob + ${ZTO_SRC_DIR}/ext/miniupnpc/connecthostport.c + ${ZTO_SRC_DIR}/ext/miniupnpc/igd_desc_parse.c + ${ZTO_SRC_DIR}/ext/miniupnpc/minisoap.c + ${ZTO_SRC_DIR}/ext/miniupnpc/minissdpc.c + ${ZTO_SRC_DIR}/ext/miniupnpc/miniupnpc.c + ${ZTO_SRC_DIR}/ext/miniupnpc/miniwget.c + ${ZTO_SRC_DIR}/ext/miniupnpc/minixml.c + ${ZTO_SRC_DIR}/ext/miniupnpc/portlistingparse.c + ${ZTO_SRC_DIR}/ext/miniupnpc/receivedata.c + ${ZTO_SRC_DIR}/ext/miniupnpc/upnpcommands.c + ${ZTO_SRC_DIR}/ext/miniupnpc/upnpdev.c + ${ZTO_SRC_DIR}/ext/miniupnpc/upnperrors.c + ${ZTO_SRC_DIR}/ext/miniupnpc/upnpreplyparse.c) + +file (GLOB libztSrcGlob ${LIBZT_SRC_DIR}/*.cpp) + if (UNIX) set (LWIP_PORT_DIR ${PROJ_DIR}/ext/lwip-contrib/ports/unix/port) endif () @@ -139,69 +208,6 @@ if (BUILDING_WIN) set (LWIP_PORT_DIR ${PROJ_DIR}/ext/lwip-contrib/ports/win32) endif () -# ----------------------------------------------------------------------------- -# | LIBRARY NAMES | -# ----------------------------------------------------------------------------- - -if (IN_XCODE) - set (XCODE_FRAMEWORK_NAME ${PROJECT_NAME}) -endif () - -if (BUILDING_WIN) - # Possibly a CMake limitation? -- Can't share target output names - set (STATIC_LIB_NAME ${PROJECT_NAME}-static) - set (STATIC_LIB_OUTPUT_NAME ${PROJECT_NAME}-static) - set (DYNAMIC_LIB_NAME ${PROJECT_NAME}-shared) - set (DYNAMIC_LIB_OUTPUT_NAME ${PROJECT_NAME}-shared) -else () - set (STATIC_LIB_NAME ${PROJECT_NAME}-static) - set (STATIC_LIB_OUTPUT_NAME ${PROJECT_NAME}) - set (DYNAMIC_LIB_NAME ${PROJECT_NAME}-shared) - set (DYNAMIC_LIB_OUTPUT_NAME ${PROJECT_NAME}) -endif () - -# ----------------------------------------------------------------------------- -# | FLAGS | -# ----------------------------------------------------------------------------- - -set (LIBZT_FLAGS "-DZT_SDK=1 -D_USING_LWIP_DEFINITIONS_=1") -set (LIBZT_FLAGS_DEBUG "-DZT_SDK=1 -DLIBZT_TRACE=1 -DLWIP_DEBUG=1 -DLIBZT_DEBUG=1 -DNS_TRACE=1 -DNS_DEBUG=1") - -set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${LIBZT_FLAGS_DEBUG}") -set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${LIBZT_FLAGS_DEBUG}") - -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} -fstack-protector") - set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fstack-protector") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBZT_FLAGS} ${SILENCE} -O3 -Wall -Wextra -std=c++11") - set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${SILENCE} -std=c++11") - set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${LIBZT_FLAGS} ${SILENCE} -O3 -std=c++11") -endif () - -#set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") -#set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address") - -# ----------------------------------------------------------------------------- -# | SOURCE FILE GLOBS | -# ----------------------------------------------------------------------------- - -set (LWIP_SRC_DIR "${PROJ_DIR}/ext/lwip/src") -set (ZTO_SRC_DIR "${PROJ_DIR}/ext/ZeroTierOne") -set (LIBZT_SRC_DIR "${PROJ_DIR}/src") - -include_directories ("${LIBZT_SRC_DIR}") -include_directories ("${ZTO_SRC_DIR}/include") -include_directories ("${PROJ_DIR}") -include_directories ("${ZTO_SRC_DIR}/osdep") -include_directories ("${ZTO_SRC_DIR}/node") -include_directories ("${ZTO_SRC_DIR}/service") -include_directories ("${PROJ_DIR}/include") -include_directories ("${LWIP_SRC_DIR}/include") -include_directories ("${LWIP_PORT_DIR}/include") - file (GLOB lwipSrcGlob ${LWIP_SRC_DIR}/netif/*.c ${LWIP_SRC_DIR}/api/*.c @@ -211,176 +217,117 @@ file (GLOB lwipSrcGlob ${LWIP_SRC_DIR}/core/ipv6/*.c) list(REMOVE_ITEM lwipSrcGlob ${LWIP_SRC_DIR}/netif/slipif.c) -file (GLOB ztoSrcGlob - ${ZTO_SRC_DIR}/node/*.cpp - ${ZTO_SRC_DIR}/service/*.cpp - ${ZTO_SRC_DIR}/osdep/OSUtils.cpp - ${ZTO_SRC_DIR}/controller/*.cpp - ${ZTO_SRC_DIR}/osdep/ManagedRoute.cpp) - -file (GLOB libztSrcGlob ${LIBZT_SRC_DIR}/*.cpp) - -file (GLOB ExampleAppSrcGlob - ${PROJ_DIR}/examples/cpp/*.cpp - ${PROJ_DIR}/examples/cpp/ipv4simple/*.cpp - ${PROJ_DIR}/examples/cpp/ipv6simple/*.cpp - ${PROJ_DIR}/examples/cpp/ipv6adhoc/*.cpp - ${PROJ_DIR}/examples/cpp/sharedlib/*.cpp - ${PROJ_DIR}/examples/ztproxy/*.cpp) - - -# header globs for xcode frameworks -file (GLOB frameworkPrivateHeaderGlob - ${INCLUDE_PATH}/libzt.h - ${INCLUDE_PATH}/libztDebug.h) -file (GLOB frameworkPublicHeaderGlob ${INCLUDE_PATH}/Xcode-Bridging-Header.h) -file (GLOB frameworkHeaderGlob ${frameworkPublicHeaderGlob} ${frameworkPrivateHeaderGlob}) - # ----------------------------------------------------------------------------- -# | PLATFORM-SPECIFIC CONFIG | +# | INCLUDES | # ----------------------------------------------------------------------------- -# ANDROID-specific -if (BUILDING_ANDROID) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DSOCKLEN_T_DEFINED=1") - set (ANDROID_NDK /Users/$ENV{USER}/Library/Android/sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi) - include_directories (${ANDROID_NDK}) -endif () - -# WINDOWS-specific MSVC flags and libraries -if (BUILDING_WIN) - # 32-bit - if(NOT BUILDING_WIN64) - set (WINLIBDIR, "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.16299.0/um/x86") - endif () - # 64-bit - if(BUILDING_WIN64) - set (WINLIBDIR, "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.16299.0/um/x64") - endif () - #find_library (ws2_32_LIBRARY_PATH NAMES WS2_32 HINTS ${WINLIBDIR}) - #find_library (shlwapi_LIBRARY_PATH NAMES ShLwApi HINTS ${WINLIBDIR}) - set (ws2_32_LIBRARY_PATH "${WINLIBDIR}/WS2_32.Lib") - set (shlwapi_LIBRARY_PATH "${WINLIBDIR}/ShLwApi.Lib") - set (iphlpapi_LIBRARY_PATH "${WINLIBDIR}/iphlpapi.Lib") - message (STATUS ${WINLIBDIR}) - message (STATUS "WS2_32=${ws2_32_LIBRARY_PATH}") - message (STATUS "ShLwApi=${shlwapi_LIBRARY_PATH}") - message (STATUS "liphlpapi=${iphlpapi_LIBRARY_PATH}") - add_definitions (-DZT_SDK=1) - add_definitions (-DADD_EXPORTS=1) -endif () - -# ----------------------------------------------------------------------------- -# | OBJECTS-PIC (INTERMEDIATE) | -# ----------------------------------------------------------------------------- - -add_library (lwip_pic ${lwipSrcGlob}) -set_target_properties (lwip_pic PROPERTIES POSITION_INDEPENDENT_CODE ON) -add_library (zto_pic ${ztoSrcGlob}) -set_target_properties (zto_pic PROPERTIES POSITION_INDEPENDENT_CODE ON) -add_library (http_pic "${ZTO_SRC_DIR}/ext/http-parser/http_parser.c") -set_target_properties (http_pic PROPERTIES POSITION_INDEPENDENT_CODE ON) +include_directories (${ZTO_SRC_DIR}) +include_directories (${ZTO_SRC_DIR}/node) +include_directories (${ZTO_SRC_DIR}/osdep) +include_directories (${ZTO_SRC_DIR}/include) +include_directories (${ZTO_SRC_DIR}/ext/miniupnpc) +include_directories (${ZTO_SRC_DIR}/ext/libnatpmp) +include_directories (${PROJ_DIR}/src) +include_directories (${PROJ_DIR}/include) +include_directories (${LWIP_SRC_DIR}/include) +include_directories (${LWIP_PORT_DIR}/include) +include_directories (${PROJ_DIR}/ext/concurrentqueue) # ----------------------------------------------------------------------------- # | OBJECT LIBRARIES (INTERMEDIATE) | # ----------------------------------------------------------------------------- -# lwip_obj -add_library (lwip_obj OBJECT ${lwipSrcGlob}) # zto_obj -add_library (zto_obj OBJECT ${ztoSrcGlob}) +add_library (zto_obj OBJECT ${zerotiercoreSrcGlob}) +set_target_properties (zto_obj PROPERTIES COMPILE_FLAGS "${SILENCE} -std=c++11 -DZT_USE_MINIUPNPC=1 -DZT_SOFTWARE_UPDATE_DEFAULT=0") if (BUILDING_WIN) target_link_libraries (zto_obj ws2_32) target_link_libraries (zto_obj ${shlwapi_LIBRARY_PATH}) target_link_libraries (zto_obj ${iphlpapi_LIBRARY_PATH}) endif () -# http_obj -add_library (http_obj OBJECT "${ZTO_SRC_DIR}/ext/http-parser/http_parser.c") + +# libnatpmp_obj +add_library (libnatpmp_obj OBJECT ${libnatpmpSrcGlob}) +set_target_properties (libnatpmp_obj PROPERTIES COMPILE_FLAGS "") + +# miniupnpc_obj +add_library (miniupnpc_obj OBJECT ${libminiupnpcSrcGlob}) +target_compile_definitions(miniupnpc_obj PRIVATE MACOSX ZT_USE_MINIUPNPC MINIUPNP_STATICLIB _DARWIN_C_SOURCE MINIUPNPC_SET_SOCKET_TIMEOUT MINIUPNPC_GET_SRC_ADDR _BSD_SOURCE _DEFAULT_SOURCE MINIUPNPC_VERSION_STRING=\"2.0\" UPNP_VERSION_STRING=\"UPnP/1.1\" ENABLE_STRNATPMPERR OS_STRING=\"Darwin/15.0.0\") + +# lwip_obj +add_library (lwip_obj OBJECT ${lwipSrcGlob}) +set_target_properties (lwip_obj PROPERTIES COMPILE_FLAGS "") + +# libzt_obj +add_library (libzt_obj OBJECT ${libztSrcGlob}) +set_target_properties (libzt_obj PROPERTIES COMPILE_FLAGS "-std=c++11") + +add_library (lwip_pic ${lwipSrcGlob}) +set_target_properties (lwip_pic PROPERTIES POSITION_INDEPENDENT_CODE ON) +add_library (zto_pic ${zerotiercoreSrcGlob}) +set_target_properties (zto_pic PROPERTIES COMPILE_FLAGS "${SILENCE} -std=c++11") +set_target_properties (zto_pic PROPERTIES POSITION_INDEPENDENT_CODE ON) # ----------------------------------------------------------------------------- -# | LIBZT BUILD TARGETS (FINAL PRODUCT) | +# | BUILD TARGETS (FINAL PRODUCT) | # ----------------------------------------------------------------------------- -# static -add_library (${STATIC_LIB_NAME} STATIC - $ - $ - $ ${libztSrcGlob}) -set_target_properties (${STATIC_LIB_NAME} PROPERTIES OUTPUT_NAME ${STATIC_LIB_OUTPUT_NAME}) +# libzerotiercore.a +add_library (zerotiercore STATIC $) +set_target_properties (zerotiercore PROPERTIES + OUTPUT_NAME zerotiercore + LIBRARY_OUTPUT_DIRECTORY ${INTERMEDIATE_LIBRARY_OUTPUT_PATH}) -# dynamic -add_library (${DYNAMIC_LIB_NAME} SHARED ${libztSrcGlob}) +# libnatpmp.a +add_library (natpmp STATIC $) +set_target_properties (natpmp PROPERTIES + OUTPUT_NAME natpmp + LIBRARY_OUTPUT_DIRECTORY ${INTERMEDIATE_LIBRARY_OUTPUT_PATH}) + +# libminiupnpc.a +add_library (miniupnpc STATIC $) +set_target_properties (miniupnpc PROPERTIES + OUTPUT_NAME miniupnpc + LIBRARY_OUTPUT_DIRECTORY ${INTERMEDIATE_LIBRARY_OUTPUT_PATH}) + +# liblwip.a +add_library (lwip STATIC $) +set_target_properties (lwip PROPERTIES + OUTPUT_NAME lwip + LIBRARY_OUTPUT_DIRECTORY ${INTERMEDIATE_LIBRARY_OUTPUT_PATH}) + +# libzt.a +add_library (zt STATIC $ +$ +$ +$ +$) +set_target_properties (zt PROPERTIES + OUTPUT_NAME zt + LIBRARY_OUTPUT_DIRECTORY ${INTERMEDIATE_LIBRARY_OUTPUT_PATH}) + +# libzt.so/dylib/dll +add_library (zt-shared SHARED ${libztSrcGlob}) message (STATUS ${libztSrcGlob}) -target_link_libraries (${DYNAMIC_LIB_NAME} lwip_pic zto_pic http_pic) -set_target_properties (${DYNAMIC_LIB_NAME} PROPERTIES OUTPUT_NAME ${DYNAMIC_LIB_OUTPUT_NAME}) -set_target_properties (${DYNAMIC_LIB_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS true) +target_link_libraries (zt-shared lwip_pic zto_pic) +set_target_properties (zt-shared PROPERTIES COMPILE_FLAGS "${SILENCE} -std=c++11 -DZT_SDK") +set_target_properties (zt-shared PROPERTIES OUTPUT_NAME ${DYNAMIC_LIB_OUTPUT_NAME} + WINDOWS_EXPORT_ALL_SYMBOLS true) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) if (BUILDING_ANDROID) - target_link_libraries (${DYNAMIC_LIB_NAME} android log) -endif () - -if (BUILDING_WIN) - target_link_libraries (${STATIC_LIB_NAME} ws2_32) - target_link_libraries (${STATIC_LIB_NAME} ${shlwapi_LIBRARY_PATH}) - target_link_libraries (${STATIC_LIB_NAME} ${iphlpapi_LIBRARY_PATH}) - target_link_libraries (${DYNAMIC_LIB_NAME} ws2_32) - target_link_libraries (${DYNAMIC_LIB_NAME} ${shlwapi_LIBRARY_PATH}) - target_link_libraries (${DYNAMIC_LIB_NAME} ${iphlpapi_LIBRARY_PATH}) -endif () - -if (BUILDING_LINUX OR BUILDING_DARWIN) - target_link_libraries (${STATIC_LIB_NAME} pthread) - target_link_libraries (${DYNAMIC_LIB_NAME} pthread) -endif () - -# xcode framework -if (IN_XCODE) - add_library(${XCODE_FRAMEWORK_NAME} STATIC - $ - $ - $ - ${libztSrcGlob} - ${frameworkHeaderGlob}) - - set_target_properties(${XCODE_FRAMEWORK_NAME} PROPERTIES - FRAMEWORK TRUE - FRAMEWORK_VERSION A - DEFINES_MODULE TRUE - MACOSX_FRAMEWORK_IDENTIFIER com.cmake.${XCODE_FRAMEWORK_NAME} - MODULE_MAP "~/op/zt/libzt/packages/module.modulemap" - PUBLIC_HEADER "${frameworkHeaderGlob}" - XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer" - ) + target_link_libraries (zt-shared android log) endif () # ----------------------------------------------------------------------------- -# | TEST APPLICATIONS AND EXAMPLES | +# | EXECUTABLES | # ----------------------------------------------------------------------------- if (SHOULD_BUILD_TESTS) -# foreach (testsourcefile ${ExampleAppSrcGlob}) -# string (REPLACE ".cpp" "" testname ${testsourcefile}) -# get_filename_component (testname ${testname} NAME) -# add_executable (${testname} ${testsourcefile}) -# if (BUILDING_WIN) -# target_link_libraries (${testname} ${STATIC_LIB_NAME}) -# else () -# target_link_libraries (${testname} ${STATIC_LIB_NAME} pthread dl) -# endif () -# endforeach (testsourcefile ${ExampleAppSrcGlob}) + add_executable (example ${PROJ_DIR}/test/example.cpp) + target_link_libraries(example zt) -if (NOT BUILDING_WIN) # only necessary for raw driver development - # selftest - #add_executable (selftest ${PROJ_DIR}/test/selftest.cpp) - #target_compile_options (selftest PRIVATE -D__SELFTEST__) - #if (BUILDING_WIN) - # target_link_libraries (selftest ${STATIC_LIB_NAME} ${ws2_32_LIBRARY_PATH} ${shlwapi_LIBRARY_PATH} ${iphlpapi_LIBRARY_PATH}) - #else () - # target_link_libraries (selftest ${STATIC_LIB_NAME} pthread) - #endif () - # nativetest - #add_executable (nativetest ${PROJ_DIR}/test/selftest.cpp) - #target_compile_options (nativetest PRIVATE -D__NATIVETEST__) -endif () -endif () + add_executable (selftest ${PROJ_DIR}/test/selftest.cpp) + target_link_libraries(selftest zt) + set_target_properties (selftest PROPERTIES COMPILE_FLAGS "${SILENCE} -D__SELFTEST__") +endif () \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index aa9609f..0000000 --- a/Jenkinsfile +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env groovy - -node('master') { - checkout scm - def changelog = getChangeLog currentBuild - mattermostSend "Building ${env.JOB_NAME} #${env.BUILD_NUMBER} \n Change Log: \n ${changelog}" -} - -parallel 'centos7': { - node('centos7') { - try { - checkout scm - sh 'git submodule update --init' - stage('linux') { - sh 'cmake -H. -Bbuild; cmake --build build' - } - } - catch (err) { - currentBuild.result = "FAILURE" - slackSend color: '#ff0000', message: "${env.JOB_NAME} broken on linux (<${env.BUILD_URL}|Open>)" - throw err - } - } -}, - -'macOS': { - node('macOS') { - unlockKeychainMac "~/Library/Keychains/login.keychain-db" - try { - checkout scm - sh 'git submodule update --init' - stage('macOS') { - sh 'cmake -H. -Bbuild; cmake --build build' - } - } - catch (err) { - currentBuild.result = "FAILURE" - slackSend color: '#ff0000', message: "${env.JOB_NAME} broken on macOS (<${env.BUILD_URL}|Open>)" - throw err - } - } -} - -mattermostSend color: "#00ff00", message: "${env.JOB_NAME} #${env.BUILD_NUMBER} Complete (<${env.BUILD_URL}|Show More...>)" \ No newline at end of file diff --git a/Makefile b/Makefile index 914e439..bc0ca4e 100644 --- a/Makefile +++ b/Makefile @@ -1,50 +1,68 @@ -# NOTE: This file only exists as a convenience for cleaning and building -# products for release. To build, use CMake. Instructions in README.md +# +# ZeroTier SDK - Network Virtualization Everywhere +# Copyright (C) 2011-2019 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. +# ifeq ($(OS),Windows_NT) -DIST_BUILD_SCRIPT := packages\dist.bat -CLEAN_SCRIPT := packages\clean.bat +DIST_BUILD_SCRIPT := ports\dist.bat +CLEAN_SCRIPT := ports\clean.bat else -DIST_BUILD_SCRIPT := ./packages/dist.sh -CLEAN_SCRIPT := ./packages/clean.sh -PACKAGE_SCRIPT := ./packages/package.sh +DIST_BUILD_SCRIPT := ./ports/dist.sh +CLEAN_SCRIPT := ./ports/clean.sh +PACKAGE_SCRIPT := ./ports/package.sh endif -.PHONY: clean -clean: - $(CLEAN_SCRIPT) - -# Build and package everything -# This command shall be run twice: -# (1) Generates projects -# -# (2) Build products and package everything - -.PHONY: dist -dist: patch - $(DIST_BUILD_SCRIPT) - -.PHONY: package -package: - $(PACKAGE_SCRIPT) - -# Initialize submodules and apply patches -.PHONY: all -all: update patch - cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release - cmake --build build - -# Remove any CMake-generated library-building projects -clean_packages: - rm -rf packages/xcode_ios - rm -rf packages/xcode_macos - -.PHONY: update -update: - git submodule update --init --recursive +CONCURRENT_BUILD_JOBS=2 # Patch submodules patch: -git -C ext/lwip apply ../lwip.patch -git -C ext/lwip-contrib apply ../lwip-contrib.patch - -git -C ext/ZeroTierOne apply ../ZeroTierOne.patch + #-git -C ext/ZeroTierOne apply ../ZeroTierOne.patch + +.PHONY: clean +clean: + rm -rf bin staging generated + +all: debug release + +release: + -mkdir generated + cmake -H. -Bgenerated/release -DCMAKE_BUILD_TYPE=Release + cmake --build generated/release -j $(CONCURRENT_BUILD_JOBS) + +debug: + -mkdir generated + cmake -H. -Bgenerated/debug -DCMAKE_BUILD_TYPE=Debug + cmake --build generated/debug -j $(CONCURRENT_BUILD_JOBS) + +# dist: +# Build and package everything +# This command shall be run twice: +# (1) Generates projects +# +# (2) Build products and package everything +.PHONY: dist +dist: patch + $(DIST_BUILD_SCRIPT) diff --git a/README.md b/README.md index 4e37aba..385488a 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,9 @@ Java JNI API: [ZeroTier.java](packages/android/app/src/main/java/ZeroTier.java) ### C++ Example ``` +#include #include +#include #include "libzt.h" @@ -36,15 +38,14 @@ int main() char *remoteIp = "10.8.8.42"; int remotePort = 8080; int fd, err = 0; - struct zts_sockaddr_in addr; - addr.sin_family = ZTS_AF_INET; + struct sockaddr_in addr; + addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(remoteIp); addr.sin_port = htons(remotePort); zts_startjoin("path", 0xc7cd7c981b0f52a2); // config path, network ID - printf("nodeId=%llx\n", zts_get_node_id()); - if ((fd = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0)) < 0) { + 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) { diff --git a/examples/android/ExampleAndroidApp/.project b/examples/android/ExampleAndroidApp/.project new file mode 100644 index 0000000..552deba --- /dev/null +++ b/examples/android/ExampleAndroidApp/.project @@ -0,0 +1,17 @@ + + + ExampleAndroidApp + Project ExampleAndroidApp created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/examples/android/ExampleAndroidApp/.settings/org.eclipse.buildship.core.prefs b/examples/android/ExampleAndroidApp/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..e889521 --- /dev/null +++ b/examples/android/ExampleAndroidApp/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/examples/android/ExampleAndroidApp/app/.classpath b/examples/android/ExampleAndroidApp/app/.classpath new file mode 100644 index 0000000..7c0adb0 --- /dev/null +++ b/examples/android/ExampleAndroidApp/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/examples/android/ExampleAndroidApp/app/.project b/examples/android/ExampleAndroidApp/app/.project new file mode 100644 index 0000000..ac485d7 --- /dev/null +++ b/examples/android/ExampleAndroidApp/app/.project @@ -0,0 +1,23 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/examples/android/ExampleAndroidApp/app/.settings/org.eclipse.buildship.core.prefs b/examples/android/ExampleAndroidApp/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..b1886ad --- /dev/null +++ b/examples/android/ExampleAndroidApp/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/examples/android/ExampleAndroidApp/app/build.gradle b/examples/android/ExampleAndroidApp/app/build.gradle index 7fedf3e..09578e2 100644 --- a/examples/android/ExampleAndroidApp/app/build.gradle +++ b/examples/android/ExampleAndroidApp/app/build.gradle @@ -20,15 +20,25 @@ android { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } + release { + debuggable true + jniDebuggable true + minifyEnabled false + } } } dependencies { + implementation 'com.squareup.picasso:picasso:2.71828' implementation files('libs/libzt-android-debug.aar') implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' + implementation("com.squareup.okhttp3:okhttp:3.12.0") implementation 'com.android.support.constraint:constraint-layout:1.1.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + + implementation 'com.github.bumptech.glide:glide:4.6.1' + annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1' } diff --git a/examples/android/ExampleAndroidApp/app/libs/libzt-android-debug.aar b/examples/android/ExampleAndroidApp/app/libs/libzt-android-debug.aar new file mode 100644 index 0000000000000000000000000000000000000000..b0f4345f1add352710c26476772c757937b93c7a GIT binary patch literal 861495 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

aiL2DzPm<~DJvG1(Qv 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

Z4)7pzqSIa!xv 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

^v}3MGQU>f*0Iloh{*Qj(qNSXB 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Ν!cc6X5Jzc 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

J&n?a%n@g)b-?i%?d=~p!f0g6H2yU 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¬w$ctX0mgrHljKBCY6cm9678;a1R` zZ^N8n9q1VkQfJ3134Jme=x3d3z6#Z6dV6>1s|NaYr~h3Omv_R%wGN8q9*1KEJ`#NT z{&CAU}j_=+g>KX2&E@HZ=zwG-#u5PQ0q1>Dk7#B%(#Fd24t;vUqqn&_rrvaIS= z&GZ$os<*eeQ&@(TVa^5`^rlGZg)f1GSKg)a>A?hKQf2TZ$ap0^|46wh193Kg;?wIf z+h5GzkejBG1a}%4Bw$(Zdw=RqmxjoLwdhpNf~y){Iqpq`K8#^r{4tU)e^LAG&<2#) zhPIh2j3RJRk5Ou(le+paE-_YVsI!Sq=u*9No9PD(#WF?nTW+GULDX`FI}IZuWrNa8 z-(iv5!&{r_^Ir8nBm9bB>*SqXdI2MkBP5-ocQmuCA(`^o+;$Eh~IHtllW^~Sf+r*uEOXc~5=^uy@h*-SQP&?+R+DermW=x6( zKL2p{*stO+4wR2$krc6_fyIt<`Iu=dR>HCRyi>K0#7f4(L~=do;oO>7;y;TST^sow zW$`S7&sMrIXp%5z-Nzw=`Qh%1|B3@`|Kizn;Izj)+bVPw@rs^VGz{*obafCBAY)0t znjIM{W0g3JF>uWY64X7yMX@ zfc`+!1#f9VuAVK9V6=5pTRL#e!S)lOWiIqRZJ;lArb~zcmo23VO|&AY$}~;X--QU( zsZugXNf|+uW^MwCc^2+gy|y{78MyvXAq(cLinx7!{)!Lr8*u|?&q&u$1JT<&j2+yN zz6{E+b!POUcV63$xZGj<-;x#PZe3y#J7+FThZQ$R*-AI~RCH>jzNGgM_hP7=0eV?A zuj<~VJr7T?vCJB{k|zBPpH{Jx<5Y9}|nk7jpbdv%4GML_AVjO8R{1@tM(N zw1l~S3P=G)y-Mh_i55Z3cz1K#1d(M#SM=7Kr7>iTw1g~mP9jU3SCdH+tXX8TI0a<4 z$sl`hBS=~LVcm#$J4$V;w7DN7%B42nfTHU>YF6DaUV4ta)QRgI$M^U5#8u8%7+&Y11$FMDFZa?m%-xyH z&lBe<^Tqkf0&#&-B~}5gE)*9k)nc`RQP|KkJ!FGHHm*RsX1av=;I`6Oe*~NRSoc-! z1AA|2+YFJ*DHCVFNUyM$i{iN4&$<>$1kIm9B_S#C|VY+M=b#v}FFvd{=leNM+XwobCq<{-+!4IqOy zSP@-Lmt}Ng4k2z$6ge>fhasGk*ctY<9$<&r>xQ+1#Io#rMwT5kl35+ht_Zsx)`8g` z%rlL7l1lk#0p=M=fVqHK%Vt|KUuXinD`qJgLeOfGA!Go5;{2*?Y-Cw9`(^S187T(6 z>p?aiDUMWfNVbSMP;VltU@gv0QFCDIedG4hwRJmEW7VK3mJJwSAVBjd!V*meYIC|MXh>H6RCGD_^5T ztf^RY5;#hfZmKXvoGMRI7I;N{nYZEoljmym>KZHPPK1s@f4N*&wT$0AjuePvnT>CX z`#pTb;}$0-X}npd85_IXvKu{*f%oDpod^2nd@^4` z|J5o|B`qWirD{?w{iSWO2y;hT1W*5k$*k{^cIQ&^F34a@r6tNTa-+Bm#`MO1yl1pM zob!U~Uf*!>>~(Ux6L%6gJ{%9Yf~;VB1jfQ}G-1A=+8K~bw6|e~%48mMRIUyq0l^cjOV!-!FJE-$k}`H8FIc*Zl4?`2UU$ z9KZIqbt1-W-Xq?ltQXfS_lox_8^jIJ+WW-&l>5c|733?!M8s#ptmqcUO&OS*ZXL*A zuo_K&&X=G=v|?Bt#nFGdw8a~t#Xk`@LQDT@|Ec&>t;K&;GD(JrYu6vi+pRwn{@D6} z@H6=V*5bG2Ola{6&5}_}+T7!qly;rczJHT_lOvOV(EgxfvwgE;i+ziu#$MwvPOP=p zI_m6oj&xzLmKrh$ybcj2!lTIt2S7K5ZCGv0FI+P@g2L9}lD1p2t$iThj} zZzDFTfiy^sq)|dFMq^yBoAelYOgc{9bUsCnJD&te=s(F*a8-i#JqGQ24EGk9gn)h3 zN?L(?A`;eq=~U~p!ZYMq=^5Z+r!ZPv`U8}5fc(MvU*v%FU-CinoN!S34fzd>!E-Y1 z-l7dBqa9}+?z_L~{4Mz{Tw^Hp+&Ea%Pq8BoN16;34gv)^U@7I!#r zBXZ!^;aq{gFUKREI}B}m+JhR@YvfgE$6@Ddt*^F$-s$N>naXQd-~H8o?_PPqmh9?@ z(5vr{@_X{1`j>1he+{JU9Uj!O)Yf9{A>SPLiL-e0g>M{_-d};^Gd}Dal-OT_);z#k zbBMeMPrl?l)cPW{=6;VBHwmq=Xsvm%Uu#NwI<=8N?3#qXVR`9=hoA*{o`~KSU|olN zvF<;e#iN711z+I$cGB5Q#bAURzjp-_-PcR8+D_GJMJUq~+^y8ZT)9=t8a!EgsC)i@ z+km$`cFe?8zpBbi{iD+2uNalqOkWH1MWr=UV*sPl`r}{WimI1O;e)j|SXI2Mfmt+g z2hJcyN&OL^P%>=bxzUO3>QSVUWNqNhMF#f$@S3n3HOS2Y1(q?}iVpftD8n6ARicX4 zt|jx;p=@)5_0PRXSKllVHq)oOP$EPd!*@%B&2;Z&5}^$w!tG2Vw0(<2SkrlBiO_aM ziSWnkQKQzQF+V_$URifT6R1H!J4qO|-~_BB&GfOL z%I^$PBV8Ui9WtSP(EJXp1Cem1T03JhqrXYA8_&%ia2Gx|eZXB8wOpXMPrI{sPcocy zAWlMRE$uO8moAGEF3)-#C2ubqf09wE&&BE3nu3v(4K(QC^0OFSB9eNvqW8V7*ZK6x zCquTvlc8qI>5#?scF16XHLS4rYSMe5?dBMu9n3fw4IDa}ynWVm3FcOGC^9Qj8Vvt2 z7rKgHhxx;kvvt7r-}dM>m3EitbQ_Fr^~~!Y%yMxU&cJ->&0`SG=o4u-h|!Wh2j>AB zS=Q4{^nf3;{G?=zfi>#__D@x&y=iLv&03C6f3dUwsdG+XJ z-3EiyACauAr{;ccL{ruG&s)??gWkR@C70eEDVO!s-Vgl19`;Spk;Fe?mRlQL-npQA zwU*_!pf}4cp2s?HE=}vi=WFgi4fV_q>CLceKs}W&nz(OjSyDOP-?;3O8vm-+Xz5pD zdcPViol%kw)@m%BJN)4bCNA9DhyQW&FH}3GPO9>7!(%H-JX{JlmJ=_)dWcssYBQWA z=E@k3dk11TW-}bbY-2?j$MN#HX%u5%ZW>u05abd4(E*$39xtcovZI7((CQm$g%1$~ z%`=9~K-&#QX}kUrofGX?UJ|XL;&C}q@GD9~#WP!?l&TWAQ*S${9v%5dv?WTOU4s51 zXuUyOa(GtueoDPrZV?KZ^BZ zl*YNSt_GU#S2=eS=pQj8irGY>fOB&eH9uMGCE0IqCvS>h-#^0^uhOczuXaeYfovLp z#d6BUd{O$@K;Zo=B1Hqd&EsCES4toW8a|IMNAK&Zb3N;Z7odhJDG9P9OJkO zWVY9QF;bB{To^9LDi+bAj3l|j2oYn_M<{t>o-&$%)-Ga9`Y2_LI7S&q3WTw^Bgb~% z8kz1`B;j7$Rjp|I-wV-0Uo$X5iN~>%~Ybfrfn%HitacDCw^Cd7;fy?($pF79h zhFX20wtHGnja~hBPZ>_9yPoQyuky9s(@5E9&11W#BiZh$L8_;rAX*Xd=*yr*+SdK@ z#Z1Y?p?$0#R-Oo!3re+*#=+A@K3?Hqh1_ASv?kyYmn-BdrU__4Lk`|dD?4$o&fM!e zHVPzi9rGPSyO=7E*Hhx>4toxoIM;I~?(R?ww;GODz-ReE)laKOn;Yo^cASqLLAxB= z-Imh?(7?6xD_p1HlPw^okBYvu-Hj23`9l8Q(JiC*j%gXQ&v^CN-DCG9ll+P#(QHp_ zNf6NY9e0?U=>~7u|J|gR%M*|W9hv+n`zXgq@pP!A7v1)0UxMlO@)089m#8%psF}Ei zimKn&Ca852eAl>#?===%S}c3xn167-I|ews#nnuwK~1r&CL^mUON@79+T$D<_87+y zdpb!*JH5j=ahx4Jf7(3BaPJ(T=D9A@IfJQ)Ad2RR&>;YM8YcgWgOhc~ay%g*$=P?-K4}(sVN|@I=dN1VlzyOVCQT zLF5(H2Bx=eaNbSshH`i)Cq*iQGs%dMpqzxUspcQ|CFoC@=aYHN_J2AwtwW`Ql8)2x zSs|`~@w~-;i^B@nY)4LnnvVdj!1wket6-#VZ@FEYn0w_{V9iXbgUeXm9tb_3gz5r zztMp^=@GuSBbK12w@clBM=53Qk!rHgo-EBJ(Q~$xXY!da`p1skJ`+6}?}wGHp7waT z!<%8=)IF=p7Eb`jLWCS6i6Jq{A|B;Gl<|-^#Va6h5Zw7NNd|cbPs(zc%#Le_iFp+x zmr3X}FwDDW;Vq89H}snu(L_=RA_%2Oh#@qHpugiF3H==h6GS=vGs}O+jh@`jFkwhK zl*s%Qp~TNUkx(M%&JZ$`Ofl18nwVwJazv2y3caXGVlR05Rv(V>m*GSw4-+_Ls5l&Y zXOj!(lp2S8B4l%CJ4VB$W(uCXiHTJV8wkGaUjCm($u(L>23WCmQnn&VyijEOt*^tZ1oTL;K01_8BRlvpCKaLpk1UAt70z&>~! z&M|q2=y`4oXl>*cHpWI`M14?*731VeK1PfXQ0t7*;w2*bBn*(R9|*?C#;Gv^Vj?9G zvw%Arh*p&%CCljLa|WJ_kY`&BxIV#bA1n@rrL5+Dt*cK5`62qNIS?Zo{_Xza1K-_Wn*-tgvVD*KI_?Sg*SAsIr8v>5#Bc6h z*Ix7KbTvMfDb+OP@PclgDFS3;#JlE%DCP%t1)bb(6fyswu_&y?oM8BzW|yjyt9nd5 zeZ||S$MC&+44#i=dQ4v?PGf%dhd8$pyXp0FM*W|lJr>i`zSm8hb1eC zAiFU1JJ6R4Y#4cgs7ywokuL5u$_-`Vw^`cnZCw4{W~tZA?8b?p0=(?2pbZ!u`UHxOx*^vVrIW=9?WxKcBs~x4A8D`^_i6j zSCh%j-+ZDK6kjR)x=$C=KQ;QNfTY_|8~8kiM|{dsF&2!TLV|tOJJ@B{&)0} zCVGG1|4uK->g=zVG|{R6>LpFII`D0JNfRv#Al+~4{_3A~Ag_P@l!-g|OVGfU1}Bu-Oy+uT1G22vqcH@bh{tzPK5!MmG_(xbd+Ql29E_OLr=o(IL6S%kFb)DOM}1xjbK%V*SpMHsc(*$G zXplR+3f|+x|GfNNF6HiF&K{n#?n~zEC!uwXeco*#VK-z5L&S7@hCD>Mc|Y@Q6NXeI zwU~FaxYj)=+c!~{e=r#g+%63*-Jy|L7%NrM{kiSp*>v;VqjhxfpQ=7bNqDl zP9UYwgNh&5tmzCN4r({WpiieVQ!E!|$`wL|6b(;o_oIJjxfCtW5@s=MwI*8UN6fz& zpb<`HmiO6YHpo;>bd!IETuE*aDka^6Xm5-piS23*;u{q61eCYY2WEjVUtA#1R~8CY zBKjVyR$BG0#lj*{mt8F^X1UDJzkZ2*sk}^BCe<-7+lyy!bmQu^!a0JBkn#v;8AnMI^y7 z(B1-3#gi)(t`ZADZ*Y7e;n)zc@u$%LT= z0;h>3=(qT|FNWYA0N34Y!!{eyLmPM~a6Pyx`Qqf$pdlulGbdm^aFnc(r-63s&LkNE z$_W|TioF`OTMI^sKAf?^m%yU;QctoS240Onh?OkFBF6|=ca%F;0$y!3p=S)a(LKX$ zl=4YF)I3@k4K=Uu#meR)M9joo9H=wrN+V>{n@5p60r7D2w0c`EsTZw`gIK*KP_L2I zs~egvWJAp*{c1)VM*_)kM{2)gV2wy|Up!k2eUL@6pa+KvLxHnw?nHaTa5B7Kdoj9g z%zzxw&zw)F#n{0|D^e@sD_+#>Fpum>6+mvctC*aIqBJ3m`LwE$g1C~$>~5fzU=m@G zD_oMCF6gouR;Q9FWQapZrj#LPp*`hZw5R+U_?d+mEp^ly+*VS}QYqip1fJfEA;nLRbZs9=T=VCxBLzer z#$1q(gnr@1{>^0=jr&5supou*3K=Z%$|&(67>7|(9?Z6Um`M*gF?-lpX$)d9!s^>Z zZQdxBO<=2eON?8)*(VWRvp zk7$jNj%)3z4(f4DB{<9aJk(Ez+#u5}1HE=x$K<_BT9)iBB_+c3q8bHODwW9BD`jFC z+!uoTs^Gq=j_dX=YFV^*Hkl<cUk z`+6g}QC<$*{w86$e6w(~gtEs6po1?XH-S990=U)&rk^*_x0s!3nZ~su&})d5d#rPr ztj4UUTuaBemJVjZt-!U=e+a#YRtvX_tL593JB2%dYu&1GE%mN70uNm4E@6$#D|b28 z33rQY?RO(u9#BBHSM~4+ubPi&sL%00+p2A>4s#73w*Jb*J^rYP%RC#yrNXfZKC!=2 zZDV4u9FFn>?m-$c>rYOsHBzp$qE%dgqbMcG3c4@bMde2Kx5{&DkBVa}Jzj-19`406 zD8U)fDgZ4#(1j~~5=oNK5)#AL(^Maanl$i_IFJMD>0-_2KUuTCZ`X1Sq1I(6L|q&u zkSvcD<03H|#buhx<=QUdgMPCv{2oX=H}L3LQF^&ndVLJn?i$y2RF=E24c}t+~a8w)kOU*v78nliS>uy~g6~mh8PIW@|5S$J%lH z8|eprM0LTMVpvT>#RNx|-Q>u$$2v0XLqI|sN5(mf6UW=fqbBW7(QNHi%+@}UOc0Cg z=wn+XO;B*IGOu}2p;!j119q9HZ;U*@1HquFcBdm7IRsUCbdX=~wE!M1@RZjGW<@n`LPAapTr=VYK zKfAeTzLs1gUJL8}=}@;ere8qse&N1ByaC3h(q8G9CtixDya0N=s-;RoB!wtZ#XtcK z82UWAH`_}T?gBswbM12-GckV)Jedw9q{DaC5zI%W+RZH>H&_^wGQ%B*azed(lR8$; z3~>gOQ*JMJoCYZcaa78%JlxfXa&YgQJ90glZcmY>_OqMs)a>S~VTG!tOS`zk2|)7| zzx-kB=8e=F2;0pKKZxDDk-i@IcDs2aUF+*xJ-)x)yp|peet)}pBic9n+09FSbh~*i z-4-0S$HcYmzI0vqcdX(6vwihOy7vnE>iyUEM*5-u()Io8Z`fA{PU8LFS>Hjj@c)qO zdn4ujxV{6;`M+&_Z=}op>iWJnR7)QZOouV-v48hC{+M#!4{1jN`tbcv>`0CDbKm85 zq(<843)_+K_;Nc^BdziE*^wIQ1HSLFBQ?_1zDw;$Fe<()*^wIQV&9KvN2;ZD{_nCQ zHByuBaywEZ=sj1mBQ?^myg!~Dsg~yXe+)ZPb9dUsT38M9VIG_!rXRqDVWY1F{#_eJ zE&V!hxecS1h63Ma!>FaffNI02rQLzy@Gb|w4%;wl>65-6(uUDUhxM~z;IB(<7_iEA z{{Pd4!EhVCmkpzlZoGmG1Nie5Z5WMo)sJYysHMBU(}qz?AM9~SnUeuyfF~m!Dys&I|qYof_98pAr@u^S{`cYD&}z=PvWKY zR?H2WC?!BYqyvW>>`WqQPBXJwnAH^&WekgvnB9XJGDZr>Fw8;=PrzIQ{%Yxr1kS3) zpGNmXyb4G2Wia_waX{?ax6S$Iq4DB)! zYelpeWsek~C%eMA*7Up)cUDxJvSbip<^?r7vIDI<23RXjdWwi@JMQHY&=;qIxHe&A z;>1?W`Hpgg&N@*lBt_0FQs~TNIxKRtVbCW-p-;FR=oJwu#)#3xAPtRz84BxyCq|Ax zcPt^C{R}goorVu;1ZbTuAY)<9JKZQRoQChK$an!WtBu#J#Lr)1B}N3Y{KFti3DA=w z(kI5qL@(L6a#<36(SejrC35VrU|`cb9F!2 zaS|IFzVoA zLz(n(g2~dGT&Rt{a*j(x|7?^{5UX&QRKg>Mkfj%^5RWY60(=i=ScSvb4t*b1;V=o` z&BhNS=iu1J4~M6RGpxc0Tp3|?8Rt;SFgyHsnB`*xSlg`FXJg4&7$M-6&_7BrjPrta zd;_!N+vq`W6p6rIgEP58F5GuAfRW%BDURA$9d&g^!Fy*4nR1qp#jwRt-vAv$MpT0| z8FN3S3oPf9+#eMN_a)Hsf||RE3b(Kex1-1p54&yzwn7LR+T!#I5QaNn9I z_1bd^we@cBo<6UB)E`;C&=$k)2$Rh(+DW9QorHPX zBoBA^X?QOae0~UN_VVoA@Pw$d+i0jW0(3D0^R0OJ{#yDr{Eqq#ACJrJoPB3(XzlKe z3({4@kvOT0ujXRKSViP8SDhZX(PA&^d|dwGc9mlye~1O%9($7Yp3LQxgt9GoR##{w z-54{&A}=E3O3;rBPBQ!qK3Z8A$}vX?s`qpj^Ox4Gi4+=Wejrxf+WpFx2AF?{Zn`iu z-h3KH{+*E793^8GGlMc8o{f~z`}&i!;kb(vP%g*U($(G=NsSlbxLE0(kbzUPUVd{w zF7D(k5%O{CcB`=>>N4-_20A{d*YX1m^p0s~NH=D87?X9UH^H>Bq||HDp@&R3(gQQG zCo#&$=v#wB#o1h5(g61*&ERsl(MI5YoQPC}7*SD(F&f?n=WTpdN#9s~^Qdg^{IN!* zfsM)&ejJr^|Ga!u(!bZJNS#+673|f49{D&25Oa1X|0aLL+H7^fG0q4TZB&ggXz$za zd*qq(yXNgV5PvQ=A>n-bqLzwX6^4or=GB&u>Ut+HI!O){-KW7;%9|`T`j)b z5&sV33gub2>`W!8soq$%h%4Oz+G;3rcgVR4EJ#COt*Fhkvb5AV=UoDL|A87jfL0R$B}ED1!Nrb@BtV4 z{fXTFYWnCdp?ZnQAErR_4#S`iDa5{0+|TUABX4LUBz+&iHDlo z{R!~&NqE{=s6KtQYOje9yEJ?b(G5bhE$j4!BavzlZ(5ll@=H{x4wvjqHElv!8n~GkpzB z4n~n0nif=L;g6jSGy|>$E(v@v2|1Y2G+Wd+thaDGUSnu zoi_T4XO#3wsJS1;oJHO>Q%{PtNY-8R(lp%?TZ2zL?!jI6TH52mos0$=+llLBf<59<)ls8tTV5`&#-D{7!@420y+@Q}>aJHHcPnc-9%8;|x(CJ+fG9qovwsIEWt{?*?qUVpLh8_zp=)Obqkekx$A&2KV z4RvDQyUt;p$(1yRvY#73DIVpz_m{W11f z$7!}VRp3JXz(CR~B7~Lfed_6?F2qxs?n9eJyq0UzASFOcYS12jxW}gA>^^h8q*nDv z`6N^@Q^i+0+=4zEBgIkDNI6%4Ht9e%WKv`*U(F|HRwq?n*q{5>g|^&PGxEi;!dN&z zUL4mlURlf+v}8g1*11>?Sb|6m7>iv1J(SswD8Rs1KoThw3MGs&DUhvG3xpz}NG>K5 zg<@%BpL|88s)y&Xb2ksl32z}v72R%Md%5_AX z)0r@`137)2S69L1CkyD~l8ie(?7JSmr+Jg) zL_}Pa%?iv0f392t@;_*Q=N9Yp9J%s>ZfimUP*}Wpe}#&qnB$GtaygseiO=8(YZ0O$ z<|>P_a_zCKY~TxC)W9P1)!4@xddk0``%Ud#j-Tm!ms7BgBGxKsYz$v?Yy+;eNPADV zSx1;FVqmQ_igh%<%LsJs1vy~>=wI{60+39qger$|;zIjE33Oqho}LMyrqWPW3UjjA zxtK&riwIg6myjhud$|8qPu~he$tXX7o&uDzqGP^tmw1#`I&Kzkkya=eeF3X~ z2V(54Bv$c6sHS73WQFrJaDF?S-`;TtSq*49t`>o5;^ZL{i)&{S3~32V!0IGlUp`RtRSy9FOQw^;GN{D~uu7Gxc<5*JuHeqY*XQ=GE!P0*`;f)#NoL zlz9{M+!!2Xd>%2SIKG$|-Rf_|m(uaBBAxZuXH~T7E>35eNPhllF=#$Rpw?m-6&pR- zrQ$*%J_&kGPLYdYJl^TbW7s2o&)xfJ{HNHS>0K(`bbWqF_t%Yx;QR?g@V}?MuYaZ} zi%7M&2>NI-Sq%JbiG7J97dY?;v7Wx>!%T|6;qblBZ?!HXxzdfmYz2;)4AQq=qJBlkfsY$QJse*%=XZPf$fPZ5)q-Ct<9 zpWKhRz<^RrC7Xa!8mvDf$ZIx}2gS|O7P19K^g*RYtYMVGbzjqnV{0m@CADy+j?^(* z&lDvac$fuNj|YM(inj&$CDKZ^197nWXr-jv+=x_FN8b;qe6^m`gB;N)Ah(L|DK2Xk zn}lY$Nr|;$4pf_9lQEmB`pnCLEP{BCTgg_2F!hl5kQ{&hp;bG?hlL&T!|a(UsoR8Y z@C=t4-(x7<2{X^O^5?=%`RB?m;Sq6{{0re1at!~7LPWyQ%(?C(4fsxm5`hTtP9hP} z=gx;1miVU6l4s%Uf06%UUi+DF&EJ(l5SL3uKa(5!`ubwqK@pxQdrstX4u}Vp=N!MW z{|4lu6zfIhM5sI$v6v2#L(0qI%SsCWs`!fi6(#=s!?z!{za}15UUQ^C`)B9=PW&Cq z+k?4Z<9o`>f@1vn?W+P}Q0Wr8pv?hCx4j!mJ(-c5^jlHS|JI@RMI=8jKCkG{nIq6* z@(C#!pd;;G<>Ld0q%JJDB_1v=>n{5nD2o~Arg|# z%U=rrBwtGZl>a6Ct9Q@jpD-^l->tE*o_^@1vbl%~=i&c(A)TB)dtMqM9~b^Wj!S<~ z-Xd>`eZHMI6qPfzfPsyiH`e(vtFb_TsxMlNH zxA1r2@3M!S6+F^e*-JVFuhc2~iBC8KPo{x9`-U`FIU&AHPDt;Ncc3rcwZH557^K%t zM^$OF2Hvyg=to4&`Lym+n8EP9;nPzf&z^2My>}3kXRF*PcCM$olt6!HTvpo^!+cMmd3-dD2$@h{($pO4f5%!UN(5sIM zj{+|%=}gpkSq(@PHD~rHPXI65dFFBP3F+6!v(5m|f-5a&oa8CwS!bNmQ;LdP_5_@N z;>^=zKb&`-*)O#z&xp^+b#z%!t?@CaG0e;M$f)yP@DJo=yUA|G%T!PD@cLjVX(27Z zJ*==km_NrA0WptNJT9Dfc4CLCX1FT<9ajo2KkB{k>Wr%a@9w`gti&?U@3h+JTYkJ7 zj#nZ^$8q+no{sUy3o23=jJg4{*DOxua$qELPlT4`7Qt*x=cmfWjyPB&VxeD6ezbrX zEHScfwDE9+CI0-5RZ!;bMz|g=+As$S3D@|zAMuX)ib%QC8U=in#o{T^jykG<%o@w& z0L+fD1u?A17V2X05>w?O=&K!m73;o>o5;#*vTmVJ!i)uXQhsqTGnk4clR zZVaUsU>+C~%Rr){-lz4V-cOPmyZ2t)0_{4v*~DGA@B7JCh=3NBt^Rj)Tj;m%)NSkN zV?UB^TSxEg`hTn2+GvaKf1=xNfi?6>x-FhZ`P@d=`>w3p+Njm{{d8L!t@iclwp-|~ zz<24kHaf-Er`v9!4+O5H+k))v>#y5x0bT1#x-FjnKDsUFIiTCxXpQ%qb=x|+G5B4& zZ5>?^{4sP}8=d6+Cf(Ksxew#4)8x-DqR-tVK^)__j=W9YUubZ+OBbz2+D`Fg2ti@SN>SGToMPv^g*+ctK8 z`qdWnk2zci{C3ki6PLT*#NB_diJQK`#9bN%Z=x^kN zw$;%JkLu&dGCHAug2H7ZhS5f-(SH_q=TIAtfF8mbj(Zn)47y?fWnnzF(VZTY0Mzr1 z9@KjAxQ@mKa5qMMc3A*-Yt;KUdr;$6&(96uPLFziqi2S@ueOqYwJq&e+tPlu&Fxp) z`~JS#a{AR)-mkW_ezi^aMECAKW9G5@W^#l{9?bq5DQ%+%|G9;J;d%XT6Sr$^*bZ#E zM_nr?Ybg7(LZ-Rscb6g#k}_IZHWqu>^WH{3)b<0UAj%{ettRN%_qB7of@g0+=ZecNWt~j67K2a)yZMqM1o8sdC!>_;b7|npi8)m&Hb(_n>7x!)c>0F#Jxw zA_62614t&3If$(m<*0@JMOh1dg>j|XLN|2kK{CP79hj9df_W2}?rDE@3yjZVcwcc% zpFhE#Uc1XQ&7WY^a99?y{06mSMlt3R&ycu);$??!%FZj{J*~t7P^4Nc@ zreWTrt#e3PSt;NFnl+Z^hVdwyx+DMf?Rb=R)aAJ}mxPPI9FMY|e$ds2N7>Z<*DqB( zO0#7%eY9&J9%Vg!qw8`!%8#tyl}lnXwRZL4Q8sq}^h*_Y;+ga2d&0IhLEHZYN?(D# z%{g|=^A*QiCT21W4c^7_$cuwp(u7)S^ry>%pkD^Td(PF~Gn4r@`f+Ys(tsjHIkzw# zV1i%9@*KGqPSwVpr2YKE2v{I%LM41MSb z+VfICp5nS+wjFmDIO}Of7jpbs`i3uAP<5?*k}Qvg88ucMBc`z#HA2pZ8Fj#9h8dM; zPXKLTOjkUcM+?4)Tv=+3mvu0c%o66stfkF9Rj(LIhJvo(>cPn3p)%H$+J)4uzFQu& z%H&b0U46TH>epsEBH`E4o&G+|V0_ao_NL3UH=W7ew37Xw;Z9>YQ-HpFDqk1@I&mz2 zcZFgtXj^Vgw~llgl^91o{V0gml98=-G~b8&t|Ohbbgdt2TkP+{1UA1nuwBQ3k<9Xj zb>S0L{#ZA*C0%O^tdP#lFgp|7`2B1bT6;FrsxAZBOsl)pan%Pn_m^j52JjMQCj<)8 zA2{%;1*od>pYT+0?Oi6W;*Nek>N&1ZRsNMcX*lk3|B~m3`gbgm^=FTm|M#+Yj%Idzsf(Q@v__YjI!s6Tn}Y42tR98!^Zlt20Fj7?S`67^_-BayL zX5PHXaL;Q4?m5FU*Wo=SEbj{9>-;L@8gNg0AW^$#ybrZ}^aA}===A~jycSTi%rzX$ z7DmeYqLBiZZ4r=mvVqqw1qpHt%#kRc+E-(sXW9ZL)>kIhS7ShCHTcvSgMBrrU9Itg z7w64Oe4aE)xw`@pbB>10u8*veb&NCJx}f`FVJ!3JkAWFc$2?|-uwESuG#m7fX2)30 z$KDa_7^S_<)C1axJ^>@~jRb#jZqAMPvlfsRE#!%_qg!#DcKFnB!slOul5w=lyythUYcWn6XK;dSRW^d}1Yufw{ND>Zb#a4|~QN`Lm> zaIc>`Ojet?tX1EZYowMw5kw5l#_m5}{AOh7qIMNo8t65^<&SLdk1Xv1E$O%wk)>Vy z<;c=#qu0SY)e zH%GMRI@;qwe`=)Pc*0psB>Z;cp$#5C%ES0;9Q<FA$~k!>tCv9APNjmr4pWSBTiDs0OZEhJmAKnaB` zTgwbhh_xlT&t+2p}-dbvggT1g0 z17*CY%8#y29LZ=B?Ka6wp45I{Jd4j)`>`kI`(u0KsgAif%tZZf0?;X5EAcabp6&}U z^S<)t!MHtss~V>p&aZ4@S(Qx^#ws?i{r%d^%vHWfJ$lo|C`LzRk0sUB6K%-M#M~bY z)lgulh6L6t5wXtI(H-grdCU=ktGySaAXSNU!G(((RR2Mv{HF1So)cw9dJ2<&^)G$0 zZbXEyI;Uy|(1m~;HG$>z?jLWr@sfBu^dvS(Kr=iD;3VX}K?6ql(Ee zj}w?@DOy>>k#>bZ9TOOWZA16juV5Vkz5ktCOx(^D>fAo5jYIK(IPUTz1IFPzsR`pA zZ>D8k;rRzV3dR93(ag#X`%~=6Vv3Rs<8XtLC?>)>h94c9+ zQ5*+Y?;LZ*Id_8)ZU-PdLMDKbA?>!{ZT@mJx`v$f3#ig=Q!(pc_ggz6~e66>xGKe>B9B$ zbVsRBVlS1;gfghN#4*E;al~>N?!Ti2d@>hB?r>x8&W7G?^#0V1x;^&D6fy;P8b(H6 zBUQCsCr%^RNz>qst0c^KHj}9PZ+IuhB9-x1lVY)0TF{0$KPO9*;LZgS=JhHkGo9l| zIrHKyP_825Mb%4_W0-dz{O(06Xa0l>;j$(GMp0cs1g_0F+QRS=H~(@TMIO-1T97RUK+2PP<%R9q#ROQ4KB1}hW-YHf4n8WBO2IvT5(&q3uKgY<``^VV} zgmH2K&{4IFI}DY=oYt#^%2t@o@_0v)P-rh=d0k`pLdQh=L`FyVx2rzA`0h0*0ig~f z6_a9+UnUEa#7Xj^wyEM20TFj&t&8NVg{$Qog#OR$2&y)QGEyd2@-u~Uv0Pr`68%MDJ*DJFc+xC&^f}5B_O9%cgXew%_WgoVgN}*y&GpO za2`*RG?2QM0Cnk@#Y!hF12<9tqpTB^;xb^Vn+HhLw^C)1APJA*t3+w`-j_yiNlp)KwpQMOfg7AK2yeH)~y`L z)izROF+@OLE*6cG3UbLHCDrk|c*KtR$zOMlB}ZW1VLT$nLaW&kIlcfh`}We;>rRY2 zIB`g+}ovp7s&uS-YCQ7zNqtBk%7R}!gZ4u7>!Y%i9N?VoI)Buthk0eu}~ zk&CYgueL4{UQsijJC+EG?MvjP!cwSru>%o;k-oU@m`0Ua%#2z#22@=HZTPYL&BAhV zx%`K=Tf`N@E%FMWmOsdd3h_Ik|1-`Wa6Gf8cy~H8xmG+T+@U%mI zRCtt)dlvH%c&SwqB>26VuJ4z77NfcP+C9Aka~|PtvyQg`Exg3`RDS2|+h?B2_M~wv zc9C7MrU-f5Z6n*@4VsmQ#D_GmnX@ofFFG-I8pmVyw3=S~ z%SN&hsOM+G1L6bnTWt@Dn}i4DO+X26$v+i-D*sl%=g>!o<9|Ya0?$qHt9oaZCxom-)a?B%2wreVU>8hyjoZd{kKZN{CX+{wLq(W z>%{DQpm&nnp!7*z1EU}V9B&Tx*;p|T=x?2>e;0D^szUS<>rX*Z11RW0_ivpjEpR;g zlvNdCMnWBrk?uE0Z?w)8=8(D49H4?XSpLG_5G=hf$7od{<|-}a%SfqED*e8-Tu}2P z>a4$)FoWVj@*Ci-2c5X%J5`=Wt`*cgr@(9F>B97WRP&qGDZ&&+HPyjBo;#3gkkkIg znNRWuP|a`IN~TiHb!TxD)HMvf+0K2gV^1d$)dN8-=i*tMF?qp#@cWZcVLy)iF5}2C zy;5X6aNhP;QzTpWn-?FX?V!^?3OspkwMnzFM&7brTlc@}7n3_HWO`ebAJwQRjDg}t z$BHp_BeQcFCEXfsG-?j2bTZp*WEqs=G*6t~XsFSX-(!+1|2n&dky4mFS}8>Yv(YEj zlH!!)H9}bq+?n8vBz1I{KTgu+M9Ov4;x|gEAgQ7*j^`ug2zF%g$KjrEgn?n)M#y@l zj-K*kOCsE=RD_;-leySl9|ltaM)pSc>zBw|jG)UrNGqUEqM$z}EbMRR2;2M?bU$yx zxUy9hI{Smv5R72E!3O2|3HSzx=?l~?Brr<`C!>WFwK2q$!T#W+I=aWtq8bNeu(2ff zWw62Z@tEc>u}9m{nbCr>X>{nn3yjj>(0{W$Ly`7gG&f>o7L*0u^+mB2anK)Y{rFoi z$JF349wDYt9lezu@8JIk$IIApYEelJo`+IR=*NgXg69_(S>b%OR*vr6^PpMA^z*B_ zIi~W${(`qIv=v1B%k+=G9@L3-wAim>$Z)ZIykHVd^7UNC&P*wt#Bha&3B-Ve(3{U7O@@RUXb0DstJg_q~fH!{*ON-)zOcA9Fx#u zc$CJfiV*uGmIwJxER@UICW;eaZJq!vDq~W>Gy!YF?8zLD`ID;(aZZ-!(Gp5Ky7I9C>bMxE)*r!Zf!A+35puf5!IkH=EWfHR z^lA7$#XKGkxlx|euufTKi}9M5-Vj85kc~wkM}Y*J+cjP`P8~0x?9|^cXNojgMxX05 z@Z=DAwsnk@p-dC6Rr64T6gAyG-7$|KewC`ps2El^z?s~R6QTT$)9^VFD(INA*H}Ea zW$xZ|=9#m?od)x4v8#@*@^JiM=9x1{F_)(+v&30Y>TLUL$LWyYg*hBlY%8^N72m2H zvpQVjm4m)J%iw*D9i^lM%KplgAuRw|F?AwZ0}$OkAr#>Pxot#(FM_L~bsk*%bo?Sx zEmTWSo!g)T8IdfJ76Yx_7}{XMHE~vGqp2^du!gSoEG0{UI&UI~#`4s;bvhLnY&m;o zoe43-W`#DHo;tUYyPZ6BZWFhP+%Bz>?;xv%J8*pmid@ZBbEH$Qdt<}Jvv}_V(y zGx9Sj6M8~_&Y}bD!pG%DG5sgCP=|4nix+i-;|VvBO)%%Sh@0)3m8XC|*V;jzRBAv{ zzcIA9;6d?0Wt511yk#Jn*hCw&v`XJ3s`88;?x`|i=GQ!ebz`nqj>l}TTc{;CO3qVe zg=S~X3e7FpPOx>exgBudT<&4ALwZ==Nq#QulpXDGTIv4FUsgQup+2hUBhqluJ|szO}p66 z^6GA(vjb+$kE@Oz@E|I|7Lba#{Ap-w{9^Hj2Z73Q_c#-%CE}b#4`l$qC_j1{KI(j$ z4ac*OCI~|+Zm&RXu#V+CcKh*1tEr(q{y3tZ-$Ew@O>CbdUV4yD^1O8h zkJT%A!J}tXuP3CeKaoFa-1U~v!*RIpllMVJ{|os*`~XI|SpQe?L-JSYLpI9ArazNE z!zk~BQQpp-f>GYd{f%&zkH{(MZ^~)$bgxxgE$d_QF;Gkgaf@y!t5E-`c!qo`ond7a znm!?)Kv{&9^>-+XaG#OCOP?uc$>-u($wNFqIiD+?Vy7n04{pR(Z|A(k3s-!^2YtCN zcp_vloQ6+3@`jPhqN!iJ~LWhKBUe})kpFw*cz{S5afZwzIb(D(i{d}f7OOlp}x z18^qG!0{(S76V3qY@ySGvqGm}7MwDHJ1`_N)@!mQA7|E$p4aQ!%Z z-uA0yo8g`h;rEB|Ex~;)+^o0?y)W?U)J1^x!_xAFkS)niB?l1lib?*WnMU~}` zS3i<;r#ngK9YRPt4?+_Hg!jV$Nr(XvC4-DI3QknU?I4B_@*kk8#vQmcQ$`;zno2WgKuC)|GxIFzRiUk^edOR(Co{gQBkg&;P^clInWg zx^?gOo_o%@=TVvp&$&uh1byYV1bwByJfEgp5pi9d{2DGT zK=kX;x1kDpWFhqG+#*;(pjWfBD}q6|?;_M2gmSSIM>7lhv`mk_4f#B__e8Krk3KQj zpEfwML4O|e7RdQPyNZBz*-C>Htwr4DaKDXXw(l4DFNBNI-}t}5_W_ z^F)w?nmDL4DDNa64vo;SBJL7@Nu^(Z0Qyw~y=sNFS>f-&F#Wo~UjQ_I!hbA&3}`IX z67f@>NS{(PmYV;{{}s@92*&ClHw0}u#0B^vX_y~|wgi;(;`ylbt6S?6edrw^`jvP( z<8SoF%ZG$tfSg@vf0BO^Xwp;SQ)*;0s%5tu!t|@0`)A%LKMnNjpTuW`XW-snioaAX za!S2MpfwKBffkNuf5krsBl6tYUrEow@8`|}*KqbUlwb3Q;rz>Ie=Qw`^Do2sH{kpm zXaAKy0_Wd4dqny_%8TNQKp$>&#Yw%qF-*UHA>&TaMQefCkJ`P{=g!lxFp|+E_ zJh3wK7|gh1jDF?7an3QlO25p``-nY&-~KeG z<#AW>?tm5e>|I3kXn1yhCwbS)=$B4vC-3<;I~o1LE3bR+a)#(vH`l_qsPrr6BQ}pg zvRCEBm;Wa;N)3Div~HW&*wqMY@p|3%t|oE2(nQzd^`)3qK2NmscEH9x{AO`8U}J;! zUU3V5ue60?V}rS#ua|OxPt67NZURi%VFqpDHt-t&8^1hn*J3oO6#MP`M)7uOqf*EJ z7`>I`U!Jei-bbnfqwO(bsXfLs_YS^N1hVMQg6-rXKiBWO!OXq5oY_W9cXOs+ee&Q9 z%3Nn z0L=T&o#bsd)wJ8T(s%@A&>mAQ@S-3eWh>hqP#c^{`oVo9D zT_CkG{oqe+^WKR(pXD3kXFTVQ+V3NZ z3-c7rr`|jsfM~ zqU4IXN`{F0J5}~#ezG`Oy0_0JPT_6R6u{KIR3b{}kJ>l&O%pfwm55VOhEikFR@LEJ zVknymRIWLI8kKZ;E8ie&a-hHCR>us!!7-hmAx)Rd_?ZHW3dh-Js=E1oRV9OX7sj$c zP3}B?t}u^kjpkA*u(pEsZa%CT0`7*)lMH2ZLB`lg%Kc0`hVm5C@oshC4i4L8Id*QV z)W|nVOcQ1YzWri;s*+rd66p2z#loVlMe??1%e$@-%H?Z%Om*92)B@cl*n8ItclF*P ztf!h;qy3hiTf1(hy50NVVS7l}uP@nee|BTn=4Ur_-6n2SHmLIUO?A+l1BThR$$CnS zd^9J^QvUW{kduLuEfbdY80J)TRY*D!y?(oW%rY7+&6^y{d975%Yw|0FYQ7r2@LJ(o zK#<+5RV~f4K=R2tvjlU}DXV#ufL4jCrRxQE&T_o%k31 zW~DHhx};(@z&6SJRs z@&L7f?Me~TaX%qnQ{B~v*_|+E6vkjPcboRNlReayAqns;LMt$m$YWI2X0g;T-ezT; zp{!fT=DQse!Zr(N^OB4_dH^jiY#!wEl2q#jt!llnKf-!pKeb+Xgn!gg#6RLFE#o5*ymk2-K) zlCvX%cae|W1_3qL822s?XpBLnF+Ul^JLmFq;m*f;=L_>-)>PUT@C#rqM!gBHf-%BQ zQWxOtG3vVgkB)2jSZOgJYmrdSmjkkv2uomHTp9LZ2s$yA;yh(JPo-UPxrEUb^?)AB z8I+4x@GPn#`VIqM8upJtPhs?tStVVEF-T$l*Lm@M%c%bX^Y)rYttvRxcOk=x+1D1G z!T)ET!LNHEHjP+p5Zsf#o!AQ?%Zk7^0 znE=#r(;1B2csf{j1}U2?{Sc)1f8h5yHt_%8xQ*9IxAGX%@it{6%>5KQM$u%H0c%7} zd6gYKKI$Z;?=F$b>wpIZqj*aXKrKJvA8>5qedBgE8CZ zK;K@@j()sI3saQTp7j+!2xDNM1ATZo`-8m=!o7S0^!8SMD`22eY^1T~H9%eN_F!f@ zhJhZ(c9`i+fPrlS?j{&!wFoWH6N}v;>T>c7dRN@5?Bvm_Vu!d>>QKL~2Rn2}h=N?OMRegcdcMgXMtdo=&JRs?y{7bjz!K*KE5x@zFs zPI9LY3~{J?op^#viNZ4EA3>Ti|c=J@&8}@?LKnSHMZaGBX7H|zTbd@8yeehyU3$M z(fh59_=dRt`xlL@iEo8{BmPOXC%*mw#(2c_FhgArtNRk@dRXSfI7IQ?MpzF&N57P^ z1XvH31FA2mHskoa!qGvwFwVM+UkWQog=1Oo(!LJT7#P{><%W;IinCPeAe;Skl>zF4 z(SuuE$Wd|DSozI3t|W%97~ZW)j|ng%@vBqq+2Vw*3Cgw4=5$RIbCii7m0YVpPbf(u zuANnOD-T?zRMS@=hGH|hNCvN@{x(+RLX|j3s83v4rmBCjg&^_FLE6X9_dAX2`3aoz+z) z%#zE1&s#+!7nci5dgln`y|{NUSHQi6**){R=7lZ24AjyK*1Q4a9+AVuNEGSvQY8V# zTt5`*Z$tGmnMT*bzNK`ng8q-AGS{`(x$GPs&2Ux2|D`VUF+#*AdO6KCa3;fro<=xo z3xQI-I)r_{fS(U_Ep#mCo!_^MyfiejBZ*c=^Wp6;4lz3;jVI${U9qB3ic?~H_HG`ac8nai>Vh?8;6j{M$!sT~F7F#jogN#wc^kS?u;(d%?$4R^G+|;B&b`+x| z*X_1v&C=7qzpD>f7pFTpy03}(jx-=e2vulF$?S~d)N3jBwZVML?z%rxyJJIypB-jJ z!d$Z&fulQic)#ZSQEnIMc1LD?(T8JnMzgTqNnW59)}6!IpMAB3^-l6sV4Q_@eVqKp z9n`|Q{&E)9fRTVkf>HBd#=^QjnuYav9|=tzluyjtLh;%<$RVGO(z8$`PCjI>ILdCc zd;l$=6C|^YGX`@s+(E5IcL5cGc7Eb&G|OCpPTWPB0%j>z{&nzW%gFJoaJ)r59)RP! z)#GDuTt}b(a9bkGl-E5v$;30em?T^7N&FitYrLFguncIMe`J=#52C$|rp(00Qa`0c zKz&1C5w**Yhx76LX|(wXmckomP&&yhMNGJd^)4Qb)cd-R&9n}Tw}-j_nS=h$rZEIr zRL!&Ju>Pfik*u2K&chzAs{F^OB?)ItPyVX>$8BV#@9X40Mhl01;gylaBG7lK(Fl4@(EKq# zRl2$Tz~A}N8UUXNsC47M)xG$8yEFL=AsxOXLrzyPvM6Sa$Pp&u9<}md_H`JCpy16< z`wD)r9J7MJDs?cgJMW;i+xoa+UjF|4$CG(mjin1Qj?!pCw^=j^ux1W%_5}LH70G6$ zcDbqNXI0#Vtlj86Q%@uQui?_9WVt{nQ1`KE#DhY3Q{k=4`KtUsG3$#pTn5~qOd~i{xd(GI?Q7MOQ`7 zQhte0-i53D5`#? ztbXkWBFdekcai|2KwZCUalaX6Q2Ch~`5U@0*2JZAo1Doo8nM1KlvClF~fB)Q8%J#%o#jns#!?#bStuB54?APZOs}T0mn#I6GZM7(KPiQC~MXoX2LeG=4}!Y$MGcuK&|AkQ1geUg8+cbM$saN`_igZum?mQZ4kkNfMHx z%$EcaxNA6%`8HAkHOXC=2^lpb$zjxtzDnE5E0VXSNPFrpE_PLn(zbhn*NZAEV}@1;h+M&CKqZ<507~ zKN>Y9VhPkbt!o<1^b|sk4e)SCeZ$iO7$887;wTP_WrT{C zk#3+J`!jybZfR7s=MB1w0`!V%BemXm`N1uiB`13jy@z(gF$|5mv@jC z{W@GJHzD?RZ!t=pTPh0L$ZW5cPjIqlG=iS;SHL~9$OrUpqs08vuuWt6Vzk8Bv)(Yf z>Oy|1Qbi?AfpM)YdPy5e^p1F)wuik=@jN_h;bg;lLpA2MV6u$CmVXj?y*OE~96N8& z{vNn%tNA(aF|+1#^Tm@D6&^FUbvRF_^B&W_Q^A!u`f=Y&b6%s35eENFes9oMSfvTD0u@Qk#3eMGxo@L=7VG40ma zEGLoEj4|uw*UoD+zvJGhh>=(2M7GL%jy)N_UIVS7@r3#>PBp9j%GPn@-r`ulLd)Vn zrh~Sn2vxCNCuk-)^pOg+@Xm-9mPfSkPTE2pyeGceAjkEfZYveXkN>l7{U;yUNH z>UU~2d^~N#ty9OxL5d3+OVu1FVM$~cnd=7bG#_MrSFD7Q|0@dcSWmHol51wrNG-k0 zl#{Q>=Y(CPo!$%RRPb2uWHmHkwoMi1579BfFE>h>eGk`Yr_$Ubn6Gj`Pr1H$TgG6C z(;(^dbx>oii)I^{rBg!3Xjj=zHoJDepp{VjH39C8g|{rGR}Hf)1)*aNy>lJhiBd!r zw8uc(Q;d~7W8{!K8b-7fBMXAD6eHTNz=$@Ck&{!*QT)5t z49A$YRPsPM5+n-D%_(Vi=#-msbY01fueFDcc88BD!$%r8N^Xn|&+Ev#*%xD`qC2YD zSEFn+GNX$lzS;<(-Ho6YNuS zA?|^7R3~Wpxzt*j?T2Y;CV?sMvTRzhG?PG#fYg+;p(SIC^qL*s5SAc!lEfj6)Ji%6 zG}1QjQJ)J%*^Y(Lh~?jf`nB@Dx)H2~qRenWo0!gd2f5KV60zo6wy}P68*6AAZQrZO82O`@zI^J1~%xDbL6jCW8Jl16qF#}2?#=6XfatW>!DK328ngV>Y^Twdo0@5?Q z=hLESn8p3=T6o9kdDKcS4voAeEBqEbkC6!s8(3Tdz9>X1N9cut<{ueT>z`Py?+!(q zop>JQUy#~m4bWGVEwO*&Y-#GsW7Jl9EO&6)SUwI~U6~UjaP6_OVRneK+N#bj8v;camW*%?@sxGl(2}Mfh!)0pQIj*f<`ju*UGMBWdAmnKM58j0K*#(~I2b zAYgUCuJ2iY$G-v3@qV2Qby&i6bU+=iN7R8a_gYCd^yz=7eQJ&9)9gSD%!i6>mN|p* z9B*1j^J9#A)<(=_b`R9U$jNlUu%@Y^{;fDCTY5Nvgh8-qxLThZM7_)v1|VarR^8)}5rlXTCz_)}17U zW^TQ2xc_ghfI6=KsXQ~cFqe(hA$6>V2O{_3b~!_OX{e)%#upHG01ge5QW}-o*=E5c znt>`MhzZc+iDIIp7eE$rWAEzaWC64DrSM#VwyvtqP?jrNdeZq^M;f2nl`f_AWOQZF z{7tQ7X&@DM#$+7H3vQEy^UY9ak}B*g;eYfbHk6^)a2qM{;5E#dY?zI98W{f%WHXOO z*3_{`M}{)oO==?<9xXjr2}M&Ei&h&TJL;%!l9f{FD$l2r%u#aD-~1iqqTfNP{Uf>P zcars9%tgOuaBMF6on)=|a=GXMJJx{1{OA zr%laB4=aG0k)9p_4t{%aqQrSCxC#yKv9*%J?r2%*wcaW%=dDU%nd#MEmeJYicaWfu zWv4e>Av=95dB{DSW9D9*Xy)#{)5zTo$G1b-ki-1aE`;`i|1FYU9DfbaBBWvL0XaiB z9bB)T-!OpDiSh-sLmSx{-siLlwu4izy*2T9#DyB)@Bb?zWf z`#5_Nr3z-nQk{r%uVSADx@N5Y9cUzL_7uJoS^r(=GqKCmlig+Pnb4KRr%0uIX^&yf^sedB z4zk*pqUNSwO>;@k;>*ODU6>CFy=BUP;!PXG`HwlA>lUFM+)Slz@l3Hotf1cE=q)o> zM1PsN$^vnL!ZH+~ALByh8u1#1>UPB?QaRQ4?jXfJ%;{LSNK^Np=TZT$De`imieD~O z^VLdjXE!+**N3Rp)I(Crvy>W8AVCU2+%Tf{B2o<;}SuyA%e z)RRi{*{4YN^7lsMv#0cx>Xfx#Bwo0Yzd^iFSpy?eeuiP9;>>9%8^jGTwi~-P_SC_( z&eu)^_r3NJQT`ze>EB8ze)ah;B5Wl^T(e_ z9^p-Ziys=zo3xS-e9?K6R`PUMr#g`Q{ct4jCLhx|M7O z+-a0!!Cfg#lIHrKNslH=4+eJ~8!JbzcSV;e*SjL+=#}Zw<>*m0s(g2({2$48m$|+> z8T!+-E6LE%s5XRzJ$J?c~L% zvMfd}8IfgMNXbw%S$1uznHxy`IG`)oP_@h&h0Y9ae)r?+dS+16b+~|!?Ltc&0hwUKm1;)~lBfb$D z(&Ud$Lz?{2X$bF&q#-N)(P_wDUvwH$?vGAG%KeOneCa_N(gqYPIt^JniiQ~c(P&6w zl9}6;#QJi?_GJfofo3@7E;EO4)JD&tk9^VR&_}-SZVug<`1NRAm1{Ju`@>b~?K;SS zCmOBm8>hE}bDmaWc3+;>@n5O8>md7}4v%Xrty}7gPV1KX#?!i#ge$MrwYKPMwb>Va zrkQ;sYxVQy=zPxjdHbO^dTk$iBl(;<^EcDywUfDHc;yE#qt9z6+5XWya|@{+iq12) zqi$X0nLEFCeV#Z*p9hq{^KJO(cJiT{>GK9uPP&8K=|N7qgKY9#NuSpNG#XcyUBmzN zMGN`B#r3~yGIRF$|1Eu1J1Oyv=(9RVwkNtitAnI@E~n4B_QK7z0~da18LiK1A%{HU z^;s?Cpyx{ZtQI1Am_CahK|kE|1=DABQhgTCZrA1YS$jt5v-XV9XSI_LykD))Y9R$K zEA;nA1~d2g8Y6eWXyzV;^04vy*JrhphrHj9KC7MF?EU)stadWn`}Or%1FAl2;2Z0+ zI>`Gj)MpKR5BjWj@}_63KC2y8qHm+m68~59S?y$(=ey8nwUhOpuhwTheAW7_W^#Xk z>wgO7(SexnMxV8V3=W0#Sp!$4&uS+=_vQ6jJIK>RSJr2>lh@tR)~Bzp&uS*``oF0@ zE3}Ujyv#n%n&BgfuzrY5HOvyK88}e`jn!pTjzrzfX(#%t+|7X=aD{er@c8n(Iql?> zYy56bI~jD1-Oa&zB6o9Q#_i@bqy1$64E<)G7;QmNxh*CXbHiZPtD#dv!~_ zBfJerlz!xGR*mCrfU5W}$J_k+eCLmmt0_~tnr7&a@mx(aDT7|JMQ}C6l&hJnay8AQ zIKa4?W?~Cip*LM$0#`#hnr7fiqH#2wSF3U}a5Qdbu2bEaGhTs{X~vAj{nap5Ih>jM z_ZlM%gqb@Ec-CH@7o@LoOdV)bzS?_Dx+?_V^11Ky=53h#2z z8{%CoSHZjdQRP||MB!SRyC(0Um1Ajzbe6LmE5eHP^kYTYkrUe&iw7 zSMeiTJfr!MX3`h996z$z_5T$=lKZXnBRj}K_gH@9qMPv}U%Ic%j|AL|A6fB5Gr7^l z^&j}$#I5|yM16@a91caMuTUe?Z&Nc5$6AZ{iCv-Wa`^6IX^LEtJz!zkWV86YPi9e_ zq)w+VyJmIM*~wC|Y*PWrf{lJl8`GCG%-8N|XG>kqk zmr8BqPG2UCJ$pL%oHGL`RU5h0hk3PX&Q78E;ENT*;$m@f&kpj0JB`0aJKuT|E}vI@B{uX8b)gOj!C^-=F!cLv+Q z-dn-bOb^mhc<*X2%h1D~38?q5?^w=P36)}%R0;PjRP)#jh3bU)obSZrYx!#7TB(Mw zk?lZL+dz7%rV*O1MGHD_g1k~#i91SX%(S)EQLQ!cN1(nb{GN{{Lrn$B_53Q~I&qbB z9lVi)H|D85as$6wxIwy+zfs=oh=+G{yH;a79r*@$N6-^5*9x`pjPhWCt{4;HgW_byuK6B z6F?D5Xiu!?ZxPl@KjMERZ*jyyD=S>LNVoF0%Il$(PkZ9z+l1R>^yiGFtvslqbS;@AVSZ@VhG%Kp3*a54gV>q^7`xl~jlu@Z+zc&g@PvA(K(6C|EYwMN@OQ`! z4)h??x_&I($=@m0!MpGF=;gbFyJXDitfTL~U41vMY*vszro2P(4|B4e936TjxShim z6w}{_hd3L0t3M8BLov*z!}k{R&-_p5Tuiv%rtm%g!_YoOuFU?OrC70K|Jv(JihqCP z4R;4Z_Zpld@7WN*Ixn5u`9Gnot=rTH(@lp5U)fHc0-0M6H1*V9O<}$B+hN)4?^W6C zh660?M|u}$g|!}5mn;R>lxz__D={Z}C=y>AdE3p|e*6ylLubgD3T70VB;q)>kz;TL zM3A|CQpUB_qok9$J6QH zA*YGf-Rags-56s4Tes86T8}=m(?yJ42Xr3lw$i#YWackBo1ZP$IE+yDr-3reA0*F$ zx^HzGX;hKZ!2zd%*1eXtJ58P-#PK&ev283O_5yx^ywVX1&%YO#CoSX`%Jbp*#qL;) zhz`&H!5KrJpB?`0_0CMC9KPGo3k=W7umr;;%wRWT+_%A8Ee=#RQ>Yt0F@pBxFW8NkhhvH#VI2PwI7z^_NjE6I) zCcTD5;XElsM&Z;8EHXk`7mJOM*5j`E9jxvt-O2kc2TlabJ8^v4$!dQpAGH6*o~9rt znI)peq?I^_aAbbniFo;qo$-~J*LESSQmv%PKM^@dIR|}Vh7u^(h>;+0m1-q#52eD_ zr3#9Y^7SAWVq+>P-x^42^dSYNSe$~mKW2JuksgSEVIY^ zUY;UMkugG_k=Fl2ME&cW8A=J%|FjeMIoYO;d@Jc3Vk3`nDo41ways&9{t#E!O4^6w z!dzV}t-T?lcAST^q4wiW;AZ49b>v$~?GPJz>{-ljNAuCiOXjSs))|b)hDX$p`IZk9wbx7bEUtQbL_7 zCDftrE`n=sCk^UT2EL6xWzl3%JY*>N?zLV+e!9THDv$wKNTrb{Q{nseRc)Y1PL(rM znXgDHgg*Gd&)HT|>V`A16tK|l%>WrRRmz}NE>rj^at6+Se~O$Tpq*m|^gUuBhGHQT zsG?y}ihy}S*&1zwT95cytkw_~N-_2qt>*=Q8qAC|!7x?Nql5_aqAZoqqBR=&H3jfx zr6wny&)`E>pHO=mJ+Xgc4$Y%k=;KG{k&b4QnN1O7bq9PV?yScY#V>v^SevDpH8z9v zc4CXLyI2>tyTJ1r_Dpq*pvl(@U*98MeQwqO{Es#uu5f#V8|rf#$kdOLa7{cU{E$J!KOkDyf%_WyXBqV42tgdh6ch*3D}X1!^s zMyn*?7Tjo2{cf<k)YJr~Y#g{On10~)># zYW2BNWX*YlmZP3+uX|X=pL96|DYh=Nubntu_&c+YD@>8_S5i3YdQLd%dfrB}y4E+5 zw*&K`?+R`+az#*dP=;?ca!x3Jf>QAj8^4ghd({O?la@yx=N2+N#QfcH4@d~hbt5}% zT)qkTn4AF`$EI7qA2|UN)R44oUln&DaX0?b$%YN6tI^V5sQcw?X>?Vu%!wD`^8vl< z;_!{vtMP!( za_5H5L_PuI<8>hqi}|w?&X*flZi@*uRnU$cXKZ)Oe*FQYsBNTxw!lc&34^SK7F-Nq z3o@YvkvZtHROzdU=>1%O@NAf-#UV`#wWKKA5};xaV@u4mB_>&Gx6Y2I{Qz{SJ8pmM z0kq@LLr?5;C-tTmBCXLYT9~~$rG>2Wn?X{1KcJ;Oqmk*c)Iw@$)TfmC1X)waQEJoz z5?idKK^jsj(9H5kLx6(BVOyUExxL}+h>oW_+-GxC9Z%{3CNUVhP-d`dQu<O&s7)2>Ck_EYN5HpW6y+i_hLzRm~@Wg9r z^jxPM;}s_U84v~Ilh6|jcdZLxjA+~eNO3d~-fwXZp2MSu{UfnUS36nk(lk{oVUTtV z&%4w_%HbQ2p8;9mOn6L^e)WlU<72SSq`^94q3g`6^|0!6!m7hRRP(c%34Eto?}}iN zd4hyoePI`7lxc?VZgl3!70?HDhX7A}#{Lt*b%)c0)B`EqEo82bX)OQ4$>IYi^DShL zi?gEE;q9P-D*$d8BX(mv#x&Za`S2Y%{xm7Atf03Dddm>7K##DqF;0wAhQ}HHUpv!) zi)|%+LoCx@5%AbgQ@Qv6(5k79B)*L}{5L_n{}Nn%=1W}j<|N69fR9AE309m#{v2ge z&ke9DVMNLVs#$o-|5E*R>N-{KWLjg%UmzDMnD5cVBfTq73VSM{)~UVBHouKL;77`R z)Q)!Ve+dr5T0gZHCFyN72ACgB{?F{V&)hxKa(O~+tWtw_cOf|_C?VUTSar_ zG`fmTh5lRWXMK}_{Y0-#?JIgV4Nz1@ZD3Nut7=hBC|iMbV-l{aNyD#91k_}I*+i_~ z<4zM-w$8|HfpQC!8==gD^1GXi+*45g9g61zCSUR@eG5s~8oNnJv#+%qcxz1@w0tB! zRU0Yt8|3Tk9m5m8j8ib$tdYvu=x;Kau7Vib-4vPU!j}FH^*bqxrxB!+q(q=bEoAmk zqWmD>-hjBWpe&c10~84;dS|_ne~-p@O{R1>*=zxsCN#%K=;91@j%OY~?+jB{yqEx# zh?{zXM&h;(pbbq7pZ;fzavCq0l%!|%bgu_6;=_?+89eo}4o1Dv7Z;po&UH?=J`ybF z*!>k%82k4wuU4D%tnR!TBuK*w%Sww4zj{6$!E##=}f$#Y5gKWkS!jlvd1Db>Rh$W`)s zmOu@Yd(qFv2y~&tYf$OJ1sC)R(1pppNC{$vZ8dQ)%A35O*<YLAE@(&-!dSMiud1o)VZ;N{|VZApIgxVK>(=oicIyS|hg=$}}jGp!|A`k?V%i z55@U@qzq%-$RgEVw1+Yt9UmjVp!R7}SB^LVkYTM!gB4`8GX+-s>Q2-_0rhh;Wc-UW z*MYf<5E*s;5oF}xZrLbgOoVX{x)B*Uy}9u1A9@fOc=mHQLk1py?B1^;;{jNwP@>3% z{^^8c%*a|uaq)nshTMsVQWJ($QXYKo&pRM(zPK@ zV5`HOp3m&DbYu%$Eu`25au#6VMb~r{193_W<|~0aS9(Hgff?>R=$i}}h#RvOw0jr^ zG!z3lK8ArT6$6FP5A!|j8xwsD16gumUoOQ!35~dtJW9q2VZfluScrktFPccUi|cQN zG4|bH8z?IBC=#aQIJ@#FM^-Fl2+gF=kCq4N5{$YR_!O!SE8)}RX+lZwjJ^yBcjwU3 z1D`w#Pa-~Ay=QvMu z%N7_r3q{SH?qZrjvYFiNZza{c(j1lQ4` z6K$;8$ZGd*>_&S1QC}6kZh-5!wu1Zs*UR0X+n1=EOf}Wb$8_Ny+2VSX|C4+4aCZ#c zXLEPd&!cB_>KUv1H}%|9EuRWs`%?W(_=-8b_yr-(TJHu)gXV9;{#omq>tsFj5m4_0 zwTI%T8vcxtaPuhc<^b+Kcd;IO7w$3*vi^#r_sr>=@oXOSxyOb0ON&B-@-`Y(8dL=M z`~7FzfV=1Vw*baoydLP!Y9n_J{`#Q22jz7rFG2YiD8GQR;k`&K=2I*(eagl9SL*Kv zKG)JI*N8PgugT>n@sCB|F*l6I6TycE(7N-H;6GF_Y&HTmw;ZDReGelVGY@3!Zzi!S zxBEXTBGUnpW-lUg9YtieipXuiwPve`OanyT>0>BtCFPzJ0dt@y10qvYL?W-Y*JYuI z+(s0568n3Ghaob16e0^eh{$Kch)UI&jLWPp$8+>#vq5NAQmkyJzx#@9`Va_hE_U@q5e0$t;FH}OYksI z(>Z<2OL-fmfURU;C_91z9&|HIW=CK$Tg4>qqOm^P=Z=QSY#5D0Lv)WR3MTWzn6v^W z9}I2-DU9ns^+yv|be)m=1C;BbR6%jC1WZElLiracZ~Q(Ij|Cfl7RKYQ%}X|a33$u` zxhstaTpsGFnF`-wgI<~fXe#D^8G+8J60;LR%iJS?&cn{xav31A8<5E#DgwRo&IN29Rk^FoGYe@BxJiJ`SKWxsW{S;1ip>Sk&l>`T6q{vI4q!9QI}uk-=#79Y zTVT82bNOs}o-ns}VIS^c&L7Hxv-sp{coMPcbTMoehOxO2`uPuZzxpH~axul`@8M{P zBa??KfhLO0H&kq9${Fy@8Gy}J@>ZZ!nclO7VsnEto$ZkZUaGgN*xcYuqvwtXI_fvU zxy+taz)&lBF)&k3q4>JsW7wPt*lF-JlO`X-rq=%>ip`HHHj|;2WCd+dTZstIG75dO zuZ4W%LJDmeMWI{Cv49z{IgKw7@XO!!cR0(?PSn#%ZUt^H4ZdVap9w}U9cOcRAE+q*~Tks28(_;O^O?%`x=)A@@9b9ci@=uIm+D5AKoe*o^cU zaow?b2K3vK2>RSg=F(k3HV!#1hX2Aa{%6UB6#q*A|7fF+<6>|z{4ZAVKTBTHxA56Q z7+EXL6C@D}b zUTfqoL3v{^QZHoPxaaT}C`Z6-$a3zgUs9h@v#(}1@QZa%eqQ~4kUNBBMbP>jN)!{s zOhEqnfr)g7FCD%<4ful9ohVTx@3(a0&SeWwOU`ybnc)-eebaiSmh{FYF}EmU_VyZs&Yi&exeq!K_YdC0%Gemh8xxHrAiDB>C^;?VBJprD4Wm8^$nW9hTGaR2i|1(dtP95EeW^Yhz95H=J@ci9nMid3A)Y@6#u%ml5uVN()|*>5Y7aB5*ETZS zTLa^eQElV~p)7&Y3+2ztjoeWvr=jTJx8XlW>x+IC9;+PZ%k}rwFRkZmnEbbEjQq!J zpeA(Tu4@h*txRYyj2(>CI<)UTlzJcqc>ZdqrMm^@6;g?xcj6u>j@iHkl+h+p%clX~ zb#&B<#;swkHZr zX(qRO7@Y`s%IK&yk6Xj;hiBOuRt5LJ8<;X~4QnOO`!L!~M}0oDd{Qq*HJ3UVt1Z6I z>O=GR^ZJSOYUDhwrTJ7Q%9(U5C&5^*_l=d&LSq@4i$H-r(%UAkt_tQHjN3oJ-}|9V zhN6Ws1;$^|@ANLC<9E?HR+efdC%tJ(de5Q=8M~Fd?_Er}(*$*fz2(hN zXP7}9s|*;cz3ygM!%=c-B3YgiI#!#;%`gW%%VyXXxc{O*KgtX{>BSk=uFkNI`U%k5 z38QA%UN6qDOgWW~$^;mdM?rSBMBSN6RHdeEWDm&9Z@p#W4pkVr&6P&(-{J2LC^tjd z3FS#B&-{leA`j@KjSqzNQnOXP)QVu*7W5iO6cf5EwC~My9+eJIU!QKnevl%e=NAp) z{tov1TC2|QGJ3_y@Fpnf(5rD&;{fZ0 zH%T_ri~`7I#VM`8aTgo8d<3Ex<}%*cHL@DjegzMNlJe+?hBFXoTh7eSjALOT|~ z7tH6ENb~qVMQ}+=q-uV-P$gD&JrdMaJ`&WPsg_suT`OLzpw@m6sLxx6W{W3+$AMQG z7?=qtKH52bf2pvYl=(U9YF*NHZ|be6nE{q*@fIG+p8=P9}Hyw&qr{Umz*PXD9ydJbHl z2-h)_T`RG8UfTSiN>L9wvtfQs=xQagp3gV$rEkfCyC=YX7u}Bsb;-YrEOzN zWbsa<^X}i=^BJfq7$I+*7mNdE1&ZlGZweUT7g=JxHC3m}#qtnxD9E&%%Z$A7<=TCK_{!f^X zy|WShfZ8`RKcEHl`*GIk6b-ausTiV(_c)irm8%g#M*PjLRwquEryK^b#LrH?NtlY@`CzMmKkM&_;r%wvZ{90Eno%t0if0H67qs;}K`72#k zszU;f#kCTB&w7$zt|d~OCju6#UAV$3t}2|J1t~pdYTZ%hG=bb4SGA+bIvo5mlf7i{llKC>_1$8s~T8M9m^~Z5H(@N&cGy6)O&5>Hj2ScMZ(`gY} zA-%e`xe9C5#2D{0EK{QKuP zE1cnJ4hA_E(5bP85X)H^Ua$1_oG5SqdT%~8?#&@M+Wh%2yY)I4k)y#39TzM1E=@d=nTvajMjlg&OmK=2DS~yU24Q#h5miVOk8lD zk*i-|yXHJ_g`cZyllWo%JJGAMtKP z=;*t{tHCEy<9E9r%y5n1uqZHoJ$S*8_~pce(YTg;e-MIDF4Pem%fge2Bxh{n6Kh7E%m!HXgz2qZwAJ%2Os)af4m$RyB=Wfkgr}3+J*=I)`&KR zfV0LqM()g9Blpknw-5e42BibaMku$zx%sbN35#0mm9Q6K4+=CEEwwaa6G<83)ErK+ zHtR|JJAm|)=1k>2(bhGS+5pqVrZ~r3y94RzTU3J=qOpHI$Ea&`Oz(-nH15e1i1}Sb zfa%G?WI2~&I%3~UXd=f0oOJ?Vx&Zp}U0(>(xnWG-?#-o`E|9VS)5m-u?Ne^On9o!( zoh4zczjPJTYrRZAkH@RM|CjpIHBOPLolCkV-NA zp0|MNY=O%9ZUo$=^&|uCEYRD@iUn}@t~Uv4*yUSEF`Y&=vZ#+s08A&q^<(h7nLgj> z!+i&ggJP*MDR}J&Tw{2*`xeu>jqtPq>c(t)E#!T;&g^t<_syZtqGeYspqcj;s8n~o zPivnJtxuEn)Y1d%-RI2@Q{H@KN*L=Q%DaVX3|POcQ+MSH<=imV8@#NaYSdl%LW*^a z>{jQ!Jmn2x-3nM=b+M7ux=UX%aRqKQTwML7iud_W!LD+X?t5yJ$p zQHF0JeQ?!qhrzC~&judG;Yp&{m<8kesSEuB)5^A!^}wah1`3oWY3ykKks;0NogifK z=%u8on}^YTq%t1wK?{>gJIjPRA5e+8Pjlg(`O-vwqBN5)bL8_g9acVHvZ`^9FqbT6 zFOZSyV(f^Y;BKO$m@kI2O{B?>UQH&c307K`pPM^x)08^4lLj~X@HCT^US|7^R-elT zvBh-%tZK9=qf8zdZ2w&GZLi&WaXo%B&nW*Oau z#x|6x`M;aUY(KL;-F=Tm5$X(1j6IS||HuB?>_Xe-GRG8t3iOkHmZq-t9G<`3g*|KV zjE;J5RAW)#wa?w?*VHzw`+O^jAL9CNhp~V8#SvM4<%PkjfeRp8RFB5M$_ppy`Oftt zSa?B=BXVR^9FgM#@j|@3W|%X_1)qEiV^w3G+yow@lMDp)1BS8_!IuY;U~JGT5Y~kO zv>rMQC6;DnhiIm< z5+3z@(;OweQ~R2LPK;zy$8nx2>1EurPm!wZfZ86zoV2dA9u3TM4&K)3hTf8QS1qH6 z$b|3B;5GT_0>-T|VB8vLOS2p0F})Lc&(lznl{_A!I!zJ*cM6N~)agVIZ$O)f-k^n2 zfr3$|P6T;4&pW5^#Ugsx7E6;Az>M5PPI~cu6XAW8Fp8CRG0tRJgYjnF%y04^&!P2j zF0~<^;n+$VhO(S!yZ)pZf7ypJ;fO_Nz{sO!^yyJYewNHA!fY6Ky!IvL=0yJgv#lgC z!1dnnEGI4xeO{^Hxh1O0uesS`3_V(fI&rCub=4$U*8!WWO zi+VOsR1XTY0ZkZX1FEMU28OaEewi~Kq=b0>9L$bN`yTs4RSCbxnbJc3;4%XWa-1Io z^_KQwchE#FORd(e(gVCiY=7d37ip|I+e3MP;^NtRdi3zEw_>Ci12l zYe=ug8fqq+XjYSEa`(`cVhuHun`u^)*5Tw!TS*qk`Xw)zxKoFt>uW>5{&!*-Hj_63 zBe4vdN#aoSScc8SFm#1jhHD~Y8Ez$m{_(L4w~{ygSBho0l??bK3E9lnuu=<7!`+)C2I5e=C?^_629Hj~Z1$e4x| z|LZXgw~~)sAM}~H&3#v1U#>R7;Ztx9zbTH_+PMICF4 z(f4lRAogmQqkx%r&})?Si;O~|kSHhf76Ie$VEi78WrO)%(qLT8fxp1>I(cQC9#A^TL zu-bGXrOcy|>$Z{^F64I$!aSy_W-qL?_+>gVM&gnd&>l8yfO**XcrcUWhLbq_RofUN z4g6JCi^qK9E5VHLl|go;j6SoC9$V=X?ASt|faCD}+w|}rdUw;~!PJpAH0ej)(DX_$ zW#kR)3VXwL{m2{GF?$0XtM|)qY^Qu{GmJ5MBtg${1I%B3FW^JvZUrrJ-SWx`O&2GI zINHnQHQGw5JuI)$j|RU z9w!D{IKU!&!aD~rs)2I_>ude{kueYeU%>TnHoU_~fdGWQicn;8mn`u~EK(vte5)9f1Cx=8TnAe|nmJ zE|IgBkV<9Pkmt^z8uwB6ro3y=0-trrTg6ojmvLy}HMmYs`;`;0hYexc_l(LbIgUm0 zO5Fp%UF3Rh{ntOMlhVUmfnl^w&g316eiH z=iEY(gb@Y`PF*^;8Gq%Y-5qMb{tkY{1C3_ali_+Z)}GQ49d^ySU;`c`tQ2W@a} zQd?ByMjZYCe#MMx(G76s2DL>@)4!EGO|5USMTu^dv^nSTbBky_n!0dYjgLF$Xaz0w zS1t6{JUENiiyA=#XKtmM)!9^bSe2u#L#d-;L$;iu>|2LlrYXzdA3cXX=m_M6rLb<0 z!jSVX2CQa*Y_TrbKyLMa@Xsc01~GA2PymQPcfVqx2bR9{eqXdrnR;a%u4Q|AD_tpEhx~Ks|#`M~_9!sD@59RBL%$r)kt1 z7}Z$13RC?C;Pc~ixPI?GJV+yQ{I-s1CFZK}sw~|o;Y zM((mWFLYI7`J#&QY~+5Sj@-|?Q-w!@*IT*#M}n&?sEtRxdj_wmtE@AWRS8*qm8va44mbgNzYHjG zsWZN-f%FX}K<_?3lqzi}w+}ImImT4urefq0jTLI-5_zu^xzLNyqDmh9sH%G_`?izS zLu`F#F+~5l#SBkFCQovL0ymDY}bol5+W_y_1Ao z;3x8gJm3SZT~^c!3fsx&Am!@h-Bp`_)-87w@>;2Y*W~95MSKx(p_7HlQ1^{~t*SSc zK-Q3)lawXm5~URS>^Wx%>U)&aK?htt0#}bX%lMffF&uT4Ni*U6Q76Xb1G&gKm!AXY z-*C>6W-If=dCCHw#syXuiVLY^c#~bU@2Ojk9EEc}Mh3=s!0`4{p2a+8T?Dan4CJ>X{ZsPYf_E^irU9&wFF&h~crrYjq-J zErfB~PWG}m8S1!Vzpvt$=GO%8f6)u5RO#f;k!z#7ROb5zU%{)-pj9@^v6uhWK#qC# z9x`#i{ci);3uVR=CKa2HZQOHsLQOZI^ClIYD}v_L>3nKeipW`$0hg%XFbjyk?W8z> zdn@eyYlbfYwcY_3%cMJv2_U;Be)7N%G688>0fwwUbkl{CAudX0(!cmP0&pR-NH zIB>9rhhiaU7B!ydxHut}pZI5tDwHIz`M9I$&=*>r<_qnt6eYE%Gh41ie$Vti?sheV z<1i<~s3r5E$ci`)0({$cGT=uaQj}M9bPYDEl1Z_?=TnfTpK-il%9Jps5XHwkJt8QQrg;%vZg4W_}`E&B0Y&;?AdPu-`U#;=}ue z6WQ#iQ9g5FMk627KyG$3&I@B08$mA5ldXak>RILPv>W&Yr;)}&ED#FdT!mXxhOyUi zFOkuz$vn>T`#p@4;cV9q;@fan5qIZoJd2oGB9u@acLT|dcv~!u;#(?|LJcYKwitL@ zEREthLzn^Q4Dhy@{7k8gFH?E(S^O**>-T(Y9}#!A%#;Vm@zB6*Fgj7f#qa)udyW&Y zB=ZbEZ@Do?sE*ofV+PH%!D6^>h0)tip7NpZE9!H$ljnVFhPgz}X6RottVx7=oj9j& z<3f14kLo!M;TS^q!#a`*bNKx)8i>=?0T|Lb4cz&^7&yB!Iu;woA&ikS;eT8slYyJg z>R0sI#bCaO`!unAxDT|Qto5-d+{}(L&Y3O2%-PlnQb#Cb zb&PBbJxSvoae|(;Rz~T&0c{HVKb1|~%Q9=yMnL2ypr}Qs%ui$C{P{AC5Q<`XQKp1AHEf7tttU+b2c`jkWX*oLWemd2{D^1 z$hP_+Z#bnZdUM4gkI7pe7aj@i1b*_l-8-SHaH;kS#tB>bh;gs@W>s7_)p@0%!3f~+-Jo(x&5*jKD( zDx~LG(JFW|tuy*p8m6%fbt+`7DKhyzkcwu=Gtf6`bA}~rg&;MB0u%Le$XU|4Ql(ri zgFIzFhgHWp@-;A3Qeos#ojtlzCX2UkuXwuEP6F z2`M@-QOf|&ENC@n;FlZbGx9t@-Ui6a0NshMHVQgSE>Am6>FTxYT5Yks82ymeQR@}J z9R|Ahb`MPKCvQO6>7D87Qr1sfBA*Q{I=4hW8CrVoIyFtHHZHfPX{DZ_fpqnHcD=St zUIqvk+r`2g822Ke5~M+ZG$=8ZLrMpvAF)*JCYkoB$<=C=ww|q%*Q@JL;FiEw z4IkGMZfaPKx`A!bHp&~h23WPRBBHHM^-gxDwn^TEb}dF*vChKk>L=_c+E3-5B5e+D ztEm@6Fb~olS9LRJ^k?#B(CA(AU7*pseRr$zN*rkPVl$n3nKb%p!#ylc-2xi@xqL6X z7c}|{`4@m$*%@cisBr!)o}cNzq!Y~Z_bb0tw}BR&=TC+*k&}7;LAD*V=sy3Tx*h3m zq~{|&|NJ9t2ht19?@%AsA5|U&jqYxx_ie@d!Zi9bEef}1K@Rc@`M*D-Z`X|P6%4%(w)W=z@wv$dH&+i0{E5-n=#&--i}80rlL#JKv)?awH~B zxCc*IR-0&@7v}il%a`pQQu?UfVf-%~N#JK8&TXRI6>dUiUErsv#{YXYS4Bi0GZMkA&(R+9iv0=)PJ zK{I0+p=X_tnxb3{(!Tip8x1?sT#(SHwPu`Z#^dh?9TJbzF41$&3_QT~Tj>E>edh4L zPX0HV|D}4Z9rUJ+#$ocZiLkjNAt0(&y7lE_Ee*6nNNkjMhOA-YYhU|!wQ-{L;-e0s zf&oXW9iL1$ys8q>j zJ4uIWwJ;*~R5*PxPp456)uZbbsRg#t*w)c&VYtV_9_WZDxvEkaI@FV$7sdB3O>L`< zkQrm}eL{pBIPN=gpr?-qkz@DK&G1J;lM5dSO=?PlJoZRvVm9qrfDZZndAcDU`*@7P z?aIngzG|bRg+@tNOFU5~Y0~gtsgSU__K_vs(W#~>-KBs>ra-z&Z-@mgjH5l#hV*@) z%?^^s=^&2>8zJ3{EutCdk!W)E?IJxHJ^@)SlLUo*PxMZaU7tRUo}+8&Z2xHVe5?v`Wr(Rra3vhfjy2G@Fm^=S*+^9;Dp( zAp*C?399`bMEmz3Mz$cAmlytj&`48TFO4*{{m(RVs4bF44z>Mf8p&?{VH!zm{yvSw zH~%n=ywdi48u_TXmqt!En>6xmGtr39@?9E%oYX@j8{7VGX{3to3mL5HwuyGbLx zcyjgN$Z1$d{m9&aBVPq!vv~hF6HeU90(7Z*GtPN{0 zHL`~_grxve|IV~XQe~8NM(*5^Pw`ASQ?0^mU*e61d>IqQHPQ+?Nxn3(B;=Q!BB*XA zWDhWRAGv2C(haq9$Y~Lf?c5Jbj+_H1mpe=;#m>Dr4UvZ+?P7;mNV|`;?`Yy~fL5|x ztSlni@TUkrOZj@urf%XZd79O4b|$cxfO(#Dvs28bRnoAAD&v(-6WceV4{z@AEixiP zlacy$Brr(t9Rxf-@PLWym-*~y+5#gDG*b)h%Rsg~Sjp!1G)=#i8;yMQ?<-b`1j zjFlbfsO#;>0fwrK!p;mW4R7qHr9o~Knja2i<4u89^Sz@RviaS$jmAfo)jn@!3RW!1 zy3Ip29!hdj{Vuw{hPrAStxMhL+tK^-NA&&s;I7I^N%k6Q1Ep!aW zIIl8}cSxM#Vzn5+Rypi}0k=AeWuWdzneP~*ZnR=Y-H+O%QTKfNNKiwSvA@I4t-gbc zqVC<+I>E&9{GM5LhUIr?CdX_{hj3&u@S1Z;5`Ki|$~Thm=IfHMXPb%ZV;HxpC3Bbi z=)~`F{7U$$c1tqzRJxQb$V1bC=`F2E+?N^oFauZ92Py;AM6~efh!uBYnDWtP9V_kx zjGM#=if4Sq-Mfl^0W0p3hFlZ>wCm1q?>PCWxx3Fwo;>&rmxlw!x}KGMKI8q2w3QJn zdC0)QMFR2W8l%y|PzEd6M|T%cE&0PK`tRE88Q_2gb6oTA^GBm{Z%s=L1Eo zNE;`QLt0_GSV(sJCa?+C`M^Xrk^30jXk2VD`A`}oDgLM%RI4ZZi+$wdvzYwk>9m@P z#v8wEivg@q+hlE$PS|~%OH6c9WoM>`n2pA%7ISPLb*8Wk{1x(Z-x?SoA0s6g+3&S4 z=5gA60;G0YwY=OdBt_AFSis~D8;$1xqsr*wD{MQsVU_U$;=>V}%BE`5sb>y&zbrX z6`;R#_0F!tSHO$f)_~p$k4wU^`@ZilC|aT0y1jO;&AsjIWwqRne5_jPj+KSYWILQJ zhnuHQ+xd=d3QsA_cYJ7C6`#WW%ks2h%FPK-{Fa{lRXzF3c)pA0m-ggW_T*3I`Q`}w z;TFtB-4v%F_O>FirxkHMtw0&KR8D1vTWv|~X-iyBTY5{SS}jWKX;EBHi+W3$?V|U` zVD+-ZZTD?oy7EG=Mj69wEpe}BWnN(U5xoz3 zx6dZJO|bM468MgKf>Y%3e>A9a4d1njRlIC7D<8m~lJe_NF+0rYFvSgU5xL$Jq?2$(uwzyLd0SINzO%HNXA~ zhwzxGS0~44v_C)?iPhq~qKEEWm3m6O!iZ=e`kdwPeXSn+X!at~Y!!2oq;B!fYsre>R*agX_{wwh**rzO zShQ`P_HlD^*Fa~S@M7!%#~Y3>9G4uTGv0ZlTI>B0`;oewEmx(&o7v6i_dj%C9>`Bc z>*uR0*a}d4ymztp<4|bE&np&o*_={k|H^BWTPv^etFy(fsKdKLw~3}M&)NH_&X3uT zd+HpIs52LJ=AsVy`jje`vH7a-RoVuR?9pzKZ_#g6ZdI?wT(%-&oqn}?8@o-T`x;fo z;+7Kc9LNnCOhy=CqL9FbDKJM_q>bX6)Paeu5fbN%uLtve&=bw_2SoSAwbv zBOuSFyB*qEc`cyi0rD(Bo~>4~Dy^DMEsQJH*8_JCdVePWOxrAP)}*4l;Y|=UZ$1;U-Q*pv0w2wr+9OR5GL8|z1>XM&bDh0 z$`5J}$qymdRrIj@u(m_qp*p0w1aYRav2rHfb(P8((`4B^2_dLHnV)=UJLR3)b{t=Es*e#l&s z$HD1_&P1MKPpQ9UzooMd)n52J_B)av+n;7nt9#jAb#M2UM69{bH?V!`+0gFuq%XEC zw8i-(dlEFW8PrrO>}UHyO`F@yyjtgOwi|hMPWqMu_@X-D8Fm1*51fAv(&WMO&mn&B zd?TZik4BZ`yTj*cJy)?MVeW8~cxWf$+fZJOM_a+-fCRu5DC zYmN6hmw{quhw7cn@XQWv!YcI-kS>4E{(v@b5)aCMWCzthYJX;blK%ubc*cjs@&2TW z`I8a*v-%hI7xfT3gg$;=exCR76yC?rqmN%iFTL2)#}s=Jef*;O0`KGJ)x+#?L?1t| zzQkTaUp|jMejecqsQrRE1$~US75|AHyHFaSHB%cfYE>!qNjr)h6UNsmIu{@cZAQ->gKd~eD_GRd!*`XTrR}Dgy^Vz?#zo~DqH`M=T|E->2CxHKx>?Gm8?M?Qk z`gits^raX0ulVE?dka`A`NYJr*ZDeo9XMVI99Ic%v$ui&l@|W1oX6R5I0mwxgd$NADvES$e(;(U%oIG>YAIIqYjoNu~qGH^cGKM6RW1e~Ag zn6JLi-jCoor+ugW|MdOS|AFrV|A*i>Rj-~5)x3H}o#>k&k5|?jwH>`2XQFzRoz*^) zKT_8kn>uQ}YVY8z|o;RT+_y&R_y9H$WP zDpEUGht?@~YF%;{huST7YZv8<+86Q{+L!W||3{9qu64c|Vj-)&@m721tN&vEis-#> zeBbyl`!4(c?fbX?TjJN~z00p&QOEko^ZQ!kytR&{UCps7BwG8~kdOw6DD7;>ZeMG> zjrD8+>ldIr33(FooXB$`?-LnqcZ@ok_w31# z8!7HIv$gkFt=<0#|3h=AIK09;+Xw)NszVW-lzASVDpAkJMk&l#ol-Pq=@jA5oIzB6& z49&y$%>&Fu2p6SEMWAQImZpv3Gvta^njuH=8S)=|hCCU%0g!G;`!40|!CSq^@d8#A zAXFi&L0FSU_&yohg!m?;ZAQ2m;TD8j5Y{5BP3xtqk({bxTIo&O0dIR+n6jjae3s#q zH3F110)0IarR>qbUO!;0A25c{iO|{4e5(s_7t+!YrXkEkn2FGh(A_Ugb&v%EeW_01 zR5zi8T9F6%dHu}qEwH|q`cEvpj+x(GfD#4Kz#PKDXc4_S0q`gEBQBiJ$V(=EMVBCb zdNjqSM-wlOITemm`WHM7Y)20WnB{?Mz$=M1Ib-~(aB2loE24>FCPcULG>R8<$i>n5 z;E}EiCPi&V$<3&-4dFI~+YxR@xC7yiXz<1mLySdNp}$Xt>JYC(u8L5N-rHRPKDqm| zlc9S2-i@dJGm{@yfSPLYyEb}us08#j2R*O{zxPBh3zb+ra}LUELE09SX>gjobO10L z5H=wF0G!UFn%Ax@59l=Q4f9AcNSfmKpb_^K;o#2MiWPU?6%?H zsKfokz)^>RqmFA^1`3}YYQ(J2h;TY)(UYNL(E|Q9;T^}&hUpkZCqM(o@%sdxmh~ zIgXnF<5LUA0mRz?udNS`DYXl!T^z3gj^hB2f65_$8a)&^=Itv+tE2Z_@C3~E(u{oL znQ)801dJ~ch7g8$i-mOXyL6hL^Q;yNG1M|ChT>98Nl%L@PU&CpIL27akN}kiKjm$> z47ko1jI$W4%q`7#SoxjN*lNbJiLi&Q;d^VpBd=&$4#Rv~L zO$yFL%}l&C4`Cj{e1!Q33lJ8>5Cs<^Rv1%dJl%}(fcOOD79%W<+1p(R3NHB^qYJ-F z@J#>Qq|QQ6XEuIk$IK2DfI24-$Hec7m}Q{?i-IShj2mfglsSkp2T*1nU>-y`2kGSZe$Xl$*}lag zY`Q23<#Rp};AtUW`tW1Zb|Ru#AJ!P#whEgH*EvFZRuf7{OOcl zPMi%+oDEK#gHnf3>JT6u2BgCXn-DfxZ#{VQ+&QIpr7{>RmBDDa(6uCD zef|6U%z7cz3-#1%D(^uUJ3FlkXM1c?R=H&=BF}CvHqSBvHk`nqSPFe zo`-PWWKiN{&|ob2v4H#+@zw!=ycCd^qU;SQdjlZfgtzv`TPbfj@|GjdgFFxN=JB_h zUUX<}o&_9CvexFHE|gvw3#vj`6-%6DGk$GC-A%E3yYsh@Qb13 zc7)pju?Zu!iRPGC;`@7$+JI+I#?@uBLtlcggxt#zlFj{WaGDTGXN$8#ZSL8jF8pr8 z)8)2#Z9y@a-jIzNmyvcE;bD|LB+L$ditsSPW~6_Lrx|t6AU^=e6rM)fX(!pF3n1rR zq`vDW4k>g!#O0^ip;IVv%H1oqf>TZcpPU5#4D1QOq8*_fp@dNS8#wLXz-ePMedN<( zt#NO2FJ3c&I~Tsth2BX+Z>0fu>zZr5{UF6sUMBJ~k>^I98+o2);<(vJ%|@@~AmryVT!N`DVyo_-07R7A)Dk#@O9P!?g&{e4ICnk?+BPMKSjw;0n=3^daitK;y-}2fHiW%v;CrIKHK*r-Z^h5@y_RO zO9k&t^{0S$rhs=&Z>Be&LESUyk^Q+H{ka|exdY)2gbX1=SckCgHPF^;kZ@v>eJ(jk zS%Z~#Z+|8OUOnK|gEQ?0XWAXJ#(1r>)|-g_q`W=I+k?CYSj(rPic?(TMp|EW*E4$_x-P}-CJ-8BzJFw$@6^Tl%} zf)7jtA3!({;Ua{K5H3Zy6mr!Kkg0BnPVhNp2flbk#1|*f=!b-`98!=65{)N%jj;e< z9FH%iyp_mXi99dzyvQrzUtERMD$MLP2y3Fv6GU(T{Myv-lGmv^taVU6Qt~a?`DW`2 zGSBgK5OT7uoFDaB2Ym{u|5L1c+7PzciMxdG>r1Q?zO?V{o(Enapgosq?FJZ^`5I^* zctICZx=^wiVKY`b$9lNSF{B(r&IyDk?8IG8l7TB4>~rz;lK}Tm*=x z@aq&x9!Gc_5Kmz2pCC!rPTZvdsR!^hq+MNxxew(I0^%V%ahIh|;2yA-0(KK%A4a(* zJcrYIxyw?#p%H0~fP5T~j{$NW>KsSNkY0y}p>91OtAI@5ZlvwDlcb>{XAe^Mq!D)+ zeTqgGLD+#3JM7^R`;C{+riCXg>N023<9v0s4JEgweRo}BLRpEtm3DKCF1LEogEWu5 zcZ?|+>%yDbS-VwYG%pd&OGKkYH0NVe0r5WXt6qBJq1N#czy91> zfM2ZL=2+6^8bv7wTZaVbyWYi^eb*YZ=^UzqL$w2{-FolW>}%`22@x%eLWwB;-T{65 z_n2Pcd@Kq7g{SPiB>WlS zmq@$qf+Xz1bEZWSe*dW?1o6zp?`J-jgwJp5tNR9Cvyp6niSim_SceT?_jpUM)xiH( zPlsxZS6cd>4n6x-`aSWLZ&(@~JAKLWL;F(Xp|Y5hCkr`4Ka4nB%60uOx@6R^h%y81Z#y_fo@8!G5*|^@KyA^;1+?0_KlIn+|kNdeT+ZVGupqz z^Q-+u%ENe1Q=mvK^pEq6^G{?CH%wsTeG}CQ{z<+`e!888QK8frwJmX~y>PrXS)Q!b z827fss>O`!SE%$$@NU~TO_sE&aMnXZ?!GNoLd#f01nWtLvypRH8-X8R#4pEos| z$l}$j2q8(Fdli!Ty}aL~@u{8)zt8h?t|2FlD+xJA?bv_4a=pGxS*H7*xzTrna-)8O z|3}JAz8~o~`Iq~a`&TG8`&Q^T`^mais>i37C}sK@WsUApJo+ulEqdKExA|^WZqsk| z->$6m-L9|nukx+(dzCwUUi}U_WkRhw{VJtIzsk>)$9&hYYgD#>o-$8Q@jj|Nsw>L1 zOxeF!S*$NnmLP4Z^4R|ClU*CbAZ#3tekMB7fU1Jf_ZX0&zdI;#XYnE}aS4{Y?EyuE_+h0=Q|c zAE@87$0V{Er0#DP0iSLpXLD^9(!G-g));%5(=_rtI6%$PP62PUlHVK{D7)Dpb)bg% zIzYGU$aY;eY1M)5ZVmQot?wkOlAN=o-%|^&vN^?`3TQLKXwRrHAuon z#Mj{Q-Ws-{@juzRqSO4awX5&vn%02G7EtN;ZDK{}$68#d+i5eoP>nI6nYd7KgzeJE zliwPn5IJj%i>>zWXw5qdsSK5{HJcnnVD=t8&AOgDsHxsmAHU<-?TnIqkXV{xn1}0~ zMfqwBsX1jI>BUCTy$Y3VHGSI|L-#B6WF=X*`5|v9Vy;7R>WNCCPBzKc7zbL(idw2J zbN#clM(X3&T7@HbujqSMnA=_@Pbj|i#s{6z7FUS^&DqsC9;uS<32*svukDg3YaH4< zW{<7-ahP|Ty-jzIqtp^F-9Dy1USmkXaIf^$Gm1s27%f`wy*;|d2(^k#`hgx^Zz!EV z-1qB^hdQb6C-A=iAMzV&uX_jzI+={m%Q z_7#v-f@GGgrzk0Us*x%`tdmjzSyRIc#6Kmpo^q$ukJ6gm-OCMHsvK4_ux_=KCQGnsd zwlgU(SQQIN13IZNyDLdBZ#9d>4i?{YD}Rk~cZ)+4i|EE_o;pMu&W6cC_E3KNei+@p zM~Uq%WW_k1EOE0@Dp}kpV03oj1a{}PL}^<+4!kE`8zYZqW9U3Hu%Js!q5w%heX(5vCU!s{|_2dd67qfD~-tGjO zz-?l!G0IwFEPgZ5(!`w9cnTw-q(xuu5VC&sef_uCP+S37-Rh;vD1KW)WQl=TH6s+~ zCfI8YS1?9<fXun>DeadkPZ6H>3E-{XXW8HAiYb zr?3<)RZc~(9%>G2K8J6ntTCQz?$vyDumsgXRzLnpT;8FTW@X@Q@nqMq!wzgGpg+lX z1=p0<`z!sq?R-#0bMMW>sIX2cU~j_OKAqbFLXW!9qv9H)z9n6a(ultgREfJ2C7C!| z(M6S)9FF8TT+#f*O%CDu8^iWXc2=9cje;rAnx z-E-vGav5ni9>x0Z+*OS9N9Jnt4b7SS6w9&g%7wY=Y;7r9A}>|1W7pBmVs#l?rrjXlpiKh}tv23_ zc*8WhXRO^M-vnr{U|l?wB?P9aKVm=9mdneLMmqqc)3buDP^U7oF7spdV|9sEviylaPH~$_UE=O&-c5mP+%uNf#Ir-1G9|9+qH8{`^ggI@EU@(;+rR36ZNsc%I2BYnzm zmw%;f*MIe$@(;-mDi3K7>bWT2w|{oX4=X$Lhrd()QTY+&QSA|34B46<3lKK4^BwQd zJ+R??Pq_RPoldx%zsR47)XAYlr;wikYBwQ2CO@Xl(YI$#4!Nd(9IDT}t0FdcvYcEw zSzl}92j^%pMRVjyEZb_wujOC!(tzilf3az!Ehy*u{xCWB)-QgOv!*iH^Ks|~KuE}) z2nZ7aAqEhffG~kHh5|&l8dGIW4c{%UXZ6}Hd6zbx)9uCx?SS#5DWm;H{tak!m8Bgp zK73yoY0Epr!my@{sU1N2GAiiyDoyNOV4LG7tL@-{N1s-H=X+ZJo&VHQT1A=Pu~(j> z9sNq!;2hEKG^I7LhVVIj_kyT>zI}ekN=Iq+T7=bW5$&>PlMdOe^Lx9qg}<<Id3uy`%8W1!@y((vHeUk@jA@SojKiMSYdMs*XZy zMybz(1JWMwG5MJGSNX5{Yszc-Nbs2v;4^PTKpvs~jr~nKE*}S!m)lFc`QS4n)YsYT z+8gp4NIS^2>&c^PzKStl^l@lQ`dt+x_2JzAXMNK!`IgFIz~`XWp(x|ZUTt(>1u3Ej zl9Fd@d%G9e@)&t~-4R%Cqy)+OL`lr%iW3Yu0@r2Hg`D+Fh|)ZbR$vh>v7 z!mR%myLf?iekz3b*vFyc(VHv&!QNBNZK>6T% zZ#=D?l}&w=)!=kz@Wu~O_e1NAXVed^H-3mWerUb1SO_qph>ux7{a8EC&dKN1bJ{2J zC)%g-r`l)oXZq*L=Xy5!W-u^fi@?ZW^#Z$~HOtL-+t+Qi-a)|iV6}yDO%AU?HlV$EJMA!h9CF)f zk6{Slz1h)qZWgPMM+NBbApSR<|4rn7WB6ad5>^`(?IsRZbN}mv|JBA+9$SPM*&W!0 zx0w4V1p8^OWlQ*4Z47IF{#=+t-uRX|r+&-+Eq|+CVOP}N6ZiuN54dNC8r;k9WO6<= zs4emYgLG1sh4!G#Zj{;WTx}!*pBelF!_tRCo{Bsbc>?fCx_Ha*kd7y5&5?Dp43ypB zB<;_C{{Ro09okkfJG6cJGK9+zn!Jo;3_xR7jMrZ@?<~0AB0X2|_fy2xW`}A4vDV$o z*=C2f0LGT-VeXa=?v~E?=7ycy+r3;MeYB{Y*`ZBtl4^c}HrL?2Rd{FB^nT!RX}(lB z1zc-eFb(~=J-7@dGeSQpNC94JoBOHHuvBfo{EU7;IiNqQJnMhX_nex{%lA@fvie`_ zzqCfV5fG|^wO$t}KUw`f`@QxD`433DH7FMTk^NCU$PTKehpGLX%Pkj~%=JEXMNuq^ zVynqMf5hFSunmmW#=KzoZqiQ1wL+0r7VN#7G?!Zxxl_JV-=u8Pf1>=v|5M*jx%WPY z5)Zfq5pW&q&luOfCC-2r$Dzdz^)7aocDH;t($dl5pR=EK zFO*;SYkjrcBULPVLWqDHt8Qgmwfp4z0OQM6tXk3DSoMB(zqU=@hP2jJYOiU5QbHey z#impqwRzmtcU2^*PTkJEhp#afcSc!!Ik(;9%ZbV4p?z<+*M^>pqWy*}t~*;ry#VqH)g;f58@uif(QV)tE`)8H4U1^WC}oD#lIds( zSwx)9Tk`iiqtKElzYQ(1p(U4F61aE!6iAUNzLD|>Wu!Jj9}TIK-`zt_zMQWQmxpU9 z{{9sM6}LQ4bL)fULCRolkS=rk{4|dZ(!?o)=%N6kM@6b%RB_sZq zG;_Y$!70N9nsNEaA{u$WF=@ukp&Pe!!_x(t8K7jz10Y?H??IxSFwG29-Jlt_MKknk zFdHQI(hl8~HfbgstNFYhnxPw{!scwy%s`cPoj%~!UCEO}FU@55GW_I=?1yP)v_&&x zIL)kS7LMEmx;WAVegm4hAJ5fCC1DI`rVH_^s~rOUqrIF*8_U~VqimJ2?2&f6BUaso zzmK#_j$L>jX^%%3?`Z63a{Q(}Wx&CXQb%`(>yk|oS<1U)=~`41Sc26`XT;ftpcxcuv746gJKhzE#SyDbpXWTbmj{0 zz34egj+y`nPekl4B=p>C_ZmuPiPwo4EFpZ$7iru1{)K7(oX!OLX(d^iz(MBQv=7ry z%hcm5QnJ=olDD~6LlVDt*Wcsf-W|y!SUlDp@u0hH&GaqS4Po-VrpBQqH+4qd>$R+O z;;m(!;d{Md>zrPrxKk_~%|@$Z*cj_xFWCp6{Xy{ZicBp7y|~V(Z_CvB>B$x3?Z~AU zDTOlK3qBh<9yl2~5jcw{meo|o;N9*B9fU$PMw^H=?nHHhK8a0IqZO|qbVh5Xp2Ps< z70Z)Zu{v2_EKFfjR6BCJI!rrRd?tz54TCH}UM4JRoo1b7xYX&OS1)Nlz*bX_IT zjm47ItuB$p1u{Ze&MP@NmxM0lx}_3x7c!Q-Dq;K~*KPXIt*tSwZ_~`_B(F;qrWFx! zv!o~2Kw{aP!0kWfqRj_qn{9s6vOBQ!e5Boh3Fp$~eoDo@O!+bJoeU*>-!BEdo$Moy zMmN;Sf~?o5>~H~}b34d_EcHq6J$|oozB65)-H@oQGdhB#6*Swj7@eh&pGo30WHpxT zHdqvG?v(1zVx~xd!KVlVYQ)jRl+Dv&SjsNyquYjJisaLV9v=X_5#(%q5 zSjtM(GFGOVv{BB=^%PYEhH`bgz&-WLP<{JL!b z=c}>!{*sQE9@_|%GZ>@NT+N#pp*hdQ$RJ>35HOO4at-atELAmaCeS{1*#BfSFyJ*l zidgMOlNAw?t5EB0toH4osAz8g8?qbHj`P)i*k@^)maMw;`!gMuhg-C$ovg_8S~E3m zC(x;_*Vx|{iRZ9QW8fdFTan{AY)Qdu)U}a4(jt{kR7`F`c1&Hm19?;1!xrp!Iy3M9 z;#<)H^Me@C|JzGC+#qQ??^B+CJNP3w&JTAbkfuz#X5K_-uF zlaxu{>#Yf-uc1wqrvlpD!D95*WYnB&^%iDBtG6bjwrgyNG^?M(tw*`*k_e`x^F4rpL3Y!0eWz6(TP-?xe zOf9wESE>?6GT-Mla@%I%Z+6=?`0H+)gTGmA{d>4k1-MZ*=x{N(2HDO}$}E$i`gZpfNt-8Q4+@gQWD;IUJ^>K`XL(`+n@nCPQmnJ|cu%tFld6bp5tQ=V|1o+LKf~;` z#Np+345L)Ch)n19QIJ5Znu)ip?>hDGVR%n=$q(^UPqPhuy{GlNR=%V{0l7Cc_u7pL z*ORPvMOBuEq*3IFi{Q)woON6if*>hZ{m{Eo_`BBiyes_Gq%#z&kWI^2lg@jk9fjs9 zTQJ75NNLjr|2iYHIo`TQPrfo=>G756w|r%mK29qUtaW{Z!+cxMRdTuAqLZN;0C{O3 ztuA$E3Seio_Kv3%vTj3b6|^$3wZxl@@stuVcI|v8$F#;f09;^z<@+>)zN$SVJfigx z$_Uj3*ljJnQo4&qH`%p8*+7dar6+MI-L%0g7IVw^kgVN++SK*iTGF+ry8ydt=?#|5 z!L8vW0`|)-kvnF+eBkMpS}#^9fy4+tP~XyP4aeL!BWpPQAyEw?NuFg|+B^O6TdEjH zw*F4jimtyl08%u#_}kQ$ft1I>rLgv^$kd%&X7d`Kb~;#ZeK&Z_2c2$So49R;K3SP0 zPlg12HWUC4{}l7!r-1;5KzYA-aCI*KN8AvY1U@xQp30`FQ+4v3Az>z-*&=ZnobqPM zGuTXZ24rwZCu%Hm$F#(98N5IG&XmFXK?d(9g3Gm{)dA{LxBhVEfUK~0zpBb(psc4n zLhh}eW8gU%oaWAwKSr!mvMQtfkWYfW^H`}hk7cN3mOoK1Sr|AnZ-ztocB(_T-_qux zdrzWlKSP|gq)Y&AZI-kY_QD%pea2z+8RLlK9_AfBhZZeIYfhioT@tkm=_}e?|4pO2 zf29rU$~!Boji)=nOCr{u(SGteb|4t#j9edw*P5n}E_##Y)AT!jy2$s`BkgHe>!xAN zn}sk7p&OywTKoR2XYEVAOKqpb_h?Tc?0ISv-&6QxNs`>ZGRdE)WK|}j#||}{@CE_S zAcWbD9Nr^N^athqzN5rJZ_QLo-I?;}9Kso;{|V{*O>faIJmryJv`n?kovDn;wOKJr z>Cado11sc`tmJ(0LuwIurdom)E#WQtYDofGl;C%wMNYJ+rdi0&V?#jQ^q$p~TiXRk z-o7FGs||Zco(dRe2nN|6n*|uNIE*Vx9Dw2Q#{)(@U@T}}-xVdKvZU-3*7x00QEw{h zP384s`e+?{jd9Ip>2#|!c_%4C=^|b__O@8kk@Ux)bPP&oS*0_q(j!oM1WJ$KrKQ`V zQ99ahM`=4s+nY1F_hMRaCppR94cZu0ZS1zre%zM*xS?d{hWm(&QpqFM9mcy@dE&pd zA2A8EyS7mh?mQ$3O?dwKUy^X{FOpD>_)f%kAwC`Pn-RYq@nXcsB0d@MVTg-}$00r! z@ycR{VA(ZEdcN`3?KX$W*_T^#d2t=-0`^zJbQY!)lisfFp|?yQdDkWHDPgJ$dl#F} z`(o;ne&~yS{xtMOn*R>t-cEYgp8$nwi)X1uIck)nMmeuBZAs*9jXR8$yaw&j6f{&D z&URW=_SXyj`Mx6m2;VsWNZ)w>C|`m9EcXO-sA+6{o{zl6pA4x@!|Ns>{atX8(}BtL z*_M~k?SUb6`AFZ>MEXpl>hpFDed26Ltvws6humMg`)p`iV=`6&E;d9>V%|#fJVO?k zkKgK2x8Hg+l-GDPl)d|C$jy$1GHVyyl5ooj4|zp3C9q^QL8~@iZcDbfQ8Bm??bc6e ze5qMT>H=0p?F@OArVF+W+&^%61O={>nzMokVgSN!@qZQ)wcNi-=OqgZv z6#tD`cG{2CqvT}1s;X`4eJ{00#M>4HQaS9QAD9;Tb9j4`wbCr|7G&c#lCc^>P2ytd zDr)1etuR?%TqXjps8<_H`S+yY`y~Da!ysdrCora8yOcn>y45Wfrs(2S(;p;OUw}9! zr?e)8YfDinDqZSMmv86qN!G+E)kb5`JcG=%<|*OG+5?hMc32V~##4%TCcN;B6;y0#{PDK z)_0sfh8mBd#$&w3Jwy7^6KkKCJ%E*59AA>f7JmI^;orZ$Qq!L;{Ib@S!N|WM!CTzs z8W6|j;A*2dm_`&#r!ooTBlKiwULZwT|Ha^IT`ZaVnx%bv)0<9g=x7_+>RZ^_RAWhJ zda~bJiT4!YJsU*NRPcuMAl3*vu>4hRYKpoWEg?Tslp_UATdwBGfg~qdCkLmxMPXr= zV54)WVzO>3$1q9Zp49j$!Yj_HSQAaxuNF#MPu(fzl(v=#*A60$n@Rh~-gY#ok@EL1MTQ6U8PH+hG_e(;>K}mS(50Wqd@f5`Ecvw;I z{PTX}&)2>WuJwMXAaHoiJ!@vJc|YW?eLs}R-Vdeiem~@D9K=H2f$WgijqyGJJ(2}k zzCZh^)q?BE^YrhrMtE|dx&$1&X7|a^oF}i{xd^;)`qq=7VmehiIv?D>;N0B0LH-;c zSzDc_EhT%cZ+)Nt{kuF9l%46%0A*)@vh&*Jsf&m|@v=9g?9C{9GcWsXc{<9b`}?76 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 z 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 z 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

_x$+l{{cH8$W#CT diff --git a/packages/android/gradle/wrapper/gradle-wrapper.properties b/packages/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3705bc5..0000000 --- a/packages/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Jul 18 09:57:38 PDT 2018 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/packages/android/gradlew b/packages/android/gradlew deleted file mode 100755 index cccdd3d..0000000 --- a/packages/android/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/packages/android/gradlew.bat b/packages/android/gradlew.bat deleted file mode 100644 index e95643d..0000000 --- a/packages/android/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/packages/android/settings.gradle b/packages/android/settings.gradle deleted file mode 100644 index e7b4def..0000000 --- a/packages/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/packages/clean.bat b/packages/clean.bat deleted file mode 100644 index 6e337a8..0000000 --- a/packages/clean.bat +++ /dev/null @@ -1,4 +0,0 @@ -rd /S /Q bin -rd /S /Q build -rd /S /Q WinBuild32 -rd /S /Q WinBuild64 \ No newline at end of file diff --git a/packages/clean.sh b/packages/clean.sh deleted file mode 100755 index 65e8421..0000000 --- a/packages/clean.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -rm -rf bin build products tmp -rm -f *.o *.s *.exp *.lib .depend* *.core core -rm -rf .depend -find . -type f \( -name '*.o' -o -name '*.o.d' -o -name \ - '*.out' -o -name '*.log' -o -name '*.dSYM' -o -name '*.class' \) -delete diff --git a/packages/dist.bat b/packages/dist.bat deleted file mode 100644 index b82f883..0000000 --- a/packages/dist.bat +++ /dev/null @@ -1,88 +0,0 @@ -REM Build all target configurations and copy results into "prebuilt" - -set PrebuiltDebugWin32Dir=staging\debug\win32 -set PrebuiltDebugWin64Dir=staging\debug\win64 -set PrebuiltReleaseWin32Dir=staging\release\win32 -set PrebuiltReleaseWin64Dir=staging\release\win64 - -mkdir %PrebuiltDebugWin32Dir% -mkdir %PrebuiltDebugWin64Dir% -mkdir %PrebuiltReleaseWin32Dir% -mkdir %PrebuiltReleaseWin64Dir% - -set DebugWinBuildDir=bin\lib\Debug -set ReleaseWinBuildDir=bin\lib\Release - -mkdir WinBuild32 & pushd WinBuild32 -cmake -G "Visual Studio 15 2017" ../ -popd -mkdir WinBuild64 & pushd WinBuild64 -cmake -G "Visual Studio 15 2017 Win64" ../ -popd - -cmake --build WinBuild32 --config Release -cmake --build WinBuild32 --config Debug - -copy %DebugWinBuildDir%\zt-static.lib %PrebuiltDebugWin32Dir%\zt.lib -copy %DebugWinBuildDir%\zt-shared.dll %PrebuiltDebugWin32Dir%\zt.dll -copy %ReleaseWinBuildDir%\zt-static.lib %PrebuiltReleaseWin32Dir%\zt.lib -copy %ReleaseWinBuildDir%\zt-shared.dll %PrebuiltReleaseWin32Dir%\zt.dll - -cmake --build WinBuild64 --config Release -cmake --build WinBuild64 --config Debug - -copy %DebugWinBuildDir%\zt-static.lib %PrebuiltDebugWin64Dir%\zt.lib -copy %DebugWinBuildDir%\zt-shared.dll %PrebuiltDebugWin64Dir%\zt.dll -copy %ReleaseWinBuildDir%\zt-static.lib %PrebuiltReleaseWin64Dir%\zt.lib -copy %ReleaseWinBuildDir%\zt-shared.dll %PrebuiltReleaseWin64Dir%\zt.dll - -rd /S /Q bin - -# Build with JNI - -mkdir WinBuild32 & pushd WinBuild32 -cmake -D JNI:BOOL=ON -G "Visual Studio 15 2017" ../ -popd -mkdir WinBuild64 & pushd WinBuild64 -cmake -D JNI:BOOL=ON -G "Visual Studio 15 2017 Win64" ../ -popd - -cmake --build WinBuild32 --config Release -cmake --build WinBuild32 --config Debug - -REM Build JAR file -REM release variant -cd packages\java -del com/zerotier/libzt/*.class -move ..\..\%ReleaseWinBuildDir%\zt-shared.dll zt.dll -javac com/zerotier/libzt/*.java -jar cf zt.jar zt.dll com/zerotier/libzt/*.class -move zt.jar ..\..\%PrebuiltReleaseWin32Dir% -REM debug variant -del com/zerotier/libzt/*.class -move ..\..\%DebugWinBuildDir%\zt-shared.dll zt.dll -javac com/zerotier/libzt/*.java -jar cf zt.jar zt.dll com/zerotier/libzt/*.class -move zt.jar ..\..\%PrebuiltDebugWin32Dir% -popd -popd - -cmake --build WinBuild64 --config Release -cmake --build WinBuild64 --config Debug - -REM Build JAR file -REM release variant -cd packages\java -del com/zerotier/libzt/*.class -move ..\..\%ReleaseWinBuildDir%\zt-shared.dll zt.dll -javac com/zerotier/libzt/*.java -jar cf zt.jar zt.dll com/zerotier/libzt/*.class -move zt.jar ..\..\%PrebuiltReleaseWin64Dir% -REM debug variant -del com/zerotier/libzt/*.class -move ..\..\%DebugWinBuildDir%\zt-shared.dll zt.dll -javac com/zerotier/libzt/*.java -jar cf zt.jar zt.dll com/zerotier/libzt/*.class -move zt.jar ..\..\%PrebuiltDebugWin64Dir% -popd -popd \ No newline at end of file diff --git a/packages/dist.sh b/packages/dist.sh deleted file mode 100755 index 1afb6ec..0000000 --- a/packages/dist.sh +++ /dev/null @@ -1,184 +0,0 @@ -#!/bin/bash - -# Call this script from the root project directory via `make dist` -# - submodules will be recursively initialized and updated -# - patches will be applied to submodules if needed -# - this script will call CMake to generate library-building packages if necessary -# - once projects have been generated, this script will use their tooling to build the libraries/packages -# - when all products have been built and moved to `tmp`, they will be compressed and moved to `products` - -OSNAME=$(uname | tr '[A-Z]' '[a-z]') -BUILD_CONCURRENCY=4 -PROJROOT=$(pwd) -BUILD_PRODUCTS_DIR=$(pwd)/bin -LIB_PRODUCTS_DIR=$BUILD_PRODUCTS_DIR/lib -FINISHED_PRODUCTS_DIR=$(pwd)/products -STAGING_DIR=$(pwd)/staging -# Windows (previously built) -WIN_PREBUILT_DIR=$PROJROOT/staging/win -WIN_RELEASE_PRODUCTS_DIR=$WIN_PREBUILT_DIR/release -WIN_DEBUG_PRODUCTS_DIR=$WIN_PREBUILT_DIR/debug -WIN32_RELEASE_PRODUCTS_DIR=$WIN_RELEASE_PRODUCTS_DIR/win32 -WIN64_RELEASE_PRODUCTS_DIR=$WIN_RELEASE_PRODUCTS_DIR/win64 -WIN32_DEBUG_PRODUCTS_DIR=$WIN_DEBUG_PRODUCTS_DIR/win32 -WIN64_DEBUG_PRODUCTS_DIR=$WIN_DEBUG_PRODUCTS_DIR/win64 -# Linux -LINUX_PROD_DIR=$PROJROOT/staging/linux -# macOS -MACOS_PROD_DIR=$PROJROOT/staging/macos -MACOS_RELEASE_PROD_DIR=$MACOS_PROD_DIR/release -MACOS_DEBUG_PROD_DIR=$MACOS_PROD_DIR/debug -# iOS -IOS_PROD_DIR=$PROJROOT/staging/ios -# Android -ANDROID_PROJ_DIR=$(pwd)/"packages/android" -ANDROID_ARCHIVE_FILENAME="zt.aar" -# Xcode -XCODE_IOS_PROJ_DIR=$(pwd)/"packages/xcode_ios" -XCODE_MACOS_PROJ_DIR=$(pwd)/"packages/xcode_macos" - -mkdir $FINISHED_PRODUCTS_DIR -mkdir $STAGING_DIR - -# Check that projects exist, generate them and exit if they don't exist -generate_projects_if_necessary() -{ - if [[ $OSNAME = *"darwin"* ]]; then - # iOS - if [ ! -d "$XCODE_IOS_PROJ_DIR" ]; then - echo "BUILDING: iOS project" - should_exit=1 - mkdir -p $XCODE_IOS_PROJ_DIR - cd $XCODE_IOS_PROJ_DIR - cmake -G Xcode ../../ - # Bug in CMake requires us to manually replace architecture strings in project file - sed -i '' 's/x86_64/$(CURRENT_ARCH)/g' $PROJNAME.xcodeproj/project.pbxproj - cd - - fi - # macOS - if [ ! -d "$XCODE_MACOS_PROJ_DIR" ]; then - echo "BUILDING: macOS project" - should_exit=1 - mkdir -p $XCODE_MACOS_PROJ_DIR - cd $XCODE_MACOS_PROJ_DIR - cmake -G Xcode ../../ - cd - - fi - # android? - if [[ $should_exit = 1 ]]; then - echo "Generated projects. Perform necessary modifications and then re-run this script" - echo "Please place previously built windows binaries in $WIN_PREBUILT_DIR before running again." - exit 0 - else - echo "Projects detected, going to build stage next" - fi - fi -} - -build_all_products() -{ - CONFIG=$1 - UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}" - - # Targets to build on and for darwin - if [[ $OSNAME = *"darwin"* ]]; then - # Xcode Frameworks --- Builds targets from a CMake-generated Xcode project - if true; then - if [[ $2 != *"JNI"* ]]; then - CURR_BUILD_PRODUCTS_DIR=$LIB_PRODUCTS_DIR/$UPPERCASE_CONFIG - # (iOS) - echo "BUILDING: iOS" - cd $XCODE_IOS_PROJ_DIR - xcodebuild -target zt -configuration "$UPPERCASE_CONFIG" -sdk "iphoneos" - xcodebuild -target zt-static -configuration "$UPPERCASE_CONFIG" -sdk "iphoneos" - cd - - CURR_ARCH="arm64" # spoof this architecture since HOSTTYPE is likely x86_64 - CURR_TMP_PRODUCT_DIR=$STAGING_DIR/$CONFIG/ios-$CURR_ARCH - mkdir -p $CURR_TMP_PRODUCT_DIR - mv $CURR_BUILD_PRODUCTS_DIR/*.framework $CURR_TMP_PRODUCT_DIR - mv $CURR_BUILD_PRODUCTS_DIR/libzt.* $CURR_TMP_PRODUCT_DIR - - # (macOS) - echo "BUILDING: macOS" - cd $XCODE_MACOS_PROJ_DIR - xcodebuild -target zt -configuration "$UPPERCASE_CONFIG" -sdk "macosx" - xcodebuild -target zt-static -configuration "$UPPERCASE_CONFIG" -sdk "macosx" - xcodebuild -target zt-shared -configuration "$UPPERCASE_CONFIG" -sdk "macosx" - cd - - CURR_TMP_PRODUCT_DIR=$STAGING_DIR/$CONFIG/macos-$(uname -m) - mkdir -p $CURR_TMP_PRODUCT_DIR - mv $CURR_BUILD_PRODUCTS_DIR/*.framework $CURR_TMP_PRODUCT_DIR - mv $CURR_BUILD_PRODUCTS_DIR/libzt.* $CURR_TMP_PRODUCT_DIR - fi - fi - # Android Archive (AAR) --- Executes a Gradle task - if true; then - CMAKE_FLAGS=$CMAKE_FLAGS" -DJNI=1" - CURR_ARCH="armeabi-v7a" # spoof this architecture since HOSTTYPE is likely x86_64 - CURR_TMP_PRODUCT_DIR=$STAGING_DIR/$CONFIG/android-$CURR_ARCH - mkdir -p $CURR_TMP_PRODUCT_DIR - echo "BUILDING: AAR" - cd $ANDROID_PROJ_DIR - ./gradlew assemble$UPPERCASE_CONFIG # e.g. assembleRelease - mv $ANDROID_PROJ_DIR/app/build/outputs/aar/app-$CONFIG.aar $CURR_TMP_PRODUCT_DIR/$ANDROID_ARCHIVE_FILENAME - cd - - fi - # Java Archive (JAR) - if true; then - CURR_BUILD_PRODUCTS_DIR=$LIB_PRODUCTS_DIR - CMAKE_FLAGS=$CMAKE_FLAGS" -DJNI=1" - CURR_TMP_PRODUCT_DIR=$STAGING_DIR/$CONFIG/macos-$(uname -m) - mkdir -p $CURR_TMP_PRODUCT_DIR - echo "BUILDING: JAR" - rm -rf $LIB_PRODUCTS_DIR # clean-lite - cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=$CONFIG "-DJNI=1 -DBUILD_TESTS=0" - cmake --build build - cd $PROJROOT/packages/java - cp $CURR_BUILD_PRODUCTS_DIR/libzt.dylib . - javac com/zerotier/libzt/*.java - jar cf zt.jar libzt.dylib com/zerotier/libzt/*.class - rm libzt.dylib - mv zt.jar $CURR_TMP_PRODUCT_DIR - cd - - fi - fi - # Linux targets - if [[ $OSNAME = *"linux"* ]]; then - CURR_BUILD_PRODUCTS_DIR=$LIB_PRODUCTS_DIR - # Ordinary libraries - if true; then - rm -rf $LIB_PRODUCTS_DIR - cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=$CONFIG "-DBUILD_TESTS=0" - cmake --build build - # -j $BUILD_CONCURRENCY - CURR_TMP_PRODUCT_DIR=$STAGING_DIR/$CONFIG/linux-$(uname -m) - mkdir -p $CURR_TMP_PRODUCT_DIR - mv $CURR_BUILD_PRODUCTS_DIR/libzt.* $CURR_TMP_PRODUCT_DIR - fi - # Java JAR file - if true; then - rm -rf $LIB_PRODUCTS_DIR - cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=$CONFIG "-DJNI=1 -DBUILD_TESTS=0" - cmake --build build - # -j $BUILD_CONCURRENCY - CURR_TMP_PRODUCT_DIR=$STAGING_DIR/$CONFIG/linux-$(uname -m) - mkdir -p $CURR_TMP_PRODUCT_DIR - cd $PROJROOT/packages/java - cp $CURR_BUILD_PRODUCTS_DIR/libzt.so . - javac com/zerotier/libzt/*.java - jar cf zt.jar libzt.dylib com/zerotier/libzt/*.class - rm libzt.dylib - mv zt.jar $CURR_TMP_PRODUCT_DIR - cd - - fi - fi -} - -main() -{ - generate_projects_if_necessary - build_all_products "release" - build_all_products "debug" -} - -main "$@" \ No newline at end of file diff --git a/packages/java/com/zerotier/libzt/ZTFDSet.java b/packages/java/com/zerotier/libzt/ZTFDSet.java deleted file mode 100644 index cf5bd7b..0000000 --- a/packages/java/com/zerotier/libzt/ZTFDSet.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -public class ZTFDSet -{ - byte[] fds_bits = new byte[1024]; - - public void CLR(int fd) - { - fds_bits[fd] = 0x00; - } - - public boolean ISSET(int fd) - { - return fds_bits[fd] == 0x01; - } - - public void SET(int fd) - { - fds_bits[fd] = 0x01; - } - - public void ZERO() - { - for (int i=0; i<1024; i++) { - fds_bits[i] = 0x00; - } - } -} \ No newline at end of file diff --git a/packages/java/com/zerotier/libzt/ZTSocketAddress.java b/packages/java/com/zerotier/libzt/ZTSocketAddress.java deleted file mode 100644 index c922251..0000000 --- a/packages/java/com/zerotier/libzt/ZTSocketAddress.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; - -import java.net.InetAddress; - -// Designed to transport address information across the JNI boundary -public class ZTSocketAddress -{ - public byte[] _ip6 = new byte[16]; - public byte[] _ip4 = new byte[4]; - - public int _family; - public int _port; // Also reused for netmask or prefix - - public ZTSocketAddress() {} - - public ZTSocketAddress(String ipStr, int port) - { - if(ipStr.contains(":")) { - _family = ZeroTier.AF_INET6; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip6 = ip.getAddress(); - } - catch (Exception e) { } - } - else if(ipStr.contains(".")) { - _family = ZeroTier.AF_INET; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip4 = ip.getAddress(); - } - catch (Exception e) { } - } - _port = port; - } - - public int getPort() { return _port; } - public int getNetmask() { return _port; } - public int getPrefix() { return _port; } - - private String ipString() - { - if (_family == ZeroTier.AF_INET) { - try { - InetAddress inet = InetAddress.getByAddress(_ip4); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - if (_family == ZeroTier.AF_INET6) { - try { - InetAddress inet = InetAddress.getByAddress(_ip6); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - return ""; - } - - public String toString() { return ipString() + ":" + _port; } - public String toCIDR() { return ipString() + "/" + _port; } -} diff --git a/packages/java/com/zerotier/libzt/ZeroTier.java b/packages/java/com/zerotier/libzt/ZeroTier.java deleted file mode 100644 index 26e337b..0000000 --- a/packages/java/com/zerotier/libzt/ZeroTier.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -import java.net.*; - -public class ZeroTier { - - public static int AF_INET = 2; - public static int AF_INET6 = 30; - public static int SOCK_STREAM = 1; - public static int SOCK_DGRAM = 2; - public static int O_APPEND = 1024; - public static int O_NONBLOCK = 2048; - public static int O_ASYNC = 8192; - public static int O_DIRECT = 65536; - public static int O_NOATIME = 262144; - public static int F_GETFL = 3; - public static int F_SETFL = 4; - - public native void start(String homePath, boolean blocking); - public native void startjoin(String homePath, long nwid); - public native void stop(); - public native boolean core_running(); - public native boolean stack_running(); - public native boolean ready(); - public native int join(long nwid); - public native int leave(long nwid); - public native String get_path(); - public native long get_node_id(); - public native int get_num_assigned_addresses(long nwid); - public native boolean get_address_at_index(long nwid, int index, ZTSocketAddress addr); - public native boolean has_address(long nwid); - public native boolean get_address(long nwid, int address_family, ZTSocketAddress addr); - public native void get_6plane_addr(long nwid, long nodeId, ZTSocketAddress addr); - public native void get_rfc4193_addr(long nwid, long nodeId, ZTSocketAddress addr); - - public native int socket(int family, int type, int protocol); - public native int connect(int fd, ZTSocketAddress addr); - public native int bind(int fd, ZTSocketAddress addr); - public native int listen(int fd, int backlog); - public native int accept(int fd, ZTSocketAddress addr); - public native int accept4(int fd, String addr, int port); - public native int close(int fd); - public native int setsockopt(int fd, int level, int optname, int optval, int optlen); - public native int getsockopt(int fd, int level, int optname, int optval, int optlen); - public native int sendto(int fd, byte[] buf, int flags, ZTSocketAddress addr); - public native int send(int fd, byte[] buf, int flags); - public native int recv(int fd, byte[] buf, int flags); - public native int recvfrom(int fd, byte[] buf, int flags, ZTSocketAddress addr); - public native int read(int fd, byte[] buf); - public native int write(int fd, byte[] buf); - public native int shutdown(int fd, int how); - public native boolean getsockname(int fd, ZTSocketAddress addr); - public native int getpeername(int fd, ZTSocketAddress addr); - public native int fcntl(int sock, int cmd, int flag); - public native int select(int nfds, ZTFDSet readfds, ZTFDSet writefds, ZTFDSet exceptfds, int timeout_sec, int timeout_usec); -} \ No newline at end of file diff --git a/packages/module.modulemap b/packages/module.modulemap deleted file mode 100644 index 2fd95d7..0000000 --- a/packages/module.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module zt { - umbrella header "Xcode-Bridging-Header.h" - - export * - module * { export * } -} diff --git a/packages/package.sh b/packages/package.sh deleted file mode 100755 index 011c29b..0000000 --- a/packages/package.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -PROJNAME="zt" -LIBNAME="lib"$PROJNAME -LIBZT_VERSION="1.2.0" -LIBZT_REVISION="1" -ZT_CORE_VERSION="1.2.12" -FILENAME_PREFIX=${LIBNAME} - -STAGING_DIR=$(pwd)/staging -STAGING_DEBUG_DIR=$(pwd)/staging/debug -STAGING_RELEASE_DIR=$(pwd)/staging/release -FINISHED_PRODUCTS_DIR=$(pwd)/products - -# Clean before zipping -find . -type f \( -name '*.DS_Store' -o -name 'thumbs.db' \) -delete - -# Emit a README file -echo $'* libzt version: '${LIBZT_VERSION}$'r'${LIBZT_REVISION}$'\n* Core ZeroTier version: '${ZT_CORE_VERSION}$'\n* Date: '$(date)$'\n\nZeroTier Manual: https://www.zerotier.com/manual.shtml\n -Other Downloads: https://www.zerotier.com/download.shtml -\nlibzt Repo: https://github.com/zerotier/libzt\n\nFor more assistance, visit https://my.zerotier.com and ask your question in our Community section' > ${STAGING_DIR}/README.md - -cp ${STAGING_DIR}/README.md ${STAGING_DIR}/debug/README.md -cp ${STAGING_DIR}/README.md ${STAGING_DIR}/release/README.md - -# Package everything together -# (debug) -PRODUCT_FILENAME=${FILENAME_PREFIX}-debug.tar.gz -echo "Making: " ${FINISHED_PRODUCTS_DIR}/${PRODUCT_FILENAME} -cd ${STAGING_DEBUG_DIR} -tar --exclude=${PRODUCT_FILENAME} -zcvf ${PRODUCT_FILENAME} . -md5 $PRODUCT_FILENAME -mv *.tar.gz ${FINISHED_PRODUCTS_DIR} -cd - - -# (release) -PRODUCT_FILENAME=${FILENAME_PREFIX}-release.tar.gz -echo "Making: " ${FINISHED_PRODUCTS_DIR}/${PRODUCT_FILENAME} -cd ${STAGING_RELEASE_DIR} -tar --exclude=${PRODUCT_FILENAME} -zcvf ${PRODUCT_FILENAME} . -md5 $PRODUCT_FILENAME -mv *.tar.gz ${FINISHED_PRODUCTS_DIR} -cd - \ No newline at end of file diff --git a/packages/pypi/LICENSE.txt b/packages/pypi/LICENSE.txt deleted file mode 100644 index 94a9ed0..0000000 --- a/packages/pypi/LICENSE.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/packages/pypi/MANIFEST.in b/packages/pypi/MANIFEST.in deleted file mode 100644 index e246643..0000000 --- a/packages/pypi/MANIFEST.in +++ /dev/null @@ -1,12 +0,0 @@ -# file GENERATED by distutils, do NOT edit -README.rst -setup.cfg -setup.py -#recursive-include ../../src *.c -recursive-include ../../src *.cpp -recursive-include ../../include *.h -#recursive-include ../../include *.hpp -include libhttp.a -include liblwip.a -include http.lib -include lwip.lib \ No newline at end of file diff --git a/packages/pypi/Makefile b/packages/pypi/Makefile deleted file mode 100644 index 5276ded..0000000 --- a/packages/pypi/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# generate a new wrapper *.cxx from the *.i interface file -wrapper: - swig -c++ -python libzt.i - -# build and package a binary distribution -bdist: - cd ../../; cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=DEBUG - cd ../../; cmake --build build - cp ../../bin/lib/*.a . - python3 setup.py bdist_wheel - -# upload to PyPI -upload: - twine upload dist/* - -clean: - rm -rf *.a - rm -rf build - rm -rf dist - rm -rf libzt.egg-info diff --git a/packages/pypi/README.md b/packages/pypi/README.md deleted file mode 100644 index 3044a33..0000000 --- a/packages/pypi/README.md +++ /dev/null @@ -1,67 +0,0 @@ -## libzt PyPI Package -[pypi/libzt](https://pypi.python.org/pypi/libzt) -*** - -## Getting started - -`pip3 install libzt` - -``` -import libzt -import time - -print('joining virtual network...') -libzt.zts_startjoin('whatev_config', 0x123456789ABCDEF1) -print('fd = ' + str(libzt.zts_socket(1,2,3))) - -print('looping forever, ping me') -while True: - time.sleep(1) -``` - -## Building - - - install SWIG - - `make wrapper` - -### macOS, Linux - -Binary distribution: - -make bdist - -Alternatively, source Distribution: - -make sdist - -Upload to PyPI: - -make upload - -Cleanup: - -make clean - -### Windows - -Binary distribution: - -bdist.bat - -Source distribution: - -sdist.bat - -Upload to PyPI: - -upload.bat - -Cleanup: - -clean.bat - -## Installing from a locally-built package/wheel - - - `pip3 install dist/.whl` - -*Note: As there appears to be no way to differentiate C and C++ code (and thus pass correct build args to each type) in a setuptools script we must separately build the `lwip` and `http_parser` libraries, copy them here, and then build the binary. See the top-level [README.md](../../README.md) for instructions on how to do that* diff --git a/packages/pypi/README.rst b/packages/pypi/README.rst deleted file mode 100644 index 6af85d2..0000000 --- a/packages/pypi/README.rst +++ /dev/null @@ -1,8 +0,0 @@ -# libzt -*ZeroTier: Encrypted P2P communication between apps and services* -*** - -A library version of [ZeroTier](https://github.com/zerotier/ZeroTierOne), **libzt** makes it easy to securely connect devices, servers, cloud VMs, containers, and apps everywhere and manage them at scale. Now you can bake this ability directly into your app or service using your preferred language. We provide a POSIX-like socket API supporting `SOCK_STREAM`, `SOCK_DGRAM`, and `SOCK_RAW` to make the integration simple. There's no need for system-wide virtual interfaces. This connection is exclusive to your app and fully encrypted via the [Salsa20](https://en.wikipedia.org/wiki/Salsa20) cipher. For a more in-depth discussion on the technical side of ZeroTier, check out our [Manual](https://www.zerotier.com/manual.shtml?pk_campaign=github_libzt) - -### Commercial License - - To be released from GPLv3, contact us directly via `contact@zerotier.com` for commercial licensing. diff --git a/packages/pypi/libzt.i b/packages/pypi/libzt.i deleted file mode 100644 index ab6efe4..0000000 --- a/packages/pypi/libzt.i +++ /dev/null @@ -1,136 +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. - */ - -%module libzt - -%include "stdint.i" - -%{ -#define SWIG_FILE_WITH_INIT -#include "../../include/libzt.h" -%} - -int zts_start(const char *path, bool blocking); - -int zts_startjoin(const char *path, const uint64_t nwid); - -void zts_stop(); - -int zts_core_running(); - -int zts_stack_running(); - -int zts_ready(); - -int zts_join(const uint64_t nwid); - -int zts_leave(const uint64_t nwid); - -void zts_get_path(char *homePath, const size_t len); - -uint64_t zts_get_node_id(); - -uint64_t zts_get_node_id_from_file(const char *filepath); - -int zts_has_address(const uint64_t nwid); - -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(); - -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); - -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_select( - int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); - -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); - diff --git a/packages/pypi/libzt.py b/packages/pypi/libzt.py deleted file mode 100644 index 267f62b..0000000 --- a/packages/pypi/libzt.py +++ /dev/null @@ -1,380 +0,0 @@ -# This file was automatically generated by SWIG (http://www.swig.org). -# Version 3.0.12 -# -# Do not make changes to this file unless you know what you are doing--modify -# the SWIG interface file instead. - -from sys import version_info as _swig_python_version_info -if _swig_python_version_info >= (2, 7, 0): - def swig_import_helper(): - import importlib - pkg = __name__.rpartition('.')[0] - mname = '.'.join((pkg, '_libzt')).lstrip('.') - try: - return importlib.import_module(mname) - except ImportError: - return importlib.import_module('_libzt') - _libzt = swig_import_helper() - del swig_import_helper -elif _swig_python_version_info >= (2, 6, 0): - def swig_import_helper(): - from os.path import dirname - import imp - fp = None - try: - fp, pathname, description = imp.find_module('_libzt', [dirname(__file__)]) - except ImportError: - import _libzt - return _libzt - try: - _mod = imp.load_module('_libzt', fp, pathname, description) - finally: - if fp is not None: - fp.close() - return _mod - _libzt = swig_import_helper() - del swig_import_helper -else: - import _libzt -del _swig_python_version_info - -try: - _swig_property = property -except NameError: - pass # Python < 2.2 doesn't have 'property'. - -try: - import builtins as __builtin__ -except ImportError: - import __builtin__ - -def _swig_setattr_nondynamic(self, class_type, name, value, static=1): - if (name == "thisown"): - return self.this.own(value) - if (name == "this"): - if type(value).__name__ == 'SwigPyObject': - self.__dict__[name] = value - return - method = class_type.__swig_setmethods__.get(name, None) - if method: - return method(self, value) - if (not static): - if _newclass: - object.__setattr__(self, name, value) - else: - self.__dict__[name] = value - else: - raise AttributeError("You cannot add attributes to %s" % self) - - -def _swig_setattr(self, class_type, name, value): - return _swig_setattr_nondynamic(self, class_type, name, value, 0) - - -def _swig_getattr(self, class_type, name): - if (name == "thisown"): - return self.this.own() - method = class_type.__swig_getmethods__.get(name, None) - if method: - return method(self) - raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name)) - - -def _swig_repr(self): - try: - strthis = "proxy of " + self.this.__repr__() - except __builtin__.Exception: - strthis = "" - return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -try: - _object = object - _newclass = 1 -except __builtin__.Exception: - class _object: - pass - _newclass = 0 - - - - - -class libztSocket: - def __init__(self, _fd, _family, _type, _proto): - self.fd = _fd - self.family = _family - self.type = _type - self.proto = _proto - - # object-centric wrpper for calls so we can have a more "pythonic" experience - def connect(self, address): - addrlen = 0 - return _libzt.zts_connect(self.fd, address, addrlen) - - def connect(self, address): - return - - def connect_ex(self, address): - return - - def getpeername(): - return - - def getsockname(): - return - - def getsockopt(level, optname, buflen): - return - - def fcntl(fd, cmd, flags): - return _libzt.zts_fcntl(self.fd, cmd, flags) - - def ioctl(control, option): - return - - def listen(): - return _libzt.zts_listen(fd, backlog) - - def accept(): - return - - def bind(address): - return - - def close(self): - zts_close(self.fd) - - def recvfrom(bufsz, flags): - return - - def recv(bufsz, flags): - return - - def recvmsg(bufsz, ancillarybufsz, flags): - return - - def send(bytes, flags): - return - - def sendall(bytes, flags): - return - - def sendto(bytes, address): - return - - def sendto(bytes, flags, address): - return - - def sendmsg(buffers, ancdata, flags, address): - return - - def setblocking(flag): - return - - def setsockopt(level, optname, int): - return - - def setsockopt(level, optname, buffer): - return - - def shutdown(how): - return _libzt.zts_shutdown(self.fd, how) - - -def zts_socket(socket_family, socket_type, socket_protocol): - fd = _libzt.zts_socket(socket_family, socket_type, socket_protocol) - return libztSocket(fd, socket_family, socket_type, socket_protocol) - - - -""" ZeroTier Control API """ - -def zts_start(path, blocking): - return _libzt.zts_start(path, blocking) -zts_start = _libzt.zts_start - -def zts_startjoin(path, nwid): - return _libzt.zts_startjoin(path, nwid) -zts_startjoin = _libzt.zts_startjoin - -def zts_stop(): - return _libzt.zts_stop() -zts_stop = _libzt.zts_stop - -def zts_core_running(): - return _libzt.zts_core_running() -zts_core_running = _libzt.zts_core_running - -def zts_stack_running(): - return _libzt.zts_stack_running() -zts_stack_running = _libzt.zts_stack_running - -def zts_ready(): - return _libzt.zts_ready() -zts_ready = _libzt.zts_ready - -def zts_join(nwid): - return _libzt.zts_join(nwid) -zts_join = _libzt.zts_join - -def zts_leave(nwid): - return _libzt.zts_leave(nwid) -zts_leave = _libzt.zts_leave - -def zts_get_path(homePath, len): - return _libzt.zts_get_path(homePath, len) -zts_get_path = _libzt.zts_get_path - -def zts_get_node_id(): - return _libzt.zts_get_node_id() -zts_get_node_id = _libzt.zts_get_node_id - -def zts_get_node_id_from_file(filepath): - return _libzt.zts_get_node_id_from_file(filepath) -zts_get_node_id_from_file = _libzt.zts_get_node_id_from_file - -def zts_has_address(nwid): - return _libzt.zts_has_address(nwid) -zts_has_address = _libzt.zts_has_address - -def zts_get_num_assigned_addresses(nwid): - return _libzt.zts_get_num_assigned_addresses(nwid) -zts_get_num_assigned_addresses = _libzt.zts_get_num_assigned_addresses - -def zts_get_address_at_index(nwid, index, addr): - return _libzt.zts_get_address_at_index(nwid, index, addr) -zts_get_address_at_index = _libzt.zts_get_address_at_index - -def zts_get_address(nwid, addr, address_family): - return _libzt.zts_get_address(nwid, addr, address_family) -zts_get_address = _libzt.zts_get_address - -def zts_get_6plane_addr(addr, nwid, nodeId): - return _libzt.zts_get_6plane_addr(addr, nwid, nodeId) -zts_get_6plane_addr = _libzt.zts_get_6plane_addr - -def zts_get_rfc4193_addr(addr, nwid, nodeId): - return _libzt.zts_get_rfc4193_addr(addr, nwid, nodeId) -zts_get_rfc4193_addr = _libzt.zts_get_rfc4193_addr - -def zts_get_peer_count(): - return _libzt.zts_get_peer_count() -zts_get_peer_count = _libzt.zts_get_peer_count - -def zts_get_peer_address(peer, nodeId): - return _libzt.zts_get_peer_address(peer, nodeId) -zts_get_peer_address = _libzt.zts_get_peer_address - - -""" Socket-Layer Control API """ - -#def zts_socket(socket_family, socket_type, protocol): -# return _libzt.zts_socket(socket_family, socket_type, protocol) -#zts_socket = _libzt.zts_socket - -def zts_connect(fd, addr, addrlen): - return _libzt.zts_connect(fd, addr, addrlen) -zts_connect = _libzt.zts_connect - -def zts_bind(fd, addr, addrlen): - return _libzt.zts_bind(fd, addr, addrlen) -zts_bind = _libzt.zts_bind - -#def zts_listen(fd, backlog): -# return _libzt.zts_listen(fd, backlog) -#zts_listen = _libzt.zts_listen - -def zts_accept(fd, addr, addrlen): - return _libzt.zts_accept(fd, addr, addrlen) -zts_accept = _libzt.zts_accept - -def zts_setsockopt(fd, level, optname, optval, optlen): - return _libzt.zts_setsockopt(fd, level, optname, optval, optlen) -zts_setsockopt = _libzt.zts_setsockopt - -def zts_getsockopt(fd, level, optname, optval, optlen): - return _libzt.zts_getsockopt(fd, level, optname, optval, optlen) -zts_getsockopt = _libzt.zts_getsockopt - -def zts_getsockname(fd, addr, addrlen): - return _libzt.zts_getsockname(fd, addr, addrlen) -zts_getsockname = _libzt.zts_getsockname - -def zts_getpeername(fd, addr, addrlen): - return _libzt.zts_getpeername(fd, addr, addrlen) -zts_getpeername = _libzt.zts_getpeername - -def zts_gethostname(name, len): - return _libzt.zts_gethostname(name, len) -zts_gethostname = _libzt.zts_gethostname - -def zts_sethostname(name, len): - return _libzt.zts_sethostname(name, len) -zts_sethostname = _libzt.zts_sethostname - -def zts_gethostbyname(name): - return _libzt.zts_gethostbyname(name) -zts_gethostbyname = _libzt.zts_gethostbyname - -#def zts_close(fd): -# return _libzt.zts_close(fd) -#zts_close = _libzt.zts_close - -def zts_select(nfds, readfds, writefds, exceptfds, timeout): - return _libzt.zts_select(nfds, readfds, writefds, exceptfds, timeout) -zts_select = _libzt.zts_select - -#def zts_fcntl(fd, cmd, flags): -# return _libzt.zts_fcntl(fd, cmd, flags) -#zts_fcntl = _libzt.zts_fcntl - -def zts_ioctl(fd, request, argp): - return _libzt.zts_ioctl(fd, request, argp) -zts_ioctl = _libzt.zts_ioctl - -def zts_send(fd, buf, len, flags): - return _libzt.zts_send(fd, buf, len, flags) -zts_send = _libzt.zts_send - -def zts_sendto(fd, buf, len, flags, addr, addrlen): - return _libzt.zts_sendto(fd, buf, len, flags, addr, addrlen) -zts_sendto = _libzt.zts_sendto - -def zts_sendmsg(fd, msg, flags): - return _libzt.zts_sendmsg(fd, msg, flags) -zts_sendmsg = _libzt.zts_sendmsg - -def zts_recv(fd, buf, len, flags): - return _libzt.zts_recv(fd, buf, len, flags) -zts_recv = _libzt.zts_recv - -def zts_recvfrom(fd, buf, len, flags, addr, addrlen): - return _libzt.zts_recvfrom(fd, buf, len, flags, addr, addrlen) -zts_recvfrom = _libzt.zts_recvfrom - -def zts_recvmsg(fd, msg, flags): - return _libzt.zts_recvmsg(fd, msg, flags) -zts_recvmsg = _libzt.zts_recvmsg - -def zts_read(fd, buf, len): - return _libzt.zts_read(fd, buf, len) -zts_read = _libzt.zts_read - -def zts_write(fd, buf, len): - return _libzt.zts_write(fd, buf, len) -zts_write = _libzt.zts_write - -#def zts_shutdown(fd, how): -# return _libzt.zts_shutdown(fd, how) -#zts_shutdown = _libzt.zts_shutdown - -def zts_add_dns_nameserver(addr): - return _libzt.zts_add_dns_nameserver(addr) -zts_add_dns_nameserver = _libzt.zts_add_dns_nameserver - -def zts_del_dns_nameserver(addr): - return _libzt.zts_del_dns_nameserver(addr) -zts_del_dns_nameserver = _libzt.zts_del_dns_nameserver -# This file is compatible with both classic and new-style classes. - - diff --git a/packages/pypi/libzt/.gitignore b/packages/pypi/libzt/.gitignore deleted file mode 100644 index 5e7d273..0000000 --- a/packages/pypi/libzt/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/packages/pypi/libzt_wrap.cxx b/packages/pypi/libzt_wrap.cxx deleted file mode 100644 index d537c89..0000000 --- a/packages/pypi/libzt_wrap.cxx +++ /dev/null @@ -1,6003 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 3.0.12 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - - -#ifndef SWIGPYTHON -#define SWIGPYTHON -#endif - -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE - - -#ifdef __cplusplus -/* SwigValueWrapper is described in swig.swg */ -template class SwigValueWrapper { - struct SwigMovePointer { - T *ptr; - SwigMovePointer(T *p) : ptr(p) { } - ~SwigMovePointer() { delete ptr; } - SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } - } pointer; - SwigValueWrapper& operator=(const SwigValueWrapper& rhs); - SwigValueWrapper(const SwigValueWrapper& rhs); -public: - SwigValueWrapper() : pointer(0) { } - SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } - operator T&() const { return *pointer.ptr; } - T *operator&() { return pointer.ptr; } -}; - -template T SwigValueInit() { - return T(); -} -#endif - -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if defined(__GNUC__) -# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - -/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ -#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) -# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 -#endif - -/* Intel's compiler complains if a variable which was never initialised is - * cast to void, which is a common idiom which we use to indicate that we - * are aware a variable isn't used. So we just silence that warning. - * See: https://github.com/swig/swig/issues/192 for more discussion. - */ -#ifdef __INTEL_COMPILER -# pragma warning disable 592 -#endif - - -#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG) -/* Use debug wrappers with the Python release dll */ -# undef _DEBUG -# include -# define _DEBUG -#else -# include -#endif - -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic C API SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "4" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the SWIG runtime code. - In 99.9% of the cases, SWIG just needs to declare them as 'static'. - - But only do this if strictly necessary, ie, if you have problems - with your compiler or suchlike. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 -#define SWIG_CAST_NEW_MEMORY 0x2 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The SWIG conversion methods, as ConvertPtr, return an integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old versions of SWIG, code such as the following was usually written: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - which is the same really, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - also requires SWIG_ConvertPtr to return new result values, such as - - int SWIG_ConvertPtr(obj, ptr,...) { - if () { - if () { - *ptr = ; - return SWIG_NEWOBJ; - } else { - *ptr = ; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - SWIG errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows to return the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() -*/ - -#define SWIG_OK (0) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast(r) (r) -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *, int *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store information on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (int)((l1 - f1) - (l2 - f2)); -} - -/* - Check type equivalence in a name list like ||... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCmp(const char *nb, const char *tb) { - int equiv = 1; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (equiv != 0 && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = SWIG_TypeNameComp(nb, ne, tb, te); - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like ||... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0; -} - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (strcmp(iter->type->name, c) == 0) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (iter->type == from) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. We choose - to print the last name, as it is often (?) the most - specific. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - size_t l = 0; - size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - const unsigned char *u = (unsigned char *) ptr; - const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - unsigned char *u = (unsigned char *) ptr; - const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - char d = *(c++); - unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = (unsigned char)((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = (unsigned char)((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (unsigned char)(d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (unsigned char)(d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - -/* Compatibility macros for Python 3 */ -#if PY_VERSION_HEX >= 0x03000000 - -#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type) -#define PyInt_Check(x) PyLong_Check(x) -#define PyInt_AsLong(x) PyLong_AsLong(x) -#define PyInt_FromLong(x) PyLong_FromLong(x) -#define PyInt_FromSize_t(x) PyLong_FromSize_t(x) -#define PyString_Check(name) PyBytes_Check(name) -#define PyString_FromString(x) PyUnicode_FromString(x) -#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) -#define PyString_AsString(str) PyBytes_AsString(str) -#define PyString_Size(str) PyBytes_Size(str) -#define PyString_InternFromString(key) PyUnicode_InternFromString(key) -#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE -#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x) -#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) - -#endif - -#ifndef Py_TYPE -# define Py_TYPE(op) ((op)->ob_type) -#endif - -/* SWIG APIs for compatibility of both Python 2 & 3 */ - -#if PY_VERSION_HEX >= 0x03000000 -# define SWIG_Python_str_FromFormat PyUnicode_FromFormat -#else -# define SWIG_Python_str_FromFormat PyString_FromFormat -#endif - - -/* Warning: This function will allocate a new string in Python 3, - * so please call SWIG_Python_str_DelForPy3(x) to free the space. - */ -SWIGINTERN char* -SWIG_Python_str_AsChar(PyObject *str) -{ -#if PY_VERSION_HEX >= 0x03000000 - char *cstr; - char *newstr; - Py_ssize_t len; - str = PyUnicode_AsUTF8String(str); - PyBytes_AsStringAndSize(str, &cstr, &len); - newstr = (char *) malloc(len+1); - memcpy(newstr, cstr, len+1); - Py_XDECREF(str); - return newstr; -#else - return PyString_AsString(str); -#endif -} - -#if PY_VERSION_HEX >= 0x03000000 -# define SWIG_Python_str_DelForPy3(x) free( (void*) (x) ) -#else -# define SWIG_Python_str_DelForPy3(x) -#endif - - -SWIGINTERN PyObject* -SWIG_Python_str_FromChar(const char *c) -{ -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_FromString(c); -#else - return PyString_FromString(c); -#endif -} - -/* Add PyOS_snprintf for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# define PyOS_snprintf _snprintf -# else -# define PyOS_snprintf snprintf -# endif -#endif - -/* A crude PyString_FromFormat implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 - -#ifndef SWIG_PYBUFFER_SIZE -# define SWIG_PYBUFFER_SIZE 1024 -#endif - -static PyObject * -PyString_FromFormat(const char *fmt, ...) { - va_list ap; - char buf[SWIG_PYBUFFER_SIZE * 2]; - int res; - va_start(ap, fmt); - res = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); -} -#endif - -#ifndef PyObject_DEL -# define PyObject_DEL PyObject_Del -#endif - -/* A crude PyExc_StopIteration exception for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# ifndef PyExc_StopIteration -# define PyExc_StopIteration PyExc_RuntimeError -# endif -# ifndef PyObject_GenericGetAttr -# define PyObject_GenericGetAttr 0 -# endif -#endif - -/* Py_NotImplemented is defined in 2.1 and up. */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef Py_NotImplemented -# define Py_NotImplemented PyExc_RuntimeError -# endif -#endif - -/* A crude PyString_AsStringAndSize implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef PyString_AsStringAndSize -# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} -# endif -#endif - -/* PySequence_Size for old Pythons */ -#if PY_VERSION_HEX < 0x02000000 -# ifndef PySequence_Size -# define PySequence_Size PySequence_Length -# endif -#endif - -/* PyBool_FromLong for old Pythons */ -#if PY_VERSION_HEX < 0x02030000 -static -PyObject *PyBool_FromLong(long ok) -{ - PyObject *result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; -} -#endif - -/* Py_ssize_t for old Pythons */ -/* This code is as recommended by: */ -/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -# define PY_SSIZE_T_MIN INT_MIN -typedef inquiry lenfunc; -typedef intargfunc ssizeargfunc; -typedef intintargfunc ssizessizeargfunc; -typedef intobjargproc ssizeobjargproc; -typedef intintobjargproc ssizessizeobjargproc; -typedef getreadbufferproc readbufferproc; -typedef getwritebufferproc writebufferproc; -typedef getsegcountproc segcountproc; -typedef getcharbufferproc charbufferproc; -static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc)) -{ - long result = 0; - PyObject *i = PyNumber_Int(x); - if (i) { - result = PyInt_AsLong(i); - Py_DECREF(i); - } - return result; -} -#endif - -#if PY_VERSION_HEX < 0x02050000 -#define PyInt_FromSize_t(x) PyInt_FromLong((long)x) -#endif - -#if PY_VERSION_HEX < 0x02040000 -#define Py_VISIT(op) \ - do { \ - if (op) { \ - int vret = visit((op), arg); \ - if (vret) \ - return vret; \ - } \ - } while (0) -#endif - -#if PY_VERSION_HEX < 0x02030000 -typedef struct { - PyTypeObject type; - PyNumberMethods as_number; - PyMappingMethods as_mapping; - PySequenceMethods as_sequence; - PyBufferProcs as_buffer; - PyObject *name, *slots; -} PyHeapTypeObject; -#endif - -#if PY_VERSION_HEX < 0x02030000 -typedef destructor freefunc; -#endif - -#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \ - (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \ - (PY_MAJOR_VERSION > 3)) -# define SWIGPY_USE_CAPSULE -# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME) -#endif - -#if PY_VERSION_HEX < 0x03020000 -#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) -#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) -#define Py_hash_t long -#endif - -/* ----------------------------------------------------------------------------- - * error manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject* -SWIG_Python_ErrorType(int code) { - PyObject* type = 0; - switch(code) { - case SWIG_MemoryError: - type = PyExc_MemoryError; - break; - case SWIG_IOError: - type = PyExc_IOError; - break; - case SWIG_RuntimeError: - type = PyExc_RuntimeError; - break; - case SWIG_IndexError: - type = PyExc_IndexError; - break; - case SWIG_TypeError: - type = PyExc_TypeError; - break; - case SWIG_DivisionByZero: - type = PyExc_ZeroDivisionError; - break; - case SWIG_OverflowError: - type = PyExc_OverflowError; - break; - case SWIG_SyntaxError: - type = PyExc_SyntaxError; - break; - case SWIG_ValueError: - type = PyExc_ValueError; - break; - case SWIG_SystemError: - type = PyExc_SystemError; - break; - case SWIG_AttributeError: - type = PyExc_AttributeError; - break; - default: - type = PyExc_RuntimeError; - } - return type; -} - - -SWIGRUNTIME void -SWIG_Python_AddErrorMsg(const char* mesg) -{ - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - - if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); - if (value) { - char *tmp; - PyObject *old_str = PyObject_Str(value); - PyErr_Clear(); - Py_XINCREF(type); - - PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg); - SWIG_Python_str_DelForPy3(tmp); - Py_DECREF(old_str); - Py_DECREF(value); - } else { - PyErr_SetString(PyExc_RuntimeError, mesg); - } -} - -#if defined(SWIG_PYTHON_NO_THREADS) -# if defined(SWIG_PYTHON_THREADS) -# undef SWIG_PYTHON_THREADS -# endif -#endif -#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ -# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) -# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ -# define SWIG_PYTHON_USE_GIL -# endif -# endif -# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ -# ifndef SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() -# endif -# ifdef __cplusplus /* C++ code */ - class SWIG_Python_Thread_Block { - bool status; - PyGILState_STATE state; - public: - void end() { if (status) { PyGILState_Release(state); status = false;} } - SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} - ~SWIG_Python_Thread_Block() { end(); } - }; - class SWIG_Python_Thread_Allow { - bool status; - PyThreadState *save; - public: - void end() { if (status) { PyEval_RestoreThread(save); status = false; }} - SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} - ~SWIG_Python_Thread_Allow() { end(); } - }; -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block -# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow -# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() -# else /* C code */ -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() -# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() -# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) -# endif -# else /* Old thread way, not implemented, user must provide it */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) -# define SWIG_PYTHON_THREAD_END_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# endif -# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) -# define SWIG_PYTHON_THREAD_END_ALLOW -# endif -# endif -#else /* No thread support */ -# define SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# define SWIG_PYTHON_THREAD_END_BLOCK -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# define SWIG_PYTHON_THREAD_END_ALLOW -#endif - -/* ----------------------------------------------------------------------------- - * Python API portion that goes into the runtime - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ----------------------------------------------------------------------------- - * Constant declarations - * ----------------------------------------------------------------------------- */ - -/* Constant Types */ -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - - -/* ----------------------------------------------------------------------------- - * Wrapper of PyInstanceMethod_New() used in Python 3 - * It is exported to the generated module, used for -fastproxy - * ----------------------------------------------------------------------------- */ -#if PY_VERSION_HEX >= 0x03000000 -SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) -{ - return PyInstanceMethod_New(func); -} -#else -SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func)) -{ - return NULL; -} -#endif - -#ifdef __cplusplus -} -#endif - - -/* ----------------------------------------------------------------------------- - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * ----------------------------------------------------------------------------- */ - -/* Common SWIG API */ - -/* for raw pointers */ -#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) - -#ifdef SWIGPYTHON_BUILTIN -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(self, ptr, type, flags) -#else -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) -#endif - -#define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) - -#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) -#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) -#define swig_owntype int - -/* for raw packed data */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - -/* for class or struct pointers */ -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) - -/* for C or C++ function pointers */ -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(NULL, ptr, type, 0) - -/* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* Runtime API */ - -#define SWIG_GetModule(clientdata) SWIG_Python_GetModule(clientdata) -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) SwigPyClientData_New(obj) - -#define SWIG_SetErrorObj SWIG_Python_SetErrorObj -#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* Runtime API implementation */ - -/* Error manipulation */ - -SWIGINTERN void -SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetObject(errtype, obj); - Py_DECREF(obj); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -SWIGINTERN void -SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetString(errtype, msg); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) - -/* Set a constant value */ - -#if defined(SWIGPYTHON_BUILTIN) - -SWIGINTERN void -SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) { - PyObject *s = PyString_InternFromString(key); - PyList_Append(seq, s); - Py_DECREF(s); -} - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) { -#if PY_VERSION_HEX < 0x02030000 - PyDict_SetItemString(d, (char *)name, obj); -#else - PyDict_SetItemString(d, name, obj); -#endif - Py_DECREF(obj); - if (public_interface) - SwigPyBuiltin_AddPublicSymbol(public_interface, name); -} - -#else - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { -#if PY_VERSION_HEX < 0x02030000 - PyDict_SetItemString(d, (char *)name, obj); -#else - PyDict_SetItemString(d, name, obj); -#endif - Py_DECREF(obj); -} - -#endif - -/* Append a value to the result obj */ - -SWIGINTERN PyObject* -SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { -#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyList_Check(result)) { - PyObject *o2 = result; - result = PyList_New(1); - PyList_SetItem(result, 0, o2); - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -#else - PyObject* o2; - PyObject* o3; - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyTuple_Check(result)) { - o2 = result; - result = PyTuple_New(1); - PyTuple_SET_ITEM(result, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SET_ITEM(o3, 0, obj); - o2 = result; - result = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return result; -#endif -} - -/* Unpack the argument tuple */ - -SWIGINTERN Py_ssize_t -SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) -{ - if (!args) { - if (!min && !max) { - return 1; - } else { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", - name, (min == max ? "" : "at least "), (int)min); - return 0; - } - } - if (!PyTuple_Check(args)) { - if (min <= 1 && max >= 1) { - Py_ssize_t i; - objs[0] = args; - for (i = 1; i < max; ++i) { - objs[i] = 0; - } - return 2; - } - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - Py_ssize_t l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), (int)min, (int)l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), (int)max, (int)l); - return 0; - } else { - Py_ssize_t i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -/* A functor is a function object with one single object argument */ -#if PY_VERSION_HEX >= 0x02020000 -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); -#else -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); -#endif - -/* - Helper for static pointer initialization for both C and C++ code, for example - static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); -*/ -#ifdef __cplusplus -#define SWIG_STATIC_POINTER(var) var -#else -#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var -#endif - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ - -/* Flags for new pointer objects */ -#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) -#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) - -#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) - -#define SWIG_BUILTIN_TP_INIT (SWIG_POINTER_OWN << 2) -#define SWIG_BUILTIN_INIT (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN) - -#ifdef __cplusplus -extern "C" { -#endif - -/* How to access Py_None */ -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# ifndef SWIG_PYTHON_NO_BUILD_NONE -# ifndef SWIG_PYTHON_BUILD_NONE -# define SWIG_PYTHON_BUILD_NONE -# endif -# endif -#endif - -#ifdef SWIG_PYTHON_BUILD_NONE -# ifdef Py_None -# undef Py_None -# define Py_None SWIG_Py_None() -# endif -SWIGRUNTIMEINLINE PyObject * -_SWIG_Py_None(void) -{ - PyObject *none = Py_BuildValue((char*)""); - Py_DECREF(none); - return none; -} -SWIGRUNTIME PyObject * -SWIG_Py_None(void) -{ - static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); - return none; -} -#endif - -/* The python void return value */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* SwigPyClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; - PyTypeObject *pytype; -} SwigPyClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - SwigPyClientData *data = (SwigPyClientData *)ty->clientdata; - return data ? data->implicitconv : 0; -} - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_ExceptionType(swig_type_info *desc) { - SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0; - PyObject *klass = data ? data->klass : 0; - return (klass ? klass : PyExc_RuntimeError); -} - - -SWIGRUNTIME SwigPyClientData * -SwigPyClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(data->klass); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); - } else { -#if (PY_VERSION_HEX < 0x02020000) - data->newraw = 0; -#else - data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); -#endif - if (data->newraw) { - Py_INCREF(data->newraw); - data->newargs = PyTuple_New(1); - PyTuple_SetItem(data->newargs, 0, obj); - } else { - data->newargs = obj; - } - Py_INCREF(data->newargs); - } - /* the destroy method, aka as the C++ delete method */ - data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); - if (PyErr_Occurred()) { - PyErr_Clear(); - data->destroy = 0; - } - if (data->destroy) { - int flags; - Py_INCREF(data->destroy); - flags = PyCFunction_GET_FLAGS(data->destroy); -#ifdef METH_O - data->delargs = !(flags & (METH_O)); -#else - data->delargs = 0; -#endif - } else { - data->delargs = 0; - } - data->implicitconv = 0; - data->pytype = 0; - return data; - } -} - -SWIGRUNTIME void -SwigPyClientData_Del(SwigPyClientData *data) { - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); -} - -/* =============== SwigPyObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -#ifdef SWIGPYTHON_BUILTIN - PyObject *dict; -#endif -} SwigPyObject; - - -#ifdef SWIGPYTHON_BUILTIN - -SWIGRUNTIME PyObject * -SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) -{ - SwigPyObject *sobj = (SwigPyObject *)v; - - if (!sobj->dict) - sobj->dict = PyDict_New(); - - Py_INCREF(sobj->dict); - return sobj->dict; -} - -#endif - -SWIGRUNTIME PyObject * -SwigPyObject_long(SwigPyObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -SwigPyObject_format(const char* fmt, SwigPyObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) { - PyObject *ofmt = SWIG_Python_str_FromChar(fmt); - if (ofmt) { -#if PY_VERSION_HEX >= 0x03000000 - res = PyUnicode_Format(ofmt,args); -#else - res = PyString_Format(ofmt,args); -#endif - Py_DECREF(ofmt); - } - Py_DECREF(args); - } - } - return res; -} - -SWIGRUNTIME PyObject * -SwigPyObject_oct(SwigPyObject *v) -{ - return SwigPyObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -SwigPyObject_hex(SwigPyObject *v) -{ - return SwigPyObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -#ifdef METH_NOARGS -SwigPyObject_repr(SwigPyObject *v) -#else -SwigPyObject_repr(SwigPyObject *v, PyObject *args) -#endif -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *repr = SWIG_Python_str_FromFormat("", (name ? name : "unknown"), (void *)v); - if (v->next) { -# ifdef METH_NOARGS - PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next); -# else - PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args); -# endif -# if PY_VERSION_HEX >= 0x03000000 - PyObject *joined = PyUnicode_Concat(repr, nrep); - Py_DecRef(repr); - Py_DecRef(nrep); - repr = joined; -# else - PyString_ConcatAndDel(&repr,nrep); -# endif - } - return repr; -} - -SWIGRUNTIME int -SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -/* Added for Python 3.x, would it also be useful for Python 2.x? */ -SWIGRUNTIME PyObject* -SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) -{ - PyObject* res; - if( op != Py_EQ && op != Py_NE ) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0); - return res; -} - - -SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void); - -#ifdef SWIGPYTHON_BUILTIN -static swig_type_info *SwigPyObject_stype = 0; -SWIGRUNTIME PyTypeObject* -SwigPyObject_type(void) { - SwigPyClientData *cd; - assert(SwigPyObject_stype); - cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; - assert(cd); - assert(cd->pytype); - return cd->pytype; -} -#else -SWIGRUNTIME PyTypeObject* -SwigPyObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce(); - return type; -} -#endif - -SWIGRUNTIMEINLINE int -SwigPyObject_Check(PyObject *op) { -#ifdef SWIGPYTHON_BUILTIN - PyTypeObject *target_tp = SwigPyObject_type(); - if (PyType_IsSubtype(op->ob_type, target_tp)) - return 1; - return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0); -#else - return (Py_TYPE(op) == SwigPyObject_type()) - || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0); -#endif -} - -SWIGRUNTIME PyObject * -SwigPyObject_New(void *ptr, swig_type_info *ty, int own); - -SWIGRUNTIME void -SwigPyObject_dealloc(PyObject *v) -{ - SwigPyObject *sobj = (SwigPyObject *) v; - PyObject *next = sobj->next; - if (sobj->own == SWIG_POINTER_OWN) { - swig_type_info *ty = sobj->ty; - SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - - /* PyObject_CallFunction() has the potential to silently drop - the active active exception. In cases of unnamed temporary - variable or where we just finished iterating over a generator - StopIteration will be active right now, and this needs to - remain true upon return from SwigPyObject_dealloc. So save - and restore. */ - - PyObject *val = NULL, *type = NULL, *tb = NULL; - PyErr_Fetch(&val, &type, &tb); - - if (data->delargs) { - /* we need to create a temporary object to carry the destroy operation */ - PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0); - res = SWIG_Python_CallFunctor(destroy, tmp); - Py_DECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - if (!res) - PyErr_WriteUnraisable(destroy); - - PyErr_Restore(val, type, tb); - - Py_XDECREF(res); - } -#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - else { - const char *name = SWIG_TypePrettyName(ty); - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); - } -#endif - } - Py_XDECREF(next); - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -SwigPyObject_append(PyObject* v, PyObject* next) -{ - SwigPyObject *sobj = (SwigPyObject *) v; -#ifndef METH_O - PyObject *tmp = 0; - if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; - next = tmp; -#endif - if (!SwigPyObject_Check(next)) { - PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject"); - return NULL; - } - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -#ifdef METH_NOARGS -SwigPyObject_next(PyObject* v) -#else -SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - SwigPyObject *sobj = (SwigPyObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -SwigPyObject_disown(PyObject *v) -#else -SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - SwigPyObject *sobj = (SwigPyObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -SwigPyObject_acquire(PyObject *v) -#else -SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - SwigPyObject *sobj = (SwigPyObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -SwigPyObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; -#if (PY_VERSION_HEX < 0x02020000) - if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) -#elif (PY_VERSION_HEX < 0x02050000) - if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) -#else - if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) -#endif - { - return NULL; - } - else - { - SwigPyObject *sobj = (SwigPyObject *)v; - PyObject *obj = PyBool_FromLong(sobj->own); - if (val) { -#ifdef METH_NOARGS - if (PyObject_IsTrue(val)) { - SwigPyObject_acquire(v); - } else { - SwigPyObject_disown(v); - } -#else - if (PyObject_IsTrue(val)) { - SwigPyObject_acquire(v,args); - } else { - SwigPyObject_disown(v,args); - } -#endif - } - return obj; - } -} - -#ifdef METH_O -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS, (char *)"acquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)SwigPyObject_append, METH_O, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)SwigPyObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_NOARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#else -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS, (char *)"acquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)SwigPyObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)SwigPyObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_VARARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#endif - -#if PY_VERSION_HEX < 0x02020000 -SWIGINTERN PyObject * -SwigPyObject_getattr(SwigPyObject *sobj,char *name) -{ - return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); -} -#endif - -SWIGRUNTIME PyTypeObject* -SwigPyObject_TypeOnce(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods SwigPyObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - /* nb_divide removed in Python 3 */ -#if PY_VERSION_HEX < 0x03000000 - (binaryfunc)0, /*nb_divide*/ -#endif - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0,/*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ -#if PY_VERSION_HEX < 0x03000000 - 0, /*nb_coerce*/ -#endif - (unaryfunc)SwigPyObject_long, /*nb_int*/ -#if PY_VERSION_HEX < 0x03000000 - (unaryfunc)SwigPyObject_long, /*nb_long*/ -#else - 0, /*nb_reserved*/ -#endif - (unaryfunc)0, /*nb_float*/ -#if PY_VERSION_HEX < 0x03000000 - (unaryfunc)SwigPyObject_oct, /*nb_oct*/ - (unaryfunc)SwigPyObject_hex, /*nb_hex*/ -#endif -#if PY_VERSION_HEX >= 0x03050000 /* 3.5 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_matrix_multiply */ -#elif PY_VERSION_HEX >= 0x03000000 /* 3.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */ -#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ -#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ - 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ -#endif - }; - - static PyTypeObject swigpyobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(NULL, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - (char *)"SwigPyObject", /* tp_name */ - sizeof(SwigPyObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)SwigPyObject_dealloc, /* tp_dealloc */ - 0, /* tp_print */ -#if PY_VERSION_HEX < 0x02020000 - (getattrfunc)SwigPyObject_getattr, /* tp_getattr */ -#else - (getattrfunc)0, /* tp_getattr */ -#endif - (setattrfunc)0, /* tp_setattr */ -#if PY_VERSION_HEX >= 0x03000000 - 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ -#else - (cmpfunc)SwigPyObject_compare, /* tp_compare */ -#endif - (reprfunc)SwigPyObject_repr, /* tp_repr */ - &SwigPyObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigobject_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - swigobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#if PY_VERSION_HEX >= 0x02060000 - 0, /* tp_version_tag */ -#endif -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ -#if PY_VERSION_HEX >= 0x02050000 - 0, /* tp_prev */ -#endif - 0 /* tp_next */ -#endif - }; - swigpyobject_type = tmp; - type_init = 1; -#if PY_VERSION_HEX < 0x02020000 - swigpyobject_type.ob_type = &PyType_Type; -#else - if (PyType_Ready(&swigpyobject_type) < 0) - return NULL; -#endif - } - return &swigpyobject_type; -} - -SWIGRUNTIME PyObject * -SwigPyObject_New(void *ptr, swig_type_info *ty, int own) -{ - SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; - } - return (PyObject *)sobj; -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - swig_type_info *ty; - size_t size; -} SwigPyPacked; - -SWIGRUNTIME int -SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->ty->name,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -SwigPyPacked_repr(SwigPyPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return SWIG_Python_str_FromFormat("", result, v->ty->name); - } else { - return SWIG_Python_str_FromFormat("", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -SwigPyPacked_str(SwigPyPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name); - } else { - return SWIG_Python_str_FromChar(v->ty->name); - } -} - -SWIGRUNTIME int -SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void); - -SWIGRUNTIME PyTypeObject* -SwigPyPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce(); - return type; -} - -SWIGRUNTIMEINLINE int -SwigPyPacked_Check(PyObject *op) { - return ((op)->ob_type == SwigPyPacked_TypeOnce()) - || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0); -} - -SWIGRUNTIME void -SwigPyPacked_dealloc(PyObject *v) -{ - if (SwigPyPacked_Check(v)) { - SwigPyPacked *sobj = (SwigPyPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -SwigPyPacked_TypeOnce(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject swigpypacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX>=0x03000000 - PyVarObject_HEAD_INIT(NULL, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - (char *)"SwigPyPacked", /* tp_name */ - sizeof(SwigPyPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)SwigPyPacked_dealloc, /* tp_dealloc */ - (printfunc)SwigPyPacked_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ -#if PY_VERSION_HEX>=0x03000000 - 0, /* tp_reserved in 3.0.1 */ -#else - (cmpfunc)SwigPyPacked_compare, /* tp_compare */ -#endif - (reprfunc)SwigPyPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)SwigPyPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigpacked_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#if PY_VERSION_HEX >= 0x02060000 - 0, /* tp_version_tag */ -#endif -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ -#if PY_VERSION_HEX >= 0x02050000 - 0, /* tp_prev */ -#endif - 0 /* tp_next */ -#endif - }; - swigpypacked_type = tmp; - type_init = 1; -#if PY_VERSION_HEX < 0x02020000 - swigpypacked_type.ob_type = &PyType_Type; -#else - if (PyType_Ready(&swigpypacked_type) < 0) - return NULL; -#endif - } - return &swigpypacked_type; -} - -SWIGRUNTIME PyObject * -SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type()); - if (sobj) { - void *pack = malloc(size); - if (pack) { - memcpy(pack, ptr, size); - sobj->pack = pack; - sobj->ty = ty; - sobj->size = size; - } else { - PyObject_DEL((PyObject *) sobj); - sobj = 0; - } - } - return (PyObject *) sobj; -} - -SWIGRUNTIME swig_type_info * -SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (SwigPyPacked_Check(obj)) { - SwigPyPacked *sobj = (SwigPyPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIMEINLINE PyObject * -_SWIG_This(void) -{ - return SWIG_Python_str_FromChar("this"); -} - -static PyObject *swig_this = NULL; - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - if (swig_this == NULL) - swig_this = _SWIG_This(); - return swig_this; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -/* TODO: I don't know how to implement the fast getset in Python 3 right now */ -#if PY_VERSION_HEX>=0x03000000 -#define SWIG_PYTHON_SLOW_GETSET_THIS -#endif - -SWIGRUNTIME SwigPyObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - PyObject *obj; - - if (SwigPyObject_Check(pyobj)) - return (SwigPyObject *) pyobj; - -#ifdef SWIGPYTHON_BUILTIN - (void)obj; -# ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - pyobj = PyWeakref_GET_OBJECT(pyobj); - if (pyobj && SwigPyObject_Check(pyobj)) - return (SwigPyObject*) pyobj; - } -# endif - return NULL; -#else - - obj = 0; - -#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) - if (PyInstance_Check(pyobj)) { - obj = _PyInstance_Lookup(pyobj, SWIG_This()); - } else { - PyObject **dictptr = _PyObject_GetDictPtr(pyobj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; - } else { -#ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - } - } -#else - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } -#endif - if (obj && !SwigPyObject_Check(obj)) { - /* a PyObject is called 'this', try to get the 'real this' - SwigPyObject from it */ - return SWIG_Python_GetSwigThis(obj); - } - return (SwigPyObject *)obj; -#endif -} - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own == SWIG_POINTER_OWN) { - SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); - if (sobj) { - int oldown = sobj->own; - sobj->own = own; - return oldown; - } - } - return 0; -} - -/* Convert a pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { - int res; - SwigPyObject *sobj; - int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0; - - if (!obj) - return SWIG_ERROR; - if (obj == Py_None && !implicit_conv) { - if (ptr) - *ptr = 0; - return SWIG_OK; - } - - res = SWIG_ERROR; - - sobj = SWIG_Python_GetSwigThis(obj); - if (own) - *own = 0; - while (sobj) { - void *vptr = sobj->ptr; - if (ty) { - swig_type_info *to = sobj->ty; - if (to == ty) { - /* no type cast needed */ - if (ptr) *ptr = vptr; - break; - } else { - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) { - sobj = (SwigPyObject *)sobj->next; - } else { - if (ptr) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */ - if (own) - *own = *own | SWIG_CAST_NEW_MEMORY; - } - } - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (own) - *own = *own | sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - res = SWIG_OK; - } else { - if (implicit_conv) { - SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; - if (data && !data->implicitconv) { - PyObject *klass = data->klass; - if (klass) { - PyObject *impconv; - data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ - impconv = SWIG_Python_CallFunctor(klass, obj); - data->implicitconv = 0; - if (PyErr_Occurred()) { - PyErr_Clear(); - impconv = 0; - } - if (impconv) { - SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv); - if (iobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - iobj->own = 0; - res = SWIG_AddCast(res); - res = SWIG_AddNewMask(res); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - } - if (!SWIG_IsOK(res) && obj == Py_None) { - if (ptr) - *ptr = 0; - if (PyErr_Occurred()) - PyErr_Clear(); - res = SWIG_OK; - } - } - return res; -} - -/* Convert a function ptr value */ - -SWIGRUNTIME int -SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { - if (!PyCFunction_Check(obj)) { - return SWIG_ConvertPtr(obj, ptr, ty, 0); - } else { - void *vptr = 0; - - /* here we get the method pointer for callbacks */ - const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; - if (desc) - desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) - return SWIG_ERROR; - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (tc) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - assert(!newmemory); /* newmemory handling not yet implemented */ - } else { - return SWIG_ERROR; - } - } else { - *ptr = vptr; - } - return SWIG_OK; - } -} - -/* Convert a packed value value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { - if (to != ty) { - /* check type cast? */ - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) return SWIG_ERROR; - } - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Create a new pointer object - * ----------------------------------------------------------------------------- */ - -/* - Create a new instance object, without calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) -{ -#if (PY_VERSION_HEX >= 0x02020000) - PyObject *inst = 0; - PyObject *newraw = data->newraw; - if (newraw) { - inst = PyObject_Call(newraw, data->newargs, NULL); - if (inst) { -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - PyDict_SetItem(dict, SWIG_This(), swig_this); - } - } -#else - PyObject *key = SWIG_This(); - PyObject_SetAttr(inst, key, swig_this); -#endif - } - } else { -#if PY_VERSION_HEX >= 0x03000000 - inst = ((PyTypeObject*) data->newargs)->tp_new((PyTypeObject*) data->newargs, Py_None, Py_None); - if (inst) { - PyObject_SetAttr(inst, SWIG_This(), swig_this); - Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; - } -#else - PyObject *dict = PyDict_New(); - if (dict) { - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } -#endif - } - return inst; -#else -#if (PY_VERSION_HEX >= 0x02010000) - PyObject *inst = 0; - PyObject *dict = PyDict_New(); - if (dict) { - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } - return (PyObject *) inst; -#else - PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); - if (inst == NULL) { - return NULL; - } - inst->in_class = (PyClassObject *)data->newargs; - Py_INCREF(inst->in_class); - inst->in_dict = PyDict_New(); - if (inst->in_dict == NULL) { - Py_DECREF(inst); - return NULL; - } -#ifdef Py_TPFLAGS_HAVE_WEAKREFS - inst->in_weakreflist = NULL; -#endif -#ifdef Py_TPFLAGS_GC - PyObject_GC_Init(inst); -#endif - PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); - return (PyObject *) inst; -#endif -#endif -} - -SWIGRUNTIME void -SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) -{ - PyObject *dict; -#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - PyDict_SetItem(dict, SWIG_This(), swig_this); - return; - } -#endif - dict = PyObject_GetAttrString(inst, (char*)"__dict__"); - PyDict_SetItem(dict, SWIG_This(), swig_this); - Py_DECREF(dict); -} - - -SWIGINTERN PyObject * -SWIG_Python_InitShadowInstance(PyObject *args) { - PyObject *obj[2]; - if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) { - return NULL; - } else { - SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]); - if (sthis) { - SwigPyObject_append((PyObject*) sthis, obj[1]); - } else { - SWIG_Python_SetSwigThis(obj[0], obj[1]); - } - return SWIG_Py_Void(); - } -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) { - SwigPyClientData *clientdata; - PyObject * robj; - int own; - - if (!ptr) - return SWIG_Py_Void(); - - clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0; - own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - if (clientdata && clientdata->pytype) { - SwigPyObject *newobj; - if (flags & SWIG_BUILTIN_TP_INIT) { - newobj = (SwigPyObject*) self; - if (newobj->ptr) { - PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0); - while (newobj->next) - newobj = (SwigPyObject *) newobj->next; - newobj->next = next_self; - newobj = (SwigPyObject *)next_self; -#ifdef SWIGPYTHON_BUILTIN - newobj->dict = 0; -#endif - } - } else { - newobj = PyObject_New(SwigPyObject, clientdata->pytype); -#ifdef SWIGPYTHON_BUILTIN - newobj->dict = 0; -#endif - } - if (newobj) { - newobj->ptr = ptr; - newobj->ty = type; - newobj->own = own; - newobj->next = 0; - return (PyObject*) newobj; - } - return SWIG_Py_Void(); - } - - assert(!(flags & SWIG_BUILTIN_TP_INIT)); - - robj = SwigPyObject_New(ptr, type, own); - if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - Py_DECREF(robj); - robj = inst; - } - return robj; -} - -/* Create a new packed object */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else -# ifdef SWIGPY_USE_CAPSULE - type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0); -# else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); -# endif - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - } - return (swig_module_info *) type_pointer; -} - -#if PY_MAJOR_VERSION < 2 -/* PyModule_AddObject function was introduced in Python 2.0. The following function - is copied out of Python/modsupport.c in python version 2.3.4 */ -SWIGINTERN int -PyModule_AddObject(PyObject *m, char *name, PyObject *o) -{ - PyObject *dict; - if (!PyModule_Check(m)) { - PyErr_SetString(PyExc_TypeError, "PyModule_AddObject() needs module as first arg"); - return SWIG_ERROR; - } - if (!o) { - PyErr_SetString(PyExc_TypeError, "PyModule_AddObject() needs non-NULL value"); - return SWIG_ERROR; - } - - dict = PyModule_GetDict(m); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); - return SWIG_ERROR; - } - if (PyDict_SetItemString(dict, name, o)) - return SWIG_ERROR; - Py_DECREF(o); - return SWIG_OK; -} -#endif - -SWIGRUNTIME void -#ifdef SWIGPY_USE_CAPSULE -SWIG_Python_DestroyModule(PyObject *obj) -#else -SWIG_Python_DestroyModule(void *vptr) -#endif -{ -#ifdef SWIGPY_USE_CAPSULE - swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME); -#else - swig_module_info *swig_module = (swig_module_info *) vptr; -#endif - swig_type_info **types = swig_module->types; - size_t i; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - SwigPyClientData *data = (SwigPyClientData *) ty->clientdata; - if (data) SwigPyClientData_Del(data); - } - } - Py_DECREF(SWIG_This()); - swig_this = NULL; -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { -#if PY_VERSION_HEX >= 0x03000000 - /* Add a dummy module object into sys.modules */ - PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION); -#else - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */ - PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table); -#endif -#ifdef SWIGPY_USE_CAPSULE - PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -#else - PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -#endif -} - -/* The python cached type query */ -SWIGRUNTIME PyObject * -SWIG_Python_TypeCache(void) { - static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); - return cache; -} - -SWIGRUNTIME swig_type_info * -SWIG_Python_TypeQuery(const char *type) -{ - PyObject *cache = SWIG_Python_TypeCache(); - PyObject *key = SWIG_Python_str_FromChar(type); - PyObject *obj = PyDict_GetItem(cache, key); - swig_type_info *descriptor; - if (obj) { -#ifdef SWIGPY_USE_CAPSULE - descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL); -#else - descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); -#endif - } else { - swig_module_info *swig_module = SWIG_GetModule(0); - descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); - if (descriptor) { -#ifdef SWIGPY_USE_CAPSULE - obj = PyCapsule_New((void*) descriptor, NULL, NULL); -#else - obj = PyCObject_FromVoidPtr(descriptor, NULL); -#endif - PyDict_SetItem(cache, key, obj); - Py_DECREF(obj); - } - } - Py_DECREF(key); - return descriptor; -} - -/* - For backward compatibility only -*/ -#define SWIG_POINTER_EXCEPTION 0 -#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - -SWIGRUNTIME int -SWIG_Python_AddErrMesg(const char* mesg, int infront) -{ - if (PyErr_Occurred()) { - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - if (value) { - char *tmp; - PyObject *old_str = PyObject_Str(value); - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str)); - } else { - PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg); - } - SWIG_Python_str_DelForPy3(tmp); - Py_DECREF(old_str); - } - return 1; - } else { - return 0; - } -} - -SWIGRUNTIME int -SWIG_Python_ArgFail(int argnum) -{ - if (PyErr_Occurred()) { - /* add information about failing argument */ - char mesg[256]; - PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - -SWIGRUNTIMEINLINE const char * -SwigPyObject_GetDesc(PyObject *self) -{ - SwigPyObject *v = (SwigPyObject *)self; - swig_type_info *ty = v ? v->ty : 0; - return ty ? ty->str : ""; -} - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (obj && SwigPyObject_Check(obj)) { - const char *otype = (const char *) SwigPyObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received", - type, otype); - return; - } - } else -#endif - { - const char *otype = (obj ? obj->ob_type->tp_name : 0); - if (otype) { - PyObject *str = PyObject_Str(obj); - const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0; - if (cstr) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", - type, otype, cstr); - SWIG_Python_str_DelForPy3(cstr); - } else { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", - type, otype); - } - Py_XDECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); -#if SWIG_POINTER_EXCEPTION - if (flags) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - SWIG_Python_ArgFail(argnum); - } -#endif - } - return result; -} - -#ifdef SWIGPYTHON_BUILTIN -SWIGRUNTIME int -SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) { - PyTypeObject *tp = obj->ob_type; - PyObject *descr; - PyObject *encoded_name; - descrsetfunc f; - int res = -1; - -# ifdef Py_USING_UNICODE - if (PyString_Check(name)) { - name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL); - if (!name) - return -1; - } else if (!PyUnicode_Check(name)) -# else - if (!PyString_Check(name)) -# endif - { - PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name); - return -1; - } else { - Py_INCREF(name); - } - - if (!tp->tp_dict) { - if (PyType_Ready(tp) < 0) - goto done; - } - - descr = _PyType_Lookup(tp, name); - f = NULL; - if (descr != NULL) - f = descr->ob_type->tp_descr_set; - if (!f) { - if (PyString_Check(name)) { - encoded_name = name; - Py_INCREF(name); - } else { - encoded_name = PyUnicode_AsUTF8String(name); - } - PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name)); - Py_DECREF(encoded_name); - } else { - res = f(descr, obj, value); - } - - done: - Py_DECREF(name); - return res; -} -#endif - - -#ifdef __cplusplus -} -#endif - - - -#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) - -#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_char swig_types[0] -#define SWIGTYPE_p_fd_set swig_types[1] -#define SWIGTYPE_p_hostent swig_types[2] -#define SWIGTYPE_p_int swig_types[3] -#define SWIGTYPE_p_long_long swig_types[4] -#define SWIGTYPE_p_msghdr swig_types[5] -#define SWIGTYPE_p_short swig_types[6] -#define SWIGTYPE_p_signed_char swig_types[7] -#define SWIGTYPE_p_sockaddr swig_types[8] -#define SWIGTYPE_p_sockaddr_storage swig_types[9] -#define SWIGTYPE_p_socklen_t swig_types[10] -#define SWIGTYPE_p_ssize_t swig_types[11] -#define SWIGTYPE_p_timeval swig_types[12] -#define SWIGTYPE_p_unsigned_char swig_types[13] -#define SWIGTYPE_p_unsigned_int swig_types[14] -#define SWIGTYPE_p_unsigned_long_long swig_types[15] -#define SWIGTYPE_p_unsigned_short swig_types[16] -static swig_type_info *swig_types[18]; -static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0}; -#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) -#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) - -/* -------- TYPES TABLE (END) -------- */ - -#if (PY_VERSION_HEX <= 0x02000000) -# if !defined(SWIG_PYTHON_CLASSIC) -# error "This python version requires swig to be run with the '-classic' option" -# endif -#endif - -/*----------------------------------------------- - @(target):= _libzt.so - ------------------------------------------------*/ -#if PY_VERSION_HEX >= 0x03000000 -# define SWIG_init PyInit__libzt - -#else -# define SWIG_init init_libzt - -#endif -#define SWIG_name "libzt" - -#define SWIGVERSION 0x030012 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a)) - - -#include - - -namespace swig { - class SwigPtr_PyObject { - protected: - PyObject *_obj; - - public: - SwigPtr_PyObject() :_obj(0) - { - } - - SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj) - { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XINCREF(_obj); - SWIG_PYTHON_THREAD_END_BLOCK; - } - - SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj) - { - if (initial_ref) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XINCREF(_obj); - SWIG_PYTHON_THREAD_END_BLOCK; - } - } - - SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) - { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XINCREF(item._obj); - Py_XDECREF(_obj); - _obj = item._obj; - SWIG_PYTHON_THREAD_END_BLOCK; - return *this; - } - - ~SwigPtr_PyObject() - { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XDECREF(_obj); - SWIG_PYTHON_THREAD_END_BLOCK; - } - - operator PyObject *() const - { - return _obj; - } - - PyObject *operator->() const - { - return _obj; - } - }; -} - - -namespace swig { - struct SwigVar_PyObject : SwigPtr_PyObject { - SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { } - - SwigVar_PyObject & operator = (PyObject* obj) - { - Py_XDECREF(_obj); - _obj = obj; - return *this; - } - }; -} - - -#include // Use the C99 official header - - -#define SWIG_FILE_WITH_INIT -#include "../../include/libzt.h" - - -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} - - -SWIGINTERN int -SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -{ -#if PY_VERSION_HEX>=0x03000000 -#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - if (PyBytes_Check(obj)) -#else - if (PyUnicode_Check(obj)) -#endif -#else - if (PyString_Check(obj)) -#endif - { - char *cstr; Py_ssize_t len; -#if PY_VERSION_HEX>=0x03000000 -#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - if (!alloc && cptr) { - /* We can't allow converting without allocation, since the internal - representation of string in Python 3 is UCS-2/UCS-4 but we require - a UTF-8 representation. - TODO(bhy) More detailed explanation */ - return SWIG_RuntimeError; - } - obj = PyUnicode_AsUTF8String(obj); - if(alloc) *alloc = SWIG_NEWOBJ; -#endif - PyBytes_AsStringAndSize(obj, &cstr, &len); -#else - PyString_AsStringAndSize(obj, &cstr, &len); -#endif - if (cptr) { - if (alloc) { - /* - In python the user should not be able to modify the inner - string representation. To warranty that, if you define - SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string - buffer is always returned. - - The default behavior is just to return the pointer value, - so, be careful. - */ -#if defined(SWIG_PYTHON_SAFE_CSTRINGS) - if (*alloc != SWIG_OLDOBJ) -#else - if (*alloc == SWIG_NEWOBJ) -#endif - { - *cptr = reinterpret_cast< char* >(memcpy(new char[len + 1], cstr, sizeof(char)*(len + 1))); - *alloc = SWIG_NEWOBJ; - } else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } else { -#if PY_VERSION_HEX>=0x03000000 -#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - *cptr = PyBytes_AsString(obj); -#else - assert(0); /* Should never reach here with Unicode strings in Python 3 */ -#endif -#else - *cptr = SWIG_Python_str_AsChar(obj); -#endif - } - } - if (psize) *psize = len + 1; -#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - Py_XDECREF(obj); -#endif - return SWIG_OK; - } else { -#if defined(SWIG_PYTHON_2_UNICODE) -#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) -#error "Cannot use both SWIG_PYTHON_2_UNICODE and SWIG_PYTHON_STRICT_BYTE_CHAR at once" -#endif -#if PY_VERSION_HEX<0x03000000 - if (PyUnicode_Check(obj)) { - char *cstr; Py_ssize_t len; - if (!alloc && cptr) { - return SWIG_RuntimeError; - } - obj = PyUnicode_AsUTF8String(obj); - if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) { - if (cptr) { - if (alloc) *alloc = SWIG_NEWOBJ; - *cptr = reinterpret_cast< char* >(memcpy(new char[len + 1], cstr, sizeof(char)*(len + 1))); - } - if (psize) *psize = len + 1; - - Py_XDECREF(obj); - return SWIG_OK; - } else { - Py_XDECREF(obj); - } - } -#endif -#endif - - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} - - - - - -SWIGINTERN int -SWIG_AsVal_double (PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; -#if PY_VERSION_HEX < 0x03000000 - } else if (PyInt_Check(obj)) { - if (val) *val = (double) PyInt_AsLong(obj); - return SWIG_OK; -#endif - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -#endif - return res; -} - - -#include - - -#include - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ -#if PY_VERSION_HEX < 0x03000000 - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else -#endif - if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - return SWIG_OverflowError; - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_bool (PyObject *obj, bool *val) -{ - int r; - if (!PyBool_Check(obj)) - return SWIG_ERROR; - r = PyObject_IsTrue(obj); - if (r == -1) - return SWIG_ERROR; - if (val) *val = r ? true : false; - return SWIG_OK; -} - - -SWIGINTERNINLINE PyObject* - SWIG_From_int (int value) -{ - return PyInt_FromLong((long) value); -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) -{ -#if PY_VERSION_HEX < 0x03000000 - if (PyInt_Check(obj)) { - long v = PyInt_AsLong(obj); - if (v >= 0) { - if (val) *val = v; - return SWIG_OK; - } else { - return SWIG_OverflowError; - } - } else -#endif - if (PyLong_Check(obj)) { - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - return SWIG_OverflowError; - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { - if (val) *val = (unsigned long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif - - -#if defined(LLONG_MAX) && !defined(SWIG_LONG_LONG_AVAILABLE) -# define SWIG_LONG_LONG_AVAILABLE -#endif - - -#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERN int -SWIG_AsVal_unsigned_SS_long_SS_long (PyObject *obj, unsigned long long *val) -{ - int res = SWIG_TypeError; - if (PyLong_Check(obj)) { - unsigned long long v = PyLong_AsUnsignedLongLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - res = SWIG_OverflowError; - } - } else { - unsigned long v; - res = SWIG_AsVal_unsigned_SS_long (obj,&v); - if (SWIG_IsOK(res)) { - if (val) *val = v; - return res; - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - const double mant_max = 1LL << DBL_MANT_DIG; - double d; - res = SWIG_AsVal_double (obj,&d); - if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, 0, mant_max)) - return SWIG_OverflowError; - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, mant_max)) { - if (val) *val = (unsigned long long)(d); - return SWIG_AddCast(res); - } - res = SWIG_TypeError; - } -#endif - return res; -} -#endif - - -SWIGINTERNINLINE int -SWIG_AsVal_size_t (PyObject * obj, size_t *val) -{ - int res = SWIG_TypeError; -#ifdef SWIG_LONG_LONG_AVAILABLE - if (sizeof(size_t) <= sizeof(unsigned long)) { -#endif - unsigned long v; - res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v); -#ifdef SWIG_LONG_LONG_AVAILABLE - } else if (sizeof(size_t) <= sizeof(unsigned long long)) { - unsigned long long v; - res = SWIG_AsVal_unsigned_SS_long_SS_long (obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v); - } -#endif - return res; -} - - -#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERNINLINE PyObject* -SWIG_From_unsigned_SS_long_SS_long (unsigned long long value) -{ - return (value > LONG_MAX) ? - PyLong_FromUnsignedLongLong(value) : PyInt_FromLong(static_cast< long >(value)); -} -#endif - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = static_cast< int >(v); - } - } - return res; -} - - - #define SWIG_From_long PyInt_FromLong - - -SWIGINTERNINLINE PyObject* -SWIG_From_unsigned_SS_long (unsigned long value) -{ - return (value > LONG_MAX) ? - PyLong_FromUnsignedLong(value) : PyInt_FromLong(static_cast< long >(value)); -} - -#ifdef __cplusplus -extern "C" { -#endif -SWIGINTERN PyObject *_wrap_zts_start(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - bool arg2 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - bool val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_start",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_start" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - ecode2 = SWIG_AsVal_bool(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_start" "', argument " "2"" of type '" "bool""'"); - } - arg2 = static_cast< bool >(val2); - result = (int)zts_start((char const *)arg1,arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_startjoin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - uint64_t arg2 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - unsigned long long val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_startjoin",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_startjoin" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_startjoin" "', argument " "2"" of type '" "uint64_t""'"); - } - arg2 = static_cast< uint64_t >(val2); - result = (int)zts_startjoin((char const *)arg1,arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_stop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - - if (!PyArg_ParseTuple(args,(char *)":zts_stop")) SWIG_fail; - zts_stop(); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_core_running(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int result; - - if (!PyArg_ParseTuple(args,(char *)":zts_core_running")) SWIG_fail; - result = (int)zts_core_running(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_stack_running(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int result; - - if (!PyArg_ParseTuple(args,(char *)":zts_stack_running")) SWIG_fail; - result = (int)zts_stack_running(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_ready(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int result; - - if (!PyArg_ParseTuple(args,(char *)":zts_ready")) SWIG_fail; - result = (int)zts_ready(); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_join(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - uint64_t arg1 ; - unsigned long long val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_join",&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_long_SS_long(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_join" "', argument " "1"" of type '" "uint64_t""'"); - } - arg1 = static_cast< uint64_t >(val1); - result = (int)zts_join(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_leave(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - uint64_t arg1 ; - unsigned long long val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_leave",&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_long_SS_long(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_leave" "', argument " "1"" of type '" "uint64_t""'"); - } - arg1 = static_cast< uint64_t >(val1); - result = (int)zts_leave(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_path(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - size_t arg2 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - size_t val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_get_path",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_get_path" "', argument " "1"" of type '" "char *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - ecode2 = SWIG_AsVal_size_t(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_get_path" "', argument " "2"" of type '" "size_t""'"); - } - arg2 = static_cast< size_t >(val2); - zts_get_path(arg1,arg2); - resultobj = SWIG_Py_Void(); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_node_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - uint64_t result; - - if (!PyArg_ParseTuple(args,(char *)":zts_get_node_id")) SWIG_fail; - result = (uint64_t)zts_get_node_id(); - resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_node_id_from_file(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - PyObject * obj0 = 0 ; - uint64_t result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_get_node_id_from_file",&obj0)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_get_node_id_from_file" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - result = (uint64_t)zts_get_node_id_from_file((char const *)arg1); - resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result)); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_has_address(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - uint64_t arg1 ; - unsigned long long val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_has_address",&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_long_SS_long(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_has_address" "', argument " "1"" of type '" "uint64_t""'"); - } - arg1 = static_cast< uint64_t >(val1); - result = (int)zts_has_address(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_num_assigned_addresses(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - uint64_t arg1 ; - unsigned long long val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_get_num_assigned_addresses",&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_long_SS_long(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_get_num_assigned_addresses" "', argument " "1"" of type '" "uint64_t""'"); - } - arg1 = static_cast< uint64_t >(val1); - result = (int)zts_get_num_assigned_addresses(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_address_at_index(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - uint64_t arg1 ; - int arg2 ; - sockaddr_storage *arg3 = (sockaddr_storage *) 0 ; - unsigned long long val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_get_address_at_index",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_long_SS_long(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_get_address_at_index" "', argument " "1"" of type '" "uint64_t""'"); - } - arg1 = static_cast< uint64_t >(val1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_get_address_at_index" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_sockaddr_storage, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_get_address_at_index" "', argument " "3"" of type '" "sockaddr_storage *""'"); - } - arg3 = reinterpret_cast< sockaddr_storage * >(argp3); - result = (int)zts_get_address_at_index(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_address(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - uint64_t arg1 ; - sockaddr_storage *arg2 = (sockaddr_storage *) 0 ; - int arg3 ; - unsigned long long val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - int val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_get_address",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_long_SS_long(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_get_address" "', argument " "1"" of type '" "uint64_t""'"); - } - arg1 = static_cast< uint64_t >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_sockaddr_storage, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_get_address" "', argument " "2"" of type '" "sockaddr_storage *""'"); - } - arg2 = reinterpret_cast< sockaddr_storage * >(argp2); - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_get_address" "', argument " "3"" of type '" "int""'"); - } - arg3 = static_cast< int >(val3); - result = (int)zts_get_address(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_6plane_addr(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - sockaddr_storage *arg1 = (sockaddr_storage *) 0 ; - uint64_t arg2 ; - uint64_t arg3 ; - void *argp1 = 0 ; - int res1 = 0 ; - unsigned long long val2 ; - int ecode2 = 0 ; - unsigned long long val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_get_6plane_addr",&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_sockaddr_storage, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_get_6plane_addr" "', argument " "1"" of type '" "sockaddr_storage *""'"); - } - arg1 = reinterpret_cast< sockaddr_storage * >(argp1); - ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_get_6plane_addr" "', argument " "2"" of type '" "uint64_t""'"); - } - arg2 = static_cast< uint64_t >(val2); - ecode3 = SWIG_AsVal_unsigned_SS_long_SS_long(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_get_6plane_addr" "', argument " "3"" of type '" "uint64_t""'"); - } - arg3 = static_cast< uint64_t >(val3); - zts_get_6plane_addr(arg1,arg2,arg3); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_rfc4193_addr(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - sockaddr_storage *arg1 = (sockaddr_storage *) 0 ; - uint64_t arg2 ; - uint64_t arg3 ; - void *argp1 = 0 ; - int res1 = 0 ; - unsigned long long val2 ; - int ecode2 = 0 ; - unsigned long long val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_get_rfc4193_addr",&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_sockaddr_storage, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_get_rfc4193_addr" "', argument " "1"" of type '" "sockaddr_storage *""'"); - } - arg1 = reinterpret_cast< sockaddr_storage * >(argp1); - ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_get_rfc4193_addr" "', argument " "2"" of type '" "uint64_t""'"); - } - arg2 = static_cast< uint64_t >(val2); - ecode3 = SWIG_AsVal_unsigned_SS_long_SS_long(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_get_rfc4193_addr" "', argument " "3"" of type '" "uint64_t""'"); - } - arg3 = static_cast< uint64_t >(val3); - zts_get_rfc4193_addr(arg1,arg2,arg3); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_peer_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - unsigned long result; - - if (!PyArg_ParseTuple(args,(char *)":zts_get_peer_count")) SWIG_fail; - result = (unsigned long)zts_get_peer_count(); - resultobj = SWIG_From_unsigned_SS_long(static_cast< unsigned long >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_get_peer_address(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - uint64_t arg2 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - unsigned long long val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_get_peer_address",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_get_peer_address" "', argument " "1"" of type '" "char *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_get_peer_address" "', argument " "2"" of type '" "uint64_t""'"); - } - arg2 = static_cast< uint64_t >(val2); - result = (int)zts_get_peer_address(arg1,arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_socket(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - int arg2 ; - int arg3 ; - int val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_socket",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_socket" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_socket" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_socket" "', argument " "3"" of type '" "int""'"); - } - arg3 = static_cast< int >(val3); - result = (int)zts_socket(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_connect(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - sockaddr *arg2 = (sockaddr *) 0 ; - socklen_t arg3 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_connect",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_connect" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_connect" "', argument " "2"" of type '" "sockaddr const *""'"); - } - arg2 = reinterpret_cast< sockaddr * >(argp2); - { - res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_socklen_t, 0 | 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_connect" "', argument " "3"" of type '" "socklen_t""'"); - } - if (!argp3) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "zts_connect" "', argument " "3"" of type '" "socklen_t""'"); - } else { - socklen_t * temp = reinterpret_cast< socklen_t * >(argp3); - arg3 = *temp; - if (SWIG_IsNewObj(res3)) delete temp; - } - } - result = (int)zts_connect(arg1,(sockaddr const *)arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_bind(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - sockaddr *arg2 = (sockaddr *) 0 ; - socklen_t arg3 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_bind",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_bind" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_bind" "', argument " "2"" of type '" "sockaddr const *""'"); - } - arg2 = reinterpret_cast< sockaddr * >(argp2); - { - res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_socklen_t, 0 | 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_bind" "', argument " "3"" of type '" "socklen_t""'"); - } - if (!argp3) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "zts_bind" "', argument " "3"" of type '" "socklen_t""'"); - } else { - socklen_t * temp = reinterpret_cast< socklen_t * >(argp3); - arg3 = *temp; - if (SWIG_IsNewObj(res3)) delete temp; - } - } - result = (int)zts_bind(arg1,(sockaddr const *)arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_listen(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - int arg2 ; - int val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_listen",&obj0,&obj1)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_listen" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_listen" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - result = (int)zts_listen(arg1,arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - sockaddr *arg2 = (sockaddr *) 0 ; - socklen_t *arg3 = (socklen_t *) 0 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_accept",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_accept" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_accept" "', argument " "2"" of type '" "sockaddr *""'"); - } - arg2 = reinterpret_cast< sockaddr * >(argp2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_socklen_t, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_accept" "', argument " "3"" of type '" "socklen_t *""'"); - } - arg3 = reinterpret_cast< socklen_t * >(argp3); - result = (int)zts_accept(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_setsockopt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - int arg2 ; - int arg3 ; - void *arg4 = (void *) 0 ; - socklen_t arg5 ; - int val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int val3 ; - int ecode3 = 0 ; - int res4 ; - void *argp5 ; - int res5 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOOOO:zts_setsockopt",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_setsockopt" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_setsockopt" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_setsockopt" "', argument " "3"" of type '" "int""'"); - } - arg3 = static_cast< int >(val3); - res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "zts_setsockopt" "', argument " "4"" of type '" "void const *""'"); - } - { - res5 = SWIG_ConvertPtr(obj4, &argp5, SWIGTYPE_p_socklen_t, 0 | 0); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "zts_setsockopt" "', argument " "5"" of type '" "socklen_t""'"); - } - if (!argp5) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "zts_setsockopt" "', argument " "5"" of type '" "socklen_t""'"); - } else { - socklen_t * temp = reinterpret_cast< socklen_t * >(argp5); - arg5 = *temp; - if (SWIG_IsNewObj(res5)) delete temp; - } - } - result = (int)zts_setsockopt(arg1,arg2,arg3,(void const *)arg4,arg5); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_getsockopt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - int arg2 ; - int arg3 ; - void *arg4 = (void *) 0 ; - socklen_t *arg5 = (socklen_t *) 0 ; - int val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int val3 ; - int ecode3 = 0 ; - int res4 ; - void *argp5 = 0 ; - int res5 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOOOO:zts_getsockopt",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_getsockopt" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_getsockopt" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_getsockopt" "', argument " "3"" of type '" "int""'"); - } - arg3 = static_cast< int >(val3); - res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "zts_getsockopt" "', argument " "4"" of type '" "void *""'"); - } - res5 = SWIG_ConvertPtr(obj4, &argp5,SWIGTYPE_p_socklen_t, 0 | 0 ); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "zts_getsockopt" "', argument " "5"" of type '" "socklen_t *""'"); - } - arg5 = reinterpret_cast< socklen_t * >(argp5); - result = (int)zts_getsockopt(arg1,arg2,arg3,arg4,arg5); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_getsockname(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - sockaddr *arg2 = (sockaddr *) 0 ; - socklen_t *arg3 = (socklen_t *) 0 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_getsockname",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_getsockname" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_getsockname" "', argument " "2"" of type '" "sockaddr *""'"); - } - arg2 = reinterpret_cast< sockaddr * >(argp2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_socklen_t, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_getsockname" "', argument " "3"" of type '" "socklen_t *""'"); - } - arg3 = reinterpret_cast< socklen_t * >(argp3); - result = (int)zts_getsockname(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_getpeername(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - sockaddr *arg2 = (sockaddr *) 0 ; - socklen_t *arg3 = (socklen_t *) 0 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_getpeername",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_getpeername" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_getpeername" "', argument " "2"" of type '" "sockaddr *""'"); - } - arg2 = reinterpret_cast< sockaddr * >(argp2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_socklen_t, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_getpeername" "', argument " "3"" of type '" "socklen_t *""'"); - } - arg3 = reinterpret_cast< socklen_t * >(argp3); - result = (int)zts_getpeername(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_gethostname(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - size_t arg2 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - size_t val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_gethostname",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_gethostname" "', argument " "1"" of type '" "char *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - ecode2 = SWIG_AsVal_size_t(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_gethostname" "', argument " "2"" of type '" "size_t""'"); - } - arg2 = static_cast< size_t >(val2); - result = (int)zts_gethostname(arg1,arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_sethostname(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - size_t arg2 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - size_t val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_sethostname",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_sethostname" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - ecode2 = SWIG_AsVal_size_t(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_sethostname" "', argument " "2"" of type '" "size_t""'"); - } - arg2 = static_cast< size_t >(val2); - result = (int)zts_sethostname((char const *)arg1,arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_gethostbyname(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - PyObject * obj0 = 0 ; - hostent *result = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_gethostbyname",&obj0)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_gethostbyname" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - result = (hostent *)zts_gethostbyname((char const *)arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_hostent, 0 | 0 ); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_close(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - int val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_close",&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_close" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - result = (int)zts_close(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_select(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - fd_set *arg2 = (fd_set *) 0 ; - fd_set *arg3 = (fd_set *) 0 ; - fd_set *arg4 = (fd_set *) 0 ; - timeval *arg5 = (timeval *) 0 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - void *argp4 = 0 ; - int res4 = 0 ; - void *argp5 = 0 ; - int res5 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOOOO:zts_select",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_select" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_fd_set, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_select" "', argument " "2"" of type '" "fd_set *""'"); - } - arg2 = reinterpret_cast< fd_set * >(argp2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_fd_set, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_select" "', argument " "3"" of type '" "fd_set *""'"); - } - arg3 = reinterpret_cast< fd_set * >(argp3); - res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_fd_set, 0 | 0 ); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "zts_select" "', argument " "4"" of type '" "fd_set *""'"); - } - arg4 = reinterpret_cast< fd_set * >(argp4); - res5 = SWIG_ConvertPtr(obj4, &argp5,SWIGTYPE_p_timeval, 0 | 0 ); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "zts_select" "', argument " "5"" of type '" "timeval *""'"); - } - arg5 = reinterpret_cast< timeval * >(argp5); - result = (int)zts_select(arg1,arg2,arg3,arg4,arg5); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_fcntl(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - int arg2 ; - int arg3 ; - int val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_fcntl",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_fcntl" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_fcntl" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_fcntl" "', argument " "3"" of type '" "int""'"); - } - arg3 = static_cast< int >(val3); - result = (int)zts_fcntl(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_ioctl(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - unsigned long arg2 ; - void *arg3 = (void *) 0 ; - int val1 ; - int ecode1 = 0 ; - unsigned long val2 ; - int ecode2 = 0 ; - int res3 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_ioctl",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_ioctl" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - ecode2 = SWIG_AsVal_unsigned_SS_long(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_ioctl" "', argument " "2"" of type '" "unsigned long""'"); - } - arg2 = static_cast< unsigned long >(val2); - res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "zts_ioctl" "', argument " "3"" of type '" "void *""'"); - } - result = (int)zts_ioctl(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_send(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - void *arg2 = (void *) 0 ; - size_t arg3 ; - int arg4 ; - int val1 ; - int ecode1 = 0 ; - int res2 ; - size_t val3 ; - int ecode3 = 0 ; - int val4 ; - int ecode4 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - ssize_t result; - - if (!PyArg_ParseTuple(args,(char *)"OOOO:zts_send",&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_send" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_send" "', argument " "2"" of type '" "void const *""'"); - } - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_send" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - ecode4 = SWIG_AsVal_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "zts_send" "', argument " "4"" of type '" "int""'"); - } - arg4 = static_cast< int >(val4); - result = zts_send(arg1,(void const *)arg2,arg3,arg4); - resultobj = SWIG_NewPointerObj((new ssize_t(static_cast< const ssize_t& >(result))), SWIGTYPE_p_ssize_t, SWIG_POINTER_OWN | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_sendto(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - void *arg2 = (void *) 0 ; - size_t arg3 ; - int arg4 ; - sockaddr *arg5 = (sockaddr *) 0 ; - socklen_t arg6 ; - int val1 ; - int ecode1 = 0 ; - int res2 ; - size_t val3 ; - int ecode3 = 0 ; - int val4 ; - int ecode4 = 0 ; - void *argp5 = 0 ; - int res5 = 0 ; - void *argp6 ; - int res6 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - PyObject * obj5 = 0 ; - ssize_t result; - - if (!PyArg_ParseTuple(args,(char *)"OOOOOO:zts_sendto",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_sendto" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_sendto" "', argument " "2"" of type '" "void const *""'"); - } - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_sendto" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - ecode4 = SWIG_AsVal_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "zts_sendto" "', argument " "4"" of type '" "int""'"); - } - arg4 = static_cast< int >(val4); - res5 = SWIG_ConvertPtr(obj4, &argp5,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "zts_sendto" "', argument " "5"" of type '" "sockaddr const *""'"); - } - arg5 = reinterpret_cast< sockaddr * >(argp5); - { - res6 = SWIG_ConvertPtr(obj5, &argp6, SWIGTYPE_p_socklen_t, 0 | 0); - if (!SWIG_IsOK(res6)) { - SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "zts_sendto" "', argument " "6"" of type '" "socklen_t""'"); - } - if (!argp6) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "zts_sendto" "', argument " "6"" of type '" "socklen_t""'"); - } else { - socklen_t * temp = reinterpret_cast< socklen_t * >(argp6); - arg6 = *temp; - if (SWIG_IsNewObj(res6)) delete temp; - } - } - result = zts_sendto(arg1,(void const *)arg2,arg3,arg4,(sockaddr const *)arg5,arg6); - resultobj = SWIG_NewPointerObj((new ssize_t(static_cast< const ssize_t& >(result))), SWIGTYPE_p_ssize_t, SWIG_POINTER_OWN | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_sendmsg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - msghdr *arg2 = (msghdr *) 0 ; - int arg3 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - int val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - ssize_t result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_sendmsg",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_sendmsg" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_msghdr, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_sendmsg" "', argument " "2"" of type '" "msghdr const *""'"); - } - arg2 = reinterpret_cast< msghdr * >(argp2); - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_sendmsg" "', argument " "3"" of type '" "int""'"); - } - arg3 = static_cast< int >(val3); - result = zts_sendmsg(arg1,(msghdr const *)arg2,arg3); - resultobj = SWIG_NewPointerObj((new ssize_t(static_cast< const ssize_t& >(result))), SWIGTYPE_p_ssize_t, SWIG_POINTER_OWN | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_recv(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - void *arg2 = (void *) 0 ; - size_t arg3 ; - int arg4 ; - int val1 ; - int ecode1 = 0 ; - int res2 ; - size_t val3 ; - int ecode3 = 0 ; - int val4 ; - int ecode4 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - ssize_t result; - - if (!PyArg_ParseTuple(args,(char *)"OOOO:zts_recv",&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_recv" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_recv" "', argument " "2"" of type '" "void *""'"); - } - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_recv" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - ecode4 = SWIG_AsVal_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "zts_recv" "', argument " "4"" of type '" "int""'"); - } - arg4 = static_cast< int >(val4); - result = zts_recv(arg1,arg2,arg3,arg4); - resultobj = SWIG_NewPointerObj((new ssize_t(static_cast< const ssize_t& >(result))), SWIGTYPE_p_ssize_t, SWIG_POINTER_OWN | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_recvfrom(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - void *arg2 = (void *) 0 ; - size_t arg3 ; - int arg4 ; - sockaddr *arg5 = (sockaddr *) 0 ; - socklen_t *arg6 = (socklen_t *) 0 ; - int val1 ; - int ecode1 = 0 ; - int res2 ; - size_t val3 ; - int ecode3 = 0 ; - int val4 ; - int ecode4 = 0 ; - void *argp5 = 0 ; - int res5 = 0 ; - void *argp6 = 0 ; - int res6 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - PyObject * obj5 = 0 ; - ssize_t result; - - if (!PyArg_ParseTuple(args,(char *)"OOOOOO:zts_recvfrom",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_recvfrom" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_recvfrom" "', argument " "2"" of type '" "void *""'"); - } - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_recvfrom" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - ecode4 = SWIG_AsVal_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "zts_recvfrom" "', argument " "4"" of type '" "int""'"); - } - arg4 = static_cast< int >(val4); - res5 = SWIG_ConvertPtr(obj4, &argp5,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "zts_recvfrom" "', argument " "5"" of type '" "sockaddr *""'"); - } - arg5 = reinterpret_cast< sockaddr * >(argp5); - res6 = SWIG_ConvertPtr(obj5, &argp6,SWIGTYPE_p_socklen_t, 0 | 0 ); - if (!SWIG_IsOK(res6)) { - SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "zts_recvfrom" "', argument " "6"" of type '" "socklen_t *""'"); - } - arg6 = reinterpret_cast< socklen_t * >(argp6); - result = zts_recvfrom(arg1,arg2,arg3,arg4,arg5,arg6); - resultobj = SWIG_NewPointerObj((new ssize_t(static_cast< const ssize_t& >(result))), SWIGTYPE_p_ssize_t, SWIG_POINTER_OWN | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_recvmsg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - msghdr *arg2 = (msghdr *) 0 ; - int arg3 ; - int val1 ; - int ecode1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - int val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - ssize_t result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_recvmsg",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_recvmsg" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_msghdr, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_recvmsg" "', argument " "2"" of type '" "msghdr *""'"); - } - arg2 = reinterpret_cast< msghdr * >(argp2); - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_recvmsg" "', argument " "3"" of type '" "int""'"); - } - arg3 = static_cast< int >(val3); - result = zts_recvmsg(arg1,arg2,arg3); - resultobj = SWIG_NewPointerObj((new ssize_t(static_cast< const ssize_t& >(result))), SWIGTYPE_p_ssize_t, SWIG_POINTER_OWN | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_read(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - void *arg2 = (void *) 0 ; - size_t arg3 ; - int val1 ; - int ecode1 = 0 ; - int res2 ; - size_t val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_read",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_read" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_read" "', argument " "2"" of type '" "void *""'"); - } - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_read" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - result = (int)zts_read(arg1,arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_write(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - void *arg2 = (void *) 0 ; - size_t arg3 ; - int val1 ; - int ecode1 = 0 ; - int res2 ; - size_t val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OOO:zts_write",&obj0,&obj1,&obj2)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_write" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "zts_write" "', argument " "2"" of type '" "void const *""'"); - } - ecode3 = SWIG_AsVal_size_t(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "zts_write" "', argument " "3"" of type '" "size_t""'"); - } - arg3 = static_cast< size_t >(val3); - result = (int)zts_write(arg1,(void const *)arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_shutdown(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - int arg1 ; - int arg2 ; - int val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"OO:zts_shutdown",&obj0,&obj1)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_shutdown" "', argument " "1"" of type '" "int""'"); - } - arg1 = static_cast< int >(val1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_shutdown" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); - result = (int)zts_shutdown(arg1,arg2); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_add_dns_nameserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - sockaddr *arg1 = (sockaddr *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_add_dns_nameserver",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_add_dns_nameserver" "', argument " "1"" of type '" "sockaddr *""'"); - } - arg1 = reinterpret_cast< sockaddr * >(argp1); - result = (int)zts_add_dns_nameserver(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_zts_del_dns_nameserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - sockaddr *arg1 = (sockaddr *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - int result; - - if (!PyArg_ParseTuple(args,(char *)"O:zts_del_dns_nameserver",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_sockaddr, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "zts_del_dns_nameserver" "', argument " "1"" of type '" "sockaddr *""'"); - } - arg1 = reinterpret_cast< sockaddr * >(argp1); - result = (int)zts_del_dns_nameserver(arg1); - resultobj = SWIG_From_int(static_cast< int >(result)); - return resultobj; -fail: - return NULL; -} - - -static PyMethodDef SwigMethods[] = { - { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL}, - { (char *)"zts_start", _wrap_zts_start, METH_VARARGS, NULL}, - { (char *)"zts_startjoin", _wrap_zts_startjoin, METH_VARARGS, NULL}, - { (char *)"zts_stop", _wrap_zts_stop, METH_VARARGS, NULL}, - { (char *)"zts_core_running", _wrap_zts_core_running, METH_VARARGS, NULL}, - { (char *)"zts_stack_running", _wrap_zts_stack_running, METH_VARARGS, NULL}, - { (char *)"zts_ready", _wrap_zts_ready, METH_VARARGS, NULL}, - { (char *)"zts_join", _wrap_zts_join, METH_VARARGS, NULL}, - { (char *)"zts_leave", _wrap_zts_leave, METH_VARARGS, NULL}, - { (char *)"zts_get_path", _wrap_zts_get_path, METH_VARARGS, NULL}, - { (char *)"zts_get_node_id", _wrap_zts_get_node_id, METH_VARARGS, NULL}, - { (char *)"zts_get_node_id_from_file", _wrap_zts_get_node_id_from_file, METH_VARARGS, NULL}, - { (char *)"zts_has_address", _wrap_zts_has_address, METH_VARARGS, NULL}, - { (char *)"zts_get_num_assigned_addresses", _wrap_zts_get_num_assigned_addresses, METH_VARARGS, NULL}, - { (char *)"zts_get_address_at_index", _wrap_zts_get_address_at_index, METH_VARARGS, NULL}, - { (char *)"zts_get_address", _wrap_zts_get_address, METH_VARARGS, NULL}, - { (char *)"zts_get_6plane_addr", _wrap_zts_get_6plane_addr, METH_VARARGS, NULL}, - { (char *)"zts_get_rfc4193_addr", _wrap_zts_get_rfc4193_addr, METH_VARARGS, NULL}, - { (char *)"zts_get_peer_count", _wrap_zts_get_peer_count, METH_VARARGS, NULL}, - { (char *)"zts_get_peer_address", _wrap_zts_get_peer_address, METH_VARARGS, NULL}, - { (char *)"zts_socket", _wrap_zts_socket, METH_VARARGS, NULL}, - { (char *)"zts_connect", _wrap_zts_connect, METH_VARARGS, NULL}, - { (char *)"zts_bind", _wrap_zts_bind, METH_VARARGS, NULL}, - { (char *)"zts_listen", _wrap_zts_listen, METH_VARARGS, NULL}, - { (char *)"zts_accept", _wrap_zts_accept, METH_VARARGS, NULL}, - { (char *)"zts_setsockopt", _wrap_zts_setsockopt, METH_VARARGS, NULL}, - { (char *)"zts_getsockopt", _wrap_zts_getsockopt, METH_VARARGS, NULL}, - { (char *)"zts_getsockname", _wrap_zts_getsockname, METH_VARARGS, NULL}, - { (char *)"zts_getpeername", _wrap_zts_getpeername, METH_VARARGS, NULL}, - { (char *)"zts_gethostname", _wrap_zts_gethostname, METH_VARARGS, NULL}, - { (char *)"zts_sethostname", _wrap_zts_sethostname, METH_VARARGS, NULL}, - { (char *)"zts_gethostbyname", _wrap_zts_gethostbyname, METH_VARARGS, NULL}, - { (char *)"zts_close", _wrap_zts_close, METH_VARARGS, NULL}, - { (char *)"zts_select", _wrap_zts_select, METH_VARARGS, NULL}, - { (char *)"zts_fcntl", _wrap_zts_fcntl, METH_VARARGS, NULL}, - { (char *)"zts_ioctl", _wrap_zts_ioctl, METH_VARARGS, NULL}, - { (char *)"zts_send", _wrap_zts_send, METH_VARARGS, NULL}, - { (char *)"zts_sendto", _wrap_zts_sendto, METH_VARARGS, NULL}, - { (char *)"zts_sendmsg", _wrap_zts_sendmsg, METH_VARARGS, NULL}, - { (char *)"zts_recv", _wrap_zts_recv, METH_VARARGS, NULL}, - { (char *)"zts_recvfrom", _wrap_zts_recvfrom, METH_VARARGS, NULL}, - { (char *)"zts_recvmsg", _wrap_zts_recvmsg, METH_VARARGS, NULL}, - { (char *)"zts_read", _wrap_zts_read, METH_VARARGS, NULL}, - { (char *)"zts_write", _wrap_zts_write, METH_VARARGS, NULL}, - { (char *)"zts_shutdown", _wrap_zts_shutdown, METH_VARARGS, NULL}, - { (char *)"zts_add_dns_nameserver", _wrap_zts_add_dns_nameserver, METH_VARARGS, NULL}, - { (char *)"zts_del_dns_nameserver", _wrap_zts_del_dns_nameserver, METH_VARARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_fd_set = {"_p_fd_set", "fd_set *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_hostent = {"_p_hostent", "hostent *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_msghdr = {"_p_msghdr", "msghdr *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_sockaddr = {"_p_sockaddr", "sockaddr *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_sockaddr_storage = {"_p_sockaddr_storage", "sockaddr_storage *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_socklen_t = {"_p_socklen_t", "socklen_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ssize_t = {"_p_ssize_t", "ssize_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_timeval = {"_p_timeval", "timeval *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_char, - &_swigt__p_fd_set, - &_swigt__p_hostent, - &_swigt__p_int, - &_swigt__p_long_long, - &_swigt__p_msghdr, - &_swigt__p_short, - &_swigt__p_signed_char, - &_swigt__p_sockaddr, - &_swigt__p_sockaddr_storage, - &_swigt__p_socklen_t, - &_swigt__p_ssize_t, - &_swigt__p_timeval, - &_swigt__p_unsigned_char, - &_swigt__p_unsigned_int, - &_swigt__p_unsigned_long_long, - &_swigt__p_unsigned_short, -}; - -static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_fd_set[] = { {&_swigt__p_fd_set, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_hostent[] = { {&_swigt__p_hostent, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_msghdr[] = { {&_swigt__p_msghdr, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_sockaddr[] = { {&_swigt__p_sockaddr, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_sockaddr_storage[] = { {&_swigt__p_sockaddr_storage, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_socklen_t[] = { {&_swigt__p_socklen_t, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_ssize_t[] = { {&_swigt__p_ssize_t, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_timeval[] = { {&_swigt__p_timeval, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_char, - _swigc__p_fd_set, - _swigc__p_hostent, - _swigc__p_int, - _swigc__p_long_long, - _swigc__p_msghdr, - _swigc__p_short, - _swigc__p_signed_char, - _swigc__p_sockaddr, - _swigc__p_sockaddr_storage, - _swigc__p_socklen_t, - _swigc__p_ssize_t, - _swigc__p_timeval, - _swigc__p_unsigned_char, - _swigc__p_unsigned_int, - _swigc__p_unsigned_long_long, - _swigc__p_unsigned_short, -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { -{0, 0, 0, 0.0, 0, 0}}; - -#ifdef __cplusplus -} -#endif -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned statically to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - - -SWIGRUNTIME void -SWIG_InitializeModule(void *clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int init; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - init = 1; - } else { - init = 0; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - iter=module_head; - do { - if (iter==&swig_module) { - /* Our module is already in the list, so there's nothing more to do. */ - return; - } - iter=iter->next; - } while (iter!= module_head); - - /* otherwise we must add our module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* When multiple interpreters are used, a module could have already been initialized in - a different interpreter, but not yet have a pointer in this interpreter. - In this case, we do not want to continue adding types... everything should be - set up already */ - if (init == 0) return; - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %d\n", swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ - /* c-mode */ -#endif -} -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - /* Python-specific SWIG API */ -#define SWIG_newvarlink() SWIG_Python_newvarlink() -#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) -#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) - - /* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - - typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; - } swig_globalvar; - - typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; - } swig_varlinkobject; - - SWIGINTERN PyObject * - swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_InternFromString(""); -#else - return PyString_FromString(""); -#endif - } - - SWIGINTERN PyObject * - swig_varlink_str(swig_varlinkobject *v) { -#if PY_VERSION_HEX >= 0x03000000 - PyObject *str = PyUnicode_InternFromString("("); - PyObject *tail; - PyObject *joined; - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - tail = PyUnicode_FromString(var->name); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; - if (var->next) { - tail = PyUnicode_InternFromString(", "); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; - } - } - tail = PyUnicode_InternFromString(")"); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; -#else - PyObject *str = PyString_FromString("("); - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - PyString_ConcatAndDel(&str,PyString_FromString(var->name)); - if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); - } - PyString_ConcatAndDel(&str,PyString_FromString(")")); -#endif - return str; - } - - SWIGINTERN int - swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { - char *tmp; - PyObject *str = swig_varlink_str(v); - fprintf(fp,"Swig global variables "); - fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str)); - SWIG_Python_str_DelForPy3(tmp); - Py_DECREF(str); - return 0; - } - - SWIGINTERN void - swig_varlink_dealloc(swig_varlinkobject *v) { - swig_globalvar *var = v->vars; - while (var) { - swig_globalvar *n = var->next; - free(var->name); - free(var); - var = n; - } - } - - SWIGINTERN PyObject * - swig_varlink_getattr(swig_varlinkobject *v, char *n) { - PyObject *res = NULL; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->get_attr)(); - break; - } - var = var->next; - } - if (res == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); - } - return res; - } - - SWIGINTERN int - swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - int res = 1; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->set_attr)(p); - break; - } - var = var->next; - } - if (res == 1 && !PyErr_Occurred()) { - PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); - } - return res; - } - - SWIGINTERN PyTypeObject* - swig_varlink_type(void) { - static char varlink__doc__[] = "Swig var link object"; - static PyTypeObject varlink_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(NULL, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - (char *)"swigvarlink", /* tp_name */ - sizeof(swig_varlinkobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor) swig_varlink_dealloc, /* tp_dealloc */ - (printfunc) swig_varlink_print, /* tp_print */ - (getattrfunc) swig_varlink_getattr, /* tp_getattr */ - (setattrfunc) swig_varlink_setattr, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc) swig_varlink_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - varlink__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#if PY_VERSION_HEX >= 0x02060000 - 0, /* tp_version_tag */ -#endif -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ -#if PY_VERSION_HEX >= 0x02050000 - 0, /* tp_prev */ -#endif - 0 /* tp_next */ -#endif - }; - varlink_type = tmp; - type_init = 1; -#if PY_VERSION_HEX < 0x02020000 - varlink_type.ob_type = &PyType_Type; -#else - if (PyType_Ready(&varlink_type) < 0) - return NULL; -#endif - } - return &varlink_type; - } - - /* Create a variable linking object for use later */ - SWIGINTERN PyObject * - SWIG_Python_newvarlink(void) { - swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); - if (result) { - result->vars = 0; - } - return ((PyObject*) result); - } - - SWIGINTERN void - SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v = (swig_varlinkobject *) p; - swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - if (gv) { - size_t size = strlen(name)+1; - gv->name = (char *)malloc(size); - if (gv->name) { - strncpy(gv->name,name,size); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - } - } - v->vars = gv; - } - - SWIGINTERN PyObject * - SWIG_globals(void) { - static PyObject *_SWIG_globals = 0; - if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); - return _SWIG_globals; - } - - /* ----------------------------------------------------------------------------- - * constants/methods manipulation - * ----------------------------------------------------------------------------- */ - - /* Install Constants */ - SWIGINTERN void - SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { - PyObject *obj = 0; - size_t i; - for (i = 0; constants[i].type; ++i) { - switch(constants[i].type) { - case SWIG_PY_POINTER: - obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); - break; - case SWIG_PY_BINARY: - obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d, constants[i].name, obj); - Py_DECREF(obj); - } - } - } - - /* -----------------------------------------------------------------------------*/ - /* Fix SwigMethods to carry the callback ptrs when needed */ - /* -----------------------------------------------------------------------------*/ - - SWIGINTERN void - SWIG_Python_FixMethods(PyMethodDef *methods, - swig_const_info *const_table, - swig_type_info **types, - swig_type_info **types_initial) { - size_t i; - for (i = 0; methods[i].ml_name; ++i) { - const char *c = methods[i].ml_doc; - if (!c) continue; - c = strstr(c, "swig_ptr: "); - if (c) { - int j; - swig_const_info *ci = 0; - const char *name = c + 10; - for (j = 0; const_table[j].type; ++j) { - if (strncmp(const_table[j].name, name, - strlen(const_table[j].name)) == 0) { - ci = &(const_table[j]); - break; - } - } - if (ci) { - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - strncpy(buff, methods[i].ml_doc, ldoc); - buff += ldoc; - strncpy(buff, "swig_ptr: ", 10); - buff += 10; - SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); - methods[i].ml_doc = ndoc; - } - } - } - } - } - } - -#ifdef __cplusplus -} -#endif - -/* -----------------------------------------------------------------------------* - * Partial Init method - * -----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" -#endif - -SWIGEXPORT -#if PY_VERSION_HEX >= 0x03000000 -PyObject* -#else -void -#endif -SWIG_init(void) { - PyObject *m, *d, *md; -#if PY_VERSION_HEX >= 0x03000000 - static struct PyModuleDef SWIG_module = { -# if PY_VERSION_HEX >= 0x03020000 - PyModuleDef_HEAD_INIT, -# else - { - PyObject_HEAD_INIT(NULL) - NULL, /* m_init */ - 0, /* m_index */ - NULL, /* m_copy */ - }, -# endif - (char *) SWIG_name, - NULL, - -1, - SwigMethods, - NULL, - NULL, - NULL, - NULL - }; -#endif - -#if defined(SWIGPYTHON_BUILTIN) - static SwigPyClientData SwigPyObject_clientdata = { - 0, 0, 0, 0, 0, 0, 0 - }; - static PyGetSetDef this_getset_def = { - (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL - }; - static SwigPyGetSet thisown_getset_closure = { - (PyCFunction) SwigPyObject_own, - (PyCFunction) SwigPyObject_own - }; - static PyGetSetDef thisown_getset_def = { - (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure - }; - PyTypeObject *builtin_pytype; - int builtin_base_count; - swig_type_info *builtin_basetype; - PyObject *tuple; - PyGetSetDescrObject *static_getset; - PyTypeObject *metatype; - PyTypeObject *swigpyobject; - SwigPyClientData *cd; - PyObject *public_interface, *public_symbol; - PyObject *this_descr; - PyObject *thisown_descr; - PyObject *self = 0; - int i; - - (void)builtin_pytype; - (void)builtin_base_count; - (void)builtin_basetype; - (void)tuple; - (void)static_getset; - (void)self; - - /* Metaclass is used to implement static member variables */ - metatype = SwigPyObjectType(); - assert(metatype); -#endif - - /* Fix SwigMethods to carry the callback ptrs when needed */ - SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); - -#if PY_VERSION_HEX >= 0x03000000 - m = PyModule_Create(&SWIG_module); -#else - m = Py_InitModule((char *) SWIG_name, SwigMethods); -#endif - - md = d = PyModule_GetDict(m); - (void)md; - - SWIG_InitializeModule(0); - -#ifdef SWIGPYTHON_BUILTIN - swigpyobject = SwigPyObject_TypeOnce(); - - SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject"); - assert(SwigPyObject_stype); - cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; - if (!cd) { - SwigPyObject_stype->clientdata = &SwigPyObject_clientdata; - SwigPyObject_clientdata.pytype = swigpyobject; - } else if (swigpyobject->tp_basicsize != cd->pytype->tp_basicsize) { - PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules."); -# if PY_VERSION_HEX >= 0x03000000 - return NULL; -# else - return; -# endif - } - - /* All objects have a 'this' attribute */ - this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def); - (void)this_descr; - - /* All objects have a 'thisown' attribute */ - thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def); - (void)thisown_descr; - - public_interface = PyList_New(0); - public_symbol = 0; - (void)public_symbol; - - PyDict_SetItemString(md, "__all__", public_interface); - Py_DECREF(public_interface); - for (i = 0; SwigMethods[i].ml_name != NULL; ++i) - SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name); - for (i = 0; swig_const_table[i].name != 0; ++i) - SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name); -#endif - - SWIG_InstallConstants(d,swig_const_table); - -#if PY_VERSION_HEX >= 0x03000000 - return m; -#else - return; -#endif -} - diff --git a/packages/pypi/setup.cfg b/packages/pypi/setup.cfg deleted file mode 100644 index 5aef279..0000000 --- a/packages/pypi/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -description-file = README.rst diff --git a/packages/pypi/setup.py b/packages/pypi/setup.py deleted file mode 100644 index 52fa43c..0000000 --- a/packages/pypi/setup.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup, Extension, Command, Distribution -import glob -import os - -class BinaryDistribution(Distribution): - def is_pure(self): - return False - -# WINDOWS -if os.name == 'nt': - projDir='..\\..' - source_list = ['libzt_wrap.cxx'] - source_list.extend(list(glob.glob(projDir+'\\src\\*.cpp'))) - source_list.extend(list(glob.glob(projDir+'\\zto\\node\\*.cpp'))) - source_list.extend(list(glob.glob(projDir+'\\zto\\osdep\\*.cpp'))) - source_list.extend(list(glob.glob(projDir+'\\zto\\service\\*.cpp'))) - source_list.extend(list(glob.glob(projDir+'\\zto\\controller\\*.cpp'))) - - source_list = list(set(source_list)-set( - [ - projDir+'\\zto\\osdep\\LinuxEthernetTap.cpp', - projDir+'\\zto\\osdep\\BSDEthernetTap.cpp', - projDir+'\\zto\\osdep\\OSXEthernetTap.cpp', - projDir+'\\zto\\osdep\\WindowsEthernetTap.cpp' - ])) - - libzt_module = Extension('_libzt', - extra_compile_args=['/std:c++14', '-DNOMINMAX=1', '-DZT_SDK', '-DSDK', '-DZT_SOFTWARE_UPDATE_DEFAULT=\"disable\"'], - extra_link_args=['/LIBPATH:.', 'WS2_32.Lib', 'ShLwApi.Lib', 'iphlpapi.Lib','lwip.lib','http.lib'], - sources=source_list, - include_dirs=[projDir+'\\include', - projDir+'\\ext\\lwip\\src\\include', - projDir+'\\ext\\lwip-contrib\\ports\\win32\\include', - projDir+'\\zto\\include', - projDir+'\\zto\\node', - projDir+'\\zto\\service', - projDir+'\\zto\\osdep', - projDir+'\\zto\\controller'] - ) -# EVERYTHING ELSE -else: - projDir='../..' - source_list = ['libzt_wrap.cxx'] - source_list.extend(list(glob.glob(projDir+'/src/*.cpp'))) - source_list.extend(list(glob.glob(projDir+'/zto/node/*.cpp'))) - source_list.extend(list(glob.glob(projDir+'/zto/osdep/*.cpp'))) - source_list.extend(list(glob.glob(projDir+'/zto/service/*.cpp'))) - source_list.extend(list(glob.glob(projDir+'/zto/controller/*.cpp'))) - - source_list = list(set(source_list)-set( - [ - projDir+'/zto/osdep/LinuxEthernetTap.cpp', - projDir+'/zto/osdep/BSDEthernetTap.cpp', - projDir+'/zto/osdep/OSXEthernetTap.cpp', - projDir+'/zto/osdep/WindowsEthernetTap.cpp' - ])) - - libzt_module = Extension('_libzt', - extra_compile_args=['-std=c++11', '-DZT_SDK', '-DZT_SOFTWARE_UPDATE_DEFAULT=\"disable\"'], - extra_link_args=['-L.','-llwip','-lhttp'], - sources=source_list, - include_dirs=[projDir+'/include', - projDir+'/ext/lwip/src/include', - projDir+'/ext/lwip-contrib/ports/unix/include', - projDir+'/zto/include', - projDir+'/zto/node', - projDir+'/zto/service', - projDir+'/zto/osdep', - projDir+'/zto/controller'] - ) - -setup( - include_package_data=True, - distclass=BinaryDistribution, - ext_modules = [libzt_module], - py_modules = ['libzt'], - name = 'libzt', - packages = ['libzt'], - version = '1.1.6a0', - description = 'ZeroTier', - long_description = 'Encrypted P2P communication between apps and services', - author = 'ZeroTier, Inc.', - author_email = 'josep@zerotier.com', - url = 'https://github.com/zerotier/libzt', - license='GPLv3', - download_url = 'https://github.com/zerotier/libzt/archive/1.1.6.tar.gz', - keywords = 'zerotier sdwan sdn virtual network socket p2p peer-to-peer', - classifiers = ['Development Status :: 3 - Alpha', - 'Environment :: MacOS X', - 'Environment :: Win32 (MS Windows)', - 'Intended Audience :: Information Technology', - 'Intended Audience :: Science/Research', - 'Intended Audience :: System Administrators', - 'Intended Audience :: Telecommunications Industry', - 'Intended Audience :: End Users/Desktop', - 'Intended Audience :: Developers', - 'License :: Free for non-commercial use', - 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', - 'Operating System :: iOS', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX :: BSD', - 'Operating System :: Unix', - 'Programming Language :: C++', - 'Programming Language :: C', - 'Programming Language :: Python', - 'Topic :: Internet', - 'Topic :: Security :: Cryptography', - 'Topic :: System :: Networking' - ], -) \ No newline at end of file diff --git a/packages/pypi/test.py b/packages/pypi/test.py deleted file mode 100644 index 53e8c71..0000000 --- a/packages/pypi/test.py +++ /dev/null @@ -1,23 +0,0 @@ -import libzt -import time - -nwid = 0x1234567890ABCDEF - -# Authorization required via my.zerotier.com if this is a private network). -print('Joining virtual network...') -libzt.zts_startjoin('whatev_config', nwid) - -fd = libzt.zts_socket(AF_INET,SOCK_STREAM,0) -if fd < 0: - print('error creating socket') -print('fd = ' + str(fd)) - -# Display info about this node -print('I am ' + str(hex(libzt.zts_get_node_id()))) -address = None -libzt.zts_get_address(nwid, address, AF_INET) -print('assigned address = ' + str(address)) - -print('Looping forever, ping me or something') -while True: - time.sleep(1) \ No newline at end of file diff --git a/src/Controls.cpp b/src/Controls.cpp new file mode 100644 index 0000000..b41375a --- /dev/null +++ b/src/Controls.cpp @@ -0,0 +1,760 @@ +/* + * ZeroTier SDK - Network Virtualization Everywhere + * Copyright (C) 2011-2019 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. + */ + +/** + * @file + * + * ZeroTier service controls + */ + +#include + +#include "Service.hpp" +#include "Node.hpp" +#include "ZeroTierOne.h" + +#include "OSUtils.hpp" +#include "VirtualTap.hpp" +#include "Debug.hpp" +#include "concurrentqueue.h" + +#include "libzt.h" + +#if defined(_WIN32) +WSADATA wsaData; +#include +#endif + +#ifdef SDK_JNI +#include +#endif + +namespace ZeroTier { + +#ifdef __cplusplus +extern "C" { +#endif +// Custom errno to prevent conflicts with platform's own errno +int zts_errno; +#ifdef __cplusplus +} +#endif + +struct serviceParameters +{ + int port; + std::string path; +}; + +int _port; +std::string _path; + +/* + * A lock used to protect any call which relies on the presence of a valid pointer + * to the ZeroTier service. + */ +Mutex _service_lock; + +/* + * A lock which protects flags and state variables used during the startup and + * shutdown phase. + */ +Mutex _startup_lock; + +/* + * A lock used to protect callback method pointers. With a coarser-grained lock it + * would be possible for one thread to alter the callback method pointer causing + * undefined behaviour. + */ +Mutex _callback_lock; + +bool _freeHasBeenCalled = false; +bool _run_service = false; +bool _run_callbacks = false; +bool _run_lwip_tcpip = false; + +//bool _startupError = false; + +pthread_t service_thread; +pthread_t callback_thread; + +// Global reference to ZeroTier service +OneService *service; + +// User-provided callback for ZeroTier events +#ifdef SDK_JNI + // Global references to JNI objects and VM kept for future callbacks + static JavaVM *jvm = NULL; + static jobject objRef = NULL; + static jmethodID _userCallbackMethodRef = NULL; +#endif + +void (*_userEventCallbackFunc)(uint64_t, int); + +extern moodycamel::ConcurrentQueue*> _callbackMsgQueue; + +////////////////////////////////////////////////////////////////////////////// +// Internal ZeroTier Service Controls (user application shall not use these)// +////////////////////////////////////////////////////////////////////////////// + +void postEvent(uint64_t id, int eventCode) +{ + // Queue callback event messages from other threads (such as lwIP driver) + _callbackMsgQueue.enqueue(new std::pair(id, eventCode)); +} + +void _process_callback_event_helper(uint64_t nwid, int eventCode) +{ +#ifdef SDK_JNI + if(_userCallbackMethodRef) { + JNIEnv *env; + jint rs = jvm->AttachCurrentThread(&env, NULL); + assert (rs == JNI_OK); + env->CallVoidMethod(objRef, _userCallbackMethodRef, nwid, eventCode); + } +#else + if (_userEventCallbackFunc) { + _userEventCallbackFunc(nwid, eventCode); + } +#endif +} + +void _process_callback_event(uint64_t nwid, int eventCode) +{ + _callback_lock.lock(); + _process_callback_event_helper(nwid, eventCode); + _callback_lock.unlock(); +} + +bool _is_callback_registered() +{ + _callback_lock.lock(); + bool retval = false; +#ifdef SDK_JNI + retval = (jvm && objRef && _userCallbackMethodRef); +#else + retval = _userEventCallbackFunc; +#endif + _callback_lock.unlock(); + return retval; +} + +void _clear_registered_callback() +{ + _callback_lock.lock(); +#ifdef SDK_JNI + objRef = NULL; + _userCallbackMethodRef = NULL; +#else + _userEventCallbackFunc = NULL; +#endif + _callback_lock.unlock(); +} + +int __zts_node_online() +{ + return service && service->getNode() && service->getNode()->online(); +} + +int __zts_can_perform_service_operation() +{ + return service + && service->isRunning() + && service->getNode() + && service->getNode()->online() + && !_freeHasBeenCalled; +} + +void _api_sleep(int interval_ms) +{ +#if defined(_WIN32) + Sleep(interval_ms); +#else + struct timespec sleepValue = {0}; + sleepValue.tv_nsec = interval_ms * 500000; + nanosleep(&sleepValue, NULL); +#endif +} + +////////////////////////////////////////////////////////////////////////////// +// Callback thread // +////////////////////////////////////////////////////////////////////////////// + +#if defined(_WIN32) +DWORD WINAPI _zts_run_callbacks(LPVOID thread_id) +#else +void *_zts_run_callbacks(void *thread_id) +#endif +{ +#if defined(__APPLE__) + pthread_setname_np(ZTS_EVENT_CALLBACK_THREAD_NAME); +#endif + while (_run_callbacks || _callbackMsgQueue.size_approx() > 0) + { + std::pair *msg; + for (int j = 0; j != 32; j++) { // TODO: Check size of queue + if (_callbackMsgQueue.try_dequeue(msg)) { + // DEBUG_INFO("deqeueuing front: %llx,%d", msg->first, msg->second); + _process_callback_event(msg->first, msg->second); + delete msg; + } + } + _api_sleep(ZTS_CALLBACK_PROCESSING_INTERVAL); + } + pthread_exit(0); +} + +////////////////////////////////////////////////////////////////////////////// +// Service thread // +////////////////////////////////////////////////////////////////////////////// + +// 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 +{ +#if defined(__APPLE__) + pthread_setname_np(ZTS_SERVICE_THREAD_NAME); +#endif + //struct serviceParameters *params = arg; + //DEBUG_INFO("path=%s", params->path.c_str()); + int err; + + try { + std::vector hpsp(OSUtils::split(_path.c_str(), ZT_PATH_SEPARATOR_S,"","")); + std::string ptmp; + if (_path[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); + } + ptmp.append(*pi); + if ((*pi != ".")&&(*pi != "..")) { + if (OSUtils::mkdir(ptmp) == false) { + DEBUG_ERROR("home path does not exist, and could not create"); + err = true; + perror("error\n"); + } + } + } + for(;;) { + _service_lock.lock(); + service = OneService::newInstance(_path.c_str(),_port); + _service_lock.unlock(); + switch(service->run()) { + case OneService::ONE_STILL_RUNNING: + case OneService::ONE_NORMAL_TERMINATION: + postEvent((uint64_t)0, ZTS_EVENT_NODE_NORMAL_TERMINATION); + break; + case OneService::ONE_UNRECOVERABLE_ERROR: + DEBUG_ERROR("fatal error: %s", service->fatalErrorMessage().c_str()); + err = true; + postEvent((uint64_t)0, ZTS_EVENT_NODE_UNRECOVERABLE_ERROR); + break; + case OneService::ONE_IDENTITY_COLLISION: { + err = true; + delete service; + service = (OneService *)0; + std::string oldid; + OSUtils::readFile((_path + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid); + if (oldid.length()) { + OSUtils::writeFile((_path + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid); + OSUtils::rm((_path + ZT_PATH_SEPARATOR_S + "identity.secret").c_str()); + OSUtils::rm((_path + ZT_PATH_SEPARATOR_S + "identity.public").c_str()); + } + postEvent((uint64_t)0, ZTS_EVENT_NODE_IDENTITY_COLLISION); + } continue; // restart! + } + break; // terminate loop -- normally we don't keep restarting + } + _service_lock.lock(); + _run_service = false; + delete service; + service = (OneService *)0; + _service_lock.unlock(); + postEvent((uint64_t)0, ZTS_EVENT_NODE_DOWN); + } catch ( ... ) { + DEBUG_ERROR("unexpected exception starting ZeroTier instance"); + } + //delete params; + // TODO: Find a more elegant solution + _api_sleep(ZTS_CALLBACK_PROCESSING_INTERVAL*2); + _run_callbacks = false; + pthread_exit(0); +} + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////// +// ZeroTier Service Controls // +////////////////////////////////////////////////////////////////////////////// + +#ifdef SDK_JNI +/* + * Called from Java, saves a static reference to the VM so it can be used later to call + * a user-specified callback method from C. + */ +JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_init(JNIEnv *env, jobject thisObj) +{ + jint rs = env->GetJavaVM(&jvm); + assert (rs == JNI_OK); +} +#endif + +zts_err_t zts_join(const uint64_t nwid) +{ + Mutex::Lock _l(_service_lock); + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + else { + service->join(nwid); + } + return ZTS_ERR_OK; +} +#ifdef SDK_JNI +JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join( + JNIEnv *env, jobject thisObj, jlong nwid) +{ + return zts_join((uint64_t)nwid); +} +#endif + +zts_err_t zts_leave(const uint64_t nwid) +{ + Mutex::Lock _l(_service_lock); + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + else { + service->leave(nwid); + } + return ZTS_ERR_OK; +} +#ifdef SDK_JNI +JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave( + JNIEnv *env, jobject thisObj, jlong nwid) +{ + return zts_leave((uint64_t)nwid); +} +#endif + +zts_err_t zts_leave_all() +{ + Mutex::Lock _l(_service_lock); + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + else { + service->leaveAll(); + } + return ZTS_ERR_OK; +} +#ifdef SDK_JNI +#endif + +zts_err_t zts_orbit(uint64_t moonWorldId, uint64_t moonSeed) +{ + Mutex::Lock _l(_service_lock); + void *tptr = NULL; + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } else { + service->getNode()->orbit(tptr, moonWorldId, moonSeed); + } + return ZTS_ERR_OK; +} +#ifdef SDK_JNI +#endif + +zts_err_t zts_deorbit(uint64_t moonWorldId) +{ + Mutex::Lock _l(_service_lock); + void *tptr = NULL; + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } else { + service->getNode()->deorbit(tptr, moonWorldId); + } + return ZTS_ERR_OK; +} +#ifdef SDK_JNI +#endif + +zts_err_t zts_start(const char *path, void (*callback)(uint64_t, int), int port) +{ + Mutex::Lock _l(_service_lock); + if (service || _run_service) { + // Service is already initialized + return ZTS_ERR_INVALID_OP; + } + if (_freeHasBeenCalled) { + // Stack (presumably lwIP) has been dismantled, an application restart is required now + return ZTS_ERR_INVALID_OP; + } +#ifdef SDK_JNI + _userEventCallbackFunc = callback; +#endif + _userEventCallbackFunc = callback; + if (!_is_callback_registered()) { + // Must have a callback + return ZTS_ERR_INVALID_ARG; + } + if (!path) { + return ZTS_ERR_INVALID_ARG; + } + if (port < 0 || port > 0xFFFF) { + return ZTS_ERR_INVALID_ARG; + } + + _path = std::string(path); + _port = port; + + serviceParameters *params = new serviceParameters(); + + /* + params->port = port; + DEBUG_INFO("path=%s", path); + params->path = std::string(path); + DEBUG_INFO("path=%s", params->path.c_str()); + + if (params->path.length() == 0) { + return ZTS_ERR_INVALID_ARG; + } + */ + + int err; + int retval = ZTS_ERR_OK; + _run_callbacks = true; + _run_service = true; + + // Start the ZT service thread +#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; + } +#if defined(__linux__) + pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME); + pthread_setname_np(callback_thread, ZTS_EVENT_CALLBACK_THREAD_NAME); +#endif + + if (retval != ZTS_ERR_OK) { + _run_callbacks = false; + _run_service = false; + _clear_registered_callback(); + delete params; + } + return retval; +} + +#ifdef SDK_JNI +JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_start( + JNIEnv *env, jobject thisObj, jstring path, jobject callback, jint port) +{ + if (!path) { + return; + } + jclass eventListenerClass = env->GetObjectClass(callback); + if(eventListenerClass == NULL) { + DEBUG_ERROR("Couldn't find class for ZeroTierEventListener instance"); + return; + } + jmethodID eventListenerCallbackMethod = env->GetMethodID(eventListenerClass, "onZeroTierEvent", "(JI)V"); + if(eventListenerCallbackMethod == NULL) { + DEBUG_ERROR("Couldn't find onZeroTierEvent method"); + return; + } + objRef = env->NewGlobalRef(callback); // Reference used for later calls + _userCallbackMethodRef = eventListenerCallbackMethod; + const char* utf_string = env->GetStringUTFChars(path, NULL); + zts_start(utf_string, NULL, port); // using _userCallbackMethodRef + env->ReleaseStringUTFChars(path, utf_string); +} +#endif + +zts_err_t zts_stop() +{ + Mutex::Lock _l(_service_lock); + bool didStop = false; + if (__zts_can_perform_service_operation()) { + _run_service = false; + service->terminate(); + didStop = true; +#if defined(_WIN32) + WSACleanup(); +#endif + return ZTS_ERR_OK; + } + return ZTS_ERR_SERVICE; +} +#ifdef SDK_JNI +JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop( + JNIEnv *env, jobject thisObj) +{ + zts_stop(); +} +#endif + +zts_err_t zts_free() +{ + Mutex::Lock _l(_service_lock); + zts_err_t retval = 0; + if (_freeHasBeenCalled) { + return ZTS_ERR_INVALID_OP; + } + _freeHasBeenCalled = true; + return zts_stop(); + // TODO: add stack shutdown logic +} +#ifdef SDK_JNI +JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free( + JNIEnv *env, jobject thisObj) +{ + zts_free(); +} +#endif + +uint64_t zts_get_node_id() +{ + Mutex::Lock _l(_service_lock); + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + return service->getNode()->address(); +} +#ifdef SDK_JNI +JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1id( + JNIEnv *env, jobject thisObj) +{ + return zts_get_node_id(); +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// Peers // +////////////////////////////////////////////////////////////////////////////// + +int zts_get_peer_count() +{ + Mutex::Lock _l(_service_lock); + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + return service->getNode()->peers()->peerCount; +} +#ifdef SDK_JNI +JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1count( + JNIEnv *env, jobject thisObj) +{ + return zts_get_peer_count(); +} +#endif + +int zts_get_peers(struct zts_peer_details *pds, int *num) +{ + // TODO: Modernize + Mutex::Lock _l(_service_lock); + if (!pds || !num) { + return ZTS_ERR_INVALID_ARG; + } + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + ZT_PeerList *pl = service->getNode()->peers(); + if (pl) { + *num = pl->peerCount; + for(unsigned long i=0;ipeerCount;++i) { + memcpy(&(pds[i]), &(pl->peers[i]), sizeof(struct zts_peer_details)); + } + } + service->getNode()->freeQueryResult((void *)pl); + return ZTS_ERR_OK; +} +#ifdef SDK_JNI +#endif + +int zts_get_peer_status(uint64_t id) +{ + Mutex::Lock _l(_service_lock); + zts_err_t retval = ZTS_ERR_OK; + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + return service->getPeerStatus(id); +} +#ifdef SDK_JNI +JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1status( + JNIEnv *env, jobject thisObj, jlong id) +{ + return zts_get_peer_status(id); +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// Networks // +////////////////////////////////////////////////////////////////////////////// + +zts_err_t zts_get_num_joined_networks() +{ + Mutex::Lock _l(_service_lock); + zts_err_t retval = ZTS_ERR_OK; + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + return service->networkCount(); +} +#ifdef SDK_JNI +JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1num_1joined_1networks( + JNIEnv *env, jobject thisObj) +{ + return zts_get_num_joined_networks(); +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// Network Details // +////////////////////////////////////////////////////////////////////////////// + +void __get_network_details_helper(uint64_t nwid, struct zts_network_details *nd) +{ + /* + socklen_t addrlen; + VirtualTap *tap = vtapMap[nwid]; + nd->nwid = tap->_nwid; + nd->mtu = tap->_mtu; + // assigned addresses + nd->num_addresses = tap->_ips.size() < ZTS_MAX_ASSIGNED_ADDRESSES ? tap->_ips.size() : ZTS_MAX_ASSIGNED_ADDRESSES; + for (int j=0; jnum_addresses; j++) { + addrlen = tap->_ips[j].isV4() ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + memcpy(&(nd->addr[j]), &(tap->_ips[j]), addrlen); + } + // routes + nd->num_routes = ZTS_MAX_NETWORK_ROUTES;; + service->getRoutes(nwid, (ZT_VirtualNetworkRoute*)&(nd->routes)[0], &(nd->num_routes)); + */ +} + +void _get_network_details(uint64_t nwid, struct zts_network_details *nd) +{ + /* + _vtaps_lock.lock(); + __get_network_details_helper(nwid, nd); + _vtaps_lock.unlock(); + */ +} + +void _get_all_network_details(struct zts_network_details *nds, int *num) +{ + /* + _vtaps_lock.lock(); + *num = vtapMap.size(); + int idx = 0; + std::map::iterator it; + for (it = vtapMap.begin(); it != vtapMap.end(); it++) { + _get_network_details(it->first, &nds[idx]); + idx++; + } + _vtaps_lock.unlock(); + */ +} + +zts_err_t zts_get_network_details(uint64_t nwid, struct zts_network_details *nd) +{ + /* + _service_lock.lock(); + zts_err_t retval = ZTS_ERR_OK; + if (!nd || nwid == 0) { + retval = ZTS_ERR_INVALID_ARG; + } + if (!service || _freeHasBeenCalled || _serviceIsShuttingDown) { + retval = ZTS_ERR_SERVICE; + } + if (retval == ZTS_ERR_OK) { + _get_network_details(nwid, nd); + } + _service_lock.unlock(); + return retval; + */ + return 0; +} +#ifdef SDK_JNI +#endif + +zts_err_t zts_get_all_network_details(struct zts_network_details *nds, int *num) +{ + /* + _service_lock.lock(); + zts_err_t retval = ZTS_ERR_OK; + if (!nds || !num) { + retval = ZTS_ERR_INVALID_ARG; + } + if (!service || _freeHasBeenCalled || _serviceIsShuttingDown) { + retval = ZTS_ERR_SERVICE; + } + if (retval == ZTS_ERR_OK) { + _get_all_network_details(nds, num); + } + _service_lock.unlock(); + return retval; + */ + return 0; +} +#ifdef SDK_JNI +#endif + +////////////////////////////////////////////////////////////////////////////// +// Multipath/QoS // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// Misc // +////////////////////////////////////////////////////////////////////////////// + +int zts_ready() +{ + Mutex::Lock _l(_service_lock); + return _run_service && _run_lwip_tcpip; +} + +#ifdef __cplusplus +} +#endif + +} // namespace ZeroTier \ No newline at end of file diff --git a/src/Controls.hpp b/src/Controls.hpp new file mode 100644 index 0000000..a60112d --- /dev/null +++ b/src/Controls.hpp @@ -0,0 +1,91 @@ +/* + * ZeroTier SDK - Network Virtualization Everywhere + * Copyright (C) 2011-2019 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. + */ + +/** + * @file + * + * Header for ZeroTier service controls + */ + +#ifndef LIBZT_CONTROLS_HPP +#define LIBZT_CONTROLS_HPP + +namespace ZeroTier { + +////////////////////////////////////////////////////////////////////////////// +// ZeroTier Internal Service Controls // +////////////////////////////////////////////////////////////////////////////// + +void postEvent(uint64_t id, int eventCode); + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Starts a ZeroTier service in the background + * + * @usage For internal use only. + * @param + * @return + */ +#if defined(_WIN32) +DWORD WINAPI _zts_run_service(LPVOID thread_id); +#else +void *_zts_run_service(void *thread_id); +#endif + +/** + * @brief [Should not be called from user application] This function must be surrounded by + * ZT service locks. It will determine if it is currently safe and allowed to operate on + * the service. + * @usage Can be called at any time + * @return 1 or 0 + */ +int __zts_can_perform_service_operation(); + +/** + * @brief [Should not be called from user application] Returns whether or not the node is + * online. + * @usage Can be called at any time + * @return 1 or 0 + */ +int __zts_node_online(); + +/** + * @brief [Should not be called from user application] Adjusts the delay multiplier for the + * network stack driver thread. + * @usage Can be called at any time + */ +void _hibernate_if_needed(); + +#ifdef __cplusplus +} +#endif + +} // namespace ZeroTier + +#endif // _H \ No newline at end of file diff --git a/include/Debug.hpp b/src/Debug.hpp similarity index 100% rename from include/Debug.hpp rename to src/Debug.hpp diff --git a/src/Intercept.cpp b/src/Intercept.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Intercept.hpp b/src/Intercept.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Options.h b/src/Options.h new file mode 100644 index 0000000..bfd7258 --- /dev/null +++ b/src/Options.h @@ -0,0 +1,59 @@ +#ifndef LIBZT_OPTIONS_H +#define LIBZT_OPTIONS_H + +////////////////////////////////////////////////////////////////////////////// +// Callbacks // +////////////////////////////////////////////////////////////////////////////// + +#define ZTS_NODE_CALLBACKS 1 +#define ZTS_NETWORK_CALLBACKS 1 +#define ZTS_NETIF_CALLBACKS 1 +#define ZTS_PEER_CALLBACKS 1 + +/** + * The maximum number of un-processed callback messages + */ +#define ZTS_CALLBACK_MSG_QUEUE_LEN 256 + +////////////////////////////////////////////////////////////////////////////// +// Timing // +////////////////////////////////////////////////////////////////////////////// + +/** + * How often callback messages are assembled and/or sent + */ +#define ZTS_CALLBACK_PROCESSING_INTERVAL 25 + +/** + * Polling interval (in ms) for file descriptors wrapped in the Phy I/O loop (for raw drivers only) + */ +#define ZTS_PHY_POLL_INTERVAL 1 + +#define ZTS_HOUSEKEEPING_INTERVAL 50 + +/** + * By how much thread I/O and callback loop delays are multiplied (unitless) + */ +#define ZTS_HIBERNATION_MULTIPLIER 50 + +////////////////////////////////////////////////////////////////////////////// +// Thread names // +////////////////////////////////////////////////////////////////////////////// + +#define ZTS_SERVICE_THREAD_NAME "ZeroTierServiceThread" + +#define ZTS_EVENT_CALLBACK_THREAD_NAME "ZeroTierEventCallbackThread" + + + + +#define LWIP_FRAMES_HANDLED_PER_CORE_CALL 16 // How many frames are handled per call from core +#define LWIP_GUARDED_BUF_CHECK_INTERVAL 5 // in ms +#define LWIP_MAX_GUARDED_RX_BUF_SZ 1024 // number of frame pointers that can be cached waiting for receipt into core + + + +#define PEER_CACHING 0 + + +#endif \ No newline at end of file diff --git a/src/RingBuffer.cpp b/src/RingBuffer.cpp deleted file mode 100644 index de3a78c..0000000 --- a/src/RingBuffer.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2019 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. - */ - -/** - * @file - * - * Ring buffer implementation for network stack drivers - */ - -#include -#include - -#include "RingBuffer.h" - -bufElementType* RingBuffer::get_buf() -{ - return buf + begin; -} - -size_t RingBuffer::produce(size_t n) -{ - n = std::min(n, getFree()); - if (n == 0) { - return n; - } - const size_t first_chunk = std::min(n, size - end); - end = (end + first_chunk) % size; - if (first_chunk < n) { - const size_t second_chunk = n - first_chunk; - end = (end + second_chunk) % size; - } - if (begin == end) { - wrap = true; - } - return n; -} - -void RingBuffer::reset() -{ - consume(count()); -} - -size_t RingBuffer::consume(size_t n) -{ - n = std::min(n, count()); - if (n == 0) { - return n; - } - if (wrap) { - wrap = false; - } - const size_t first_chunk = std::min(n, size - begin); - begin = (begin + first_chunk) % size; - if (first_chunk < n) { - const size_t second_chunk = n - first_chunk; - begin = (begin + second_chunk) % size; - } - return n; -} - -size_t RingBuffer::write(const bufElementType * data, size_t n) -{ - n = std::min(n, getFree()); - - if (n == 0) { - return n; - } - const size_t first_chunk = std::min(n, size - end); - memcpy(buf + end, data, first_chunk * sizeof(bufElementType)); - end = (end + first_chunk) % size; - if (first_chunk < n) { - const size_t second_chunk = n - first_chunk; - memcpy(buf + end, data + first_chunk, second_chunk * sizeof(bufElementType)); - end = (end + second_chunk) % size; - } - if (begin == end) { - wrap = true; - } - return n; -} - -size_t RingBuffer::read(bufElementType * dest, size_t n) -{ - n = std::min(n, count()); - - if (n == 0) { - return n; - } - if (wrap) { - wrap = false; - } - const size_t first_chunk = std::min(n, size - begin); - memcpy(dest, buf + begin, first_chunk * sizeof(bufElementType)); - begin = (begin + first_chunk) % size; - if (first_chunk < n) { - const size_t second_chunk = n - first_chunk; - memcpy(dest + first_chunk, buf + begin, second_chunk * sizeof(bufElementType)); - begin = (begin + second_chunk) % size; - } - return n; -} - -size_t RingBuffer::count() -{ - if (end == begin) { - return wrap ? size : 0; - } - else if (end > begin) { - return end - begin; - } - else { - return size + end - begin; - } -} - -size_t RingBuffer::getFree() -{ - return size - count(); -} - diff --git a/src/Service.cpp b/src/Service.cpp new file mode 100644 index 0000000..5d251f0 --- /dev/null +++ b/src/Service.cpp @@ -0,0 +1,1230 @@ +/* + * ZeroTier SDK - Network Virtualization Everywhere + * Copyright (C) 2011-2019 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 +#include +#include +#include +#include +#include +#include +#include + +#include "version.h" +#include "ZeroTierOne.h" + +#include "OSUtils.hpp" +#include "Constants.hpp" +#include "Mutex.hpp" +#include "Node.hpp" +#include "Utils.hpp" +#include "InetAddress.hpp" +#include "MAC.hpp" +#include "Identity.hpp" +#include "World.hpp" +#include "Salsa20.hpp" +#include "Poly1305.hpp" +#include "SHA512.hpp" + +#include "Phy.hpp" +#include "Thread.hpp" +#include "OSUtils.hpp" +#include "PortMapper.hpp" +#include "Binder.hpp" +#include "ManagedRoute.hpp" +#include "BlockingQueue.hpp" + +#include "Service.hpp" +#include "Debug.hpp" +#include "concurrentqueue.h" + +#include "libzt.h" +#include "lwipDriver.hpp" + +#ifdef __WINDOWS__ +#include +#include +#include +#include +#include +//#include +#define stat _stat +#else +#include +#include +#include +#include +#include +#include +#endif + +// Use the virtual netcon endpoint instead of a tun/tap port driver +#include "VirtualTap.hpp" +namespace ZeroTier { typedef VirtualTap EthernetTap; } + +// Interface metric for ZeroTier taps -- this ensures that if we are on WiFi and also +// bridged via ZeroTier to the same LAN traffic will (if the OS is sane) prefer WiFi. +#define ZT_IF_METRIC 5000 + +// How often to check for new multicast subscriptions on a tap device +#define ZT_TAP_CHECK_MULTICAST_INTERVAL 5000 + +// How often to check for local interface addresses +#define ZT_LOCAL_INTERFACE_CHECK_INTERVAL 60000 + +namespace ZeroTier { + +// Concurrent queue for callback message processing +moodycamel::ConcurrentQueue*> _callbackMsgQueue; + +namespace { + +static std::string _trimString(const std::string &s) +{ + unsigned long end = (unsigned long)s.length(); + while (end) { + char c = s[end - 1]; + if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) + --end; + else break; + } + unsigned long start = 0; + while (start < end) { + char c = s[start]; + if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) + ++start; + else break; + } + return s.substr(start,end - start); +} + +class OneServiceImpl; + +static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf); +static void SnodeEventCallback(ZT_Node *node,void *uptr,void *tptr,enum ZT_Event event,const void *metaData); +static void SnodeStatePutFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len); +static int SnodeStateGetFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],void *data,unsigned int maxlen); +static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,void *tptr,int64_t localSocket,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl); +static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); +static int SnodePathCheckFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int64_t localSocket,const struct sockaddr_storage *remoteAddr); +static int SnodePathLookupFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int family,struct sockaddr_storage *result); +static void StapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); + +struct OneServiceIncomingPacket +{ + uint64_t now; + int64_t sock; + struct sockaddr_storage from; + unsigned int size; + uint8_t data[ZT_MAX_MTU]; +}; + +class OneServiceImpl : public OneService +{ +public: + // begin member variables -------------------------------------------------- + + const std::string _homePath; + std::string _authToken; + const std::string _networksPath; + const std::string _moonsPath; + + Phy _phy; + Node *_node; + bool _updateAutoApply; + unsigned int _multipathMode; + unsigned int _primaryPort; + unsigned int _secondaryPort; + unsigned int _tertiaryPort; + volatile unsigned int _udpPortPickerCounter; + + // + std::map peerCache; + + // + unsigned long _incomingPacketConcurrency; + std::vector _incomingPacketMemoryPool; + BlockingQueue _incomingPacketQueue; + std::vector _incomingPacketThreads; + Mutex _incomingPacketMemoryPoolLock,_incomingPacketThreadsLock; + + // Local configuration and memo-ized information from it + Hashtable< uint64_t,std::vector > _v4Hints; + Hashtable< uint64_t,std::vector > _v6Hints; + Hashtable< uint64_t,std::vector > _v4Blacklists; + Hashtable< uint64_t,std::vector > _v6Blacklists; + std::vector< InetAddress > _globalV4Blacklist; + std::vector< InetAddress > _globalV6Blacklist; + std::vector< InetAddress > _allowManagementFrom; + std::vector< std::string > _interfacePrefixBlacklist; + Mutex _localConfig_m; + + std::vector explicitBind; + + /* + * To attempt to handle NAT/gateway craziness we use three local UDP ports: + * + * [0] is the normal/default port, usually 9993 + * [1] is a port derived from our ZeroTier address + * [2] is a port computed from the normal/default for use with uPnP/NAT-PMP mappings + * + * [2] exists because on some gateways trying to do regular NAT-t interferes + * destructively with uPnP port mapping behavior in very weird buggy ways. + * It's only used if uPnP/NAT-PMP is enabled in this build. + */ + unsigned int _ports[3]; + Binder _binder; + + // Time we last received a packet from a global address + uint64_t _lastDirectReceiveFromGlobal; + + // Last potential sleep/wake event + uint64_t _lastRestart; + + // Deadline for the next background task service function + volatile int64_t _nextBackgroundTaskDeadline; + + // Configured networks + struct NetworkState + { + NetworkState() : + tap((EthernetTap *)0) + { + // Real defaults are in network 'up' code in network event handler + settings.allowManaged = true; + settings.allowGlobal = false; + settings.allowDefault = false; + } + + EthernetTap *tap; + ZT_VirtualNetworkConfig config; // memcpy() of raw config from core + std::vector managedIps; + std::list< SharedPtr > managedRoutes; + NetworkSettings settings; + }; + std::map _nets; + Mutex _nets_m; + + // Termination status information + ReasonForTermination _termReason; + std::string _fatalErrorMessage; + Mutex _termReason_m; + + // uPnP/NAT-PMP port mapper if enabled + bool _portMappingEnabled; // local.conf settings +#ifdef ZT_USE_MINIUPNPC + PortMapper *_portMapper; +#endif + + // Set to false to force service to stop + volatile bool _run; + Mutex _run_m; + + // end member variables ---------------------------------------------------- + + OneServiceImpl(const char *hp,unsigned int port) : + _homePath((hp) ? hp : ".") + ,_phy(this,false,true) + ,_node((Node *)0) + ,_updateAutoApply(false) + ,_primaryPort(port) + ,_udpPortPickerCounter(0) + ,_lastDirectReceiveFromGlobal(0) + ,_lastRestart(0) + ,_nextBackgroundTaskDeadline(0) + ,_termReason(ONE_STILL_RUNNING) + ,_portMappingEnabled(true) +#ifdef ZT_USE_MINIUPNPC + ,_portMapper((PortMapper *)0) +#endif + ,_run(true) + { + _ports[0] = 0; + _ports[1] = 0; + _ports[2] = 0; + + _incomingPacketConcurrency = std::max((unsigned long)1,std::min((unsigned long)16,(unsigned long)std::thread::hardware_concurrency())); + char *envPool = std::getenv("INCOMING_PACKET_CONCURRENCY"); + if (envPool != NULL) { + int tmp = atoi(envPool); + if (tmp > 0) { + _incomingPacketConcurrency = tmp; + } + } + for(long t=0;t<_incomingPacketConcurrency;++t) { + _incomingPacketThreads.push_back(std::thread([this]() { + OneServiceIncomingPacket *pkt = nullptr; + for(;;) { + if (!_incomingPacketQueue.get(pkt)) + break; + if (!pkt) + break; + if (!_run) + break; + + const ZT_ResultCode rc = _node->processWirePacket(nullptr,pkt->now,pkt->sock,&(pkt->from),pkt->data,pkt->size,&_nextBackgroundTaskDeadline); + { + Mutex::Lock l(_incomingPacketMemoryPoolLock); + _incomingPacketMemoryPool.push_back(pkt); + } + if (ZT_ResultCode_isFatal(rc)) { + char tmp[256]; + OSUtils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc); + Mutex::Lock _l(_termReason_m); + _termReason = ONE_UNRECOVERABLE_ERROR; + _fatalErrorMessage = tmp; + this->terminate(); + break; + } + } + })); + } + } + + virtual ~OneServiceImpl() + { + _incomingPacketQueue.stop(); + _incomingPacketThreadsLock.lock(); + for(auto t=_incomingPacketThreads.begin();t!=_incomingPacketThreads.end();++t) + t->join(); + _incomingPacketThreadsLock.unlock(); + + _binder.closeAll(_phy); + + _incomingPacketMemoryPoolLock.lock(); + while (!_incomingPacketMemoryPool.empty()) { + delete _incomingPacketMemoryPool.back(); + _incomingPacketMemoryPool.pop_back(); + } + _incomingPacketMemoryPoolLock.unlock(); + +#ifdef ZT_USE_MINIUPNPC + delete _portMapper; +#endif + } + + virtual ReasonForTermination run() + { + try { + { + const std::string authTokenPath(_homePath + ZT_PATH_SEPARATOR_S "authtoken.secret"); + if (!OSUtils::readFile(authTokenPath.c_str(),_authToken)) { + unsigned char foo[24]; + Utils::getSecureRandom(foo,sizeof(foo)); + _authToken = ""; + for(unsigned int i=0;iaddress() % 45500) : _secondaryPort; + for(int i=0;;++i) { + if (i > 1000) { + _ports[1] = 0; + break; + } else if (++_ports[1] >= 65536) { + _ports[1] = 20000; + } + if (_trialBind(_ports[1])) + break; + } + +#ifdef ZT_USE_MINIUPNPC + if (_portMappingEnabled) { + // If we're running uPnP/NAT-PMP, bind a *third* port for that. We can't + // use the other two ports for that because some NATs do really funky + // stuff with ports that are explicitly mapped that breaks things. + if (_ports[1]) { + _ports[2] = (_tertiaryPort == 0) ? _ports[1] : _tertiaryPort; + for(int i=0;;++i) { + if (i > 1000) { + _ports[2] = 0; + break; + } else if (++_ports[2] >= 65536) { + _ports[2] = 20000; + } + if (_trialBind(_ports[2])) + break; + } + if (_ports[2]) { + char uniqueName[64]; + OSUtils::ztsnprintf(uniqueName,sizeof(uniqueName),"ZeroTier/%.10llx@%u",_node->address(),_ports[2]); + _portMapper = new PortMapper(_ports[2],uniqueName); + } + } + } +#endif + // Main I/O loop + _nextBackgroundTaskDeadline = 0; + int64_t clockShouldBe = OSUtils::now(); + _lastRestart = clockShouldBe; + int64_t lastTapMulticastGroupCheck = 0; + int64_t lastBindRefresh = 0; + int64_t lastUpdateCheck = clockShouldBe; + int64_t lastMultipathModeUpdate = 0; + int64_t lastCleanedPeersDb = 0; + int64_t lastLocalInterfaceAddressCheck = (clockShouldBe - ZT_LOCAL_INTERFACE_CHECK_INTERVAL) + 15000; // do this in 15s to give portmapper time to configure and other things time to settle + int64_t lastLocalConfFileCheck = OSUtils::now(); + for(;;) { + _run_m.lock(); + if (!_run) { + _run_m.unlock(); + _termReason_m.lock(); + _termReason = ONE_NORMAL_TERMINATION; + _termReason_m.unlock(); + break; + } else { + _run_m.unlock(); + } + + const int64_t now = OSUtils::now(); + + // Attempt to detect sleep/wake events by detecting delay overruns + bool restarted = false; + if ((now > clockShouldBe)&&((now - clockShouldBe) > 10000)) { + _lastRestart = now; + restarted = true; + } + + // Refresh bindings in case device's interfaces have changed, and also sync routes to update any shadow routes (e.g. shadow default) + if (((now - lastBindRefresh) >= (_multipathMode ? ZT_BINDER_REFRESH_PERIOD / 8 : ZT_BINDER_REFRESH_PERIOD))||(restarted)) { + lastBindRefresh = now; + unsigned int p[3]; + unsigned int pc = 0; + for(int i=0;i<3;++i) { + if (_ports[i]) + p[pc++] = _ports[i]; + } + _binder.refresh(_phy,p,pc,explicitBind,*this); + } + // Update multipath mode (if needed) + if (((now - lastMultipathModeUpdate) >= ZT_BINDER_REFRESH_PERIOD / 8)||(restarted)) { + lastMultipathModeUpdate = now; + _node->setMultipathMode(_multipathMode); + } + + // + generateEventMsgs(); + + // Run background task processor in core if it's time to do so + int64_t dl = _nextBackgroundTaskDeadline; + if (dl <= now) { + _node->processBackgroundTasks((void *)0,now,&_nextBackgroundTaskDeadline); + dl = _nextBackgroundTaskDeadline; + } + + // Sync multicast group memberships + if ((now - lastTapMulticastGroupCheck) >= ZT_TAP_CHECK_MULTICAST_INTERVAL) { + lastTapMulticastGroupCheck = now; + std::vector< std::pair< uint64_t,std::pair< std::vector,std::vector > > > mgChanges; + { + Mutex::Lock _l(_nets_m); + mgChanges.reserve(_nets.size() + 1); + for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { + if (n->second.tap) { + mgChanges.push_back(std::pair< uint64_t,std::pair< std::vector,std::vector > >(n->first,std::pair< std::vector,std::vector >())); + n->second.tap->scanMulticastGroups(mgChanges.back().second.first,mgChanges.back().second.second); + } + } + } + for(std::vector< std::pair< uint64_t,std::pair< std::vector,std::vector > > >::iterator c(mgChanges.begin());c!=mgChanges.end();++c) { + for(std::vector::iterator m(c->second.first.begin());m!=c->second.first.end();++m) + _node->multicastSubscribe((void *)0,c->first,m->mac().toInt(),m->adi()); + for(std::vector::iterator m(c->second.second.begin());m!=c->second.second.end();++m) + _node->multicastUnsubscribe(c->first,m->mac().toInt(),m->adi()); + } + } + + // Sync information about physical network interfaces + if ((now - lastLocalInterfaceAddressCheck) >= (_multipathMode ? ZT_LOCAL_INTERFACE_CHECK_INTERVAL / 8 : ZT_LOCAL_INTERFACE_CHECK_INTERVAL)) { + lastLocalInterfaceAddressCheck = now; + + _node->clearLocalInterfaceAddresses(); + +#ifdef ZT_USE_MINIUPNPC + if (_portMapper) { + std::vector mappedAddresses(_portMapper->get()); + for(std::vector::const_iterator ext(mappedAddresses.begin());ext!=mappedAddresses.end();++ext) + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); + } +#endif + + std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses()); + for(std::vector::const_iterator i(boundAddrs.begin());i!=boundAddrs.end();++i) + _node->addLocalInterfaceAddress(reinterpret_cast(&(*i))); + } + + // Clean peers.d periodically + if ((now - lastCleanedPeersDb) >= 3600000) { + lastCleanedPeersDb = now; + OSUtils::cleanDirectory((_homePath + ZT_PATH_SEPARATOR_S "peers.d").c_str(),now - 2592000000LL); // delete older than 30 days + } + + const unsigned long delay = (dl > now) ? (unsigned long)(dl - now) : 100; + clockShouldBe = now + (uint64_t)delay; + _phy.poll(delay); + } + } catch (std::exception &e) { + Mutex::Lock _l(_termReason_m); + _termReason = ONE_UNRECOVERABLE_ERROR; + _fatalErrorMessage = std::string("unexpected exception in main thread: ")+e.what(); + } catch ( ... ) { + Mutex::Lock _l(_termReason_m); + _termReason = ONE_UNRECOVERABLE_ERROR; + _fatalErrorMessage = "unexpected exception in main thread: unknown exception"; + } + + { + Mutex::Lock _l(_nets_m); + for(std::map::iterator n(_nets.begin());n!=_nets.end();++n) + delete n->second.tap; + _nets.clear(); + } + + delete _node; + _node = (Node *)0; + + return _termReason; + } + + virtual ReasonForTermination reasonForTermination() const + { + Mutex::Lock _l(_termReason_m); + return _termReason; + } + + virtual std::string fatalErrorMessage() const + { + Mutex::Lock _l(_termReason_m); + return _fatalErrorMessage; + } + + virtual std::string portDeviceName(uint64_t nwid) const + { + Mutex::Lock _l(_nets_m); + std::map::const_iterator n(_nets.find(nwid)); + if ((n != _nets.end())&&(n->second.tap)) + return n->second.tap->deviceName(); + else return std::string(); + } + + virtual std::string givenHomePath() + { + return _homePath; + } + + void getRoutes(uint64_t nwid, void *routeArray, unsigned int *numRoutes) + { + Mutex::Lock _l(_nets_m); + NetworkState &n = _nets[nwid]; + *numRoutes = *numRoutes < n.config.routeCount ? *numRoutes : n.config.routeCount; + for(unsigned int i=0; i<*numRoutes; i++) { + ZT_VirtualNetworkRoute *vnr = (ZT_VirtualNetworkRoute*)routeArray; + memcpy(&vnr[i], &(n.config.routes[i]), sizeof(ZT_VirtualNetworkRoute)); + } + } + + virtual Node *getNode() + { + return _node; + } + + virtual void terminate() + { + _run_m.lock(); + _run = false; + _run_m.unlock(); + _phy.whack(); + } + + virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const + { + Mutex::Lock _l(_nets_m); + std::map::const_iterator n(_nets.find(nwid)); + if (n == _nets.end()) + return false; + settings = n->second.settings; + return true; + } + + // ========================================================================= + // Internal implementation methods for control plane, route setup, etc. + // ========================================================================= + + // Checks if a managed IP or route target is allowed + bool checkIfManagedIsAllowed(const NetworkState &n,const InetAddress &target) + { + if (!n.settings.allowManaged) + return false; + + if (n.settings.allowManagedWhitelist.size() > 0) { + bool allowed = false; + for (InetAddress addr : n.settings.allowManagedWhitelist) { + if (addr.containsAddress(target) && addr.netmaskBits() <= target.netmaskBits()) { + allowed = true; + break; + } + } + if (!allowed) return false; + } + + if (target.isDefaultRoute()) + return n.settings.allowDefault; + switch(target.ipScope()) { + case InetAddress::IP_SCOPE_NONE: + case InetAddress::IP_SCOPE_MULTICAST: + case InetAddress::IP_SCOPE_LOOPBACK: + case InetAddress::IP_SCOPE_LINK_LOCAL: + return false; + case InetAddress::IP_SCOPE_GLOBAL: + return n.settings.allowGlobal; + default: + return true; + } + } + + // Apply or update managed IPs for a configured network (be sure n.tap exists) + void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes) + { + char ipbuf[64]; + // assumes _nets_m is locked + if (syncIps) { + std::vector newManagedIps; + newManagedIps.reserve(n.config.assignedAddressCount); + for(unsigned int i=0;i(&(n.config.assignedAddresses[i])); + if (checkIfManagedIsAllowed(n,*ii)) + newManagedIps.push_back(*ii); + } + std::sort(newManagedIps.begin(),newManagedIps.end()); + newManagedIps.erase(std::unique(newManagedIps.begin(),newManagedIps.end()),newManagedIps.end()); + for(std::vector::iterator ip(n.managedIps.begin());ip!=n.managedIps.end();++ip) { + if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) { + if (!n.tap->removeIp(*ip)) + fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf)); + } + } + for(std::vector::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) { + if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) { + if (!n.tap->addIp(*ip)) + fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf)); + } + } + n.managedIps.swap(newManagedIps); + } + + } + + // ========================================================================= + // Handlers for Node and Phy<> callbacks + // ========================================================================= + + inline void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len) + { + const uint64_t now = OSUtils::now(); + if ((len >= 16)&&(reinterpret_cast(from)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) + _lastDirectReceiveFromGlobal = now; + + OneServiceIncomingPacket *pkt; + _incomingPacketMemoryPoolLock.lock(); + if (_incomingPacketMemoryPool.empty()) { + pkt = new OneServiceIncomingPacket; + } else { + pkt = _incomingPacketMemoryPool.back(); + _incomingPacketMemoryPool.pop_back(); + } + _incomingPacketMemoryPoolLock.unlock(); + + pkt->now = now; + pkt->sock = reinterpret_cast(sock); + ZT_FAST_MEMCPY(&(pkt->from),from,sizeof(struct sockaddr_storage)); + pkt->size = (unsigned int)len; + ZT_FAST_MEMCPY(pkt->data,data,len); + + _incomingPacketQueue.postLimit(pkt,16 * _incomingPacketConcurrency); + } + + inline void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) {} + inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) {} + void phyOnTcpClose(PhySocket *sock,void **uptr) {} + void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len) {} + inline void phyOnTcpWritable(PhySocket *sock,void **uptr) {} + inline void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable) {} + inline void phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN) {} + inline void phyOnUnixClose(PhySocket *sock,void **uptr) {} + inline void phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len) {} + inline void phyOnUnixWritable(PhySocket *sock,void **uptr) {} + + inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwc) + { + Mutex::Lock _l(_nets_m); + NetworkState &n = _nets[nwid]; + + switch(op) { + + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: + if (!n.tap) { + char friendlyName[128]; + OSUtils::ztsnprintf(friendlyName,sizeof(friendlyName),"ZeroTier One [%.16llx]",nwid); + + n.tap = new EthernetTap( + _homePath.c_str(), + MAC(nwc->mac), + nwc->mtu, + (unsigned int)ZT_IF_METRIC, + nwid, + friendlyName, + StapFrameHandler, + (void *)this); + *nuptr = (void *)&n; + } + // After setting up tap, fall through to CONFIG_UPDATE since we also want to do this... + + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: + ZT_FAST_MEMCPY(&(n.config),nwc,sizeof(ZT_VirtualNetworkConfig)); + if (n.tap) { // sanity check + syncManagedStuff(n,true,true); + n.tap->setMtu(nwc->mtu); + } else { + _nets.erase(nwid); + return -999; // tap init failed + } + break; + + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: + if (n.tap) { // sanity check + *nuptr = (void *)0; + delete n.tap; + _nets.erase(nwid); + } else { + _nets.erase(nwid); + } + break; + + } + return 0; + } + + inline void nodeEventCallback(enum ZT_Event event,const void *metaData) + { + // Feed node events into lock-free queue for later dequeuing by the callback thread + if (event <= ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION) { + _callbackMsgQueue.enqueue(new std::pair(0x0000000000, event)); + } + switch(event) { + case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { + Mutex::Lock _l(_termReason_m); + _termReason = ONE_IDENTITY_COLLISION; + _fatalErrorMessage = "identity/address collision"; + this->terminate(); + } break; + + case ZT_EVENT_TRACE: { + if (metaData) { + ::fprintf(stderr,"%s" ZT_EOL_S,(const char *)metaData); + ::fflush(stderr); + } + } break; + + default: + break; + } + } + + inline void generateEventMsgs() + { + // Generate messages to be dequeued by the callback message thread +#if ZTS_NETWORK_CALLBACKS + Mutex::Lock _l(_nets_m); + for(std::map::iterator n(_nets.begin());n!=_nets.end();++n) { + int mostRecentStatus = n->second.config.status; + VirtualTap *tap = n->second.tap; + uint64_t nwid = n->first; + if (n->second.tap->_networkStatus == mostRecentStatus) { + continue; // No state change + } + switch (mostRecentStatus) { + case ZT_NETWORK_STATUS_NOT_FOUND: + _callbackMsgQueue.enqueue(new std::pair(nwid, ZTS_EVENT_NETWORK_NOT_FOUND)); + break; + case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: + _callbackMsgQueue.enqueue(new std::pair(nwid, ZTS_EVENT_NETWORK_CLIENT_TOO_OLD)); + break; + case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: + _callbackMsgQueue.enqueue(new std::pair(nwid, ZTS_EVENT_NETWORK_REQUESTING_CONFIG)); + break; + case ZT_NETWORK_STATUS_OK: + if (tap->netif4 && lwip_is_netif_up(tap->netif4)) { + _callbackMsgQueue.enqueue(new std::pair(nwid, ZTS_EVENT_NETWORK_READY_IP4)); + } + if (tap->netif6 && lwip_is_netif_up(tap->netif6)) { + _callbackMsgQueue.enqueue(new std::pair(nwid, ZTS_EVENT_NETWORK_READY_IP6)); + } + _callbackMsgQueue.enqueue(new std::pair(nwid, ZTS_EVENT_NETWORK_OK)); + break; + case ZT_NETWORK_STATUS_ACCESS_DENIED: + _callbackMsgQueue.enqueue(new std::pair(nwid, ZTS_EVENT_NETWORK_ACCESS_DENIED)); + break; + default: + break; + } + n->second.tap->_networkStatus = mostRecentStatus; + } +#endif // ZTS_NETWORK_CALLBACKS +#if ZTS_PEER_CALLBACKS + // TODO: Add ZTS_EVENT_PEER_NEW + ZT_PeerList *pl = _node->peers(); + if (pl) { + for(unsigned long i=0;ipeerCount;++i) { + if (!peerCache.count(pl->peers[i].address)) { // Add first entry + if (pl->peers[i].pathCount > 0) { + _callbackMsgQueue.enqueue(new std::pair(pl->peers[i].address, ZTS_EVENT_PEER_P2P)); + } + if (pl->peers[i].pathCount == 0) { + _callbackMsgQueue.enqueue(new std::pair(pl->peers[i].address, ZTS_EVENT_PEER_RELAY)); + } + } else { + if (peerCache[pl->peers[i].address] == 0 && pl->peers[i].pathCount > 0) { + _callbackMsgQueue.enqueue(new std::pair(pl->peers[i].address, ZTS_EVENT_PEER_P2P)); + } + if (peerCache[pl->peers[i].address] > 0 && pl->peers[i].pathCount == 0) { + _callbackMsgQueue.enqueue(new std::pair(pl->peers[i].address, ZTS_EVENT_PEER_RELAY)); + } + } + peerCache[pl->peers[i].address] = pl->peers[i].pathCount; + } + } + _node->freeQueryResult((void *)pl); +#endif // ZTS_PEER_CALLBACKS + } + + inline int networkCount() + { + Mutex::Lock _l(_nets_m); + return _nets.size(); + } + + inline void join(uint64_t nwid) + { + _node->join(nwid, NULL, NULL); + } + + inline void leave(uint64_t nwid) + { + _node->leave(nwid, NULL, NULL); + } + + inline void leaveAll() + { + Mutex::Lock _l(_nets_m); + for(std::map::iterator n(_nets.begin());n!=_nets.end();++n) { + _node->leave(n->first, NULL, NULL); + } + } + + inline int getPeerStatus(uint64_t id) + { + ZT_PeerList *pl = _node->peers(); + int status = ZTS_EVENT_PEER_UNREACHABLE; + if (pl) { + for(unsigned long i=0;ipeerCount;++i) { + if (pl->peers[i].address == id) { + status = pl->peers[i].pathCount > 0 ? ZTS_EVENT_PEER_P2P : ZTS_EVENT_PEER_RELAY; + break; + } + } + } + _node->freeQueryResult((void *)pl); + return status; + } + + inline void nodeStatePutFunction(enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len) + { + char p[1024]; + FILE *f; + bool secure = false; + char dirname[1024]; + dirname[0] = 0; + + switch(type) { + case ZT_STATE_OBJECT_IDENTITY_PUBLIC: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str()); + break; + case ZT_STATE_OBJECT_IDENTITY_SECRET: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str()); + secure = true; + break; + case ZT_STATE_OBJECT_PLANET: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str()); + break; +#if PEER_CACHING + case ZT_STATE_OBJECT_PEER: + OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "peers.d",_homePath.c_str()); + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.10llx.peer",dirname,(unsigned long long)id[0]); + break; +#endif + default: + return; + } + + if (len >= 0) { + // Check to see if we've already written this first. This reduces + // redundant writes and I/O overhead on most platforms and has + // little effect on others. + f = fopen(p,"rb"); + if (f) { + char buf[65535]; + long l = (long)fread(buf,1,sizeof(buf),f); + fclose(f); + if ((l == (long)len)&&(memcmp(data,buf,l) == 0)) + return; + } + + f = fopen(p,"wb"); + if ((!f)&&(dirname[0])) { // create subdirectory if it does not exist + OSUtils::mkdir(dirname); + f = fopen(p,"wb"); + } + if (f) { + if (fwrite(data,len,1,f) != 1) + fprintf(stderr,"WARNING: unable to write to file: %s (I/O error)" ZT_EOL_S,p); + fclose(f); + if (secure) + OSUtils::lockDownFile(p,false); + } else { + fprintf(stderr,"WARNING: unable to write to file: %s (unable to open)" ZT_EOL_S,p); + } + } else { + OSUtils::rm(p); + } + } + + inline int nodeStateGetFunction(enum ZT_StateObjectType type,const uint64_t id[2],void *data,unsigned int maxlen) + { + char p[4096]; + switch(type) { + case ZT_STATE_OBJECT_IDENTITY_PUBLIC: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str()); + break; + case ZT_STATE_OBJECT_IDENTITY_SECRET: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str()); + break; + case ZT_STATE_OBJECT_PLANET: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str()); + break; +#if PEER_CACHING + case ZT_STATE_OBJECT_PEER: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "peers.d" ZT_PATH_SEPARATOR_S "%.10llx.peer",_homePath.c_str(),(unsigned long long)id[0]); + break; +#endif + default: + return -1; + } + FILE *f = fopen(p,"rb"); + if (f) { + int n = (int)fread(data,1,maxlen,f); + fclose(f); + if (n >= 0) + return n; + } + return -1; + } + + inline int nodeWirePacketSendFunction(const int64_t localSocket,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl) + { + // Even when relaying we still send via UDP. This way if UDP starts + // working we can instantly "fail forward" to it and stop using TCP + // proxy fallback, which is slow. + + if ((localSocket != -1)&&(localSocket != 0)&&(_binder.isUdpSocketValid((PhySocket *)((uintptr_t)localSocket)))) { + if ((ttl)&&(addr->ss_family == AF_INET)) _phy.setIp4UdpTtl((PhySocket *)((uintptr_t)localSocket),ttl); + const bool r = _phy.udpSend((PhySocket *)((uintptr_t)localSocket),(const struct sockaddr *)addr,data,len); + if ((ttl)&&(addr->ss_family == AF_INET)) _phy.setIp4UdpTtl((PhySocket *)((uintptr_t)localSocket),255); + return ((r) ? 0 : -1); + } else { + return ((_binder.udpSendAll(_phy,addr,data,len,ttl)) ? 0 : -1); + } + } + + inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) + { + NetworkState *n = reinterpret_cast(*nuptr); + if ((!n)||(!n->tap)) + return; + n->tap->put(MAC(sourceMac),MAC(destMac),etherType,data,len); + } + + inline int nodePathCheckFunction(uint64_t ztaddr,const int64_t localSocket,const struct sockaddr_storage *remoteAddr) + { + // Make sure we're not trying to do ZeroTier-over-ZeroTier + { + Mutex::Lock _l(_nets_m); + for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { + if (n->second.tap) { + std::vector ips(n->second.tap->ips()); + for(std::vector::const_iterator i(ips.begin());i!=ips.end();++i) { + if (i->containsAddress(*(reinterpret_cast(remoteAddr)))) { + return 0; + } + } + } + } + } + + /* Note: I do not think we need to scan for overlap with managed routes + * because of the "route forking" and interface binding that we do. This + * ensures (we hope) that ZeroTier traffic will still take the physical + * path even if its managed routes override this for other traffic. Will + * revisit if we see recursion problems. */ + + // Check blacklists + const Hashtable< uint64_t,std::vector > *blh = (const Hashtable< uint64_t,std::vector > *)0; + const std::vector *gbl = (const std::vector *)0; + if (remoteAddr->ss_family == AF_INET) { + blh = &_v4Blacklists; + gbl = &_globalV4Blacklist; + } else if (remoteAddr->ss_family == AF_INET6) { + blh = &_v6Blacklists; + gbl = &_globalV6Blacklist; + } + if (blh) { + Mutex::Lock _l(_localConfig_m); + const std::vector *l = blh->get(ztaddr); + if (l) { + for(std::vector::const_iterator a(l->begin());a!=l->end();++a) { + if (a->containsAddress(*reinterpret_cast(remoteAddr))) + return 0; + } + } + } + if (gbl) { + for(std::vector::const_iterator a(gbl->begin());a!=gbl->end();++a) { + if (a->containsAddress(*reinterpret_cast(remoteAddr))) + return 0; + } + } + return 1; + } + + inline int nodePathLookupFunction(uint64_t ztaddr,int family,struct sockaddr_storage *result) + { + const Hashtable< uint64_t,std::vector > *lh = (const Hashtable< uint64_t,std::vector > *)0; + if (family < 0) + lh = (_node->prng() & 1) ? &_v4Hints : &_v6Hints; + else if (family == AF_INET) + lh = &_v4Hints; + else if (family == AF_INET6) + lh = &_v6Hints; + else return 0; + const std::vector *l = lh->get(ztaddr); + if ((l)&&(l->size() > 0)) { + ZT_FAST_MEMCPY(result,&((*l)[(unsigned long)_node->prng() % l->size()]),sizeof(struct sockaddr_storage)); + return 1; + } else return 0; + } + + inline void tapFrameHandler(uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) + { + _node->processVirtualNetworkFrame((void *)0,OSUtils::now(),nwid,from.toInt(),to.toInt(),etherType,vlanId,data,len,&_nextBackgroundTaskDeadline); + } + + bool shouldBindInterface(const char *ifname,const InetAddress &ifaddr) + { +#if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) + if ((ifname[0] == 'l')&&(ifname[1] == 'o')) return false; // loopback + if ((ifname[0] == 'z')&&(ifname[1] == 't')) return false; // sanity check: zt# + if ((ifname[0] == 't')&&(ifname[1] == 'u')&&(ifname[2] == 'n')) return false; // tun# is probably an OpenVPN tunnel or similar + if ((ifname[0] == 't')&&(ifname[1] == 'a')&&(ifname[2] == 'p')) return false; // tap# is probably an OpenVPN tunnel or similar +#endif + +#ifdef __APPLE__ + if ((ifname[0] == 'f')&&(ifname[1] == 'e')&&(ifname[2] == 't')&&(ifname[3] == 'h')) return false; // ... as is feth# + if ((ifname[0] == 'l')&&(ifname[1] == 'o')) return false; // loopback + if ((ifname[0] == 'z')&&(ifname[1] == 't')) return false; // sanity check: zt# + if ((ifname[0] == 't')&&(ifname[1] == 'u')&&(ifname[2] == 'n')) return false; // tun# is probably an OpenVPN tunnel or similar + if ((ifname[0] == 't')&&(ifname[1] == 'a')&&(ifname[2] == 'p')) return false; // tap# is probably an OpenVPN tunnel or similar + if ((ifname[0] == 'u')&&(ifname[1] == 't')&&(ifname[2] == 'u')&&(ifname[3] == 'n')) return false; // ... as is utun# +#endif + + { + Mutex::Lock _l(_localConfig_m); + for(std::vector::const_iterator p(_interfacePrefixBlacklist.begin());p!=_interfacePrefixBlacklist.end();++p) { + if (!strncmp(p->c_str(),ifname,p->length())) + return false; + } + } + { + // Check global blacklists + const std::vector *gbl = (const std::vector *)0; + if (ifaddr.ss_family == AF_INET) { + gbl = &_globalV4Blacklist; + } else if (ifaddr.ss_family == AF_INET6) { + gbl = &_globalV6Blacklist; + } + if (gbl) { + Mutex::Lock _l(_localConfig_m); + for(std::vector::const_iterator a(gbl->begin());a!=gbl->end();++a) { + if (a->containsAddress(ifaddr)) + return false; + } + } + } + { + Mutex::Lock _l(_nets_m); + for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { + if (n->second.tap) { + std::vector ips(n->second.tap->ips()); + for(std::vector::const_iterator i(ips.begin());i!=ips.end();++i) { + if (i->ipsEqual(ifaddr)) + return false; + } + } + } + } + + return true; + } + + bool _trialBind(unsigned int port) + { + struct sockaddr_in in4; + struct sockaddr_in6 in6; + PhySocket *tb; + + memset(&in4,0,sizeof(in4)); + in4.sin_family = AF_INET; + in4.sin_port = Utils::hton((uint16_t)port); + tb = _phy.udpBind(reinterpret_cast(&in4),(void *)0,0); + if (tb) { + _phy.close(tb,false); + tb = _phy.tcpListen(reinterpret_cast(&in4),(void *)0); + if (tb) { + _phy.close(tb,false); + return true; + } + } + + memset(&in6,0,sizeof(in6)); + in6.sin6_family = AF_INET6; + in6.sin6_port = Utils::hton((uint16_t)port); + tb = _phy.udpBind(reinterpret_cast(&in6),(void *)0,0); + if (tb) { + _phy.close(tb,false); + tb = _phy.tcpListen(reinterpret_cast(&in6),(void *)0); + if (tb) { + _phy.close(tb,false); + return true; + } + } + + return false; + } +}; + +static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf) +{ return reinterpret_cast(uptr)->nodeVirtualNetworkConfigFunction(nwid,nuptr,op,nwconf); } +static void SnodeEventCallback(ZT_Node *node,void *uptr,void *tptr,enum ZT_Event event,const void *metaData) +{ reinterpret_cast(uptr)->nodeEventCallback(event,metaData); } +static void SnodeStatePutFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len) +{ reinterpret_cast(uptr)->nodeStatePutFunction(type,id,data,len); } +static int SnodeStateGetFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],void *data,unsigned int maxlen) +{ return reinterpret_cast(uptr)->nodeStateGetFunction(type,id,data,maxlen); } +static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,void *tptr,int64_t localSocket,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl) +{ return reinterpret_cast(uptr)->nodeWirePacketSendFunction(localSocket,addr,data,len,ttl); } +static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) +{ reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,nuptr,sourceMac,destMac,etherType,vlanId,data,len); } +static int SnodePathCheckFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int64_t localSocket,const struct sockaddr_storage *remoteAddr) +{ return reinterpret_cast(uptr)->nodePathCheckFunction(ztaddr,localSocket,remoteAddr); } +static int SnodePathLookupFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int family,struct sockaddr_storage *result) +{ return reinterpret_cast(uptr)->nodePathLookupFunction(ztaddr,family,result); } +static void StapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) +{ reinterpret_cast(uptr)->tapFrameHandler(nwid,from,to,etherType,vlanId,data,len); } + +} // anonymous namespace + +std::string OneService::platformDefaultHomePath() +{ + return OSUtils::platformDefaultHomePath(); +} + +OneService *OneService::newInstance(const char *hp,unsigned int port) { return new OneServiceImpl(hp,port); } +OneService::~OneService() {} + +} // namespace ZeroTier diff --git a/src/Service.hpp b/src/Service.hpp new file mode 100644 index 0000000..d977c5e --- /dev/null +++ b/src/Service.hpp @@ -0,0 +1,203 @@ +/* + * ZeroTier SDK - Network Virtualization Everywhere + * Copyright (C) 2011-2019 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. + */ + +#ifndef ZT_ONESERVICE_HPP +#define ZT_ONESERVICE_HPP + +#include +#include + +#ifdef SDK_JNI +#include +#endif + +namespace ZeroTier { + +class VirtualTap; +// Use the virtual libzt endpoint instead of a tun/tap port driver +namespace ZeroTier { typedef VirtualTap EthernetTap; } + +// Forward declaration so we can avoid dragging everything in +struct InetAddress; +class Node; + +/** + * Local service for ZeroTier One as system VPN/NFV provider + */ +class OneService +{ +public: + + /** + * Returned by node main if/when it terminates + */ + enum ReasonForTermination + { + /** + * Instance is still running + */ + ONE_STILL_RUNNING = 0, + + /** + * Normal shutdown + */ + ONE_NORMAL_TERMINATION = 1, + + /** + * A serious unrecoverable error has occurred + */ + ONE_UNRECOVERABLE_ERROR = 2, + + /** + * Your identity has collided with another + */ + ONE_IDENTITY_COLLISION = 3 + }; + + /** + * Local settings for each network + */ + struct NetworkSettings + { + /** + * Allow this network to configure IP addresses and routes? + */ + bool allowManaged; + + /** + * Whitelist of addresses that can be configured by this network. + * If empty and allowManaged is true, allow all private/pseudoprivate addresses. + */ + std::vector allowManagedWhitelist; + + /** + * Allow configuration of IPs and routes within global (Internet) IP space? + */ + bool allowGlobal; + + /** + * Allow overriding of system default routes for "full tunnel" operation? + */ + bool allowDefault; + }; + + /** + * @return Platform default home path or empty string if this platform doesn't have one + */ + static std::string platformDefaultHomePath(); + + /** + * Create a new instance of the service + * + * Once created, you must call the run() method to actually start + * processing. + * + * The port is saved to a file in the home path called zerotier-one.port, + * which is used by the CLI and can be used to see which port was chosen if + * 0 (random port) is picked. + * + * @param hp Home path + * @param port TCP and UDP port for packets and HTTP control (if 0, pick random port) + */ + static OneService *newInstance(const char *hp,unsigned int port); + + virtual ~OneService(); + + /** + * Execute the service main I/O loop until terminated + * + * The terminate() method may be called from a signal handler or another + * thread to terminate execution. Otherwise this will not return unless + * another condition terminates execution such as a fatal error. + */ + virtual ReasonForTermination run() = 0; + + /** + * @return Reason for terminating or ONE_STILL_RUNNING if running + */ + virtual ReasonForTermination reasonForTermination() const = 0; + + /** + * @return Fatal error message or empty string if none + */ + virtual std::string fatalErrorMessage() const = 0; + + /** + * @return System device name corresponding with a given ZeroTier network ID or empty string if not opened yet or network ID not found + */ + virtual std::string portDeviceName(uint64_t nwid) const = 0; + + /** + * Whether we allow access to the service via local HTTP requests (disabled by default in libzt) + */ + bool allowHttpBackplaneManagement = false; + + /** + * @return Reference to the Node + */ + virtual Node * getNode() = 0; + + /** + * Fills out a structure with network-specific route information + */ + virtual void getRoutes(uint64_t nwid, void *routeArray, unsigned int *numRoutes) = 0; + + virtual int networkCount() = 0; + virtual void leaveAll() = 0; + virtual void join(uint64_t nwid) = 0; + virtual void leave(uint64_t nwid) = 0; + virtual int getPeerStatus(uint64_t id) = 0; + + /** + * Terminate background service (can be called from other threads) + */ + virtual void terminate() = 0; + + /** + * Get local settings for a network + * + * @param nwid Network ID + * @param settings Buffer to fill with local network settings + * @return True if network was found and settings is filled + */ + virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const = 0; + + /** + * @return True if service is still running + */ + inline bool isRunning() const { return (this->reasonForTermination() == ONE_STILL_RUNNING); } + +protected: + OneService() {} + +private: + OneService(const OneService &one) {} + inline OneService &operator=(const OneService &one) { return *this; } +}; + +} // namespace ZeroTier + +#endif diff --git a/src/ServiceControls.cpp b/src/ServiceControls.cpp deleted file mode 100644 index faf1e30..0000000 --- a/src/ServiceControls.cpp +++ /dev/null @@ -1,1177 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2019 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. - */ - -/** - * @file - * - * ZeroTier service controls - */ - -#include - -#include "OneService.hpp" -#include "Node.hpp" -#include "ZeroTierOne.h" - -#include "Constants.hpp" -#include "lwIP.h" -#include "OSUtils.hpp" -#include "ServiceControls.hpp" -#include "VirtualTap.hpp" -#include "Defs.hpp" - -#include "lwip/stats.h" - -#if defined(_WIN32) -WSADATA wsaData; -#include -#endif - -#ifdef SDK_JNI -#include -#endif - -struct zts_network_details; -struct zts_peer_details; -struct zts_network_details; - -namespace ZeroTier { - -class VirtualTap; - -/* - * A lock used to protect any call which relies on the presence of a valid pointer - * to the ZeroTier service. - */ -Mutex _service_lock; - -/* - * A lock which protects flags and state variables used during the startup and - * shutdown phase. - */ -Mutex _startup_lock; - -/* - * A lock used to protect callback method pointers. With a coarser-grained lock it - * would be possible for one thread to alter the callback method pointer causing - * undefined behaviour. - */ -Mutex _callback_lock; - -std::string homeDir; -int servicePort = ZTS_DEFAULT_PORT; -bool _freeHasBeenCalled = false; -bool _serviceIsShuttingDown = false; -bool _startupError = false; -bool _nodeIsOnlineToggle = false; - -pthread_t service_thread; -pthread_t callback_thread; - -// Collection of virtual tap interfaces -std::map vtapMap; -Mutex _vtaps_lock; - -// Global reference to ZeroTier service -OneService *zt1Service; - - -// User-provided callback for ZeroTier events -void (*_userCallbackFunc)(uint64_t, int); -#ifdef SDK_JNI -// Global references to JNI objects and VM kept for future callbacks -static JavaVM *jvm = NULL; -jobject objRef = NULL; -jmethodID _userCallbackMethodRef = NULL; -#endif - -std::map peerCache; - -////////////////////////////////////////////////////////////////////////////// -// Internal ZeroTier Service Controls (user application shall not use these)// -////////////////////////////////////////////////////////////////////////////// - -std::queue*> _callbackMsgQueue; - -void _push_callback_event(uint64_t nwid, int eventCode) -{ - _callback_lock.lock(); - if (_callbackMsgQueue.size() >= ZTS_CALLBACK_MSG_QUEUE_LEN) { - DEBUG_ERROR("too many callback messages in queue (see: ZTS_CALLBACK_MSG_QUEUE_LEN)"); - _callback_lock.unlock(); - return; - } - _callbackMsgQueue.push(new std::pair(nwid,eventCode)); - _callback_lock.unlock(); -} - -void _process_callback_event_helper(uint64_t nwid, int eventCode) -{ -#ifdef SDK_JNI - if(_userCallbackMethodRef) { - JNIEnv *env; - jint rs = jvm->AttachCurrentThread(&env, NULL); - assert (rs == JNI_OK); - env->CallVoidMethod(objRef, _userCallbackMethodRef, nwid, eventCode); - } -#else - if (_userCallbackFunc) { - _userCallbackFunc(nwid, eventCode); - } -#endif -} - -void _process_callback_event(uint64_t nwid, int eventCode) -{ - _callback_lock.lock(); - _process_callback_event_helper(nwid, eventCode); - _callback_lock.unlock(); -} - -bool _is_callback_registered() -{ - _callback_lock.lock(); - bool retval = false; -#ifdef SDK_JNI - retval = (jvm && objRef && _userCallbackMethodRef); -#else - retval = _userCallbackFunc; -#endif - _callback_lock.unlock(); - return retval; -} - -void _clear_registered_callback() -{ - _callback_lock.lock(); -#ifdef SDK_JNI - objRef = NULL; - _userCallbackMethodRef = NULL; -#else - _userCallbackFunc = NULL; -#endif - _callback_lock.unlock(); -} - -void _api_sleep(int interval_ms) -{ -#if defined(_WIN32) - Sleep(interval_ms); -#else - struct timespec sleepValue = {0}; - sleepValue.tv_nsec = interval_ms * 500000; - nanosleep(&sleepValue, NULL); -#endif -} - -int _zts_node_online() -{ - return zt1Service && zt1Service->getNode() && zt1Service->getNode()->online(); -} - -int _zts_can_perform_service_operation() -{ - return zt1Service && zt1Service->isRunning() && zt1Service->getNode() && zt1Service->getNode()->online() && !_serviceIsShuttingDown; -} - -void _hibernate_if_needed() -{ - _vtaps_lock.lock(); - if (vtapMap.size()) { - lwip_wake_driver(); - } else { - lwip_hibernate_driver(); - } - _vtaps_lock.unlock(); -} -#ifdef SDK_JNI -#endif - -/* - * Monitors the conditions required for triggering callbacks into user code. This was made - * into its own thread to prevent user application abuse of callbacks from affecting - * the timing of more sensitive aspects of the library such as polling and packet processing - */ -#if defined(_WIN32) -DWORD WINAPI _zts_monitor_callback_conditions(LPVOID thread_id) -#else -void *_zts_monitor_callback_conditions(void *thread_id) -#endif -{ -#if defined(__APPLE__) - pthread_setname_np(ZTS_EVENT_CALLBACK_THREAD_NAME); -#endif - - while (true) - { - if (_serviceIsShuttingDown) { - break; - } - _service_lock.lock(); - _callback_lock.lock(); - -#if ZTS_NODE_CALLBACKS - // ZT Node states - if (!_zts_node_online()) { - if (_nodeIsOnlineToggle) { - _nodeIsOnlineToggle = false; - _process_callback_event_helper((uint64_t)0, ZTS_EVENT_NODE_OFFLINE); - } - _service_lock.unlock(); - _callback_lock.unlock(); - _api_sleep(ZTS_CALLBACK_PROCESSING_INTERVAL); - // Only process pending network callbacks if the node is online - continue; - } - if (_zts_node_online()) { - uint64_t nodeId = 0; - if (_zts_can_perform_service_operation()) { - nodeId = zt1Service->getNode()->address(); - } - if (!_nodeIsOnlineToggle) { - _nodeIsOnlineToggle = true; - _process_callback_event_helper(nodeId, ZTS_EVENT_NODE_ONLINE); - } - } -#endif - - // Handle messages placed in the message queue - while (_callbackMsgQueue.size()) { - std::pair *msg = _callbackMsgQueue.front(); - _callbackMsgQueue.pop(); -#if ZTS_NETIF_CALLBACKS - // lwIP netif - if (msg->second & (ZTS_EVENT_NETIF_STATUS_CHANGE)) { - _vtaps_lock.lock(); - if (!vtapMap.count(msg->first)) { - if (msg->second & (ZTS_EVENT_GENERIC_DOWN)) { - _process_callback_event_helper(msg->first, msg->second); - } - delete msg; - msg = NULL; - _vtaps_lock.unlock(); - continue; - } - if (msg->second == ZTS_EVENT_NETIF_UP_IP4 && vtapMap[msg->first]->_networkStatus == ZTS_EVENT_NETWORK_OK) { - _process_callback_event_helper(msg->first, ZTS_EVENT_NETWORK_READY_IP4); - } - if (msg->second == ZTS_EVENT_NETIF_UP_IP6 && vtapMap[msg->first]->_networkStatus == ZTS_EVENT_NETWORK_OK) { - _process_callback_event_helper(msg->first, ZTS_EVENT_NETWORK_READY_IP6); - } - if (msg->second & (ZTS_EVENT_NETIF_STATUS_CHANGE)) { - vtapMap[msg->first]->_netifStatus = msg->second; - } - _vtaps_lock.unlock(); - _process_callback_event_helper(msg->first, msg->second); - } -#endif // ZTS_NETIF_CALLBACKS - delete msg; - msg = NULL; - } - -#if ZTS_NETIF_CALLBACKS // Section for non-queued lwIP netif messages - // lwIP netif states - _vtaps_lock.lock(); - if (vtapMap.size()) { - std::map::iterator it; - for (it = vtapMap.begin(); it != vtapMap.end(); it++) { - VirtualTap *vtap = (VirtualTap*)it->second; - uint64_t eventCode = vtap->recognizeLowerLevelInterfaceStateChange(vtap->netif4); - if (eventCode != ZTS_EVENT_NONE) { - _process_callback_event_helper(vtap->_nwid, eventCode); - } - eventCode = vtap->recognizeLowerLevelInterfaceStateChange(vtap->netif6); - if (eventCode != ZTS_EVENT_NONE) { - _process_callback_event_helper(vtap->_nwid, eventCode); - } - } - } - _vtaps_lock.unlock(); -#endif // ZTS_NETIF_CALLBACKS - -#if ZTS_PEER_CALLBACKS - // TODO: Add peerCache clearning mechanism - // TODO: Add ZTS_EVENT_PEER_NEW message? - ZT_PeerList *pl = zt1Service->getNode()->peers(); - if (pl) { - for(unsigned long i=0;ipeerCount;++i) { - if (!peerCache.count(pl->peers[i].address)) { // Add first entry - if (pl->peers[i].pathCount > 0) { - _process_callback_event_helper(pl->peers[i].address, ZTS_EVENT_PEER_P2P); - } - if (pl->peers[i].pathCount == 0) { - _process_callback_event_helper(pl->peers[i].address, ZTS_EVENT_PEER_RELAY); - } - } - else { - if (peerCache[pl->peers[i].address] == 0 && pl->peers[i].pathCount > 0) { - _process_callback_event_helper(pl->peers[i].address, ZTS_EVENT_PEER_P2P); - } - if (peerCache[pl->peers[i].address] > 0 && pl->peers[i].pathCount == 0) { - _process_callback_event_helper(pl->peers[i].address, ZTS_EVENT_PEER_RELAY); - } - } - peerCache[pl->peers[i].address] = pl->peers[i].pathCount; - } - } - zt1Service->getNode()->freeQueryResult((void *)pl); -#endif // ZTS_PEER_CALLBACKS - -#if ZTS_NETWORK_CALLBACKS - - _vtaps_lock.lock(); - // Second, inspect network states for changes we should report - // TODO: Use proper ZT callback mechanism - // TODO: _push_callback_event(_nwid, ZTS_EVENT_NETWORK_DOWN); - ZT_VirtualNetworkList *nl = zt1Service->getNode()->networks(); - for(unsigned long i=0;inetworkCount;++i) { - OneService::NetworkSettings localSettings; - zt1Service->getNetworkSettings(nl->networks[i].nwid,localSettings); - if (!vtapMap.count(nl->networks[i].nwid)) { - continue; - } - if (vtapMap[nl->networks[i].nwid]->_networkStatus == nl->networks[i].status) { - continue; // no state change - } - VirtualTap *vtap = vtapMap[nl->networks[i].nwid]; - uint64_t nwid = nl->networks[i].nwid; - switch (nl->networks[i].status) { - case ZT_NETWORK_STATUS_NOT_FOUND: - _process_callback_event_helper(nwid, ZTS_EVENT_NETWORK_NOT_FOUND); - break; - case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: - _process_callback_event_helper(nwid, ZTS_EVENT_NETWORK_CLIENT_TOO_OLD); - break; - case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: - _process_callback_event_helper(nwid, ZTS_EVENT_NETWORK_REQUESTING_CONFIG); - break; - case ZT_NETWORK_STATUS_OK: - if (vtap->netif4 && lwip_is_netif_up(vtap->netif4)) { - _process_callback_event_helper(nwid, ZTS_EVENT_NETWORK_READY_IP4); - } - if (vtap->netif6 && lwip_is_netif_up(vtap->netif6)) { - _process_callback_event_helper(nwid, ZTS_EVENT_NETWORK_READY_IP6); - } - _process_callback_event_helper(nwid, ZTS_EVENT_NETWORK_OK); - break; - case ZT_NETWORK_STATUS_ACCESS_DENIED: - _process_callback_event_helper(nwid, ZTS_EVENT_NETWORK_ACCESS_DENIED); - break; - default: - break; - } - vtapMap[nwid]->_networkStatus = nl->networks[i].status; - } - _vtaps_lock.unlock(); - zt1Service->getNode()->freeQueryResult((void *)nl); - -#endif // ZTS_NETWORK_CALLBACKS - - // Finally, check for a more useful definition of "readiness" - /* - std::map::iterator it; - for (it = vtapMap.begin(); it != vtapMap.end(); it++) { - VirtualTap *tap = it->second; - if (tap->_lastConfigUpdateTime > 0 && !tap->_lastReadyReportTime && tap->_ips.size() > 0) { - tap->_lastReadyReportTime = tap->_lastConfigUpdateTime; - _process_callback_event(tap->_nwid, ZTS_EVENT_NETWORK_READY); - } - }*/ - _service_lock.unlock(); - _callback_lock.unlock(); - _api_sleep(ZTS_CALLBACK_PROCESSING_INTERVAL); - } - DEBUG_INFO("exited from callback processing loop"); - pthread_exit(0); -} - -// Starts a ZeroTier service in the background -#if defined(_WIN32) -DWORD WINAPI _zts_start_service(LPVOID thread_id) -#else -void *_zts_start_service(void *thread_id) -#endif -{ -#if defined(__APPLE__) - pthread_setname_np(ZTS_SERVICE_THREAD_NAME); -#endif - void *retval; - zt1Service = (OneService *)0; - - if (!homeDir.length()) { - DEBUG_ERROR("homeDir is empty, could not construct path"); - _startupError = true; - retval = NULL; - } if (zt1Service) { - DEBUG_INFO("service already started, doing nothing"); - retval = NULL; - } - try { - std::vector hpsp(OSUtils::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); - } - ptmp.append(*pi); - if ((*pi != ".")&&(*pi != "..")) { - if (OSUtils::mkdir(ptmp) == false) { - DEBUG_ERROR("home path does not exist, and could not create"); - _startupError = true; - retval = NULL; - perror("error\n"); - } - } - } - if (!_startupError) { - for(;;) { - _service_lock.lock(); - zt1Service = OneService::newInstance(homeDir.c_str(),servicePort); - _service_lock.unlock(); - switch(zt1Service->run()) { - case OneService::ONE_STILL_RUNNING: - case OneService::ONE_NORMAL_TERMINATION: - _process_callback_event((uint64_t)0, ZTS_EVENT_NODE_NORMAL_TERMINATION); - break; - case OneService::ONE_UNRECOVERABLE_ERROR: - DEBUG_ERROR("fatal error: %s", zt1Service->fatalErrorMessage().c_str()); - _startupError = true; - _process_callback_event((uint64_t)0, ZTS_EVENT_NODE_UNRECOVERABLE_ERROR); - break; - case OneService::ONE_IDENTITY_COLLISION: { - _startupError = true; - delete zt1Service; - zt1Service = (OneService *)0; - std::string oldid; - OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid); - if (oldid.length()) { - OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid); - OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str()); - OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str()); - } - _process_callback_event((uint64_t)0, ZTS_EVENT_NODE_IDENTITY_COLLISION); - } continue; // restart! - } - break; // terminate loop -- normally we don't keep restarting - } - } - - _serviceIsShuttingDown = true; - _service_lock.lock(); - delete zt1Service; - zt1Service = (OneService *)0; - _service_lock.unlock(); - _serviceIsShuttingDown = false; - _process_callback_event((uint64_t)0, ZTS_EVENT_NODE_DOWN); - DEBUG_INFO("exiting zt service thread"); - } catch ( ... ) { - DEBUG_ERROR("unexpected exception starting ZeroTier instance"); - } - pthread_exit(0); -} - -#ifdef __cplusplus -extern "C" { -#endif - -////////////////////////////////////////////////////////////////////////////// -// ZeroTier Service Controls // -////////////////////////////////////////////////////////////////////////////// - -#ifdef SDK_JNI -/* - * Called from Java, saves a reference to the VM so it can be used later to call - * a user-specified callback method from C. - */ -JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_init(JNIEnv *env, jobject thisObj) -{ - jint rs = env->GetJavaVM(&jvm); - assert (rs == JNI_OK); -} -#endif - -zts_err_t zts_set_service_port(int portno) -{ - zts_err_t retval = ZTS_ERR_OK; - _service_lock.lock(); - if (zt1Service) { - // Stop service before attempting to set a port - retval = ZTS_ERR_SERVICE; - } - else { - if (portno > -1 && portno < ZTS_MAX_PORT) { - // 0 is allowed, signals to ZT service to bind to a random port - servicePort = portno; - retval = ZTS_ERR_OK; - } - } - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_set_1service_1port( - JNIEnv *env, jobject thisObj, jint port) -{ - zts_set_service_port(port); -} -#endif - -int zts_get_service_port() -{ - return servicePort; -} -#ifdef SDK_JNI -JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1service_1port( - JNIEnv *env, jobject thisObj) -{ - return zts_get_service_port(); -} -#endif - -zts_err_t zts_join(const uint64_t nwid, int blocking) -{ - zts_err_t retval = ZTS_ERR_OK; - - _vtaps_lock.lock(); - retval = vtapMap.size() >= ZTS_MAX_JOINED_NETWORKS ? ZTS_ERR_INVALID_OP : ZTS_ERR_OK; - _vtaps_lock.unlock(); - - if (retval == ZTS_ERR_OK) { - _service_lock.lock(); - if (blocking) { - if (!zt1Service) { - retval = ZTS_ERR_SERVICE; - } else { - while (!_zts_node_online()) { - if (_serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - break; - } - _api_sleep(ZTS_WRAPPER_CHECK_INTERVAL); - } - } - } else { - if (!zt1Service || !_zts_node_online()) { - retval = ZTS_ERR_SERVICE; - } - } - if (retval == ZTS_ERR_OK) { - if (nwid == 0) { - retval = ZTS_ERR_INVALID_ARG; - } - if (zt1Service) { - zt1Service->getNode()->join(nwid, NULL, NULL); - } - } - _service_lock.unlock(); - } - return retval; -} -#ifdef SDK_JNI -JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join( - JNIEnv *env, jobject thisObj, jlong nwid) -{ - return zts_join((uint64_t)nwid); -} -#endif - -zts_err_t zts_leave(const uint64_t nwid, int blocking) -{ - zts_err_t retval = ZTS_ERR_OK; - _service_lock.lock(); - if (blocking) { - if (!zt1Service) { - retval = ZTS_ERR_SERVICE; - } else { - while (!_zts_node_online()) { - if (_serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - break; - } - _api_sleep(ZTS_WRAPPER_CHECK_INTERVAL); - } - } - } else { - if (!zt1Service || !_zts_node_online()) { - retval = ZTS_ERR_SERVICE; - } - } - if (retval == ZTS_ERR_OK) { - if (nwid == 0) { - retval = ZTS_ERR_INVALID_ARG; - } - if (zt1Service) { - zt1Service->getNode()->leave(nwid, NULL, NULL); - } - } - _vtaps_lock.lock(); - vtapMap.erase(nwid); - _vtaps_lock.unlock(); - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave( - JNIEnv *env, jobject thisObj, jlong nwid) -{ - return zts_leave((uint64_t)nwid); -} -#endif - -zts_err_t zts_leave_all(int blocking) -{ - zts_err_t retval = ZTS_ERR_OK; - /* - if (!zt1Service || _freeHasBeenCalled || _serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - } - else { - struct zts_network_details nds[ZTS_MAX_JOINED_NETWORKS]; - int numJoined = ZTS_MAX_JOINED_NETWORKS; - zts_get_all_network_details(nds, &numJoined); - for (int i=0; igetNode()->orbit(tptr, moonWorldId, moonSeed); - } - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -#endif - -zts_err_t zts_deorbit(uint64_t moonWorldId) -{ - zts_err_t retval = ZTS_ERR_OK; - void *tptr = NULL; - _service_lock.lock(); - if (!zt1Service || _freeHasBeenCalled || _serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - } - else if (_zts_can_perform_service_operation()) { - zt1Service->getNode()->deorbit(tptr, moonWorldId); - } - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -#endif - -int zts_core_running() -{ - _service_lock.lock(); - int retval = zt1Service == NULL ? false : zt1Service->isRunning(); - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_core_1running( - JNIEnv *env, jobject thisObj) -{ - return zts_core_running(); -} -#endif - -int zts_ready() -{ - _service_lock.lock(); - _vtaps_lock.lock(); - bool stackRunning = vtapMap.size() > 0 ? true : false; - _vtaps_lock.unlock(); - _service_lock.unlock(); - return zts_core_running() && stackRunning; -} -#ifdef SDK_JNI -JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_ready( - JNIEnv *env, jobject thisObj) -{ - return zts_ready(); -} -#endif - -zts_err_t zts_start_with_callback(const char *path, void (*callback)(uint64_t, int), int blocking) -{ - _startup_lock.lock(); - zts_err_t retval = ZTS_ERR_OK; - if (zt1Service) { - // Service is already initialized - retval = ZTS_ERR_SERVICE; - } - if (_freeHasBeenCalled) { - // Stack (presumably lwIP) has been dismantled, an application restart is required now - retval = ZTS_ERR_INVALID_OP; - } - if (!path) { - retval = ZTS_ERR_INVALID_ARG; - } - - _userCallbackFunc = callback; - - if (retval == ZTS_ERR_OK) { - homeDir = path; -#if defined(_WIN32) - // initialize WinSock. Used in Phy for loopback pipe - WSAStartup(MAKEWORD(2, 2), &wsaData); - HANDLE serviceThread = CreateThread(NULL, 0, _zts_start_service, NULL, 0, NULL); - if (_is_callback_registered()) { - HANDLE callbackThread = CreateThread(NULL, 0, _zts_monitor_callback_conditions, NULL, 0, NULL); - } - // TODO: Add thread names on Windows (optional) -#else - _startupError = false; - retval = pthread_create(&service_thread, NULL, _zts_start_service, NULL); -#if defined(__linux__) - pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME); -#endif - if (_is_callback_registered()) { - retval = pthread_create(&callback_thread, NULL, _zts_monitor_callback_conditions, NULL); -#if defined(__linux__) - pthread_setname_np(callback_thread, ZTS_EVENT_CALLBACK_THREAD_NAME); -#endif - } - // Wait for confirmation that the ZT service has been initialized, - // this wait condition is so brief and so rarely used that it should be - // acceptable even in a non-blocking context. - while(!zt1Service) { - if (_serviceIsShuttingDown || _startupError) { - // ZT service startup/binding might have failed for some reason - retval = ZTS_ERR_SERVICE; - break; - } - _api_sleep(10); - } -#endif - if (blocking && retval == ZTS_ERR_OK) { - // block to prevent service calls before we're ready - // waiting for zerotier service thread to start - while (zts_core_running() == false || zt1Service->getNode() == NULL) { - if (_serviceIsShuttingDown || _startupError) { - // ZT service startup/binding might have failed for some reason - retval = ZTS_ERR_SERVICE; - break; - } - _api_sleep(ZTS_WRAPPER_CHECK_INTERVAL); - } - if (retval == ZTS_ERR_OK) { - // waiting for node address assignment - while (zt1Service->getNode()->address() <= 0) { - if (_serviceIsShuttingDown || _startupError) { - retval = ZTS_ERR_SERVICE; - break; - } - _api_sleep(ZTS_WRAPPER_CHECK_INTERVAL); - } - } - if (retval == ZTS_ERR_OK) { - // Waiting for node to come online. Ensure the node is authorized to join the network - while (true) { - _service_lock.lock(); - if (_serviceIsShuttingDown || _startupError) { - retval = ZTS_ERR_SERVICE; - break; - } - if (zt1Service && zt1Service->getNode() && zt1Service->getNode()->online()) { - // Node is fully online - break; - } - _api_sleep(ZTS_WRAPPER_CHECK_INTERVAL); - _service_lock.unlock(); - } - _service_lock.unlock(); - } - } - } - _startup_lock.unlock(); - return retval; -} - -#ifdef SDK_JNI -JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_start_1with_1callback( - JNIEnv *env, jobject thisObj, jstring path, jobject userCallbackClass) -{ - jclass eventListenerClass = env->GetObjectClass(userCallbackClass); - if(eventListenerClass == NULL) { - DEBUG_ERROR("Couldn't find class for ZeroTierEventListener instance"); - return; - } - jmethodID eventListenerCallbackMethod = env->GetMethodID(eventListenerClass, "onZeroTierEvent", "(JI)V"); - if(eventListenerCallbackMethod == NULL) { - DEBUG_ERROR("Couldn't find onZeroTierEvent method"); - return; - } - objRef = env->NewGlobalRef(userCallbackClass); // Reference used for later calls - _userCallbackMethodRef = eventListenerCallbackMethod; - if (path) { - const char* utf_string = env->GetStringUTFChars(path, NULL); - zts_start_with_callback(utf_string, NULL, false); - env->ReleaseStringUTFChars(path, utf_string); - } -} -#endif - -zts_err_t zts_start(const char *path, int blocking = false) -{ - return zts_start_with_callback(path, NULL, blocking); -} -#ifdef SDK_JNI -JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_start( - JNIEnv *env, jobject thisObj, jstring path, jboolean blocking) -{ - if (path) { - const char* utf_string = env->GetStringUTFChars(path, NULL); - zts_start(utf_string, blocking); - env->ReleaseStringUTFChars(path, utf_string); - } -} -#endif - -zts_err_t zts_startjoin(const char *path, const uint64_t nwid) -{ - zts_err_t retval = ZTS_ERR_OK; - if ((retval = zts_start(path, true)) < 0) { - return retval; - } - while (true) { - try { - zts_join(nwid); - break; - } - catch( ... ) { - _api_sleep(ZTS_WRAPPER_CHECK_INTERVAL); - retval = ZTS_ERR_SERVICE; - } - } - return retval; -} -#ifdef SDK_JNI -JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_startjoin( - JNIEnv *env, jobject thisObj, jstring path, jlong nwid) -{ - if (path && nwid) { - const char* utf_string = env->GetStringUTFChars(path, NULL); - zts_startjoin(utf_string, (uint64_t)nwid); - env->ReleaseStringUTFChars(path, utf_string); - } -} -#endif - -zts_err_t zts_stop(int blocking) -{ - zts_err_t retval = ZTS_ERR_OK; - _service_lock.lock(); - // leave all networks - /* - _vtaps_lock.lock(); - if (vtapMap.size()) { - std::map::iterator it; - for (it = vtapMap.begin(); it != vtapMap.end(); it++) { - VirtualTap *vtap = (VirtualTap*)it->second; - zt1Service->getNode()->leave(vtap->_nwid, NULL, NULL); - } - vtapMap.clear(); - } - _vtaps_lock.unlock(); - */ - // begin shutdown - peerCache.clear(); // TODO: Ensure this is locked correctly - bool didStop = false; - if (_zts_can_perform_service_operation()) { - _serviceIsShuttingDown = true; - zt1Service->terminate(); - didStop = true; - } - else { - // Nothing to do - retval = ZTS_ERR_SERVICE; - } -#if defined(_WIN32) - WSACleanup(); -#endif - _service_lock.unlock(); - if (blocking && retval == ZTS_ERR_OK && didStop) { - // Block until ZT service thread successfully exits - pthread_join(service_thread, NULL); - } - _clear_registered_callback(); - return retval; -} -#ifdef SDK_JNI -JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop( - JNIEnv *env, jobject thisObj) -{ - zts_stop(); -} -#endif - -zts_err_t zts_free() -{ - zts_err_t retval = 0; - _service_lock.lock(); - if (_freeHasBeenCalled) { - retval = ZTS_ERR_INVALID_OP; - _service_lock.unlock(); - } else { - _freeHasBeenCalled = true; - _service_lock.unlock(); - retval = zts_stop(); - } - // PENDING: add stack shutdown logic - return retval; -} -#ifdef SDK_JNI -JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free( - JNIEnv *env, jobject thisObj) -{ - zts_free(); -} -#endif - -uint64_t zts_get_node_id() -{ - uint64_t nodeId = 0; - _service_lock.lock(); - if (_zts_can_perform_service_operation()) { - nodeId = zt1Service->getNode()->address(); - } - _service_lock.unlock(); - return nodeId; -} -#ifdef SDK_JNI -JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1id( - JNIEnv *env, jobject thisObj) -{ - return zts_get_node_id(); -} -#endif - -int zts_get_peer_count() -{ - unsigned int peerCount = 0; - _service_lock.lock(); - if (_zts_can_perform_service_operation()) { - peerCount = zt1Service->getNode()->peers()->peerCount; - } else { - peerCount = ZTS_ERR_SERVICE; - } - _service_lock.unlock(); - return peerCount; -} -#ifdef SDK_JNI -JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1count( - JNIEnv *env, jobject thisObj) -{ - return zts_get_peer_count(); -} -#endif - -int zts_get_peers(struct zts_peer_details *pds, int *num) -{ - zts_err_t retval = ZTS_ERR_OK; - if (!pds || !num) { - retval = ZTS_ERR_INVALID_ARG; - } - if (retval == ZTS_ERR_OK) { - _service_lock.lock(); - if (_zts_can_perform_service_operation()) { - ZT_PeerList *pl = zt1Service->getNode()->peers(); - if (pl) { - *num = pl->peerCount; - for(unsigned long i=0;ipeerCount;++i) { - memcpy(&(pds[i]), &(pl->peers[i]), sizeof(struct zts_peer_details)); - } - } - } - else { - retval = ZTS_ERR_SERVICE; - } - _service_lock.unlock(); - } - return retval; -} -#ifdef SDK_JNI -#endif - -zts_err_t zts_get_num_joined_networks() -{ - zts_err_t retval = ZTS_ERR_OK; - if (!zt1Service || _freeHasBeenCalled || _serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - } - else { - _vtaps_lock.lock(); - retval = vtapMap.size(); - _vtaps_lock.unlock(); - } - return retval; -} -#ifdef SDK_JNI -JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1num_1joined_1networks( - JNIEnv *env, jobject thisObj) -{ - return zts_get_num_joined_networks(); -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// Network Details // -////////////////////////////////////////////////////////////////////////////// - -void __get_network_details_helper(uint64_t nwid, struct zts_network_details *nd) -{ - socklen_t addrlen; - VirtualTap *tap = vtapMap[nwid]; - nd->nwid = tap->_nwid; - nd->mtu = tap->_mtu; - // assigned addresses - nd->num_addresses = tap->_ips.size() < ZTS_MAX_ASSIGNED_ADDRESSES ? tap->_ips.size() : ZTS_MAX_ASSIGNED_ADDRESSES; - for (int j=0; jnum_addresses; j++) { - addrlen = tap->_ips[j].isV4() ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); - memcpy(&(nd->addr[j]), &(tap->_ips[j]), addrlen); - } - // routes - nd->num_routes = ZTS_MAX_NETWORK_ROUTES;; - zt1Service->getRoutes(nwid, (ZT_VirtualNetworkRoute*)&(nd->routes)[0], &(nd->num_routes)); -} - -void _get_network_details(uint64_t nwid, struct zts_network_details *nd) -{ - _vtaps_lock.lock(); - __get_network_details_helper(nwid, nd); - _vtaps_lock.unlock(); -} - -void _get_all_network_details(struct zts_network_details *nds, int *num) -{ - _vtaps_lock.lock(); - *num = vtapMap.size(); - int idx = 0; - std::map::iterator it; - for (it = vtapMap.begin(); it != vtapMap.end(); it++) { - _get_network_details(it->first, &nds[idx]); - idx++; - } - _vtaps_lock.unlock(); -} - -zts_err_t zts_get_network_details(uint64_t nwid, struct zts_network_details *nd) -{ - _service_lock.lock(); - zts_err_t retval = ZTS_ERR_OK; - if (!nd || nwid == 0) { - retval = ZTS_ERR_INVALID_ARG; - } - if (!zt1Service || _freeHasBeenCalled || _serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - } - if (retval == ZTS_ERR_OK) { - _get_network_details(nwid, nd); - } - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -#endif - -zts_err_t zts_get_all_network_details(struct zts_network_details *nds, int *num) -{ - _service_lock.lock(); - zts_err_t retval = ZTS_ERR_OK; - if (!nds || !num) { - retval = ZTS_ERR_INVALID_ARG; - } - if (!zt1Service || _freeHasBeenCalled || _serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - } - if (retval == ZTS_ERR_OK) { - _get_all_network_details(nds, num); - } - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -#endif - -////////////////////////////////////////////////////////////////////////////// -// HTTP Backplane // -////////////////////////////////////////////////////////////////////////////// - -zts_err_t zts_enable_http_backplane_mgmt() -{ - zts_err_t retval = ZTS_ERR_OK; - _service_lock.lock(); - if (!zt1Service || _freeHasBeenCalled || _serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - } - else { - zt1Service->allowHttpBackplaneManagement = true; - } - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -#endif - -zts_err_t zts_disable_http_backplane_mgmt() -{ - zts_err_t retval = ZTS_ERR_OK; - _service_lock.lock(); - if (!zt1Service || _freeHasBeenCalled || _serviceIsShuttingDown) { - retval = ZTS_ERR_SERVICE; - } - else { - zt1Service->allowHttpBackplaneManagement = false; - } - _service_lock.unlock(); - return retval; -} -#ifdef SDK_JNI -#endif - -#ifdef __cplusplus -} -#endif - -} // namespace ZeroTier \ No newline at end of file diff --git a/src/libzt.cpp b/src/Sockets.cpp similarity index 82% rename from src/libzt.cpp rename to src/Sockets.cpp index 8e1d520..f43fe21 100644 --- a/src/libzt.cpp +++ b/src/Sockets.cpp @@ -33,9 +33,12 @@ #include #include "lwip/sockets.h" -#include "Defs.hpp" +#include "lwip/def.h" + #include "libzt.h" +#include "Options.h" #include "Debug.hpp" +#include "Controls.hpp" #ifdef SDK_JNI #include @@ -45,67 +48,27 @@ //#include //#include #endif +#endif -#ifdef __cplusplus -extern "C" { - -#endif - void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr); - void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr); - void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, fd_set *dest_fd_set); - void fdset2ztfdset(JNIEnv *env, int nfds, fd_set *src_fd_set, jobject dest_ztfd_set); -#ifdef __cplusplus -} -#endif -#endif +namespace ZeroTier { ////////////////////////////////////////////////////////////////////////////// // Socket API // ////////////////////////////////////////////////////////////////////////////// +extern bool _run_service; +extern bool _run_lwip_tcpip; + #ifdef __cplusplus extern "C" { #endif -// Custom errno to prevent conflicts with platform's own errno -int zts_errno; - -// lwIP prototypes copied from lwip/src/include/sockets.h -// Don't call these directly, call zts_* functions instead -int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_shutdown(int s, int how); -int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); -int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); - int lwip_close(int s); -int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_listen(int s, int backlog); -ssize_t lwip_recv(int s, void *mem, size_t len, int flags); -ssize_t lwip_read(int s, void *mem, size_t len); -ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt); -ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); -ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags); -ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags); -ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags); -ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen); -int lwip_socket(int domain, int type, int protocol); -ssize_t lwip_write(int s, const void *dataptr, size_t size); -ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt); -#if LWIP_SOCKET_SELECT -int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout); +#ifdef SDK_JNI +void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr); +void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr); +void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, fd_set *dest_fd_set); +void fdset2ztfdset(JNIEnv *env, int nfds, fd_set *src_fd_set, jobject dest_ztfd_set); #endif -#if LWIP_SOCKET_POLL -int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); -#endif -int lwip_ioctl(int s, long cmd, void *argp); -int lwip_fcntl(int s, int cmd, int val); -const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size); -int lwip_inet_pton(int af, const char *src, void *dst); // Copied from lwip/src/include/sockets.h and renamed to prevent a name collision // with system definitions @@ -119,11 +82,11 @@ struct lwip_sockaddr { // ZeroTier Socket API // ////////////////////////////////////////////////////////////////////////////// -int zts_ready(); +extern int zts_errno; int zts_socket(int socket_family, int socket_type, int protocol) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_socket(socket_family, socket_type, protocol); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_socket(socket_family, socket_type, protocol); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_socket( @@ -142,7 +105,7 @@ int zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen) if (addrlen > (int)sizeof(struct sockaddr_storage) || addrlen < (int)sizeof(struct sockaddr_in)) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_connect(fd, addr, addrlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_connect(fd, addr, addrlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_connect( @@ -164,7 +127,7 @@ int zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) if (addrlen > (int)sizeof(struct sockaddr_storage) || addrlen < (int)sizeof(struct sockaddr_in)) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_bind(fd, addr, addrlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_bind(fd, addr, addrlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_bind( @@ -180,7 +143,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_bind( int zts_listen(int fd, int backlog) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_listen(fd, backlog); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_listen(fd, backlog); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_listen( @@ -193,7 +156,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_listen( int zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_accept(fd, addr, addrlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_accept(fd, addr, addrlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept( @@ -210,7 +173,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept( #if defined(__linux__) int zts_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) { - return !zts_ready() ? ZTS_ERR_INVALID_OP : ZTS_ERR_INVALID_OP; + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_INVALID_OP : ZTS_ERR_INVALID_OP; } #endif #ifdef SDK_JNI @@ -229,7 +192,7 @@ int zts_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) int zts_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_setsockopt(fd, level, optname, optval, optlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_setsockopt(fd, level, optname, optval, optlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_setsockopt( @@ -279,7 +242,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_setsockopt( int zts_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_getsockopt(fd, level, optname, optval, optlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_getsockopt(fd, level, optname, optval, optlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getsockopt( @@ -340,7 +303,7 @@ int zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen) if (*addrlen > (int)sizeof(struct sockaddr_storage) || *addrlen < (int)sizeof(struct sockaddr_in)) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_getsockname(fd, addr, addrlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_getsockname(fd, addr, addrlen); } #ifdef SDK_JNI JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_getsockname(JNIEnv *env, jobject thisObj, @@ -362,7 +325,7 @@ int zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) if (*addrlen > (int)sizeof(struct sockaddr_storage) || *addrlen < (int)sizeof(struct sockaddr_in)) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_getpeername(fd, addr, addrlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_getpeername(fd, addr, addrlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getpeername(JNIEnv *env, jobject thisObj, @@ -377,23 +340,23 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getpeername(JNIEnv *env, int zts_gethostname(char *name, size_t len) { - return !zts_ready() ? ZTS_ERR_INVALID_OP : ZTS_ERR_INVALID_OP; // TODO + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_INVALID_OP : ZTS_ERR_INVALID_OP; // TODO } #ifdef SDK_JNI #endif int zts_sethostname(const char *name, size_t len) { - return !zts_ready() ? ZTS_ERR_INVALID_OP : ZTS_ERR_INVALID_OP; // TODO + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_INVALID_OP : ZTS_ERR_INVALID_OP; // TODO } #ifdef SDK_JNI #endif +/* struct hostent *zts_gethostbyname(const char *name) { - return (struct hostent *)(!zts_ready() ? NULL : NULL); + return (struct hostent *)((!_run_service || !_run_lwip_tcpip) ? NULL : NULL); // TODO: Test thread safety - /* char buf[256]; int buflen = 256; int h_err = 0; @@ -409,14 +372,14 @@ struct hostent *zts_gethostbyname(const char *name) return *result; return lwip_gethostbyname(name); - */ } #ifdef SDK_JNI #endif +*/ int zts_close(int fd) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_close(fd); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_close(fd); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_close( @@ -429,7 +392,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_close( int zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_select(nfds, readfds, writefds, exceptfds, timeout); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_select(nfds, readfds, writefds, exceptfds, timeout); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_select(JNIEnv *env, jobject thisObj, @@ -482,7 +445,7 @@ int zts_fcntl(int fd, int cmd, int flags) translated_flags = 1; } #endif - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_fcntl(fd, cmd, translated_flags); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_fcntl(fd, cmd, translated_flags); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_fcntl( @@ -498,7 +461,7 @@ int zts_ioctl(int fd, unsigned long request, void *argp) if (!argp) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_ioctl(fd, request, argp); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_ioctl(fd, request, argp); } #ifdef SDK_JNI JNIEXPORT int JNICALL Java_com_zerotier_libzt_ZeroTier_ioctl( @@ -532,7 +495,7 @@ ssize_t zts_send(int fd, const void *buf, size_t len, int flags) if (!buf || len <= 0) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_send(fd, buf, len, flags); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_send(fd, buf, len, flags); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_send( @@ -554,7 +517,7 @@ ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags, if (addrlen > (int)sizeof(struct sockaddr_storage) || addrlen < (int)sizeof(struct sockaddr_in)) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_sendto(fd, buf, len, flags, addr, addrlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_sendto(fd, buf, len, flags, addr, addrlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_sendto( @@ -572,7 +535,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_sendto( ssize_t zts_sendmsg(int fd, const struct msghdr *msg, int flags) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_sendmsg(fd, msg, flags); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_sendmsg(fd, msg, flags); } #ifdef SDK_JNI #endif @@ -582,7 +545,7 @@ ssize_t zts_recv(int fd, void *buf, size_t len, int flags) if (!buf) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_recv(fd, buf, len, flags); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_recv(fd, buf, len, flags); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recv(JNIEnv *env, jobject thisObj, @@ -601,7 +564,7 @@ ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags, if (!buf) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_recvfrom(fd, buf, len, flags, addr, addrlen); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_recvfrom(fd, buf, len, flags, addr, addrlen); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recvfrom( @@ -619,7 +582,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recvfrom( ssize_t zts_recvmsg(int fd, struct msghdr *msg, int flags) { - return !zts_ready() ? ZTS_ERR_SERVICE : -1; // Not currently implemented by stack + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : -1; // Not currently implemented by stack } #ifdef SDK_JNI #endif @@ -629,7 +592,7 @@ int zts_read(int fd, void *buf, size_t len) if (!buf) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_read(fd, buf, len); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_read(fd, buf, len); } int zts_read_offset(int fd, void *buf, size_t offset, size_t len) { @@ -637,7 +600,7 @@ int zts_read_offset(int fd, void *buf, size_t offset, size_t len) return ZTS_ERR_INVALID_ARG; } char *cbuf = (char*)buf; - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_read(fd, &(cbuf[offset]), len); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_read(fd, &(cbuf[offset]), len); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_read(JNIEnv *env, jobject thisObj, @@ -671,7 +634,7 @@ int zts_write(int fd, const void *buf, size_t len) if (!buf || len <= 0) { return ZTS_ERR_INVALID_ARG; } - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_write(fd, buf, len); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_write(fd, buf, len); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write__IB(JNIEnv *env, jobject thisObj, @@ -700,7 +663,7 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write_1byte(JNIEnv *env, int zts_shutdown(int fd, int how) { - return !zts_ready() ? ZTS_ERR_SERVICE : lwip_shutdown(fd, how); + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : lwip_shutdown(fd, how); } #ifdef SDK_JNI JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_shutdown( @@ -712,14 +675,14 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_shutdown( int zts_add_dns_nameserver(struct sockaddr *addr) { - return !zts_ready() ? ZTS_ERR_SERVICE : -1; // TODO + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : -1; // TODO } #ifdef SDK_JNI #endif int zts_del_dns_nameserver(struct sockaddr *addr) { - return !zts_ready() ? ZTS_ERR_SERVICE : -1; // TODO + return (!_run_service || !_run_lwip_tcpip) ? ZTS_ERR_SERVICE : -1; // TODO } #ifdef SDK_JNI #endif @@ -778,7 +741,7 @@ void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr) { struct sockaddr_in *in4 = (struct sockaddr_in*)ss; jfieldID fid = (*env).GetFieldID(c, "_port", "I"); - (*env).SetIntField(addr, fid, ntohs(in4->sin_port)); + (*env).SetIntField(addr, fid, lwip_ntohs(in4->sin_port)); fid = (*env).GetFieldID(c,"_family", "I"); (*env).SetIntField(addr, fid, (in4->sin_family)); fid = env->GetFieldID(c, "_ip4", "[B"); @@ -794,7 +757,7 @@ void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr) { struct sockaddr_in6 *in6 = (struct sockaddr_in6*)ss; jfieldID fid = (*env).GetFieldID(c, "_port", "I"); - (*env).SetIntField(addr, fid, ntohs(in6->sin6_port)); + (*env).SetIntField(addr, fid, lwip_ntohs(in6->sin6_port)); fid = (*env).GetFieldID(c,"_family", "I"); (*env).SetIntField(addr, fid, (in6->sin6_family)); fid = env->GetFieldID(c, "_ip6", "[B"); @@ -819,7 +782,7 @@ void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr) { struct sockaddr_in *in4 = (struct sockaddr_in*)ss; fid = (*env).GetFieldID(c, "_port", "I"); - in4->sin_port = htons((*env).GetIntField(addr, fid)); + in4->sin_port = lwip_htons((*env).GetIntField(addr, fid)); in4->sin_family = AF_INET; fid = env->GetFieldID(c, "_ip4", "[B"); jobject ipData = (*env).GetObjectField (addr, fid); @@ -833,7 +796,7 @@ void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr) { struct sockaddr_in6 *in6 = (struct sockaddr_in6*)ss; jfieldID fid = (*env).GetFieldID(c, "_port", "I"); - in6->sin6_port = htons((*env).GetIntField(addr, fid)); + in6->sin6_port = lwip_htons((*env).GetIntField(addr, fid)); fid = (*env).GetFieldID(c,"_family", "I"); in6->sin6_family = AF_INET6; fid = env->GetFieldID(c, "_ip6", "[B"); @@ -850,3 +813,5 @@ void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr) #ifdef __cplusplus } #endif + +} // namespace ZeroTier diff --git a/src/VirtualTap.cpp b/src/VirtualTap.cpp index 76a287d..e5c7cea 100644 --- a/src/VirtualTap.cpp +++ b/src/VirtualTap.cpp @@ -35,13 +35,12 @@ #include "Node.hpp" #include "OSUtils.hpp" -#include "Constants.hpp" // libzt -#include "ServiceControls.hpp" -#include "OneService.hpp" +#include "Service.hpp" extern void _push_callback_event(uint64_t nwid, int eventCode); #include "Mutex.hpp" -#include "lwIP.h" +#include "lwipDriver.hpp" +#include "libzt.h" #ifdef _MSC_VER #include "Synchapi.h" @@ -51,10 +50,7 @@ namespace ZeroTier { class VirtualTap; -extern OneService *zt1Service; -extern void (*_userCallbackFunc)(uint64_t, int); -extern std::map vtapMap; -extern Mutex _vtaps_lock; +extern OneService *service; /** * A virtual tap device. The ZeroTier core service creates one of these for each @@ -86,11 +82,6 @@ VirtualTap::VirtualTap( snprintf(vtap_full_name, sizeof(vtap_full_name), "libzt%llx", (unsigned long long)_nwid); _dev = vtap_full_name; ::pipe(_shutdownSignalPipe); - - _vtaps_lock.lock(); - vtapMap[_nwid] = this; - _vtaps_lock.unlock(); - lwip_driver_init(); // Start virtual tap thread and stack I/O loops _thread = Thread::start(this); @@ -198,10 +189,10 @@ std::string VirtualTap::deviceName() const std::string VirtualTap::nodeId() const { - if (zt1Service) { - char id[ZTS_ID_LEN]; + if (service) { + char id[16]; memset(id, 0, sizeof(id)); - sprintf(id, "%llx", (unsigned long long)((OneService *)zt1Service)->getNode()->address()); + sprintf(id, "%llx", (unsigned long long)((OneService *)service)->getNode()->address()); return std::string(id); } else { @@ -283,74 +274,9 @@ void VirtualTap::threadMain() void VirtualTap::Housekeeping() { -/* - Mutex::Lock _l(_tap_m); - OneService *service = ((OneService *)zt1Service); - if (!service) { - return; - } - nd.num_routes = ZTS_MAX_NETWORK_ROUTES; - service->getRoutes(this->_nwid, (ZT_VirtualNetworkRoute*)&(nd.routes)[0], &(nd.num_routes)); -*/ - -/* - InetAddress target_addr; - InetAddress via_addr; - InetAddress null_addr; - InetAddress nm; - null_addr.fromString(""); - bool found; - char ipbuf[INET6_ADDRSTRLEN], ipbuf2[INET6_ADDRSTRLEN], ipbuf3[INET6_ADDRSTRLEN]; - - // TODO: Rework this when we have time - // check if pushed route exists in tap (add) - /* - for (int i=0; iat(i).target; - via_addr = managed_routes->at(i).via; - nm = target_addr.netmask(); - for (size_t j=0; j", target_addr.toString(ipbuf), nm.toString(ipbuf2), via_addr.toString(ipbuf3)); - routes.push_back(std::pair(target_addr, nm)); - routeAdd(target_addr, nm, via_addr); - } - } - } - // check if route exists in tap but not in pushed routes (remove) - for (size_t i=0; iat(j).target; - via_addr = managed_routes->at(j).via; - nm = target_addr.netmask(); - if (routes[i].first.ipsEqual(target_addr) && routes[i].second.ipsEqual(nm)) { - found=true; - } - } - if (found == false) { - DEBUG_INFO("removing route to <%s,%s>", routes[i].first.toString(ipbuf), routes[i].second.toString(ipbuf2)); - routes.erase(routes.begin() + i); - routeDelete(routes[i].first, routes[i].second); - } - } -*/ + // } -////////////////////////////////////////////////////////////////////////////// -// Not used in this implementation // -////////////////////////////////////////////////////////////////////////////// - void VirtualTap::phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *local_address, const struct sockaddr *from,void *data,unsigned long len) {} void VirtualTap::phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) {} diff --git a/include/VirtualTap.hpp b/src/VirtualTap.hpp similarity index 99% rename from include/VirtualTap.hpp rename to src/VirtualTap.hpp index 6fe509e..03eda32 100644 --- a/include/VirtualTap.hpp +++ b/src/VirtualTap.hpp @@ -43,7 +43,7 @@ extern int errno; #include "MulticastGroup.hpp" #include "Mutex.hpp" -#include "Defs.hpp" +#include "Options.h" #if defined(_WIN32) #include diff --git a/src/lwIP.cpp b/src/lwipDriver.cpp similarity index 88% rename from src/lwIP.cpp rename to src/lwipDriver.cpp index 9a776cc..faf95d0 100644 --- a/src/lwIP.cpp +++ b/src/lwipDriver.cpp @@ -30,15 +30,10 @@ * lwIP network stack driver */ -#include #include #include "MAC.hpp" - #include "Mutex.hpp" -#include "Constants.hpp" -#include "VirtualTap.hpp" -#include "Constants.hpp" // libzt #include "netif/ethernet.h" #include "lwip/netif.h" @@ -53,15 +48,23 @@ #include "lwip/ethip6.h" #include "lwip/ip_addr.h" #include "lwip/nd6.h" -#include "lwip/dns.h" #include "lwip/netifapi.h" -#include "lwIP.h" +#include "VirtualTap.hpp" +#include "lwipDriver.hpp" +#include "libzt.h" +#include "Controls.hpp" +extern void postEvent(uint64_t id, int eventCode); #if defined(_WIN32) #include #endif +/** + * Length of human-readable MAC address string + */ +#define ZTS_MAC_ADDRSTRLEN 18 + namespace ZeroTier { bool main_loop_exited = false; @@ -69,13 +72,12 @@ bool lwip_driver_initialized = false; bool has_already_been_initialized = false; int hibernationDelayMultiplier = 1; +extern bool _run_lwip_tcpip; + Mutex driver_m; std::queue rx_queue; -ZeroTier::Mutex _rx_input_lock_m; - -extern void _push_callback_event(uint64_t nwid, int eventCode); -extern void _process_callback_event_helper(uint64_t nwid, int eventCode); +Mutex _rx_input_lock_m; void lwip_hibernate_driver() { @@ -93,6 +95,8 @@ static void tcpip_init_done(void *arg) sys_sem_t *sem; sem = (sys_sem_t *)arg; lwip_driver_initialized = true; + _run_lwip_tcpip = true; + postEvent((uint64_t)0, ZTS_EVENT_NETWORK_STACK_UP); driver_m.unlock(); sys_sem_signal(sem); } @@ -157,6 +161,7 @@ static void main_lwip_driver_loop(void *arg) tcpip_callback_with_block(my_tcpip_callback, NULL, 1); } main_loop_exited = true; + _run_lwip_tcpip = false; } // Initialize the lwIP stack @@ -191,14 +196,16 @@ void lwip_driver_shutdown() while(!main_loop_exited) { usleep(LWIP_GUARDED_BUF_CHECK_INTERVAL*1000); } + /* if (tcpip_shutdown() == ERR_OK) { sys_timeouts_free(); } + */ } void lwip_dispose_of_netifs(void *tapref) { - ZeroTier::VirtualTap *vtap = (ZeroTier::VirtualTap*)tapref; + VirtualTap *vtap = (VirtualTap*)tapref; if (vtap->netif4) { netif_remove((struct netif*)(vtap->netif4)); netif_set_down((struct netif*)(vtap->netif4)); @@ -222,7 +229,7 @@ err_t lwip_eth_tx(struct netif *netif, struct pbuf *p) char *bufptr; int totalLength = 0; - ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap*)netif->state; + VirtualTap *tap = (VirtualTap*)netif->state; bufptr = buf; for (q = p; q != NULL; q = q->next) { memcpy(bufptr, q->payload, q->len); @@ -232,56 +239,54 @@ err_t lwip_eth_tx(struct netif *netif, struct pbuf *p) struct eth_hdr *ethhdr; ethhdr = (struct eth_hdr *)buf; - ZeroTier::MAC src_mac; - ZeroTier::MAC dest_mac; + MAC src_mac; + MAC dest_mac; src_mac.setTo(ethhdr->src.addr, 6); dest_mac.setTo(ethhdr->dest.addr, 6); char *data = buf + sizeof(struct eth_hdr); int len = totalLength - sizeof(struct eth_hdr); - int proto = ZeroTier::Utils::ntoh((uint16_t)ethhdr->type); + int proto = Utils::ntoh((uint16_t)ethhdr->type); tap->_handler(tap->_arg, NULL, tap->_nwid, src_mac, dest_mac, proto, 0, data, len); /* if (ZT_MSG_TRANSFER == true) { char flagbuf[32]; memset(&flagbuf, 0, 32); - char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[ZTS_ID_LEN]; + char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[16]; snprintf(macBuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x", ethhdr->dest.addr[0], ethhdr->dest.addr[1], ethhdr->dest.addr[2], ethhdr->dest.addr[3], ethhdr->dest.addr[4], ethhdr->dest.addr[5]); - ZeroTier::MAC mac; + MAC mac; mac.setTo(ethhdr->dest.addr, 6); mac.toAddress(tap->_nwid).toString(nodeBuf); DEBUG_TRANS("len=%5d dst=%s [%s TX <-- %s] proto=0x%04x %s", totalLength, macBuf, nodeBuf, tap->nodeId().c_str(), - ZeroTier::Utils::ntoh(ethhdr->type), flagbuf); + Utils::ntoh(ethhdr->type), flagbuf); } */ - - return ERR_OK; } -void lwip_eth_rx(ZeroTier::VirtualTap *tap, const ZeroTier::MAC &from, const ZeroTier::MAC &to, unsigned int etherType, +void lwip_eth_rx(VirtualTap *tap, const MAC &from, const MAC &to, unsigned int etherType, const void *data, unsigned int len) { struct pbuf *p,*q; struct eth_hdr ethhdr; from.copyTo(ethhdr.src.addr, 6); to.copyTo(ethhdr.dest.addr, 6); - ethhdr.type = ZeroTier::Utils::hton((uint16_t)etherType); + ethhdr.type = Utils::hton((uint16_t)etherType); /* if (ZT_MSG_TRANSFER == true) { char flagbuf[32]; memset(&flagbuf, 0, 32); - char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[ZTS_ID_LEN]; + char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[16]; snprintf(macBuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x", ethhdr.dest.addr[0], ethhdr.dest.addr[1], ethhdr.dest.addr[2], ethhdr.dest.addr[3], ethhdr.dest.addr[4], ethhdr.dest.addr[5]); - ZeroTier::MAC mac; + MAC mac; mac.setTo(ethhdr.src.addr, 6); mac.toAddress(tap->_nwid).toString(nodeBuf); DEBUG_TRANS("len=%5d dst=%s [%s RX --> %s] proto=0x%04x %s", len, macBuf, nodeBuf, tap->nodeId().c_str(), - ZeroTier::Utils::ntoh(ethhdr.type), flagbuf); + Utils::ntoh(ethhdr.type), flagbuf); } */ if (etherType == 0x0800 || etherType == 0x0806) { // ip4 or ARP @@ -390,23 +395,23 @@ static void netif_status_callback(struct netif *netif) if (!netif->state) { return; } - ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap *)netif->state; + VirtualTap *tap = (VirtualTap *)netif->state; if (netif->flags & NETIF_FLAG_UP) { - ZeroTier::VirtualTap *vtap = (ZeroTier::VirtualTap*)netif->state; + VirtualTap *vtap = (VirtualTap*)netif->state; if (netif == vtap->netif6) { // DEBUG_INFO("netif=%p, vtap->netif6=%p", netif, vtap->netif6); - _push_callback_event(tap->_nwid, ZTS_EVENT_NETIF_UP_IP6); + postEvent(tap->_nwid, ZTS_EVENT_NETIF_UP_IP6); } if (netif == vtap->netif4) { // DEBUG_INFO("netif=%p, vtap->netif4=%p", netif, vtap->netif4); - _push_callback_event(tap->_nwid, ZTS_EVENT_NETIF_UP_IP4); + postEvent(tap->_nwid, ZTS_EVENT_NETIF_UP_IP4); } } if (!(netif->flags & NETIF_FLAG_UP)) { if (netif->flags & NETIF_FLAG_MLD6) { - _push_callback_event(tap->_nwid, ZTS_EVENT_NETIF_DOWN_IP6); + postEvent(tap->_nwid, ZTS_EVENT_NETIF_DOWN_IP6); } else { - _push_callback_event(tap->_nwid, ZTS_EVENT_NETIF_DOWN_IP4); + postEvent(tap->_nwid, ZTS_EVENT_NETIF_DOWN_IP4); } } // TODO: ZTS_EVENT_NETIF_NEW_ADDRESS @@ -421,8 +426,8 @@ static void netif_remove_callback(struct netif *netif) if (!netif->state) { return; } - ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap *)netif->state; - _push_callback_event(tap->_nwid, ZTS_EVENT_NETIF_REMOVED); + VirtualTap *tap = (VirtualTap *)netif->state; + postEvent(tap->_nwid, ZTS_EVENT_NETIF_REMOVED); //print_netif_info(netif); } @@ -434,12 +439,12 @@ static void netif_link_callback(struct netif *netif) if (!netif->state) { return; } - ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap *)netif->state; + VirtualTap *tap = (VirtualTap *)netif->state; if (netif->flags & NETIF_FLAG_LINK_UP) { - _push_callback_event(tap->_nwid, ZTS_EVENT_NETIF_LINK_UP); + postEvent(tap->_nwid, ZTS_EVENT_NETIF_LINK_UP); } if (netif->flags & NETIF_FLAG_LINK_UP) { - _push_callback_event(tap->_nwid, ZTS_EVENT_NETIF_LINK_DOWN); + postEvent(tap->_nwid, ZTS_EVENT_NETIF_LINK_DOWN); } //print_netif_info(netif); } @@ -480,7 +485,7 @@ static err_t netif_init_6(struct netif *netif) return ERR_OK; } -void lwip_init_interface(void *tapref, const ZeroTier::MAC &mac, const ZeroTier::InetAddress &ip) +void lwip_init_interface(void *tapref, const MAC &mac, const InetAddress &ip) { char ipbuf[INET6_ADDRSTRLEN]; char macbuf[ZTS_MAC_ADDRSTRLEN]; @@ -502,7 +507,7 @@ void lwip_init_interface(void *tapref, const ZeroTier::MAC &mac, const ZeroTier: macbuf, ip.toString(ipbuf), ip.netmask().toString(nmbuf)); netif_set_up(n); netif_set_link_up(n); - ZeroTier::VirtualTap *vtap = (ZeroTier::VirtualTap*)tapref; + VirtualTap *vtap = (VirtualTap*)tapref; vtap->netif4 = (void*)n; } if (ip.isV6()) @@ -525,7 +530,7 @@ void lwip_init_interface(void *tapref, const ZeroTier::MAC &mac, const ZeroTier: n->hwaddr[3], n->hwaddr[4], n->hwaddr[5]); DEBUG_INFO("initialized netif as [mac=%s, addr=%s]", macbuf, ip.toString(ipbuf)); - ZeroTier::VirtualTap *vtap = (ZeroTier::VirtualTap*)tapref; + VirtualTap *vtap = (VirtualTap*)tapref; vtap->netif6 = (void*)n; } // Set netif callbacks, these will be used to inform decisions made diff --git a/include/lwIP.h b/src/lwipDriver.hpp similarity index 98% rename from include/lwIP.h rename to src/lwipDriver.hpp index c4d146d..e9c2fda 100644 --- a/include/lwIP.h +++ b/src/lwipDriver.hpp @@ -30,8 +30,8 @@ * lwIP network stack driver */ -#ifndef ZT_LWIP_HPP -#define ZT_LWIP_HPP +#ifndef LIBZT_LWIP_DRIVER_HPP +#define LIBZT_LWIP_DRIVER_HPP #include "Debug.hpp" #include "lwip/err.h" @@ -51,7 +51,7 @@ struct zts_sorted_packet // lwIP pbuf containing packet (originally encapsulated by ZT packet) struct pbuf *p; // ZT VirtualTap from which this packet originates - ZeroTier::VirtualTap *vtap; + VirtualTap *vtap; // lwIP netif we should accept this packet on struct netif *n; }; diff --git a/src/lwipRawDriver.cpp b/src/lwipRawDriver.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/lwipRawDriver.hpp b/src/lwipRawDriver.hpp new file mode 100644 index 0000000..e69de29 diff --git a/include/lwipopts.h b/src/lwipopts.h similarity index 99% rename from include/lwipopts.h rename to src/lwipopts.h index 8847ccb..cd0547e 100644 --- a/include/lwipopts.h +++ b/src/lwipopts.h @@ -67,7 +67,7 @@ * Don't redefine byte-order functions if they're already available */ #if __ANDROID__ -#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1 +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 0 #endif /** @@ -84,7 +84,7 @@ * Enable or disable debug, see debug ection near end of file * for more options. */ -#define LWIP_DEBUG 0 +//#define LWIP_DEBUG 0 /* flag for LWIP_DEBUGF indicating a tracing message * (to follow program flow) diff --git a/test/create_test_identities.sh b/test/create_test_identities.sh deleted file mode 100755 index 5f38015..0000000 --- a/test/create_test_identities.sh +++ /dev/null @@ -1,11 +0,0 @@ -# !/bin/bash -# Generates test identities and joins them to a test network - -NWID=$1 - -mkdir -p alice bob carol ted - -./../bin/selftest generate_id ${NWID} alice -./../bin/selftest generate_id ${NWID} bob -./../bin/selftest generate_id ${NWID} carol -./../bin/selftest generate_id ${NWID} ted diff --git a/test/echotest.cpp b/test/echotest.cpp deleted file mode 100644 index dcce325..0000000 --- a/test/echotest.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - - // Echo program to aid in the operation of selftest - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "libzt.h" - -#define ECHOTEST_MODE_RX 333 -#define ECHOTEST_MODE_TX 666 - -#define MAX_RX_BUF_SZ 16384 -#define MAX_TX_BUF_SZ 16384 - -std::map testConf; - -void loadTestConfigFile(std::string filepath) -{ - std::string key, value, prefix; - std::ifstream testFile; - testFile.open(filepath.c_str()); - while (testFile >> key >> value) { - if (key == "name") { - prefix = value; - } - if (key[0] != '#' && key[0] != ';') { - testConf[prefix + "." + key] = value; // format: alice.ipv4 172.30.30.1 - //fprintf(stderr, "%s.%s = %s\n", prefix.c_str(), key.c_str(), testConf[prefix + "." + key].c_str()); - } - - } - testFile.close(); -} - -long int get_now_ts() -{ - struct timeval tp; - gettimeofday(&tp, NULL); - return tp.tv_sec * 1000 + tp.tv_usec / 1000; -} - -void start_echo_mode(std::string ipstr, int listen_port) -{ - DEBUG_TEST(); - DEBUG_TEST("listening for connections on port (%d)", listen_port); - - int backlog = 128; - int err = 0; - int sockfd, accfd; - - - struct sockaddr_in addr; - struct sockaddr_in client; - socklen_t clen = sizeof client; - addr.sin_port = htons(listen_port); - addr.sin_addr.s_addr = inet_addr(ipstr.c_str()); - addr.sin_family = AF_INET; - - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - DEBUG_ERROR("error creating socket (err=%d, errno=%s)", err, strerror(errno)); - if ((err = bind(sockfd, (struct sockaddr *)&addr, (socklen_t)sizeof(struct sockaddr_in)) < 0)) - DEBUG_ERROR("error binding to interface (err=%d, errno=%s)\n", err, strerror(errno)); - if ((err = listen(sockfd, backlog)) < 0) - DEBUG_ERROR("error placing socket in LISTENING state (err=%d, errno=%s)\n", err, strerror(errno)); - - DEBUG_TEST("accepting test connections..."); - while(true) - { - if ((accfd = accept(sockfd, (struct sockaddr *)&client, &clen)) < 0) { - DEBUG_ERROR("error accepting connection (err=%d, errno=%s)", accfd, strerror(errno)); - return; - } - DEBUG_TEST("\n\nconnection accepted! (fd=%d)", accfd); - - // Read initial test parameters from other host - int err = 0; - int mode = 0; // rx/tx - int count = 0; // of incoming byte stream, or requested outgoing - int len = sizeof mode + sizeof count; - int tot = 0; // total bytes read from remote test stream (selftest) - char pbuf[64]; // test parameter buffer - char rbuf[MAX_RX_BUF_SZ]; - - memset(pbuf, 0, sizeof pbuf); - - DEBUG_TEST("reading %d bytes (test parameters)", len); - if ((err = read(accfd, pbuf, len)) < 0) { - DEBUG_ERROR("error while reading test parameters from remote selftest host (err=%d, errno=%s)", err, strerror(errno)); - return; - } - - memcpy(&mode, pbuf, sizeof mode); - memcpy(&count, pbuf + sizeof mode, sizeof count); - - DEBUG_TEST("mode = %d, count = %d", mode, count); - - float totKB=0, totMB=0; - /* - Mode 1 (Measure performance of other host's TX): - - Receive incoming TX test config (total bytes intended) - - Prepare receiver - - Record time of first received byte - - Record time of last received byte - - Send results back to other host's selftest instance - */ - - // read 'count' bytes and send back before/after timestamps - if (mode == ECHOTEST_MODE_TX) - { - DEBUG_TEST("entering READ mode, as soon as bytes are read we will start keeping time..."); - if ((err = read(accfd, rbuf, sizeof rbuf)) < 0) { - DEBUG_ERROR("there was an error reading the test stream. aborting (err=%d, errno=%s)", err, errno); - return; - } - - tot += err; - - long int start_time = get_now_ts(); - totKB=0; - totMB=0; - DEBUG_TEST("Received first set of bytes in test stream. now keeping time"); - - while(tot < count) { - if ((err = read(accfd, rbuf, sizeof rbuf)) < 0) { - DEBUG_ERROR("there was an error reading the test stream. aborting"); - return; - } - tot += err; - totKB = (float)tot / (float)1024; - totMB = (float)tot / (float)(1024*1024); - DEBUG_TEST("read = %d, totB = %d, totKB = %3f, totMB = %3f", err, tot, totKB, totMB); - - } - DEBUG_TEST("total received = %d (%d MB)", tot); - long int end_time = get_now_ts(); - DEBUG_TEST("read last byte (tot=%d). stopping timer. sending test data back to remote selftest", tot); - - memset(pbuf, 0, sizeof pbuf); - memcpy(pbuf, &start_time, sizeof start_time); - memcpy(pbuf + sizeof start_time, &end_time, sizeof end_time); - DEBUG_TEST("copied test data, sending..."); - - if ((err = write(accfd, pbuf, sizeof start_time + sizeof end_time)) < 0) { - DEBUG_ERROR("error while sending test data to remote selftest host (err=%d, errno=%s)", err, strerror(errno)); - return; - } - DEBUG_TEST("sleeping before closing socket and accepting further selftest connections"); - sleep(3); - } - - /* - Mode 2 (Measure performance of other host's RX): - - Receive incoming RX test config (total bytes requested) - - Prepare transmitter - - Send bytes as fast as possible - */ - - // send 'count' bytes as quickly as possible - if (mode == ECHOTEST_MODE_RX) - { - totKB=0; - totMB=0; - while(tot < count) { - if ((err = write(accfd, rbuf, sizeof rbuf)) < 0) { - DEBUG_ERROR("error while sending test byte stream to echotest"); - return; - } - tot += err; - totKB = (float)tot / (float)1024; - totMB = (float)tot / (float)(1024*1024); - DEBUG_TEST("wrote = %d, totB = %d, totKB = %3f, totMB = %3f", err, tot, totKB, totMB); - } - DEBUG_TEST("sleeping before closing socket and accepting further selftest connections"); - sleep(3); - } - close(accfd); - } - close(sockfd); -} - - -int main(int argc , char *argv[]) -{ - if (argc < 5) { - fprintf(stderr, "usage: echotest to \n"); - fprintf(stderr, "e.g. : echotest test/selftest.conf bob to alice\n"); - return 1; - } - - std::string from = argv[2]; - std::string to = argv[4]; - std::string me = from; - - int start_port = 0; - int port_offset = 0; - int echo_listen_port = 0; - - std::string local_echo_ipv4; - - std::string nwid, stype, path = argv[1]; - std::string ipstr, ipstr6, local_ipstr, local_ipstr6, remote_ipstr, remote_ipstr6; - - // loaf config file - if (path.find(".conf") == std::string::npos) { - fprintf(stderr, "Possibly invalid conf file. Exiting...\n"); - exit(0); - } - loadTestConfigFile(path); - - // get echo details - local_echo_ipv4 = testConf[me + ".echo_ipv4"]; - nwid = testConf[me + ".nwid"]; - start_port = atoi(testConf[me + ".port"].c_str()); - port_offset = 100; - - // get destination details - remote_ipstr = testConf[to + ".ipv4"]; - remote_ipstr6 = testConf[to + ".ipv6"]; - - if (me == "alice" || me == "ted") { - echo_listen_port = start_port + port_offset + 1; - } - if (me == "bob" || me == "carol") { - echo_listen_port = start_port + port_offset; - } - - fprintf(stderr, "Test Parameters:\n\n"); - - fprintf(stderr, "ORIGIN:\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, "\tnwid = %s\n", nwid.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, "I am %s\n", me.c_str()); - DEBUG_TEST("Starting echo mode... %s : %d", local_echo_ipv4.c_str(), echo_listen_port); - start_echo_mode(local_echo_ipv4, echo_listen_port); - return 1; -} \ No newline at end of file

bv3DB!V$4=n8&Fkl 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�ATV+8k|7PamxtGn&Ay8EzxFYJs+ zl%L@U86fE&r&QN@-h!a}TEzByv6`Y(Q+%4sq}y}-URhJ5w5wmmi=QGAzxRI%^s>Bs z|H$tUK5ci9?PAh7Kk8U5w%Ty+0v$0gKdhma?VNQ=&eK?9S8Rc9XOQtW8YXSCRDXqF z@b2;6{Z5g3S5}OpiCXRsvQ7NX3Q%`f-Owe8S7Qi0UXW-@s0BDN72X|uACdTuF`6z( zQOh2b7djWG)*{n&8#_KQFB5tHWX!7FKXGidgAjrP7l z<25{*9L6NhI0)jn9nXi zG_@B4=+&pob8s#E%)HRHM5XPRK1i+7m2EXf&|pccJ|=B2I&+IG8IF~++s&Xopt0&l zPfP1(|L>$F$1k2+!f&89N;e^BdCR1E0YyTyG;>fdx9h_$&)?K@$9MUMJ67HHueNn3 z&FMBty475lCg?O+(T1x@iqn}$)W~v+dOwTqo6fSG9TN#HteGcd09Bz~AAAHT%#d^68i5rB{&W=K8gV>EeP8 zj+>v+`5GQx^wk;%`L2n{MM({mNNerLeFP;wk~S+4i(*gLOW zPeZFh)I-c=c~>a8R!@3ctY3BI_{y#jUj7x*lfEjb{Onj%3$P0_UT-Mw%l=)f^l{43 zH9-#(&=k{Lp|=k9-*!j9{r=eCI;y=RcrD0Iq)JMRq5a6G=)XH&U%nFW(A%bSUc&D* zKY3C6lS?FIn&6vD_3T&Z&T7S(I*~@!zN0TW&gPt;G|v(LWT2Xhg-}0By-bLem(yI5 z6EMEnzG>=Z+9@Vm%uJJ{kaeeyiM#Ej|<#&CfYqB<=sxfp7dQ6d!8yi=KpW^hQpQTT%$5yVOuW z-_U-wL+|(QNyIU9`_;uUmQ6TW8}jPDi^ljKe-C;r8+-6mdKsWkyA9T3eaN_MhHDU{#-F<0_mE_93uG4%~*2?ng3^pSX0ioZ7yYi8gh?^ z4oy34Y5e%d{~f;ZZJ^+Dy?WY{LZ#Pl6_dKBI$uED(&^F@FQf6l$9m6YtnZ1eH@va^ zVj|xYk82|5&}vqOTwC^=B2l+c+Z|-1I=9R0-j07AM~y_QbC)&6R$UTua< zR@F8>7WczH)_L-j~b6Sx~p1aViZRN7f3x zY#iIx?=??#_=NIf7ZpwEl>tT>py!)Rzjg9{k#_I7dP}7?Bc$!;wE>s>9LOnm&tNZEK{n+nMsr%qjGP(Gz)6_j6kJGpv{QEK|!%te&pQ^blodUzkwa zerxrzv#V4|_UrK-l=#$J$tQ%Et5>P=GpPIV>RGXWgj^+fj$Xe5H;z?yeiuYlPbc;P zJ&r>X$9%gQokR}keui{EKE1qSO)W2T^>k(5I7Zpg@}oNCM&^_=+p()uNm}*z+9f`E z1yot1YBgD}Qsrk@_cN+zWsa#O*sa%Z$muZ)7A^Od@l?mvj=0_6aMA*s_o3y z4Qt2L4J&osu)=Osjvu$F`AHCG>KVjzA=Ggg`s3KZ-Dx4pk49t~I+d2n)64IFMCT=^ z{qNLyH6I(J>>Qn^?vvWi|3`G5cgg=wotL*HMA_v^*(q&MpqJhMh;C{5s6IF1^O|l+ zqOw%%dAK^iXwNfgJwnYhoq0_08x&6B8x&4o>KhYIO{!jp9L_umM_uC1GPIwX{6FlS z31C#!_5Ux6h=_!QNZd*ltv_pBa4k}$ z7Oi!wRckG^N-bKqy46~$)KY4#+SXdN{;Z<@@8{n0W?nXkTFvh-8GYoPclWb=&$;*A z_ufi>rRV$WsrfI}Gf>y_$gx-U(o>qubNM5r9`iWLLMaMXnOSz`jZmwVZ$`T5==SxD zl6p*T4<9#pEP*ig#3E4!EKmP0)l+(O$LmyMybNQcQZq3hud*vTW|;yOJmd|M6tiJ{ zt!nqakjKkEpLRl@Q#;!yd_L`5)=4|9Zp;&pFkLbC;;GHdjQO$v3%KTC?HeS;%#3eu z-%j4=)Xt{yqPKDMHrq~SX|O=}hMVs-QED^Ky{4ocv)ygIzXup{WK#yrWqFWiLQxr|&&w{$Q?eN@8wz4*R z=!Q!pJxqHkSLx@y59JK8EYBl9 zIL=kR1<@PFwUNgt<$FUwk(4tV(Z>775pP?LijLV|As~5 z4%WxtE^Yfg7v$a7Yp+0cvj5}W()R1}B~p?Mz1S77gMFu6*%RH_dZ#~sX{leAy>|JZU3GgPt?jgp{UWFRm%5{w+sC;xT{q?-a8_)pXpY1m2w>fP@2J& z)1`j1)5^QkVzRZm(^50GV;x`VWmqZon8z9}R=)3at?}10uvI-?KPP+1lck@)vVpEl zKfU_b`0HQauKrf*za<^Mo4VCbN$-}dftSo3U)IpjAmV%TPsWt}7&y74gFUzHYM{@|U($iD?C+)SFXhaTFuIKEe5!b7?<$~N=A{dna(g|6m z>VSWlm2+?3SbLnhxTA88m+DA4qXapA{w*wO@27@IZeyn-{JA|&m^-v^VzQSq_!G9j zx$wW!erJ2PKiQs-Pxf5Zz{0lr$GH26sLVf^4UJn1{CTf2*gil;N5)?GlFa@|`#r^5 z3Ot`<^LuW`Y#Z=Y-Iu>B`_>i~`0d=*OEuKJz^iv|=k*>`;MaXyevp)pd*i6>sJ!Lz z=6rwq<{OjX3D1vWMVTF{XnZf6-+=1ubx32 z)zkGoJTK+>#|&Qdm4TT}+=G;Fsbq+>&F#Bh!-OyjV)5cCUDxgXSJ^nEx1=x3rgwIK zva@@P$L0CswCl}!)!JV5%C`adbP);fc`(xo2=k`-?J|V(z4cfi*L!q-&o58oG{*-1ZV`^I?DSUIG*EPL%cz?aKy|R%b+kb10>#bfPL?hQ_`RA`U@5qk# zNv!wEuUEc}$$tK~zsK8^J(oL{mw(+4NRrv8fk#{3Yk|DGD7ppp3VL`XSM3* zWxe}c(wo^SF~(9Dvq{)-vcce9Hh^8~?Ng?;6Crq^Qb}(~8P(VKTEX-C%2a`rhx*z% z!*LJ`>=QjP~>B+usBPc(zwFIrGg?dFAWc zqp6{!3#FX7J@jppYIJk2lW@^ zoS^?1)?YqHXrwA*DW%by_ORS6gLrBW@sAK6?jiTMj+Sv3cop#RA>+=ex@=GRo+H1~ zfwt;f=+4xEvVsj!HBi3P#qYd*Y_@kv*|3jo=Vgf3h1d)+cwd|CA&7(a^}W^SHA!ir zZ!`CkJy;O)gs6ZxaX;VdRYvVEYEDY&{4ZdWhWGgK!R!bp(hphsYc3`3*nRrX)yNd8phQgg94H${{X3RMtHC zEf_8jGd-seD44lHcDoH zWGfTGfv6ZIwhC7naXyT_pg(3;_kBY3sJkfZwuDI{x;hhQi}T9Z0ADo!i3CAnqQV| z=7oR*1nW2LR=#$XF=RPz@|hX?jB%YBVc}i z-_x!EEg)scK>3CTzrKTPcWOu(ILO!Q4TJ2gejX|P_m;i0CYuly5QBx72(iBqv(s# zUkA7L>hlM)%bQx>G+*6PK73m%Vbt5^gO{S4sF>O=#J&&<<;_t2AVNYAL6|R6QUUMd zP%p{1wen0@BXNjhJVjq$53cGfTQK-NCEr+ogOq25;5(FRvk-rW*doN%-Q=Il&h7r~ z$IImlz4Qx(YyIhmw;AO_s(DjVOlz>@V$Vu1l!0s`Wpy8!dGZ@0k)r9;Dv6<9gSbFa zUNJ-5%_p5r{=Ppf#ETG*3&H3zoOs^PiOn7-G9m3jhj#E>T;{F|C#-p9)`~MLp<9Rf z%U%0*X4zbCwKmQGcr}}Of{US-A?} z>FEH1>fycZ*Whdm5(ytf%I*4Wgy%Y+71a6=_xJoBc5{yTJu^U5*o62(yk@cq@e0I? zLh$iTwQYd!5tJQ2Cpp-6-hTeReQ2w-luKaRb-d-rZYT0ijGD4Ye7X?NLGWps4025u zS>8fQy}Y{dCWwT*l@b?k-d=0mG{oalrWxYd-ttm?ejZ9ZWU}?~t%{ElNB0^jC4J>X z*8Hv#<4Tb7wh(cMgG4M5h!OqdVGoFtWVTiT;Z0rgAnuWrp%9xTr9Z^hes(9C`Mtio z?ap1K9tyEmQiedRAK(iZSMDkA z+@+nngm@WZK9k}rc$+clcF+ZzHN(yaNB z?R0t3?}u2}y1gxXw?k|e;ys9WrOdk!MT6ygy;R*G#Iq2o!M;}{mh59w9wy~PA>J@r zwU6(H*UK_vTTOQc$n5K4h?0E;rHz1v_&dbILfi(iU5J;ARa&Mu*rk1l(%D5Z|{}h8`$y?4zBjLOc!;72;9T(F1*qAAgW_LF=gPnuA1@ zO?QOYM49)5cmSf`!SePsej5(9+Iuh3{`0nD42W9LJV<%8W;d`ygr@Um$RgV=G9R?l?ZL ze3#6d@1@LUAvQp4J>2K2HXmUbvOg*B9bvQehM4{(TXhpv&;63@hT&HrbM4m<{oD~U zO@vrDLLS86cm7D5atF2DCdBO!caN0Mqwy;lEnbES76@?@L_~-;jP{PUO7S|xQ;Bc1)R}GWCCe zlpG;8LYyco1Wel1(n5I+Hou39r8}g&S!`>28)8U_E%T<4oDgq7#7k_M*CCoqiccl!@ zUiIzg+pQ6q`X4P zZF|TUSorZxcr#xjrPTikf#+n6b~`E03&A(y)r&&B1F=nrm-m!^G86K-gZ*+|(r3|e zBBPV~i1e~ZC%58ek@ALQTMV(imv6Oirp(%o?<4qWTcDvm>;h(&OGNc zL^>KJg&9)jH7qP=p_IIM(|j+FZ1oWD_{a0Ce7bG{Df`M=Kn(=9x-(Pt8^x}8xw(2- zvYl$G?(6egFN^iCl4at5vMn^9Ana$i_L|@8Vld6##|h135rVrlnN{kC_iCeuTx|6$ zIpxgvugtwQZwk0dUT1F5>HI#v?Kc}m56wa=|4jB${Odk*_v&CC-|BsK+yFF>*YZzh z9)HkY9o~n_%(eb5J?2I2=0T0jobGlJFyCe~HkIMQrhy&S8TZB-ml5%TZIu#YB}B6j zXZDd~$E!2ms?NK1>+>UXcP68cRbteub?9TBbISB{kW4BcC572}kq2Q@Wwqd5QfBJ2 z5&b3Q^gaR)?+5Zt&?WkTErQ7*(S5EVk)1Tj^J8;ul%xB=pLA=X1w z32~hfun_AY76@?-#EC+zg*ZuwH4wEzTm?}t#1#-H3vro|wh$LXB!svSqDhDgAWjwH ze26oJI1l11AUOIxIGtxm(7GnGQn`m1N!op4y{B{BCu_)`*P@*9dV3 z#C1a4&`18s>~rjFk3|1HI>3>WJncV8JeCQ$d6{{sS6^p)(7N)zF@O8#_4o7Wr9OTB zWJX!;jkR1xv}!+PzeJLm0bL;}r|u^#$>7l_vGZn9#`KlP-1tqGb%IEA)*j(3K4;LM~IUl-V>q$;zJ?o zA$sp;i4a6TA!;E82(c7mkPs(9>?_1#h#^97k68^BVj;wEAr?R!Aw&(tC?Tp0--MV2 zQ6R+e5G6t!2T>*jcez!$5YvsYgqXUY{FCucU3re-)4cntv-4Hv+^$>seQD*Dy}!Ov zt$YL<=!pKf@Al}*J3l_|dqKLgx2m%|o$dGQ%KL`9V#8gLPiOB1>B_r9+VB6jIObow z?)@VpTa%~%$2{j(I6vtol7%P7l5V`AFcvR7HB}f1*Lwe!6ciOE6Lp2tV$oD07D*P= z#p9|e77jTlx`|j#*iDp|2jYoXotsPs>VlC-ZLn^6z-@A)sX&7piMxrMbU2zSD-ERb z9DS0j5=m#$Bi1pu!>D+iHXZH=fdEoMbAPNQI-zGR)H~(buANy7z{u#|N8&x{b!bsX9YS zX9yT61ibu#a5S9C(af6>ZF0usIVZt*V%%x$j0>b$h2hHe*(?Xse1;&heGG3wGRxHbtC9H`Nde z4N$egWVlXOo6w9@dQ7ppU@DfFSW{76E|i;-44>)-Qcg72866#M1mK2}PGhh++?Z~3 zlIeInmOwP*)B0D~{(rYQRah5`)}<2(-S{bKH|@5i3mQ~YIFU+gZEB3gLM?T{MmJJk zJ}r~$E99D(Oogw|4U7wc+gmZ*@M3Wg)e^76WH zqAnc?YBc~6QVqfAL@i9WIgqNzi6;WJT0qMyxiCWmO4v;<3NI3E~t7)!JSVu_H}r-T~`HoKwRTvZ#3bra_+8{2X|>aMV33z*SK?UpuS&LO%$aR3eSWM#5U>Z$bWT6r*@2Gcn9O-5Yp&Ws8|CE!E&oT@ zyUb1b^-liPz%6>X!=Z>_?yw6TH99q8#K&oC)$U--s9f!jwNLn*M2ncFYS3^FpX5|l zEtoQ^a(ZCutU1%Z9GE(#dWOOYM6#XCuP_5$6b>~n$*)-Mw(JaAP#UW}qeeM9tgI;* z(SBfO)#+YF(~(F#mH0n}S#H$0v7GsOn4gbP>c|ZbJv$b1cU zsJWEq%>S6~p|F_(ij_2G&Yb4Qy6D>Q&j~yWc?!83=!%o0O zxU|cwpLSOv%d;*cR0qIU<&5c;QO!)aE^~v4-O{>II{jBOFQEP5=M-S%IaS@IL}tKC zR1P?jUr{g2pXb&mcd9p|oa*D|%%7#TW=3F6Rbb}488c>8R@WGXD(Xf^GDFhAl@4dz z#&~Kc!1Fnyh7N5~dOp});;xM9DYr?PW;>!?x6Jbb(lzai4BKW#g3FSNEFx4_o;btF zcZ&6)=in(lXRZrs6SeVcMNU}jg8zEPU$riso4aIZO4Xw_|G%hBxUsF;Fm+s@XNwb^ ztk_j$)wDUYE31wT%$+jr%QI>M)816Gb>l3j?M-~%L2q)aR!Mf#c zs@xeFQiZ{Esv#9y?nb>;x?pWx$gN-25I%W%q%j(cpOQ$X(oHLxTTU%1E*V=ouI#As z6I9z$zE#6o*IAJWr&4ZI)di#G3ad_fU?$=>(o1N))|__}^}#wlQbtu6cilv?Af!56 z;0s5c#-RSk4w_ZK<S zwZ0@yTcxh3RVPfDSEVIQPd&N96?0OrrNj!UlT%qZ$I2;pKo?776Jv2Vs*7b-Jm*AR zXOZqkneN6CHDlhqIrIE=B{ae`xlTCl1Vf>ORs^#|+b)|Dl<8ig-bnA=$1fKS(D921$SkFIOOHaX2Dw;^$Y}mfO7CidB2I9F(FH7;s1p^) zy39>jvQmYUQ*F9FtF%dNZxGC^oKrP##+2y;x_aBHI)(?acdd4QZzWcjig>;1sOhPd za|WpTP%==fhou%xRRQA?0``qb-AaJ72){wM7YUKn4UJa1X6W6O32(EY}>T9+PdXVLojI;vcs`-GSZ^m zvm14i4e3+}{~3%ro|AU9i!k?;+)%*)MO%T8Y0TUkQ~1$9$3qMyV)3}v<+y|u(U_yL zJzQ`6Ngck}+=K8~k>jQs+(b=F+?_PCIoF9rZE9007BR7}z#R_;yS(fqR{hBx7ENmKXiP547S%*U zC?O>!_2ZOu!m*}yO0>fQQH@-kmq^7r8fKOXZE(W)qsqpWjx8z9P7FGqJgE88=LY6Zo2qK2wfY-inPf(lA**K`tF#-cuAV-n zW{R3QZ;GBNO`SheRn4f8KYGSwvR2Lw%&tB*FlBC~kE*Pi`{f!nW!~JtSLV-{KSNc2 zwK`B!IeW&O`8BF)dYN3UoLd&iHZpsbPB?bnocVJVP3e@Gh4bdjw#3{yb7r;WqDGf^ zpwWO$xs%eCs;79fXUx_;n6mKWt7M(FghHy+3hAr4!$w(;>Y&L?TH8W74cs89nm=n+ zF85n^kAOeg8?`eFdp#C!(cKRwmT5?} z)52wr8;zxxHGmHdF+G1w#?lEkKV%BDt0|zf$}rj~c&3#0(wUtt@Ng7^lUtyYVSTwkyLQG+fiFw??Qnt)Qww%4-ptI{BD;&9M$mL z$ljvH;4%&R>5$g3NlrY!BH~7+OV$epSn6n7T;qjcv<@b;Lnq8&&L1{Ab2REtn>D9; zM%SXt_R6Je*Sh7k(NWtGvwcPnyRKHt8`NrX1fg9WUS+ccR)lp_L97&sEemL;8_*G1 zM>S^PKQkb?V%JhykIGj-*=tHbt@^7~8q}(4%*niI3#O|X)iqP5>eSPrzN%qLzvUbs$xq)SgSUTQW>uvM3<|V$iYkY)itc^8y+M&9Lw(w4soy34QLvLF} zrIeA}jve?X1r9x3@Mc08Q;B8FZN9h2&Z680kFg{;17x?wlf>WUFk zDBE}KbkoF71s#Z-;7R5StpdGIA~ai_1^Z0BowRA^3$2>;rF2p#;nsItMkjPqq^?0v z6wSy9A}&U*pmF(79E5xS7w&u)F#5A zWv;4C#DXF2J3HFvu{0J^jp;}#-1<^|IHG~xnpQi~$+2~5wdby;vBg|v9z9USMMXu5 zTS+PR#1tke#N37!Lz!EA9uc>HE92FAX5><~SlNkKWk^mIxQSXgu_BgOt}mM6c5RvL zCHym1mC&f28qN;ZDeeXEH?vlznj*odF0F&GMt7DQU6yLl-3lgSQHmDxkEy9t8a*x+ zPeP9)Wt`XiG<#n%;wE%eI-yLOlyTCkoLY8O#cH$_6{{klE2Fisbkt+!JU6M?E(BXD z=cOa=EFCu3E7OAU))!_6Q*{j*#B_o;lIf^+2@KGavyd4mCpy{CNlPV@X-&i|5v{i; z^V}xc4OL_2+lu>gh3SM=oLHlpIi+UGEJtqr%}<$)b~;nFTbE9_^GqHcPq)6)==f_G zptR;LTH?f-+(f;eUYi@BNp<3kd2?ziXUq#6H)r+?RoE0vfMkWD2VHUAVecn{4)Be90YU^L2|B7lUg3kkb) znV6VOw2wGY)ZUY6494^9?IC+pJ+Jk>BL5Q+6E$45P3KY|Wp2ipqx>(kMlpinHWSud4kDq+Pn63C8A*QbY@Zj9&HEy7dj?eThSsERWxPj(L57Tcd^ z8rDHyN7r(lMXhU`5Y9jNKU?Sv(Dij-<)#CKXqS9vhBgDvp zl7-6iAoFWx=8t!b0|=&MPqiv{ikfwfx>#d8;_4Ke$#VT@CxQo{gvmzS7%TxF0jU+()>$o>$mwz{izfk?O!{$whvfbGqJPRumybD=0Yh#H< zqvAO`&z-B93(V?x(P!0(Kq@BjU>9o61c~Me@{k)z1<{xym6Jn1Cr)(CwOps7!aLK! zk52luIVP(l1>)5biFaq7>+`;y4s}a9qU-IuE7lj;;|Kan!MvtyQzRb zw|Qi+HXIEmS^|3JuBSjz9Yexx7f$CFkJEEobFkzqqAJ&=yY?%N>5HwFwruUO=4M!yCTaC>sb+?i1t`Z0JzabqdRry zzJAt&TPcYaTX(e8KiZ7LQ7lMXM3KT}aZbZDAMHw0!Fb%|j<08hzQ&9-YGW+2#^{)n z31!7~#p8-YCGPm6>PyPTmjx$`8yB2V>z0&;#uk^=7mqC~sjV+5cE%Qz6l8R&#@~xC zRsiSil+KxwSeA4~jVdT8&<=Kvnf{80&5m*kvt9pHZ^YGRc>a{naQL$GRa&#muu-V& zgl#*)@sj5Yn>r0vy^QVS3q5wPBmPnP_o%mVv>Wiwj zZCc|=;?J0uPUkt=Zw0sBphvi$bZTwcZ6IlqGqGZcvg>jFmjm=ba}P9sX3%Vz_k~@% z>a?{l>VVtfNe_DTpvPy19-jegJk>Sx8yj8ZjLKb9yaeCKJ#)G5(`FL+MN{cu(!6?w zJ7)T7l;@}ARZ2aI{ohvXC8{xC9!#)zQPXZ9RbDP}SS;bRzEkRt%sMD$Zj<^;*$X=^ zWJTaFC0E)oE%IxFcPD-7oY_Y^ zjp?L$0gkzyEUL)sibZ@wv5N%<{vqIT2WC!f&M#l=FARjYMtd{)@3Uq zX}ly&)pZm#7ZsUXps|o^q8WL4xku@wqUPeFnH{xPA4}ARLm@Y6fGJqV=4bO7a)*a| zl96Dtp;W#>))=&YcO_6BQ-b1J?ZSaW||&tG`9=7 zYc$uq0d7}R7xvl)Fc>|74Yr$ zr5#=^>j@%u6hzp)tGgCDd2Y*&{b(oi8a?Cq#V?M|AKk@_1v|(%`pD6FRF#Kr`b&9x zGP>4=m)l{~%8iEfeBQi|-e|CFJm!I}9QIDOx@s*!+3GXTuQ>5w!URa8)#%P3mn>g& z69_g3%rNa6fuef)Ry}2*GiDbuhdhT7PwGJaj4%L)Lb1l|2YJ5mTCv1D#$w)gku2~Y zUEx^~J+o+X9a+)EtjZl_YBQS}Y$sZ4&6tWFwq}jZzVgd1R_B;k^*N(jJ+rk-S)FA- zM|LMm{8kT_yKX#SUTc@p#e`cgSJ0fC-294gQeG38YeJxo(yiL!2u!6dfetFRc>-?4 zycnl5x3J6VFIy=+Htsr_YSl2SQ=YQ)>=Ed>mD;oU^Z%gQwrQ-ht^Yrl-7#)10?BE3$nKT`=+tAJ6s&cZg`>OHsDbz*C|gKrt^~+?7i6yJ_u; zBfDpNl&MFVKAkdU%JyJWk2-yNb^2_3-J_#DI{N8#w0$M$RnH1SYu&Mr44QY!*=Mx9 zSG)M%_F~`0l~E~=X_>DMaVKY&(Xb_I;`}2=7L+cmP(J3_bNfk3#b=!qkJPn9Q^96? z(aCp|e8-9JT$VedRXUn^LRR^nmQ@qe(d?7*p$hY{sm$A}%txm(6hUH!5IJSj%yY6H zIeO7(HTpDtEYZgq`Y6{&-e@(^*YgS<$YoX6ey>><$#ZlW^T=;7Q&U<#EovUl?Rn(3 z=aJi;K63koSB533O@OkiGo+KKWS26HE<6|8qcuHRv(r`S9wq5flASC!_ozsZitKzH zxkpQSw4^Hw#65b_qbJ?A^4p_)J<9iAU(($L)TC!6_v5eRnipnzuL8E~rMii9$_Xc( z)`@lyog~VJ)@*9Xji|z8Z8%yOj;s7Km0zk7v2@B+P2r#_OeYhW#E{#h%2hm=YB2k4 zQwd$A?{&npr%Y3`PAt`e;^~tFdm^=v>b1~xCg1vTR)FECuB2tU%L{39a#cJLOU3H6 zfi$@ZQ#KWgIkAXtA>>9=;Z#duFchL*-Z$MCOw~0g?}9EB2~#H18?THCM{qS@^73T6FAC3qvW`Czr_oXa-f+C(_C3QasHN~KaN6;X{5l~PfiEv?*I6<1BAN!3)A zRBlRX`KVy6nx>{rnX7819IK|ynWL)Jyc#u6<*DLwogo?u)Bk|^rj1t6^70j0^~?2G zQf{*ul^!hpZlBd5rziK0YD$H9Rdv_vGx-DlT5E%vc7w|U<|{3x3W|Hl3AZktU`KAi zrWpW9q_O(WvUFVBw(QGcl|(BNpFGw|9X=)P21wzH73QyhEXha2o>4BC*Cj|$Tz$gT@SW_adM~9bU1^{9#CtyR(sI?>R+q|;HBom(AmT=sr5bz}M3$lP_}0PZS?j=r-Fs zi-nkbb8}%q0sptT8mtZ5N)Tf}w~-7ka|<*&s8&}pjK;~D$8$y|eUXC(L=)AFOqT1T z%b7dOsLkBfVVO^4zFb;^>VoNI4Jn^0sXRwnR8&q=ETZ#iO>_8OxrSkVZIu3hlxj*D z%LYW$f|?q8V)z@akF}wq!A8kh7n85ZiOOk>N=KKY=c*MB`)kh+NAm^I^GyiitVr+; z@`OVm7miA{Ryi^^?QNLSDx;^1*`}khXny;v#vZd6X38d9^N6tqZtaWWu|zOo!50-% z<>fjys*5n}9F?mylSZjC2|%?8EL!5IF>>yx3Z*kFQcKjtiIdbsm7AZh@+-!u+#`=v zxy~_;PISukzZDge7*=eBN;YWaQFz#qLG4L{+L;DtsrtCisB}g>(q&Pt2RW9DM(Zc4 z3SCc*3bknVYhP!tc~3DpnX@B~a8%&fS#zdNnH30BSzA#BV-!7xHCAtQ)%g{A_~!Py zj()v1?8{6%LdWu^7uL>lZ08-%{yLt4bT;#7H{CKIk-nJ3yK+7&qA#-NV8wO%P_5s&QE$%BIv z4PoXGeEUSz^Ewe_r&p?=pg?C|qPsFi+pL-YEmHAtvm41!(+bSTQpO(bQyH&7X1Hl&O^l zKwI~NXHtXF(H@XwQWwmt4ph6~Su!2h7K-;txXZM{Xuzn81e3{DS?9*$N?MLL=+2g? zP}&I7P{ocm5hQd=9jLOfM&Uj8ll zT6N%9ZAz80XXSI|?KC|Nh$RXdG;ehTI8T`Lxpl&8Fll<=msc>+n30)E`nsmOXj6Cu617RA9eXk?T}_BVvR=>Ei2qDUo*RiZ>C#;QcAN{my9GL<+= zCC0171f4{(PA@J|$s(03R!My_RwYYSa-2$*spL^AIbJ0v=p>SLIysAVj$)mqSm!C$ znTmC;Vx6s6=PS|qN~lNYE7AE%biNXuuSDl7(fLYrz7m~ptj;&KScQsINdK#CV5|z2 zs?azUDpR4ORA{^kP0&ds>vY{}NVgi&t%h`~A>C?7w;Ix|hIFeT-D;?WdUQVBYDl*l z(yfMct0CQLNVgi&t%h`~A>FFS{EXyU{i=$K8e_3gOP!7(BE{pT=~L5&H|+gMefsX!Z+H9aDDOx5x3l{C zNj`thf%*vRV^4jYqK~9Lh6r7&4^;AGeJq!<%k-xu=X1(~qf;LD2+twdH;r@K(u6g9)gZ_5^2fr=(-vgq(V?XV+*N;!@ySeu2Lx_Y0dA9zA- z8nEA&AN%EP1w+)Aw_JSEnO9HW{eZII#L!Kz&TO9e{evFf-1|F+Up(P0)$5JbW3Kx1 zomKbV|JK-1-+93O-8$!{yT6mTZ}#zzuf1UPWz8p?GBWb?@2CD?uS1@GX3O_pTlLQ~ z&iUcX!Ncx4=8d0B8TI=CQ8lpdy*HfnqtScx8`J0ZjhZ7*sWU7yM(@#g&C~}E*C}~> zzdN^AO|L7}*vI?7``+XIb;`Am1#i|Vqx#;svcFQ_RW(a{sqH4^?2q~l)+srC{h5{;x~W! zrEQ^CU!Icq#rNl|_@B$?|6_1^*l(lfPG0=tKHuv7#}DT(nVI+G$>;pIZrHx#27YVF zrad+c{%P+edrx2dcIEGn9Hz&Z?>uytZo%nw@EalZ^&s@oYA?`2bpic7|pjw?HA{Dfd_UC6CB+Gs7l{~iPO9Jtq@y$A2J z?|%CqFyz344jy{QutSF*<{W;+mqv^nH99AE%#nHd1%=rv%8#Bnsp6Q)wx(qb;ggp~ z8l$oJDT!n%-L#^)<vwMGj z-~AhZ@xU)PJ^0YC9)9G}#~%On6Hh+%^fSMC_P5XdZu9S-e__iXUi{+OHP^S|%@=e_s0fAFEPPc-3veXNteD|hhsS|5FJ7xK6L zdr=41!N&eR{K)!~lA=H$spmj$h;`I}o)1TY8r!SJdpD`dtT!tu){#^^oszjmmEZlU}Wqx+QUTuDRwE6A6lVAV-y?6K< z(8u@d+o#W-{rdIWt$+3hAnewEcinQ|er@|=eoFrJdfHq5?cFL@?{;Uc)BEWEyt9sI zUwi7&ht~Y+zz^d$Z+ZWtkDmSTqmSlnx%a;9KU(q8JDT32>4DEJpYqR37TmYb_K!Y# zNz)Uzf9>L14}0ocd7A#arq5n8zc^>{SAH{7({F3~$B*1_>qWPm@|~cjw`=;bZ@&Je z6-TUn?KDmI)jqqix_R;?m5<+cg{B8;`h+L$UedDf#It^+>HRf*)PnbCmt8jafyXpG zOw)6&I&OUIwJR=uS<@pl{j2h`Mm}~<>UZjck3P!N^xIe7f90>AJa^q8nl9D!Uv3$5 z;8g=k|2a<66E%I|9plElzij*+b2U9((?=ik&@+F0_Tg2_H9bqy8-D$pp`)k&;lXn> zU8CtM9vS(wC$3$7={ij>*7U0DYtI-Fx#fionht6Do#z94Ev&!!d%x9mMAM`G^~)D8 zeRtbi|I~C!)Ay|W=%yQQ{qc_n=&_%!>2Dr?dStgi?KehhdX=WDi+)kM^rL$pIY!eL zXnOvr4VPSSPSq7BYWgxw|NP9{_=pw%`D04cYc+k*J%739+MoaNhKn@4UelMIkvi|m zzz^R2fu?WK^pjWLc+sWt=|A11>AN(&{D8ghfA@|4=l@aD_iFm?;$nCH$lHJYA5Cx4 z^etaI?Wu>h9rJB?{kT5*9ew1OO@kM|RG`nF)yHpEC&S+!G2*65eZEB>gC139zxm^D zd{C#)U((0lhVHXE)c-H{o~h6OP95jXjqUOHy%&5NS?D9rJ$T!~1Ap@Lo%(!xCQ6;W z_6dFNVesJVpMB*OO%F6w?JW=ft@&2sxBd08YLCm_ZJuz<*N5x#Vfwi9fZZQC?TITl zj@RcS^bueD+G$UeoOw~TKF`xf!^&50UO)bs-!|&=Qhm%gV$Ff0M$ftSJbgYkZr%e6Np-VQs zsm~YdW8q&9xgjq+d-Y!0RzjM7?OXAoq1SsoKU&ifO&`DFpKHGTy~gXNYC5IqbC#cR z*J;gryt!D@r)zq}L4RoZ?n^ayt zmoeUTSH8FSt}&PYO4DmK{pY~CZ~y$-nJ@lH)9W=o@`4F3ls<6v_1iUl3w^xys_!M% zJoL^G9R%N{=_l@cwWj+1Ek7yN^u3ziHsy#n4}5F;d9yUVNz>OiFaFKdPdJa)Yx;3b z|FQb;)80C9$W>q0^s|~SFFNeXEk9nj?P^VL(exE}{&{ir)4#v*ZcV=gPp5x>{qIk| z`u(Rg{dZ(Jef{@m&1(AD-!%QUriZSbeD^;uy!o5`v_Q8bqg5x|F!-N`J>_V+ukLeh z@g=YRW&Pl*kJj`+O@C+L+V8%9_29qG*Yy6RzkPJ=@12}m;+h_&>2sd^{;4N@dHTw4 zYI=mG^Z#&5pUE#Be*g8F&eQZoA5A~0aP6`SH)^_6(^KxbVC{Df9Q*9^nx3fX9~|=M zyH>w&@HPL|^z>dG`LE(wszJLsabQjxm(f0diT|BJ?dL;TuY44@Y`mov^C)PC{ zIQlq4AAi=z&B|iqh5D${$7{-t&(%khKEA1s-|1s-eFXIJ4Slc%vEOGsz#aTn>f;dU z1Nt;TS$_OQS={}HvbvY6k2+=N5KENRn||{5Z~FM?QyhCsJLo06MxTdDd;2P@pU+8u z{#PIPFl6%|`Mdw8uwv^)iG$0KAzCWG=1bKYro&s$AkJfTUmQ$EZFY> z`T*#$^SzX{31X1H>SL@v4pJ5qj#hTQJxSRZiSrYc#SUUFV!4}z5AYbfdso>t%G>lY zQ`#LQa`=jr3CTHjGeI9$O8Q~S+6HyKqK}h=K2#qMC~L!C(#Ib9cuVAf9FGwBZIkwY zBkdli?7AsqJJ&~lT^|SQ<0|17c3Q5FhxPHiJ}Q)r0U5*F(yvNo^=h@Wcf7LpOdc?h zn2Wd#`)`)ESeyN&vg?}gj@WpFQIR3E>P_E=-acEBP>ALI0Ksy^A0_&DR3Aa!nKOW6_-O3-+sgWHbZDhMPSeLj z%IXLH51l}^;0AhxJ%OLt%~XBdt*m^&59}5D`je!ggXsQG^>LK4^MxPiW0A7*9xnC2 zBgR?LwoTlCy?~Xs3m>8~UfSV)6ZQf|fe+mK0ZYE7kF%7un=9mq3lF&u#C-V` z;WPeih2+7GzAJJe7ThZR;ySi^jqn(mUoL(9mXzHp`~Q;i=oPWh z9A)R}cL=}XDZb_bIR~?zk+FdfU^zPCD60ccii{o=S^kf*`o(x2mb}D$=<8BtagsLA zR8~LVk^cTcu5Xud!)Nq_b!mJ&nEbM`{tjHjA926!P@&=VIZ_6kMBl+~>?k7roFMcw z!l!a+bAs@bvg4&ctQE`>p6n)kxJ&wleWJ%3mGupbk@)abkuBIwyz(cJ8?r1FK6m%8 zyYUa1VT)i2_Jr-gH{uL*6aEt0{a#s{0~_&a*b4TIFGGKkJNoVE2zG`oFux%FcvsqT zl#OHFQ&x`XA2>q%fPVZ?Sv#W5_oYo@4r~BBC$`yF`UWx9=}^bFwSVK=6X&5Ttec|qqeMQB$ymWh z^Z`u5KEPZs9$yCDo+SMRb0gB1VriGTEm(zKV|$~e?lsEl?IFU8LDDY%9A9>m$d-5- z>}&DK1)C;5Nh_-_*m`&Wx*Pvk_dr+BGkg{}i2p?QkSlhL?D0w10k(!+{!>}og!kwH zx(TLXzu-)<)I;n=e2E>hzJ!cCogh{LNAXwRl>UH?*e?2x4q{(hmDMG54I7^=2j|3> zU>PyWWMy?7eZdB&D7yyFxQ>!M_|+{kF2=`Pi+GKB8Q8}>0-Z!xi0#l@{3iB>-7`l5 zGtejO2(swW&9RMqc!O;yzS$iao z#J<23Fo&3eIq%Pj!LtPvi+rLu7n z{^K|)J5YFpPu{AmzkF8skA0&H+~+t;#*!y}XCBJ@99;wR_mgqFFZI$EIyyt-3!l*G zSEW4ltrGd+6POci7r7!QbPtR~ufZmKHfy2C|F6P(_zWhNNjY%wI%&%hnQjtZz`I(h z58MRLZ;&zmNBW7+ib!4fD{KMTGxzwNXN#)E#d zCQN*SofETQ_nu9m&)5*U4~}3X*flW=c8Wb!3lGrkzet~nHSh)K>_^fz<33RMf;|xf zfD0i>qaRz9#a}Q3e?z>5je>8)pSQ^P86PnlI*ko^dOl6~K@5g1{6_e9gvd52?a@Z1 z$fQulhV6$XKfa6k+v}2tH12y4%Mh~=+ukpIyFltVL#`9&=17?fh4-WrtM`|_fEUDr z;N}4`RdimZCc zxN?LS=o;}Q`j;zX$FC9xTrM>AZ4rL&E;6CM>!d&Q1y`Vq3&e;4QjSDe26+--9!hm zW$Y3iB~HfPz|ArlSB>MX&;l!gjqiTI8}(S)YTxgLTV={(4 z{LmwG2RuUd=nT3D#wVnWeWdTCfyZDa@h0&o@f29Z8fb~|>}e^JBjcfeWs;75;y3pb z8LX3Qf0lai)7&emk~)a>mkA%pkG``OS}kJ+o6(Ke<@&Y41L9+16EG3|Vm&7+e4`BZ z2qt3h_=1qgsk?vOjeqDb@@2gao}fEm2r|N^Co78yjudd9J~C>75e_PSWoZUuVE<tFCz!dJ;OB|1>AwRL=M#G&W$!`xSjVp5Z)MBu(RK?;npM12>h3kq;#;df`n?{4 zYg+ECZZBGWG|Z^bcW!TKH(vC1Tp>NgNwrIiwUzr*q-G`+Twpd3i{cddCPU2C6_IT< z&l5Sk#;dN9WxdskLkJ+Bau#<)8C`WvI@_(}G)L>%1pZGvmI|Pcstg%J{6FpF*Cx!J zSm9H-Ko(p6Yvk&cp^^QKGZG0mK(+??^w~t!ThfDaC=8E>;PF43;FHQ(77?|MQ{Zo~ z=b@3TD_*}T2|7t>zU|n}UWgv*nL;=Ru~TU7x}=KlDN&Uj+7y8iv)eB1NZOq~Nl3p& zHnu;XH5>dapH)cd=y-hHx3p5{9+>@)OWqaLW|QYZRXqcygPKIi`DB8XTwu`u0%3B< zDK>zU@Yn0{)7M>Tb;me!C56r|2A7p902*)Dk%r4a)fY1-*~G?KFq1F+3mBc!bxQjS zwkx5Y7ZS(maEP=+OG=xE(rjbnTJhxXW?PXcOOvp9-YV%20Z=`wBYTyYr~yY5T54I? zzu;TXKw>MVVyLX+GQrBkAOrM)occ|&B3%<1VoQ%r#{M<#s;dLpyxbr_|M9BQ@GnZJ zGGv+)2BQ@pg4wVl%KWQ2r>KOGiiE(l`Tg|YwGS|Dk$F)E_#Gbi)Vd>*t*|(7ti*m? zLfa)`v&i#=5q*p2^ty!L!b&56ipY_v@+cGTwGa2*+L% z)!Hv%0k>h`42`&gKO&x@3R;gQ;g46n&WR-mGg{22sg3>N%oOG944Nh+QMngoH@ieFL9_bY+T6$1 zWaY_xt=enco@i|8{(UNg(P7{8m`uB?y0)t`O0M2#VFI}F z*WwRmIONx?C~z_3qJcN+ILi=5Nzslh@TVKDiE2lA;7ewwJ3n>o56M7 zw{p1Cog~mSv^d>6;Eh%eT{7G-Zy8LF?`xBp$4s(Jhn7sgg|D5v*J8&+PYX;`D)Gvm z&7X72$`@K{BgbD!w0gI%>Ee2CSz9YoxmB6{U@KA=zpk?)U$L6}&1_9H*8odp&|Lz= zC2z}7$$0J-?!H?9k8eOTRePdPfWZF2mjv#6T=EsQUJo$>hYDOL5?u6I!K$yF+gvUa zK&tl6ktLTT=5P0{uVW!rnCL$EuSyLY+1>jw^)h~hOM0w~kNY1e()N)ve{~48-&!)> zI?&DLr!DD55*c@;NN+7~x~J~2ukBCE_zLfxiE%C{-j3=tA|jm2{YIx&SDCHql};&G%9&?|1&|TXu8(VM9xe-(N4@r$-hYBFCV` z%f(mUbQjM_UiM>r{~ae~dr_~Qr_I%KB`9TdrQN~jv{d$m-4K|_`} zC@zyv*GX@g2g(yRD6t4Y%PlV)LLb%3i>-vOwdn0->)err64ZgoK+5@=e^1Bgm+vKe zQc<&!wHAx+?tBNgmSW+pcZsK+#XJG`tS|0H+@zUI&FZTh7fnDNTcQ-8@7g?hnqfj> zOY598irjaU4V4rEP3Ko`i!u@X=ECfVB|Io}<}&n4@~m;*$Z?)8RgUNAzC{#hX%|Us zPF{sC6BjDLJX4c+e`5c;X+EGHLv2qG^<|^x=Y?JNQAU`c66XAms zvc1C3i=Y6OmDuMG9M|*j&8z+Ud@F(C3{R=81?)mo>>S*IO-C&Txvy_K7a~+zl$$Q? z9m}A&J4(U;`aFDpjt3lW|h2-Ug8j6eP2UGbZCLS2pw-riah;JA>Mkcft!R*=t2ZJfM?OITyT~9$`&DYpW*;qePFe zZhBj}IL{mfCr(=pbIDPB=^l%2%ixMj^m}?dFCw)2&i^4D{@JbrnlB`A$^H5+Nj*gs z%3PSS;;Oxl=UITuacK42vyJZ z&{&CY4vw)jy{CmE+7Dj(NaxD!wT-baxS)Aj&pPw7j?|rM8OUIF>>o{;Q~tJQ((VsE zo!JvER32PRIq-CsXuOgqx5!G_iE6G*zVocd_G*ZjjPI~v`*?ScvuEUQgoE>$;|jP8 z6&D1$ZTU;Bk#Eg!(mxVzU*l&L@uQYK7r;byX9JeF=#iFYITs^`B!Q4K=kg-t^Eg}< zFj;rnDev)KtM?P%hm4_<@gLyjl%x9nsWq0@8kG3_8s<;<*93zy#3##AI6ujOZ$N0Ds2$@~5agnN_P|9ATl-FoL;{Sg%*NF@JRhqIc_ zQL|@pAjJ3oau9c`k2`MUm`vagV@GF6n`kWJY+mx8l`E$x^xgP6hFtpQJuBy-jK2aqYbPZejkfjfzjw_*Ex_p=F=h*0YuHu50ig{^&DoizxbG{`~ zZ5DfZj+aqx2oiQHYaXlV#R67JW zpi*#?AAfMy)s^#cgzNR0j0T2jUnKaFG?z`&uHmX-#^F;Qf*1o`M-^s-gl?YcKlQR|7tbB-$hpO3do z5Yuk9^YuhX1>Zr2nT9Q2V9!1jlkmkobscYfM&29Su{Z~66}rCvYK0HVThw}UM|6hQ zt!{}wX11g4#m?WV2j%Dbwiiu*pG+69k-7q}HPNSY`K*X`M!35=|k`R+yE(8orgauk;OZvK&B$@%8ive!z& z?G&JLc_9xmvA8{AEp!D~cLek~Sz=y?mY69-(jAO0h^D2wPLG`ACtQQ_cC@SJ=|+Q> zg&WGBy3*eMIb6AJ^WPNv5PaJR@Xiya6iy>HIGETod!T{wBT*=?0bZn>;dam4Dd z%%j<%$stv5(SEEU%nLMrcb)8eRH^pryS+%t| z$EXo5^N`IXF6`gbnq?W4qkcSm6y!4JuIo}MUYZ?NSQ$j)cITGj2E6Ay)s7`)CZFZ~ zoV?kKcjsnlKRnclz#P>O@E7C_tKg}Lup@Do%a@BMZ0DW14C4x}c;w7a6oe+y%thCP zr`w;l`fW<%CRAa}6G@fAJvk#`O0YZ%q@s(5t>$pNci^K=9B&)b=I!`ST;{7RN)qaC zI4`Sn_!83K8)3YQ4!h*{xeUK{^#iPaC*&t(88Ni?YzTb)Wm3XKW3pf2JVFz%5^6NP zuPGSd{)QmZ1&LLp^cP>H8jQC+CBB<7eEMH7 z>{yH*s1KjwD}2h8w?(q9$EYw=1T ziz;!3vmz;KAkl+%H=_TNsXku0CUM3Y=y-YSO3Wctk|G)q4c7o+=)dE4CrVU#u5&5a z6ng3%v3EA5qffT;5}y!_0^+sK+FUd;z&gB#vN|_ffjjT(+;c1Gs>Z9wG+U|Pdx#=h zdy%Z~$&71_yy6PSc-dE622wT316du{81XF;-0<`UD+x+oB8{?RxWawImp6$1zDu|< zA+9*ipzX*SMdIOjn(7$PL>nXdo=He!t7IJYZad>c))PynO~+~y3Yuu1$9AK#W}|B@ zG9V{xo*$4DO?cJd%Fvqy6mCau4R~Ca$jk)|8S}+FZAh~jCJ7`^mG45oMmaWfH26^U zp$oEcj(x#H}}{F||V$oBN;*`}bntA!BGSr`l*sAG9n5%WW;v3=XgH8JS7) z{s`O5_zXtZ%m$T?gd^tLkZDNYk6GneA zkFbk;g0}DCok2aAlzrL`qNL(4>m=q0?U&1LHGMR&$6wjIJw3oWVykb-M6`s4ja$KW zjC&w;jn7Kkyvrr*ZsMq&%Y!x#$Dg~ZK;9&bhl%vNs0x?kAB>fSl0P}xT0xfAqkO(e zE$YyDorevt?JG50T9Nl4yY<#-UW*Tzb%4(aKn>t+G?0fuR6K{W(W%M?d}AG+a@#rUzyo95S~VzZT|Ri8 z(?3A40w6^ZwovWCZDzwW2ut2Qbx&Hb zMSySCKQEQ)?DE$i<0xHcrod~IC-1(j?1$y$PXV=V!uc#(YnP&v(SMeAbzG_EkWo2p zjk?j^sfOkw@%=E%A?B|QPM{{c&0s7)<#_17)96sqOm0vJ4){f6S)@Y1p9d0aI|%kh zse$%QAIdTG*KP+b9}SJ>Q1cSoE#KInwU!BIwbQTZS`w8T5Z>8Jflix*kDw-HMl%p% zyv8M46%*Ch=JGrVczL5$sRBMG+e}jsAnhF<90qgwUnX9o01lkZqt+vW9jE`%Zf%=- ztDGPoQ+Uc08qI{%q zfn)986w+sC-=!xzGd}Z)@Sz5~Yrlb)qiFZ~oQB}5Z39jEY3SCzvOoDpSIC|zatB99 ze;!fjfQR7F#PB!R<-g<>kZN+nQ@Z&Y_&$U`>HpydLz#WH@!#=^lVjq8W;A$G!}(7kJ*e-XfU{wS>G*$qkJKdgd%kaSybO7C z)hj$pd9hKvw>%_wroRU3FzX%@$o-PB|WPbGb8_=PW4*``fGX5h@HM| z+19vc{v@X#7i5v3fZVleG~eMzNOw{dgLZ8kGlV*D?gdC zeo{=Hp6KPMhDv9j{@74p3XV<7lqh?w@nb{L=~)R+7;HfJ*xwE4YqpE}5G zJdw#Fd{`>FB-bOj55eu6-l3+dD4vHQ<-_;>Dt3A2Cd9F$1O(ju;VI`Uk3~_Px)=&# z93fR<7EtAa3cuBge(=Hh6q)s}a!!XBNXh^FVgb5fRwlDwXWe;@VgHanhgY+ScI3;W zWD|IkoA4jNm|3d^g(p`=__2&eCBb>m}-pI3R=}qUS9V#e!9%#e`Mz^o;Oz}?`F*3 z{gdy%(AI=JdX{A%r_v*$=uSJrjZR7YW3%}c%H={VrzMuLrwzVYEb~xLX}~@waGX}umK?jdA1<91)1<0~wmf-edjZs!;`@c*kVbao z(gHnUzF|9egtXJRAMZ_YV}yjWW*zcGK#T7b((i_Ky^5N@!qaR-r}>)zWtV1w75DGV zs~OUlOMF?$l#t&E!QTey$cV0!$mr>~#O5W}p>|zJa#P#$>r%Q2@1}|EmXKpcIfa#B z9e+;l#AGG~nqMzA>>*-X=g8mnnW2Rg$$R^aziEoyIHrkmTH=C($fxbZ9_AIwNd>g= z$9)Kw^cxejFWQbSv}pLZD&FlBV8Y;5@qT6k@0#Do&XvHP)kfL?kB?_FWgVw#fBpQL zu`xrS>Z@|t$+G0s-+n8)RtX1RQqg_%n^0<^YK(P?81$2TQ)|K8_MmA1uT_KHS!2DcyGlQZ$JJB$B++lZoJ;`Q*mJwf$!s zLeCz@pKgn@e10#i2a;LKFAUpxIzjs;dv;B@1xc^fpFj2ph<1F&FV#Q{{#?o*`>5x z&9bFqhW=K#AnH~4_Ws#xQ0sg|I~K&FavBKSotU^G4SN1Jb!j4m}Z)bAzKAe*S^ zA%>d|o-y9O>FJ=o&%QF%x@K46kUalLziIc+cj9=%7-NENfJ#!s^)}7gG~21wRJyLv zLmn<}8V>8o9eV`!KB($jShzy%U!ih^t?0ApubllMYxO0&OFe(PYqGDr*wworYMXzC zt^SgoN``v%iweK)_s)4ZF3~k1wGBSKob4!OK9XWmGOXaEtwC!4W&M+#m9H)&ex{6= z#Zc8~zG&1@GJLC!JEO}KGDhw?9LlhnBT=9{y*GHnzt>8RGs#7>1EB(IBz=6Cx(4v0 z_6l{D`DTo^bK|Hz8c-KA)~V^oTSFBs4p-ZLoa{Syha7NxA7Nc!2^;_|8Y`2EQi(1w z;4rf~)c;F9^|*e`zn*O?TM6ct-aZ*HNw+ypA_=hT`lpXX?VIcF%SdnMY)LM95A3JP zfuMCJ7$;@>&tbm*NNZ`eO#V|-(HH=jK_KQqeIwft>Fye5T7dKKU^3FiRD@)$6)B%% zF|~5VqT6;N& z@Y$bpn&N(<7>$Q3AiGQ<6Qj5tcP+NE} z9cTX$;YUiqD;e+n4Y+Ertx1|ahQ}=2ST&mPM&iF7{xneQgVEt>B(DDftcOqgEvLlz zOf?6V98ePXO#T~bgg0D!;ucfbO=3#q$vCQFYr z9+;vv_Zw|e@<|)ZwD)Wc`yOW0>GrqGBS*?|V>1^AG_y4~y*Iy{&G3w(`~FI3^khAE zs4wCF8TOmLM%Bz|-~CDz=qm(PYd|b9qS;15gJuGd5m z34c5zbZADkg@nswbok_2bgI|+HuO!=cjTl4VJTx-qMW&B;aUS|DXmYXI+`$!JFCWN zZAwPt-m7p@HAW2bVT19Moj$ySRTne$>X3jK zd8K6#?wn>=c$K&*jWo2y$CWWZ^8iJ_ZCRfpkkY1}jy#*CS&U{$c)uiaxYa^7&j~H%&VwDMxhDJe1v;x7+KXDg}&-~9K zMgHbDK=$|L79wq>vT-ADt2cJ_KaGafAP<|-+>I}E8+^V6HiiC+`55N+adYmi5?&GI z&K08aQDyn9kSY&<#FZw~rD2ZN$+9sfX&E2lozBS#PTGv37vJdD`JmdU+H@<7)D<`Miw``tU#G2#mx9`boZ0D4`+Ttq^% zXDJ(_taZXITxTD77G9P{`j|J$os*4QW$=LGku9l=QJjcca+zD0q%ntdip41Nl#veH z$hJV5O0GyR{j)Rt>b-Sz?@IlY5Ym_0y`eqOU4kMk{zPYZ7pF>QSY;8)tU33%D;Q1~ zydJ8b4+|2W0(c(KNTU9u_+sH+DV@OFJ~K|(t3?ALYeGl%mU(mQv+FO+p3Gz_!tC`l z{y>4UN<__yz-nX(DrvpS&0G@`06M93Em*2*FmrYE;Zzn z$ZKqwLCNsRy=+zg&iXNAj7{wi89AeBe%zx4Euq5~h8*IvX}cwR>Wkf-)dWep8yP8N zNgJDO+=M^BmqQ6kvT#`q$;n6O*2 zmXD0Hn6RTMe(KGmPSmRAdC65LDW`W$Q>JaH9wqCfYvDgw(NPP;{6rxSSZ4ihbIv+H zj+11GdtWI1qHGN8b{_Y$xz1FdZk2>6knWzI>uW%S-gW?gQgL_B9F>{1Xjb75li$p) z+OExB*tAC2YVFTH&f&2f^Pi24K|Is`f+00)JNG7J331x<{jXwcVERL*GgGRYMGpc< zk&NPvs-j(UEZyG|q5u=gx2S1D@$|#BZWU9+rRV&8&uPMFSSNp%kShal zx)mNp+ExYn+bELe{xrNcM)^KT+MP)-8*k%VTMpUTts|Rebqt4i+t#Go1boZmwro>9 zQ#lQ#_ZejhSvq14f6n=XUsEaou zX+2RSFe(o_>gUpeZYtH(EC`j3&}wfpDuJg9O}*?l6S8c|Hy)nSpJr}KFBZfTJBqA1 zxrwWnl!|rgUwbaVKP^+yJ#-4?)>{2#P*Iqadtrn5N(x=Td{oa`Kq7GCGU`V{5;#M0Lp^ba^nCBEZh;LXf5xxn1^&JqWi z2{84mK#X;P+eEW>4ddZjqb|E_`@_~Lwv*9Jqg>E*wy#vxMt_0af*e2RHbz&z?9vt%|-ZHu?b12*mty`#xkb^_x8z7HR~nvSMe1l^ck(OD94|_#~W<^c%*A~3sr;EI%)`OCsz7Gyq`!+^BUh;LIM@_#+kQzto_1+Es z8903^Uu!+CPiPaBt2(0pB>S` z_Xp=?1WYrpjPLZM1T90SY70S=EQ49Jx+=LsQKIB*b z=pXS|-H_D=LBUelUh=%|4&t|vk8$AlSc)Bu_UB|^-nR{Pby*Nb*+rFiYWV)vsoG_* zyO8#MS}E0V1_gb_D&=%C#%4yuSg{h`3H^(nB|D!bhgF))6O%Ri>2+pGM0|tv>>_$` zdJN3_B*&3ht1a7H8{lj#Z#Kr#ieDfwDI5?dVr(aqneFRx2 zxcM{R2Z1n;Pi9L4^KvR+*}k3ODfFFrbZjy^*Gj9v-@|jE>~NO>=a!9np`fSk%4&Y* ztOD}ax=tN&TRX%jt-;RR1l%BV_ieQ*&cz1qRbMysX_a`N41v`oRR6n(F4&cSEdae*6<5q6fznBV3aD_x6I>#1T9fjVWZ+ z(d}b9zQEC*A`UPrldEs+ek{FDdwB!O|A@~OIJN5Kt}gmameiaE)P~%KI=B2T%NbFg zbFrFKby=04Uq&A;r2+JMu1ZG8n8$76nYr|7mPnkGv77l?=GA@g6xxb>_?Mh?HHqi1 z31&@{GkIAf4YrTMp2jxcxIFXO?fcRy)LkFj+caNnUth}605ph4sG&0M4 zUqR`{Xlp2}aK+dZjITG|#WaGZaKapzC}BiD>TkwU=1Hmw*sdpz!cr17? z|DgLG`Z}VBivP|KONF%Yv0A(Mvk>?;Ksf3l$TDoBALR4vsiHubq=CKCdu`k&#)!BM zy8y5(xI4*=1-TEF-P}g%Ww_AKAlg2H{>|%n_g65TD&BvYU4GNQO}_N4My{vBc-zl1Kj|@F{g%{Pt;3n77A{Tlm-&;4h8ixmO_Xt)^Ia5v#;2X!+u9Iih;VQv+ynIbB1CW zMT|dHh>j^55MWc0tgYAm5N(_ zV0*l5^&;r=AL^yjW_>n2kc=As1V;`KUP-d`!5ZY7qhcOh4vBWzSdk>!EmrMo=Y*;B zWbcwJwl2t#yc0M6bIg|$Q-U&2c-^Rge3mQ@B#@CMCrMWLD5Manao;~DG)Q>;G?@Z; z6a_nU82V|=Za3|t2a2FDHka}ymwCnR@y4~(NKdtU|@)x=9fg@IsnChVf`qCKQgtvc) zxs*WE(KCIt`h8U#;jz7+>**%hz?Tv2yno*f5x9ioXOJ!h22p|3K36PD;(QaGZaq&6HnrTRBC zi%>`{@b!(#Y1G?Z@@V?Ud*suC8t<-=Vuw(&tDgFHRv#h;i!9%Lm1N?bc)7;gbwKwr zjJ`kZX{_8fQA!0iwVgQQZg)?AqI{R&KY;Z4Qr4;tsmwd0_A79b|LI6*({Bf2?ZZX= zi&%6;FIw6on0`vQ#>AHX*!*WFAz6xsO^>fUQ)-Elwm7}nm&3_%nN_aK(t-U>_ILTs zx={jNas}1Z=IyFT!hc1s4%<;L64sFQXFA#8B;A(pBC;4jzD+HghTMnif`3)53YWOp z-Rv9HwzZ`FX=R*YJg{*5SCT5qv9$Zp`|5+OKp6c!u|)D89sx zl(v?P@)cH!mI*m-sTF5GeFcjRFPA0A)+AX_V<$^#`L(~2IYBIWAere1Ex*6Gd#IGl zI~>d`?AZ+!9=@B!slzY8n^%PxDz$)oo%OXq;V~k!B>6FGs7U5p71ItiUjaY)?spK9;XwB&jn;R-)+a#0&79Lt}=)CP8 zcb+wv{p!QM(T{GGk|#(Yp}FSlfO zzSaWi`G%>2Qe^^52rMcso%*LmI|g=ly~9BZK8}8D*Qg7dHJ$W9;44irPdet`HGMq^ zLsoPaY}7C5istjq+VY3#=UU;tQ#I)0pBVtlE_v!_#O@Q862Zwv&wN1RcQiWz#Ypk) z#7m;B6c~8~>OTjU;JaK<#q@wJIGQ;cF zSLgzi7TWZ;fghCF8?jrP^rFJ7J*N`5%Ib&!?YxS`1o%!nz_mrosejFFKx+}mkjNm7 zT5lHTP2=v6Un#=c`2v%?cN3_&bn*tC^W1a6L;txi-hjbrpfi=@5> z9*z9cu{2v6da+eGM&;y@h>_f+{VRf1TVJG8eiWn}s(jib`)!LEY(@V{VMg;>ynM~8 z1IA)SMZthYTZdr@TzXwy%)8N(Z0!B{@0^-#XrOZtWYLjTD=2c%=F8Y`rhfpA^;Y}> ze=A5&1|s8?N6+h1oI`LG2y5&!GDa?7u`dfK(J2w*6#N5EuT3a3e|&(F-@d<;Gae!b z?@0IrApPcQiT1Ca>q7VEJiVJhmmVi)BW%Xy+NP4LEZn<8oHg$yzT=F?dLsvHGhY9f z>6Znnqstb~BIB0OW9}C!SRRK`)pe%fV}xg%H@>!SE$NaD?FhXOntn!bS-3~|)4tI^ zU&a;)=3)lsLzk!AJT+p~2U36@3!<+o^hVr>Gjh(zUB%4Nd}39oY%cViM~*r0V^Ug2 z5k`1w?w)=Qn%Zco|9TZcFDpysA-b)rKfx% zr1w|})n3Fm4iu`K%l18LWHm%TJ?D@IsA$-`*Ei4AG<+W6mQX|z!tT2*4wUwi9!*-= zC-w$yQ4{ES80IbKS4dtpOMk|7(DiY5A(2VXR2JC9SuKS9LO#JvM1p#8=8X&m$Qm5d zGE_X|`IQH!vU;yp+|(OAVyhVpijq=~HX62^4c7X$gvz1e23nG$3#3h;^rObFC9{L? zp59s3?9AB7VBVP4X$i2kh7{4?8|7YWK`OFg+Q_i70mXMR#YA}~lbYPOAQDH5qH@Ef zQ^Q{lgFA7kZk5iPuod{;fT$-u9CNm|!x=}U0&;bi|K}q7WLu%|HciUuseBub{?3+R z!itpMQMXkEaM1zfl!G770BSO{soS_3`MO?@giLekzUcwGk!_#af(2SGSp~a+AyCcD z#NXx}&F@LYxgpb;;S2JhA89)u{W2E|)*YWOBv{gJv*i5+<0rPB?Jn*=&%=D?D(wlv zbkyIFIk*a#@9ERt3o04s1$rDbXgLrK#s!CfT0%=i%^YL3VfO-bG9@06jKj+x#;R}9 zfTRVjgkFzu)fR%PzuWlk#DI7GC6R^6CTa=C?QRpp_c0lA|K9uzKb6bDESJ=hN~M`Y z7u0j32&-bcf##N_Iu4Np+2;fQQ6&2T1$;p3I znAXH2YEL}K(&u)KO3JL&1gHM?`<9wWQYUk>@>w<-SoO^_Lb^GO4!qU4F8O>77_p+tPnUN<9V#iIR@gujeI?IgC1p{|r5=Z2_1&3!8VLeuDmZAu9^`*?saT7yB*(i*dVtMeHi#kWKpm4o_( zk~b6Y2bUQBse<>jI<1PSVtGtcr~&y`p)Mv*7&z#+ec0K6ieje~P-VS!9VHzd2r5ck zZqfL8pZ7u?ol=;v8vu>ZnC0~JITUxo;^}D4&fMd;#$j0g#!rN3{S1G4e z+U&E@tdE`?fGi$P8ZI`%yN^)tX0S&=Yc}Y2*U*n{1o*!EK4z+q>sr3+Tra0O`(6 zO@@tmml>2-cPwna(2AtQdY4?HKVFso5+>`DSQrks-t&19Pm72Ln_5TzE zB@ph~WC91i2F^8Ypd#SAE&=3ml3TalfVskM*f5sAzAkH`T|fZRR%!|HvgQKzLS>>lO)t|#;~V*EsGRkJPa10#(IWJJ%(32VDe0rM@Yr!yoJ@*H9MVe*S*j_r_HY0&XY+@}byo52y zIc6r^x1mXy#&04ys$?6xncSD@XDaomYUQlHg!zy2|B;f^G@Z`Pd>c!lUCDqitTbL{ zBe`yedRubQUMDb+{TOH>(o)rc=o63>X1^EhF6ks?IWT*{_pN@QgDp4> zH~SQfDDpX>6xpalyR%uCHVRLEWtZ%8hpc}5;1}pu=kOt?;qBgSs#f6re7^xXT37yN z+et7eBR-k(HRrL!$aoY9IfV3kqSQ00P2$$*xC|X*2H2JPK3I&B_c>-iA?qKi6O?lf zJm$~y!`#*p`VVQVM6&aHW2dmbvX{)?z|t4@$SCd(6^afh>^cb3NS?s}T-EmX$1|slX70Zceu|@%CrS(mx%X&1oPfoe zTjhr*^}qmVAU)dX5ns)~bYJa;Jj@0W*+^}83I_mu!q17&>Ao;<|M`W!vm#Jjr!y^H8pk4i?&MGnbHMO;t zp&cWM@%5{@F|9WdQz{VF@cd_>_VP5}#yL2vG7wWyYT?#(e(BT>f+7pF?Fe$-EAcju<6S?rMQLVR3@sSa%ZIeAxpI)^r&+!XB!rQBIGG#K>yJzrRX#lPZ}w!W~f0DEg0 zayr8l{ddYmms5Bga^Kv{^C0loR44LxmF+axWmcmJ@;J#DK0BQ(mb2`&B_!e`ryAPn z=p~9ILiy$AZtzyUB*y=S`1Gte@=9kS=Y@$QNqgMuVoK`nQn z<}>Y$F(}Fr12;Db#x2Xglg!OU6=3yayMt$oAt9JInpWW;67qdGTpTsNiwmp$k016+ z%0p<@bE950H5l0p>Xg?zvY(duVAvDV7OiJI3+3wW=Cyv+`>O@-y{Q$gzsvsG1XjZ4 zDQ(7?j_O<8m!bZZtID0^pJFBrDb+pFj~*Yk;jD3m&eIr9n>ty1(!iO9Pu9416KdNL zsoRHl%PNAIbd#36QD#`q{Gx-4jegm?jTGhUHIK+h1{z*|2QmAq=_0@FU^L;*H^{jm3_A#GW4(ca~`n}Q# zp<&m`#OWb}vfPS-!%y>hcAcE88sN^&7S(3|FU6zcN{UQZuL8H5A=Xoa!?Vf_{Pv>? zWK@9gbWh-}2;tr|`LaaLKb(>8@C6QWQeI8^aMlkgW&k6Ke<~?$E>Lp>8h3d^ z-ZyTg@>GI2KA@?~nR^X9-WBA)??%t`uj1W{U&*Nr~6 zU4h$MT4>fOXn?ZhdC3iL8wkq_c+GG!t}`!JWibx!D`%cg+FC~Utp{fzeGyyinJkxn zKn*HIbW30HrP(X0B)LyAc!nNW7nq}I;d~LW%jI`EgQzQRP)rVWlQfhEeGK_?35ZE% z{j1wEBS!4#^gmsrkm=k1pru6wMZBucm$WKQvLl(Yd|wj-4_B6L!e?KL^->+~n zLL$$+J0629gvb1wP&5H@|Mk!x=Q3PXjLJxZ)pmX8ck{w$O#bSESJ(BABm5xi zYw~cP@hq{h$2A!S*I(KhtT_oUb)T$0T$T7iUJO?OtGY-5_jfJJw_valhbA-crj&JG z!L<>!`_xm4@@|fAlfIms&(VW}G|aQtQ6K7U)3o=2nmsOf?1M3WN~O;J&6+4P_5GxT z?bmBnV;2r#xxTBuBo-_Ne3CRM({VT_k|__eQr5`J2_c$UwJ5@zxDQnApr2u8uX0~> zdhF~HD=c9f*^Jp!2Oq1ILj1iKWqGMf`4wcf5-{AEJ;vjUzc|5@(P6$jnr{PNH{bP= zDdCu334JjxX+eQz^GrS{c9RlM)y6-Ewj_TT$RjQNs^1bh6i4P@)$C`MzU;;6zV6U1kC3Bu zdQKQ^bc}da+-z>q;dK1Y`34^A=hOk%qZ3)GKg7=%xGi{xc-H$cz2UX4*Gq5Swh zTTdlGui+klvt(m2@9=X-_}rL>nnqg;Yf5oyR(diPGt5_-vtARg$olbjC@FN`P0*pD zt&_fA&ic4mO#b2B7v{$t>Wge~xU#pb_Sd61DM&99t!Z<`$P#NlU1gaR4;YP2tei>B zN@f03BB$=0+F3HmLNXtCTqaVW&{_JcKN)IEI#{?*lI}AyQnPz$>@y$%MV+0bZU;S{>}e&8_RLy<+ScGxLa0En(o$EXpvSt z690=_S5Zp%cHneZa`((?0!vL(tAK0yv`(M3@J2+i%4ebC(N(kMySDLsK8K?!y}mn& zuXOK?1?~p`H*|D@4g(%)fqwlG*hfd{;}V2^(C7O_5};|Db>Nd@tEGS>NFZAUSc3wq zOJ)`B>3BCUX+Y02y-0%*MjSOe@A2m2@vB<}ySH|&`?2bNuj9wc4(xVPw5%llDe2!F zD;G|(Sg~pNxe5aIe%Ew{+xb5pC!9WfBqM9AM3MpOrwsj;RJrWS8JDp!a9G}pDUFJU zMK9AO{7+Y~Y-^Uvl3hzJWlOcziDR_mYS^b0Ibdwrl0=Ijd{iGq7cLEoTjzbg&#>l5 z{;M%N(hw9_h<3iUsM!#x9s^^Bg48T*-#*&w((~?~UJXen%LzLhbabFVUrPh;XRwQQ z30bRWhJx{hISTX&;+v7l85&AF927ABEi5qJNY)tk%U@9lQ zRjd|&3P`YH+pB|+_y+4YSciAu|JD_i~L`rE)16;NdDg7C39I)Lpo{mDg~yphM*^&^`AB z^9eK_IGRPxikg;A#l0MkS5x9I^iNmD#t^F6x_OlSowz^ICE!h4T7f9JN=(AxURs4l zqS;~*^1z6t`77`f@<;eTE!s*dm@9$OfnT674>HQMgF}%mb2?FD-{t0ki4h~oO%3Mn zvc#I=B|70KJcrZ=Wcx}SoCq$OKUgP{tf$(5J`vk1PR-~nM!jxOdq+SP+)g(c`MNu- zF8A+Sk?K3ZHwfQ-Mu|g|VAY=za#+&g{j8ZOmna?j%Ni%%@aAW*k;3CHy?FYdq?1A3 zyXHXAPi+k&{}uH)7YUfy2(vCWpOqt!pR-Jig92@g31-#SGMYsJC!>d>KYfH^x(O<NcxLSUy(W zF?71W#!G>Ow2b{M3^q+P6d7WsmfEPE=mq)HTe-!5%dQ~Ksz#4^K+rMPP97VJIm z*Z97?MSPx_7`Pxx$$Mp6;oUlhoDo!aJwrbC3i`99>gGC8Z1kJt6-R>@?$>O{>#`t) zf1j@C;#4<`cO?nn7(!(MDsDKatv@j(_+Dvwu@i4)c0U)0c0GOeQ0ACt=GM#M!5xv% zyktg2YK4zx&iB_N}4{$^_ZZgj0GK1BHUZ`e$0L>XjcpGp!xtu zLp~#nT~IgJ1Wc0jE+Um0KPZo8rI!$njj{P z5eWF`kP_fwe*;#Ov?RPQS-m^FSQjd~=df_3pwMdmS!zL3^@Pueyp6}0L|6qSR8i=g zl1_?s>H{JL27e-b2xHgOA1H#_S_ZrXYVxKiFx~Rn7t(KuaRt+P)MzK>Z?J0a+ido0 zZi3lV@g4f`!E>gytp}`!5LPO#(mirHk8d!SsTa9e*PUJwO{5)~Z|Ym}q@9Y&;#0A? zSzxQI2(5$B^F$35$EfQbdivXjBLqJLK^=Y@VYL(BP{4P%k$5oC@Jlzy_@98O70i7< z%zw<6ire8Ih9$kLyxd4fQd!xm?b01R;b+5|qGZE`<|CHvHG)!@r(sy7;UUjs(1pr+ zx>`(0R$|%~l=VX^Ni%9kP1@zolTl`yCXRlDG`cws5%Y|UNzSiL7^bI9Q-=N$_x-~b zh*WU*9<#UbHLKd;D}&)6=|T^u&mDkj>H`{fR03M{c(cv|LJ2~PXt@%SPlj3%?=jnVpijgf2_quiFOY3P&#7#Dl2rOJ>g$ zH_turdqrD)@_blt5uiaB$T?#0M#$gOvaz~(1AIcM_#o+pX7zFZe+OoCwOS3w%7h^o z%fE+@M}*duea&HrXD**_nsf1#f4DkhT0%?|6^+Pr0Ygx^osumidk*88C zUiRxgP@*paemTqb%eLtc=++{KAf7<|O<~_#doyX`q6Hky%Lepv&L*-BY)VI|HgOEn zkejq+ez8>es{e|35Hx4#?JM5U5uG%t$lD}q;8zY#cFnVDB5!Rj96SPNm# zt*Gnno#zW&qo1@VsyRVQJnH#xlaCg8?ue`YeKPKjpbNI9fPDs=QdmzV)duZ$3X;># zgljRk0V)4Z9flN>Vng<$@-jDZo$BVxzw~}4%hyQ86E>A=Bx;70fB3GAyW^bEQ_4tb zOJ9r~q$9G>Ex}hTy*{#BpRAvNb^Liaggpa*L8d$`YwbK&%KC_T!F^oZy&hz(4ZC8; zw<|{bV!NEoZnv}*zJ)QrK4O{%((8l$rc!h1WLsW1wjs%J!uH$khK5_~X&eMhQVg0b z<%;26z^2$&{=r4+f~#n9-Q(4xBWT!(S(NcVidj0LHyJ_Nefk+^J0+nb1r>usDRi6W z4Zh%c`7_<|NB!~ZMI}L$&Gi6`Q&H}%%5Xc&BZh;1kvlbR zk%zRh;&oz_^1fLoe>l$Il__rFt68$U+5+B8Oy<7}2+1=}#F)qHIh zU^~&SUBhfw%{)6)oGBov7~g&NsXJZ}Swb5k7Ck(@z^M7KSCC(oR7ra$SZkU^=d^VcP5;@V`q__>#H zE|X@uo|n6U0?@MS8ol(>Ab>|6*m%Rk$UkFE);qJ~>VLW~sQ9PmPThYicqR=_LpW{5 zqwev(QfL)7$RA6hO(q|TLyxa{O5bAGo-}KaJh8K5Ve$G%>uTjP2RI`;z>1+1P?BKO zRT1AjvX!&jNmN2EY+!YViC`>uf9>VU6_QQYvta%|O5Gj5cGYAQQj&T+MwF!A1aC*= z>xOEIYMmKM$rDj0j1^DZb4BqIW&fD-u{j|#xb_>!A4k2#ke+^|{)inzvEYojkQ=t5dDj27e9M`Q;Z8R3B#`H6D3P zfK9``V;d9bUj(yEfikM$gggnJDi-|VY^5p9d&>Yncdd!>eBLx`XT_)~-^>P`#jPjG zE;S}HmuGT0YqNL0)01fJiqdjVML00mO9c02w00~TFMJ7{*Ws(CE~Q6$WRZgmTP)nV z@JGBVawA*zYVd((&n0E7-@YYA4BYU2fXr)vPKGAysKA0tg$1Q>=xL$ZMrvkxH?q%- z<4WH3t71y(M6bhlndI=Nsm->214M=eTgg`U@??U7xx4t|*`SO3TY;=BiuT;^)FPWl zzBR26w1VCp`Zc3>!W%#g3PiAw8PT}{FZWJjP4jiWz&4nT>KY1QOAz{2l#jGkORQEgEKp=UY4y4 z>YnTRvia1?*xA43&(NGfbBNLMRmayQ zFu2PiyMpm6rnA2*vuc6VnCLVSdQ(Zzx3x)emz~Ac*DVNy;djUZM$FR}@ z`!T~jyyFWp{x#U{5UeekDm@zZB{Q-thVO3T>*#hrb~UiSIXuV@dPW$*DHYkHtfgr& zbKQ~WI0|D^4Mg7`CR3*1_ezPo74=a;`>-F2+Fv2@X2Lcz_rWT;nPdGIeCH8t*Bg0- zx(DSOO5ul0$9=cDN`y%##@*RUrP zu@pK{RdWfgjWO+&MqL`e>Nxe&B4n|~QyE~5*%;a`_%&9x!|aeQgu2C=|0Yq(cCw;v zF9=K&Z*75OuC&+MZ+5@z1OcmkTn(%=))Npo!D^sb6Q@%8T1W${dacn%$L#uW0-ih< zIL3 zI)=)%mgK$)e)yx}fx+Wd!*iG+Pa+sxZeHdfKFR4}N8OfN7T;LJLt-(;oKzo8_;h$n zd=3sV>C6c_nw(^%xb0%P4!TMw*7W`)I=(6ct;uGBLY;xAgSjJR86~-av+!lYkFZtm zNr62w=&gGs`0P)WvML`dhXgknDx}2S7xNy{?QB(*mwSv;X1(=(*bRkgJ3kV({2#{R z2s{o89-pIdGtB?S^B&}H+z4mq{9fZoy5smhb>>*|4=bamhleBeTE3VeO&D|BIS3#z zcZwKAV5q4$-0o+s{%XiTRZG-PhNv1Y%*yJ?Lu}9@GfZ#idrD^xR-PG{_2g1kdr#Ew z-re= z6qMmUiMciLRb2I{*3a;@m8GNL^;8C&(VXqYPzA5f_hqBF!*IGZDy&k3oBYSZKKtyU z9tq#iiuazl;xc63yr{Dta*K0~9DU8=kyZ0CvgC~yIbE<7%~~uj?z~7+ke&-I__4*R zc}WZh>AJ_&1#z?@rAq*>6vA%W07Upe!hEQ>^@L(ARV(LyZM@<8iuST%b7$taP6)Rm z=UHfwwP+e@yyJ3f4p^qyIL=Th_E1M8%dv0f0BJLf>Av9*P;fRS)%PB>KOW@1%bLtY zAr8ow>V(4GEF0`5ogJCq>sS3psYWFT<1x|nS{6Y1;{WlY=d*^Q1<>8g?(_dfK`Yfi z7FE6tOQ1!y9`v|1tkYqBdg>~7KQHP~(rAF<-vLP{vDY?kwZW_yR}GS|dH*&Y^i;4M zSVT${w9iBNdHCg7kOIaTvh-I^Ilc76ZXk?Y8pn%(M0>94nE=Y8B< zQ44rwW28FyDxB?YnO7l|MljnFqCjR{X-P6A{)3U&q$&5rs?Ina{Ox`kq{=p zn}q87U&43aL(D}dmI>jdHg)-p*U8LgLkX;szfl!)YK)F>eQHv)9iI)JKH_^%HtBs~ zHnv{KpxXanB@kME?|=+>gsxm#IO{#Y_1h&?-#G(q~%{Lz+ zO-bs&zHoNV7b#GL_Nq}RrYFq3i?$s z?}3I_`*Qn;b4v7S;R{<2%oX^L!}Yh6zVSa&I{zSL$au!Rl{;CFJO((k1Gv)t*MvC4H4$S%k=4yLcZdN1i#cz!R{(gcu4>v~me zrd-!nzV)u4+Z1_4c{-@!Smw+wgIC&uZA8kZ3iqk6Xr)eMVi=>N^q$P^8svU*y;S$> zMaYZVl2FcS&d!KGxu+)0j-PEbT8C&^_jqk4+61%bs4g4s-0l6k75BWSDb}d$W#kDC zZ{7fW0(vtVcGa(s@j;MN&@NZ(og20M<775SOXHDd1>H4AI_ihN*Y*4?RS+V2VUwTK zV#+OJ7jv!xeEQd3Bg-?UU%Q=SwqsG3`*-7>VuoJZRACP%S}BHm$z1!1sNG1b*WygF z3-eFIHA9O|Jf~WM%;q1W-fo)xSv7+0U;Q1^en7v)%@Y|RGJLMVsxvnkH($C(;v?Vv z_px7%TUW8QI@5B56m)B2L`gPD{7`XIRgo=(s*hjKfnbJP;CjMVBb+rLYbzZ1ix}lqdRv*oSzsN zE`P;^CIV}dQ+=_$T#gJ*xMZy0OxZj_&9;;>I;&Ka-6!d&9G_yrAlwHV^;@W5ry(bu zmfMvoxI04am-;N2C(dHAQqsEbIYVE$gb{BTKKk#tO4EXMt9ALM)P>(1ue;Y%DnN|U`^A;eYfUE`Pa&) zDW+~xF*M>jq?88p7jL+U^u64FY{AtxVOl?Snr(wpe8eDmZ!~bFv{5;I_3!c?F!iI( z)$lAi{fkX0WcQ$XCKgq`bKFDAVm?1#w#6r#_fsu_HWZs@?^VXi>?%g%|5`^V?pO|j z{#DRFw8hEFrEYO}83{wCOBh^5e{3o|c@rc9o^>A@y8hVwq8#eiTIp~qQ>z;}J73Nf zKINuyS^p%@98r3j-#9EIisF%yD5Rh%nUCueb`TDx{xs64mO$Uf?9Z)WaiW;7B=;zO zHlg%A$S<*$Kesr*C%rW)sd^yzXo1PEaI-q+VR02|OOR>O0>T;Zv+{fNDquKRQUMS1|7qkoZEDh+5VIxCWt)jMp@yne?fo6lwpL0WYA0iS?Sf%m}1s(dUF6bX`JSCUeWLhLl`X~IZ zo#JicEH=kSzk(7l=_js&a&u#Ev@V>z?IU)@Oj1Vo0VH4^!VVC96*(O^ZgnwsGReLI z9?O0py5yzZY>)vS2oYTKZ&Ta)`d)zi=@%No=5R7qS#S%C^c?qFt^knmspI}xX833bQa3;&Km;_SJX;cfyO&By!&v{1F&`_ zP4IsFWSYM+xt7VjPuC^+C=|eCP*X~T1;bL+;@;*6ft{KN9RGaF?6&3v$V5vEV@5)i zqn5W+B66sW0=D6xo%nFy_Xkn=6+zjf?@bTOk}Z?#4U#MPqV)yLTqc|6wzzh5;fyG$ z7?6L`tKG1mvn=EtMOnrR&sT6?K%FZH@G~Z%UC$2sdQ?8SD1Egtz5Djc5ASSF5PLO3 z2%zPyRL3%sk(V*kE#}Ie7VI3p-7P?~9aGlp@GfD&+|_#ZHz>AedIxx0s?op5<|B+! zZaVRH)}%RSB=gX}UdVs7A8xDJ>6}cUnYk(cQs^)6n!XT;aO#S(S_e|LeB)BDxCdNa zM4qtu0&B^mE-)T`4QC`}ECqLtB)%2U$1^?C^E4;S?T<@2c6-od+~#s;U*t{ZUsbVL zUa*7F;uqpT&)!R$%|=XfEUIX&UckvC)R3eQ4QuH57TmUdYzvFGX<1f&jQ&G);Sp9> zD^GA*HX|He{TEVjiucW_e(kmBxrI9N0-HR7$p|LwHk@XD;^lH4ni$VM>649>@0s7; zL>;%`>Q27RMC3aKkLqFZCo)pQlf)rD8&qh^z{b}JvMXw0?a2Q`e94=_s8d$z{$0bB zjtMwN<hIL%9-bhJ{%jz3YZn6)E^zOmsoKC)qi*l;PsX;JnqnKQdtP07&k3s zNzmnykl6NULHHOUH8q^X;&cM5C*LGKousD`9&iOK*@UvklBMkEiHi*QWOAgJ=zDGO zhz)FelTXL~5#ZUrw0fN ztW9_FDXH)H2)F@z^tF+*5BjD5^K~Qn)=qe(Qqx6jN4Df2t)D8ZPbaU{tsO_CzVPB` zLx=fy_|0&&-H{%(?&aJKA1c~4VS*66h}Tqb*85{OzUC|Y1I#Ns|FkVuj_(1OR0 zk&(Cj(v+3&Yvet4^gNq~^OosV?E|EU_1ArF<$!F#kL-v&6`%Eu)C(w<~j`&tEEd|Jc@}7|mk!g?U17h#W_8LSx@<@{6>-GVm7U+`zpY zTV>+`voeVayuq$dhg=(8{%#@)L9y}hH6G5nCC4Dv>KwNoWRgF)#R-~fat_%O*5g() zN6Tja=Rt};x_`7@fIf03+L-OgoRgnJAg<(p>>>A?Ksq!$-@$KX7I)VNl}-+Y?%=)? zNGyrpLW2@bGm@+-Q#%1Kx?PXDnpl>8Z-N>Ioi}jo%Ky{x#H=-0@xQ%j%FUOy8t|DUjopUhO^^86fZ7e%okVd(gNxJIp+`o>j z`WtC^Nys7FRU6=)Wuzyl6K{4)Tz{fgOLj@Haq4~8fWxwO)$b2)e(b~aAUEK`-W&M6 z;@a$2;rx7|`Tz!be$;i*Nv&}CiV8l(4P_vAg1cl6ZWWa1BoKG{CPr=BDy#QNZ6-=r zT0BIz$=eI99(gpsKQS2dz>sj+eZxBz86e(=!eYQ4V_O^qeB*JV+@5xJJXp&<=6sjh z+hF`&i+M8dTwTfji-^A`8jgjH0&NWPy!y7%a6tPn20l`-lpW6)+}n5z%`&9nCoC#;o(pE>WykK5@s9UrNQOq; z!>ej3;rILi8e?LLZrdN?9W=pjf!_`~#K#=|4B3xAoklxTQ5@$e20`DAeDRWg;nRxc zq6OPzk;CXm-s5`Cmun0vV$*4YWm2CSZR&|@$8_8yhMeR>kF30Ple9$6 z4q1G)*{Ui1j)$MK;lE_IJqVoQgU- z=Mc5QSrq<&83zx#pFcohQTWJP?BU*EKs1L!Ya&Wb;V8p~?HvNQ0)y9^q}+y*)XLJj zU+iIi3FQUzd){#0VZBcHf7!Z)=96}1i3r8!(ZaCy&*T4s5RH_w!DA4h>_HDRLpPI( z@8ZfaPn2DrgQ%s^U*`^HUEi4g-C*T+2dr>J(|HL7SvSLfS?+)YR36%sD@a?$DSZiy zw-!IMY|^f+jQ)riRc!T6)nDBn{^K-=uoDn3&Kc)Hht) zz|Nl}Tt9u+-BBlF0cbZrw(?f}V(7HC?^ho+nqz*kyru=g6 z6>6>bzovI>4F-Nk^@Od;!>4i{d=-7qmjIo)%TP$tLi`~emwI5XWNn%YTbil zyTd&ON@7dmq(0)%ih>vYD^2&i+|Sm=8Zfv^Ula2i-x1C9#|i)#ZvLc8%N@(Gl4v7+ zCBhwIXF-!2S)=Qt*W5*8#u`B_fv$~!+tFP%g1^Qy|4qrHH*sXN%y!iz`>3aCbX%_& z>sTq$53G$EjyaIYa?w3L>9drFn_xK;p-78BfLy=W1&$5SeU)bo0P!O#59 z9&l?&h!eQ#kAC2jo!{VX;2MCV<*NrUCH#fKAU1vWaC(RxSYB#4W9DPI{%ySxU z9a*2Jwj$B;YHizBX>-xePct~@A zCdAQS;>z@FHIjoujEJ(DtdM3h(+nwUNH)DC`q#~r)STIGQuUw}mQ40fy4d;}+;LXx zdSFm`-Z(fm(zq4NdUQwkty?i1-|I;}&DALXptE9K@IxNz#@MXp~JeJVm%8?XXMX65sR!_Qq&!1!3r4Ubn146b?I5eylP8T_R0ipoFc z@NsiiP?(tD`nO}5e?)i+;W-TQqCbK|AdE&mH%Hxr<~-Yeg+m)eBI%Cu4MJ8uW1d(Sr3~#X9hI}Wa^&MvBSpFT>u5dJGwiZy%8xhJn zA$nOUEsM^|0jbiNeX;Gti2bNvs%DiG^?TcG%HMj8wJtBYoHA+62T$XC=?dcw_q)6q zvp8-!LGeUTdmrv1XFVa=jW}k+t6&eMV5Qf13!6m}pbFki?r`o|s(B;AvfX;1P7?Vu zUbXePybIWpIAIZX2c?m?B%HN!)eQXhtkF;Nc7B64_jWPO<`uHvU|lo@cr=mCRN8zP@o{lKIZM z{wtr{?rI%6X-e$a$N#du!O~#NFBfx?Zqv{b)wLDjsT)AAfKE?c$97mKIcc=+wODbs z3iKK4W3N*;1G)+Z&6_*ake`Qbh$zu+(+y&Qbr(uDFzgy{cbWhNYHn2n7*m8gN_ucs zW0?bm|Dk?wf^4^ro!#J_U}x6aq|r|Ic69@hKbsugChM|w{(r*wtoy1VAhG8&<(_hp zjVlYKuK4`ng~K<;Hbs1qvIXVc0wk9IrQAwzn_ZFqIy$skvU$Px{%Myq8muR*%c*Lv zq7i+0apkG8DYbY6ZQ9zY;^Sx)*UrT{&)Lr|`Qi>bH`BIQkQj?r7Hrd~ zl;0>A>YHWyHNokk8_d`+v`%ye>zX) zY3!Fre%LwfZnd$&2(586^y=sT5bWPMH!goJ^9q*1%cNthAE25OEauI|xqJ!=7Ps}T z_E*c}r!~C?c@0~sa=~k1Bg2;Ey&@R8qVAD6JfuPLZ&;k$VFDiW9m#ws-kcu_5fyrk zd2u<;`x(H_a3=!P#9d1|WSq($&(3v~ijn`Hx^wXR!Yd6#vH^ws<5`E`kT_-VmExa! zDnECv=(OlUwXxRL3Wb6z9-UVx-h}Hw+q(9}(<6?jgU|SNoad&fCk_O4T+T4I{)=(pV@a0^0>T@{N|(XLw;kMU zabZ^-e>Fwe1pX=I8fm?Eg!i7E!5Ig*hS&JHZJf#Ch_e|7xkFrT=X5r$HXARxQ_bIK zknJ95DmZu-A2^%f|CmDdY=Rs#?Wq95#~-aq{72Tg)ajOk4AU{XM_#=1VB!W{&;9ns ziBiK5C}%5(8EBrbEPJU-`@3>)~rODMj)Q}h^!hwwews^Ij!}hvml&>jVs2JjeWTCBuG-=h`vvB* z8cegZZsGIRuDBIP;R~ehW>275b zD+AFFs)~=sirtWZUmTc(bqhh>0gpdJ98%H-LPQ_?B1y^kJM^0SBIE-$#w!$oT->lq z%;w4>Mcq#u=*97##lhCy^|>_?Vd_ID+b$xkRB+j<2^{)5F6gW;{fH@xbQl2xx_A4J zb8oCOqU+Tkg3*a zQ~VPBk&4zBQr}X?l*%#A5gUOrjx`A6g=SGJ(X6#&^%~v<|JVr}6w{re_8@X5HUAf5 zDc;x{D2a!OOQLiqJuk`sGLS_d@9CotB^Wkd*S{s51Gwvi5B)j5a=!~@AathrXvFMv z|I805C1HBh>TB0=h}b!GOT~(yolQYsOrMyJIutnMbFrqq_<1)}K}0DPb)_pIGV%y! zrZ0%SvZrF9R7AMrQ!VN=y@ebr^?-ks!YQJJlZcb2%19ooc6JMc*oO_E=T@dzjQrZ_y>BJ$7 z7G^W?Y<>c3^1Df`hj#1_;&fHxdRKGMY$Lc9F*LuOl7%0$a+c2IOLIWV;g}qk%$ABAw(N`15`pQ6tgzTP_y6VdnOtK_tM(-E$=n0ACUfh z=6RjH`-~oCLAx28a3OTyuL#>OK>#GK1)En_3O=E@c6r8J#=SD{oE2D`~q69 zc;=L-fVPE@%e$1`r>+rnp!sJBVuF?t$zhB@v9VT?2VPdT=Q*1R$q(#CZ$e5q&T!IX zRYuWd^MNMa<2$QY1cIv~W}ka-lVt`iLikFsi`e>ViJfCEOsKc@#p`$0|C3)IGD z2euM-2mI8nqgG$5#j@5G3;bsU`?*QD;TN>2`<@V$GN6u9?Xdi$N>gVzF?lJ1@7|)v z2t^i4E23XduV*EDp`-p1DT5Y}qzPOmth9;l`jVMU z^KdC!aATqZZu7axhwaPF%_<{r<%Tm*Vv{|k9yVR7(OpF-?`Wc{A*1bhekn1dBYcJ` zQc|HP1syA&X#TGiw__jW(2SgQQd&XA?R1b$on$noMz%cUFQw_zNGCGw{V=&#;>$AC z{}@n$SS=*=Ct|n$(e2jZ?^i0*mDscKtW5uiI~6;_ebgZFJMuntl?{`<{nn@MiJodt zDN=&pQ5iR_wgnJt&dBU&SadO~{TBH?i4r-JSa7c%(flFS8p9}~skjZ3&B`Iq(e9^P zzsav4uSqg<2M8HD3{$PK$l9U#-h0ZgFFNC@QcT_ksoOm)*=kjki{n=dm}`PJ(&1$L zn)0vS>zhb+g&fqFOZUoIX5iE)3+j&Q>rIiI&w~A?-7E_?>4dxV>K?RlSy|qf z^3O{GwafSH6CX)<)Me+yCM8Pc)46m*m1b6 z-%L6L2)zKom_UMK!wLZ^T`L$qPjyw!wr2T-;mSw%HpP{fRl)iNpTdLbTHNAsi!(yT zfxJYO+oVA7L#x#m>ak4cZsf{I{bt8Sf0=RKafLe;oLE?pvs`=oxHYl!_Gr{+gs<9KK{e%q|z6&arFKgN;{?02#>J_})y8!-t1gw6zltb`GYl&?$e zBr~y)^5HGcKBu~Z6yS78LF9wjGD7AG{gQB~Wm@_jr|kd#Ep0^<$Ic5&Pfm({BddE>qAKD32ql4Yd@UuITxylAw zLyeQ43dr{+ysjLWBS*6lr^b%%gst@;ynrcRI zuL=CYmljXZxELh)%&y`G8Fk#3eQ7R1e;5h&1TOEz{B%5HJJ1czE5c+5&1}(hr^d_T zO2{)-8F{>hKYVX7+usM<6B`mpO72w#buz6$HlaBdVK1|{iUY=THdk1uxapDI#^c;; zYz(Ldi9TO(x_~_L4p``Ddoji`xCCCmn%G>8e(q%8h=j;+x#*e;F>SU3tSnLM1zDx> ztvZtX-6>8YgUqb78>`o6dwzwoCY{WdFi2Db7@E zl&zEHYVV=&)t$U2i&?0!o_ntQ44Yq*2NjV;lEIifqcnHRCO+%@OevCpjf%-jE?#pA zkz?hlxpDi4T~V;dR&o5NeIDqk9qwE|2)qf|HKribnrVK*P6EpYE0ydw{;fEFKhR?& zN(s&*ao@LQLhz^7n>FzR6`!t~JhVd3{c!9G_Y*tB0@ZW5!f4#1oWAM*H9Q~9FQB%? zZ8-$apT9RYZhWewZZZ=vax0;P+*dmoR9bWnFJ-1Y_jjez(YCr4lFN z{Q$iaTKr~U{Vk^S1z9E^CWicCWSx;-=663L#&@bLtj{FFIJDQ8OQ^kCnzZ?G0<#tR9e}M{88mIScnVG_G|L?G>Jjp46Dcl3K>4`*5PP4Ez?c9 z=el*eEG^_d9#=@vAWgok7_?~inov;v737JQg@>KXI^8DBz>;6O18t9&A9EF2FUufgKa3`<$I<1t?wavFs6O0RleIk9 zv0QL?Mf_%@OL_+3g4~FJ#Ch;9$K1rP`FleCt2km!?*f0Tl1^_8F-W>qESf1W`49f#~5*Q|6xD z)tidoVt&*V1Bc*KU^b?{qKEog^4%8AkKt(ic_bptGs=CP#ZWj`oDkwSHjGH1?^ZE; zSCIcyFKDSkMH!sv_~>rUQoP_%=Awcw9UbU+#c%Urf}gLYi_ne!iA-onVuHq?`3)8) z45F>i3jaoL)*&Th6n0tmDi}yBh@qsy9$r=VPb6$iiTVx!#YZ7gx{MM~1ySNl=Yc@@ zKwXoeVTrMXdc@?{c4@ce)Zdb}iI0@oeari$bt>sS4A9oHGg#tG*ES=j`DpvmQ3wwu z7t_sHra_kv@qZtBe51)f(5d~KA0)}uCU-hTkeEj}>wS?T>E{?@H$oLN z?PZ+p{UiN!-ezx_d7!!P`g9;-yis$KpkMgaS}TDyP5o>zeKO`C+6g3i6(ti^UI5tcPq1D|fJ)vJ-dRI6>=#RxTL#pZ3PXIv_g=|bKVcK_ z#Po-I`Ty2BrQXd6+ys(V`u2~&*G1jfL@c{v%3*O$Z{?^m)_6XNaQk%Uc5*jtGft1z zi(@zJ_Iw7MBfqC`>2s7>Qa;$gy&xMm@~7_1@d7NndI78uB1a0|K|;Rc({hulx>$$( zUO7{KU&(>Gm6L$dHr0Um+(yozSw&}I{iuTm=NB%)o`J)Ptkv)VLM6v@npp^|85^{AhoO@ZkZJDVRR zrlqg#b@=e;p-5ZSEU~L)?Jm*>4eZ)^)&mk;3V8zL>WdLRXnjaXo!+MRhs#S4xE*)A0}}U7P!9sT6oSm8}+0c||&%eI3iV$g7jwU^OpRIDG35 zm6azwKU`wWzTd1zhntP*hJLfI+)NU16u``N+)@dlQ&ii>T1^UYJB=Ut4MWOh!ws(H z4KXf-Ao+7NEN9lbTLkwP^SyGjA<|qfZ1zCP@mBh2$A>#4&Y2HU ze5XaWtCbn0>E*$ecH&Bk9QNY$uKLQIa>HhhsYg&@y(SU%&C}a&%ZS#ES@Yrxy)MLq z&fp!o>9Z(bV8nLxEVTk8!DVZFaWj>jHp6(c=TS;YE88^8?v_z^nMPG%LE$EnW5lwk z@2#`vv>;esB*MQh(-YL%3?9>vrch9I-t&qrcRkX#F}&z*)FRWlq2R;;Wa4flOja?* z*;7}J=~6zE8a~?*s^(Rbyb-YuK8a)KMap2(f^N%-D}6G)k8Sz8q*T~^)n+`8W)x)w z{6lp*J)Tz(DV427NgFl3wFtK4Jx@g4Z{?rP;wIu6CV+0bU0nyyCDeHOTA_Z8=8Z!v zh=(#89hb)!1A(JZ|Belf2O7a`m#V5IQR?fZKY247A1T%xT)D-p1wz9ClIhh(NFGVB zik?A1;;m}DhY8QU3$>@ui$_n#K6P|?J`$AFJW039Mq5z`Pa&m z9S1Me#Nq@aVc}i1ECy#c&P~$;#F>Y!q#v$Ox2~hkMu> z)j!oSc9lwu-I~k{n25=}qD%q_(-gE;t%+j~d2+X@vBH+F<<{{KjAm5_bxB#Pu48$O z6WSK*E5%?8@#1wM=W9nSqbmTfnTND8S5gNDa|u8xG;>0lD348^QGd)i=SiG$D+v|8$eT^OwDzm zvG;g=%jFc!I_Y+yra)R9Eab!4)0Uo^YVdppsHx1rvByE8>^6wbqgAKLpa%-ZOZ9iiVo~WJN#7a`K6=x(989o zHiM3vWmlf}=~Z1}@?ichiXGgZTW(7Nll#5bW=^=@Ov5fwdVy;8yjB0^=VkYTd9_ch zbuYH4S3cwgd_VN1JUc@%;AG>8M~yn?KkFSjs4icBV*Zoc>{lJlYhO;b-20if5~*V` zSR4wubkpmOPe{$t!tI&$iF*GwUO2c{`j=YWjh~)HHwNxrc+Jucx(_uee%!Iz)A`}U zo%z1{Tzr6RI`o?ayzbcQd1tBiOL@=ES=$R+h6(q_x0U+!m`(u9TWdgpP%WkTgp0F{ zIv?>m?#r*5L8lWITYigLMejus(Uq2JZ!Sune+%iRQC?XZ9Vk_{hy3+mbw;umZ|#nn z63)iS$8E(Om9z&*Eb4a7_#c(j?nRB&R>oXwJ$)Y)?4krq&A&HtbWf1|us1uZxxMYzDTxk3*(HkX6hvFC8Uib4n>v`5%?;nO9X1FWGVL1+E zO8j+gtS~myJdZR2xtdMi^U*LrV%(^*NnTlEW;VU;WOK)n^f{7A?PV$FS-Ui|%zj-9 zj8NpD7gb=|I*0tZH{*up)wyQVuox-ffgQscI}2Yj=_GGcJvEXv-OyZ<3aL>J1NwWu|Hpx^fR>dS9+` zp24-Jj+~hi{cvKSz#WU(5e8{SC+}&j_PEI}%01;r^N@X`&)=uhli}q<-DoeOE^{F4 zfnUv!vfDr2af+;5b4`6N#*9PJ`sK00fZLh@ruR8*O2a2QIBonwFPUi7x`!w5hjXS|GIqNsws*aMcP_L|x+FNwy<{q3D`;XtR!G;AIGXA>dGKM>n@>g|u@9?es3$0BR2#U}x zF+WgX5pYPS zdwl%*uiLM#mJER(GYUV=3|lFW5hz!uZ-xEYdHGjM*;enc>wRu<1C)HSkkjwN*eLUu zZ(Iug^3_4>bXx?whXzlN%MG<}I~`lPzq-CewtAe?niEy3R()`&^6=@luD<7yZFA!K zRfFF9yL6A!k~FWzlr|g;jVX;g78+`@m)dX9u8!eT{f`{)YMW^@FvWg&LL1#5 zQQUZocYnll#niFHHj(VPEvf0mdi?dm_v01`9sKItSA+mU(Lj?`*n|Py8fZsCisbB0v z(kQjn&RN~frS_x7^f8;c<}&_zvgqWEx7v4dvb`qtUQEn%_KzrVKle8Xugk`@2xMKF zbk~^ENBP_9htEn1j?o5m$nnw?a%mUMUbexo`1)tZ!lV*6d%f@uzILAWJgKI%XAS9F z?}mGhJv}8MBB=gCsF-&C?&jYUH9t6#Q7i4 zd)k;j(BeC8w;9#sU))8WjgRd)QMJ*|h^9@>j~TL>eYDxIlTmWvfGx+NO zCODA7p%?I#N^PzRIDKK`LC!JFS5;4-$ZcP-j?X)4G-x^sRIa^KiB>*_q;^?8AFJl- z*?O^(!gQZ66SwnGtHeL&lJmB;b=N*kepKQ+{n&8yet(ub>O<|h#P{WbYQ9Ez+afB?P^2y=rLm@wym8z|xKD5NrQyszbVFY9 zBWJfr8gJkBwnM3zE#-zgd`Di0k4N~-Sf*BOPdeJ_o3{Blx1h$g_vx3%a_s^KDE*G4 z5>LOJfd8tM1w)U06tix5e~t{t)vy1u%|Iz(7CIh%$%LnLbvxgcZIhdZq`GyxJuj>? z%iUk!#BnF^=Wg?R0tW)^p1h8r3EF8E-56+Db3uAYuv@*GbNjkX-kleO_Cgk%sR43( z*L{KBY~JWZQBqVs7m^#DQ!$9oanpYPM>(HYvj1TW)r-=JTKk3i=G!l4ln+HEMD5EM zv)_~WL)5CYwJpCH$KM&*-ge(uz%t_)S4+E&s*<8)qly1`Q-0+!)wsL2MPsV>ymL5X zqHV+EVz35x+Jb`%F-e)9hz7R|O3*QVw&!xzpD)UeO)p4Zt2X{=SkUSZ z+aLev`=XPr3fj%+sy#v(nF$}HQFc|8RaFoAazA%Jy7Isw4|T&<5C6%5C@Ez}!b|V6 z>l^;etuQ()+)#bx#9dK|I%Byz$UCY72yMC5k5CqFYeYT}tlDtR)HB8v*CkQ^xLiPCu&lpU$3 ztY`K*VV`{Y2kF>19{PsF^pvyqG!?R$f#Xj7wYpgXyG3F%YaKp1b^I*0JF;6zuEnChXq&l_9<`Lz zTI^KuLgfmPa<{9$r$qSD!wfEkp6Q+9SuIjuXz3{vt%6zaQx11MvlP$jlX_*Yp+Io- z|D+;Hv=Gl4mNHXOdtz03O*Xz{^L;~g^AtS-{z%xnzN_Pj{#AXATQpu0H_1uxv?ldh z#_2gyS5qy0pGNB4DyjZv;3&#hrOaKU=eT-(k-DmcIrZ4R{NE~`l~qwg&#xoe5E~3X z&5aW^dV3l>)vq-qxOb{IoNx1vE5DO=c;qc*qNN~8?fIc@g|6~!P1VSxoO5Z_3apg$A(XVAhBTCWit8aS6rZ0R%iYFbKK1TZG zIOf-+DE-eazl7B@hIh#nQSIxg=KS#Yll6*@gS6`W_Nl;C>6 zhWu&v3lv>eGer=z{%n1R$VC{C94w}Bp3>*yUIRg^S3?k_4LSsI{{4g?LGZT4qc5Xv zoUrmvwr)6iuLBBP5NiN00C=IDJhAR84ijeNMZ0+a&Ad->MGUOP8RzDVc9SO%?Ag$Q zn1sL{W-X&IuYD^UyOD7)Tawl<+2G8E1wx1k*qQ+mF?PHJN6ZQB?ds{VqW2k;v%?Cz zW+7OM;Z54Dh^IzuBBX&3d3sN=YSwS zZU};dMQ^Er@Ne2Kws=>ZtpVBvcMo?@;2Y#_+B6}>4Pgav$l}a*G%sLznOtbCrd|zH&}kl!5MX3bj4%Y zTX&lliD6yDCMI2rHHTT8QN9xY4&XE?J_y>o$N`Ic$dZFmAwy>T!^+#d$PO!%Xk}K& zQsN9&TkI;R7r~%HD=w125=~f>{5y@v8ndhGJB=(witfHJs{}-bh%?t1>lIl3oyw)6 z3wyG+XI|yP9?BeGv8cf*1&|p(f*^|_ytlp=0Yqawa9%hMZ);~X&gGxV9CEo4`sSIw z-*B1L%vtPphzBY*07cRWHQ6jV7@V}6EJjLXdWC*uC5wU5nys?Fw70@8cOoN*Srv7M zrcI&WK(K~DmqZwwv^)WWEYvdDw5w9|?0ul*9_TU%zBi-G3S!_}FmoAJn25eRAkBQv z%klTFybxAawYN_=TTTfa-S>iyG;?Hm0tQ*jnc3_qS)u@3wg+^inRZ~=z{dn8K@5EC znF$}v=NlZ&_N@q3mMN}zD%+Le(JT0cP0PJ}WCRuunWtNa?thC*QEW6<{?7*jDU zL@_Y3XDqTP-M_)a%hKBFb2quPKtv^hsmP+##*%|U+;XA4CuYKXLLGuqK$k_BYn97N z76T=F_JaIaXz(%~9h@g#xcxF$UQTV@-5?zyb&%^zs{&rV;$IQKdHiyf7M_e=DZo~@ z(BQevC>)T33+}t44?Kj9fNwza4Mtp9Krr5)m?c;La-qLDI%y>iGskTN$A&^AR3T z$FE;NgChgL3v67poz-r{2u5yaY5=@=5o6DFNYA@460q9z8Rti?mm~mZaY$nXAuX<4 zvY4G2k?#Js1YTTf$}1)*62D7m(cNsW6!??Ke1pSv4&YZxaCjs=(8%&|ondBn>_!GE bAD|Z_y|hqxz~vfT5y6id82=Frf}sBcCoAiz literal 0 HcmV?d00001 diff --git a/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/HTTPWorker.java b/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/HTTPWorker.java new file mode 100644 index 0000000..0f15fb8 --- /dev/null +++ b/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/HTTPWorker.java @@ -0,0 +1,79 @@ +package com.example.exampleandroidapp; + +import com.zerotier.libzt.ZeroTierSocketFactory; +import com.zerotier.libzt.ZeroTier; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.concurrent.ThreadLocalRandom; + +import okhttp3.FormBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +public class HTTPWorker extends Thread { + + @Override + public void run() { + long tid = Thread.currentThread().getId(); + // Test: Perform randomly-delayed HTTP GET requests + if (true) { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.socketFactory(new ZeroTierSocketFactory()); + OkHttpClient client = builder.build(); + Request request1 = new Request.Builder() + .url("http://11.7.7.223:80/warandpeace.txt") + .build(); + Request request2 = new Request.Builder() + .url("http://11.7.7.223:8082/pumpkin.jpg") + .build(); + RequestBody formBody = new FormBody.Builder() + .add("message", "Your message") + .build(); + Request request3 = new Request.Builder() + .url("http://11.7.7.223:8082/") + .post(formBody) + .build(); + + long i = 0; + for (;;) { + try { + System.out.println("PEER STATUS IS = " + ZeroTier.get_peer_status(0x7caea82fc4L)); + int randomNum = ThreadLocalRandom.current().nextInt(0, 2 + 1); + i++; + Response response = null; + if (randomNum == 0) { + response = client.newCall(request1).execute(); + } + if (randomNum == 1) { + //response = client.newCall(request2).execute(); + response = client.newCall(request1).execute(); + } + if (randomNum == 2) { + //response = client.newCall(request3).execute(); + response = client.newCall(request1).execute(); + //System.out.println(tid+"::POST"); + //continue; + } + InputStream in = response.body().byteStream(); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[16384]; + while ((nRead = in.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + System.out.println(tid+"::GET: i="+i+", len="+buffer.toByteArray().length); + + } catch (Exception e) { + System.out.println(e); + e.printStackTrace(); + //System.exit(0); + } + + } + } + } + +} \ No newline at end of file diff --git a/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MainActivity.java b/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MainActivity.java index 3e8edae..12a6425 100644 --- a/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MainActivity.java +++ b/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MainActivity.java @@ -1,103 +1,442 @@ package com.example.exampleandroidapp; +import java.util.concurrent.ThreadLocalRandom; +import java.io.ByteArrayOutputStream; +import java.net.*; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okhttp3.FormBody; + import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZTSocketAddress; -import com.zerotier.libzt.ZTFDSet; +import com.zerotier.libzt.ZeroTierSocket; +import com.zerotier.libzt.ZeroTierSocketFactory; +import com.zerotier.libzt.ZeroTierSSLSocketFactory; +//import com.zerotier.libzt.ZeroTierEventListener; +import com.zerotier.libzt.ZeroTierSocketImplFactory; +import com.example.exampleandroidapp.MyZeroTierEventListener; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +//import java.net.HttpURLConnection; +import javax.net.ssl.HttpsURLConnection; +import java.net.URL; +import javax.net.ssl.SSLContext; + +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Callback; +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestBuilder; +import com.bumptech.glide.RequestManager; +import android.widget.ImageView; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.security.cert.X509Certificate; public class MainActivity extends AppCompatActivity { + String requestURL = "http://11.7.7.223:80/"; - // Used to load the 'native-lib' library on application startup. - static { - System.loadLibrary("zt-shared"); + private static String createDataSize(int msgSize) { + StringBuilder sb = new StringBuilder(msgSize); + for (int i=0; i threads = new ArrayList<>(); + for(int i = 0;i < 5;i++){ + try { + Thread.sleep(500); + } catch (Exception e) {} + HTTPWorker thread = new HTTPWorker(); + thread.start(); + threads.add(thread); + } + + System.out.println("sleeping..."); + try { + Thread.sleep(60000000); + } catch (Exception e) {} + + System.exit(0); + + // Test: setsockopt() and getsockopt() [non-exhaustive] + /* + if (true) { + try { + ZeroTierSocket zts = new ZeroTierSocket(); + zts.connect(new InetSocketAddress("11.7.7.223", 8082)); + zts.setSoTimeout(1337); + int to = zts.getSoTimeout(); + assert to == 1337; + + } catch (Exception e) { + + } + } + */ + + // Test: Perform randomly-delayed HTTP GET requests + if (false) { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.socketFactory(new ZeroTierSocketFactory()); + OkHttpClient client = builder.build(); + Request request1 = new Request.Builder() + .url("http://11.7.7.223:8082/") + .build(); + + long i = 0; + for (;;) { + try { + Thread.sleep((long)(Math.random() * 250)); + Response response = client.newCall(request1).execute(); + i++; + System.out.println("GET: i="+i+", len="+response.toString().length()); + //response.close(); + + } catch (Exception e) { + System.out.println(e); + System.exit(0); + e.printStackTrace(); + } + + } + } + + // Test: Perform randomly-delayed HTTP GET requests + if (true) { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.socketFactory(new ZeroTierSocketFactory()); + OkHttpClient client = builder.build(); + Request request1 = new Request.Builder() + .url("http://11.7.7.223:80/warandpeace.txt") + .header("Transfer-Encoding", "chunked") + //.header("Connection","close") + .build(); + + Request request2 = new Request.Builder() + .url("http://11.7.7.223:8082/pumpkin.jpg") + .header("Transfer-Encoding", "chunked") + .header("Connection","close") + .build(); + + String postMessage = "what?"; + try { + postMessage = new String(createDataSize(1024).getBytes(), "UTF8"); + } + catch (Exception e) + { + System.out.println(e); + } + + MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + okhttp3.RequestBody body = RequestBody.create(JSON, postMessage); + + //RequestBody formBody = new FormBody.Builder() + // .add("message", postMessage) + // .build(); + Request request3 = new Request.Builder() + .url("http://11.7.7.223:8082/") + //.retryOnConnectionFailure(true) + .header("Transfer-Encoding", "chunked") + .header("Connection","close") + //.header("Connection","keep-alive") + .post(body) + .build(); + + long i = 0; + for (;;) { + try { + System.out.println("iteration="+i); + int randomNum = ThreadLocalRandom.current().nextInt(0, 2 + 1); + Thread.sleep(10); + i++; + Response response = null; + if (randomNum == 0) { + System.out.println("(0) GET: war"); + response = client.newCall(request1).execute(); + + } + if (randomNum == 1) { + System.out.println("(1) GET: pumpkin"); + response = client.newCall(request2).execute(); + + } + if (randomNum == 2) { + System.out.println("(2) POST: data"); + response = client.newCall(request3).execute(); + response.close(); + continue; + } + InputStream in = response.body().byteStream(); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[16384]; + while ((nRead = in.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + System.out.println("GET: i="+i+", len="+buffer.toByteArray().length); + response.close(); + + } catch (Exception e) { + System.out.println(e); + e.printStackTrace(); + } + + } + } + + + // Test: Perform randomly-delayed HTTP GET requests + if (true) { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.socketFactory(new ZeroTierSocketFactory()); + OkHttpClient client = builder.build(); + + Request request = new Request.Builder() + .url(requestURL+"warandpeace.txt") + .build(); + + long i = 0; + for (;;) { + try { + //Thread.sleep((long)(Math.random()) ); + //System.out.println("iteration="+i); + i++; + Response response = client.newCall(request).execute(); + //System.out.println(response.body().string()); + + InputStream in = response.body().byteStream(); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[16384]; + while ((nRead = in.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + + System.out.println("\tCOMPLETE, i="+i+", len="+buffer.toByteArray().length); + + + /* + //Bitmap bitmap = BitmapFactory.decodeByteArray(buffer.toByteArray(), 0, buffer.toByteArray().length); + //ImageView imageView = (ImageView) findViewById(R.id.imageView); + //imageView.setImageBitmap(bitmap); + */ + /* + BufferedInputStream bufferedInputStream = new BufferedInputStream(in); + Bitmap bitmap=BitmapFactory.decodeStream(bufferedInputStream); + ImageView imageView = (ImageView) findViewById(R.id.imageView); + imageView.setImageBitmap(bitmap); + */ + + // + // Thread.sleep(5000); + //response.close(); + } catch (Exception e) { + System.out.println("EXCEPTION:"+e); + //System.exit(0); + e.printStackTrace(); + } + + } + } + + + + // ... + + // Test #2: HttpURLConnection + if (false) + { + + + // Create a trust manager that does not validate certificate chains + TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + } + }; + + SSLContext context = null; + + // Set runtime default socket implementation factory + try { + //Socket.setSocketImplFactory(new ZeroTierSocketImplFactory()); + //SSLSocket.setSocketImplFactory(new ZeroTierSocketImplFactory()); + + context = SSLContext.getInstance("SSL"); + //context.init(null, null, null); + context.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); + } catch (Exception e) { + e.printStackTrace(); + } + + // Create all-trusting host name verifier + HostnameVerifier allHostsValid = new HostnameVerifier() { + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + // Install the all-trusting host verifier + HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); + + + ZeroTierSSLSocketFactory customSocketFactory = new ZeroTierSSLSocketFactory(context.getSocketFactory()); + HttpsURLConnection.setDefaultSSLSocketFactory(customSocketFactory); + + + + + // Test HTTP client + String GET_URL = "https://10.6.6.152"; + String USER_AGENT = "Mozilla/5.0"; + try { + URL obj = new URL(GET_URL); + HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); + + con.setSSLSocketFactory(customSocketFactory); + + con.setRequestMethod("GET"); + con.setRequestProperty("User-Agent", USER_AGENT); + System.out.println("neat?"); + int responseCode = con.getResponseCode(); + System.out.println("GET Response Code :: " + responseCode); + if (responseCode == HttpsURLConnection.HTTP_OK) + { + // success + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + System.out.println(response.toString()); + } else { + System.out.println("GET request failed"); + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println(e); + } } - ).start(); } } diff --git a/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MyZeroTierEventListener.java b/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MyZeroTierEventListener.java new file mode 100644 index 0000000..27c6d89 --- /dev/null +++ b/examples/android/ExampleAndroidApp/app/src/main/java/com/example/exampleandroidapp/MyZeroTierEventListener.java @@ -0,0 +1,82 @@ +package com.example.exampleandroidapp; + +import com.zerotier.libzt.ZeroTier; +import com.zerotier.libzt.ZeroTierEventListener; + +public class MyZeroTierEventListener implements ZeroTierEventListener { + + public boolean isNetworkReady = false; + public boolean isOnline = false; + + public void onZeroTierEvent(long id, int eventCode) + { + if (eventCode == ZeroTier.EVENT_NODE_UP) { + System.out.println("EVENT_NODE_UP: nodeId=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_NODE_ONLINE) { + // The core service is running properly and can join networks now + System.out.println("EVENT_NODE_ONLINE: nodeId=" + Long.toHexString(ZeroTier.get_node_id())); + isOnline = true; + } + if (eventCode == ZeroTier.EVENT_NODE_OFFLINE) { + // Network does not seem to be reachable by any available strategy + System.out.println("EVENT_NODE_OFFLINE"); + } + if (eventCode == ZeroTier.EVENT_NODE_DOWN) { + // Called when the node is shutting down + System.out.println("EVENT_NODE_DOWN"); + } + if (eventCode == ZeroTier.EVENT_NODE_IDENTITY_COLLISION) { + // Another node with this identity already exists + System.out.println("EVENT_NODE_IDENTITY_COLLISION"); + } + if (eventCode == ZeroTier.EVENT_NODE_UNRECOVERABLE_ERROR) { + // Try again + System.out.println("EVENT_NODE_UNRECOVERABLE_ERROR"); + } + if (eventCode == ZeroTier.EVENT_NODE_NORMAL_TERMINATION) { + // Normal closure + System.out.println("EVENT_NODE_NORMAL_TERMINATION"); + } + if (eventCode == ZeroTier.EVENT_NETWORK_READY_IP4) { + // We have at least one assigned address and we've received a network configuration + System.out.println("ZTS_EVENT_NETWORK_READY_IP4: nwid=" + Long.toHexString(id)); + isNetworkReady = true; + } + if (eventCode == ZeroTier.EVENT_NETWORK_READY_IP6) { + // We have at least one assigned address and we've received a network configuration + System.out.println("ZTS_EVENT_NETWORK_READY_IP6: nwid=" + Long.toHexString(id)); + isNetworkReady = true; + } + if (eventCode == ZeroTier.EVENT_NETWORK_DOWN) { + // Someone called leave(), we have no assigned addresses, or otherwise cannot use this interface + System.out.println("EVENT_NETWORK_DOWN: nwid=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_NETWORK_REQUESTING_CONFIG) { + // Waiting for network configuration + System.out.println("EVENT_NETWORK_REQUESTING_CONFIG: nwid=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_NETWORK_OK) { + // Config received and this node is authorized for this network + System.out.println("EVENT_NETWORK_OK: nwid=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_NETWORK_ACCESS_DENIED) { + // You are not authorized to join this network + System.out.println("EVENT_NETWORK_ACCESS_DENIED: nwid=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_NETWORK_NOT_FOUND) { + // The virtual network does not exist + System.out.println("EVENT_NETWORK_NOT_FOUND: nwid=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_NETWORK_CLIENT_TOO_OLD) { + // The core version is too old + System.out.println("EVENT_NETWORK_CLIENT_TOO_OLD: nwid=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_PEER_P2P) { + System.out.println("EVENT_PEER_P2P: id=" + Long.toHexString(id)); + } + if (eventCode == ZeroTier.EVENT_PEER_RELAY) { + System.out.println("EVENT_PEER_RELAY: id=" + Long.toHexString(id)); + } + } +} diff --git a/examples/android/ExampleAndroidApp/app/src/main/res/layout/activity_main.xml b/examples/android/ExampleAndroidApp/app/src/main/res/layout/activity_main.xml index 84f1951..6b12ce5 100644 --- a/examples/android/ExampleAndroidApp/app/src/main/res/layout/activity_main.xml +++ b/examples/android/ExampleAndroidApp/app/src/main/res/layout/activity_main.xml @@ -15,4 +15,12 @@ app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + \ No newline at end of file diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.sln b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.sln deleted file mode 100644 index 618e086..0000000 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2027 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleWindowsCSharpApp", "ExampleWindowsCSharpApp\ExampleWindowsCSharpApp.csproj", "{74F548E3-64FD-41FF-9416-0AE1FC24E8BE}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {74F548E3-64FD-41FF-9416-0AE1FC24E8BE}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {BC236939-C661-4FEB-8935-4A61C2ECEC19} - EndGlobalSection -EndGlobal diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/App.config b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/App.config deleted file mode 100644 index 00bfd11..0000000 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.csproj b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.csproj deleted file mode 100644 index 8dd76e7..0000000 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp.csproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - - Debug - AnyCPU - {74F548E3-64FD-41FF-9416-0AE1FC24E8BE} - Exe - ExampleWindowsCSharpApp - ExampleWindowsCSharpApp - v4.6.1 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs deleted file mode 100644 index 03fc748..0000000 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -using System.Net; - -using ZeroTier; - -namespace ExampleWindowsCSharpApp -{ - class Program - { - static void Main(string[] args) - { - ulong nwid = 0xe4da7455b2b9ee6a; - - Console.Write("waiting for libzt to come online...\n"); - libzt.zts_startjoin("config_path", nwid); - Console.Write("I am " + libzt.zts_get_node_id().ToString("X") +"\n"); - Console.Write("ZT ready\n"); - - int fd; - int err = 0; - bool clientMode = false; - - if ((fd = libzt.zts_socket(2, 1, 0)) < 0) - { - Console.Write("error creating socket\n"); - } - - // CLIENT - if (clientMode == true) - { - string remoteAddrStr = "172.28.221.116"; - Int16 remotePort = 2323; - // Convert managed address object to pointer for unmanaged code - libzt.SockAddrIn addr = new libzt.SockAddrIn(); - addr.Family = (byte)libzt.SockAddrFamily.Inet; - addr.Port = IPAddress.HostToNetworkOrder((Int16)remotePort); - addr.Addr = (uint)IPAddress.Parse(remoteAddrStr).Address; - IntPtr addrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(libzt.SockAddrIn))); - Marshal.StructureToPtr(addr, addrPtr, false); - int addrlen = Marshal.SizeOf(addr); - - if ((err = libzt.zts_connect(fd, addrPtr, addrlen)) < 0) - { - Console.Write("error connecting to remote server\n"); - } - - // Send message - string msgStr = "Hello from C#!"; - byte[] msgBuf = Encoding.ASCII.GetBytes(msgStr); - int buflen = System.Text.ASCIIEncoding.ASCII.GetByteCount(msgStr); - - if ((err = libzt.zts_write(fd, msgBuf, buflen)) < 0) - { - Console.Write("error writing to remote server\n"); - } - - libzt.zts_close(fd); - Marshal.FreeHGlobal(addrPtr); - } - else // SERVER - { - string localAddrStr = "0.0.0.0"; - Int16 bindPort = 5050; - libzt.SockAddrIn addr = new libzt.SockAddrIn(); - addr.Family = (byte)libzt.SockAddrFamily.Inet; - addr.Port = IPAddress.HostToNetworkOrder((Int16)bindPort); - addr.Addr = (uint)IPAddress.Parse(localAddrStr).Address; - IntPtr addrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(libzt.SockAddrIn))); - Marshal.StructureToPtr(addr, addrPtr, false); - int addrlen = Marshal.SizeOf(addr); - - if ((err = libzt.zts_bind(fd, addrPtr, addrlen)) < 0) - { - Console.Write("error binding to local port\n"); - } - if ((err = libzt.zts_listen(fd, 1)) < 0) - { - Console.Write("error putting socket in listening state\n"); - } - int accfd; - Console.Write("waiting to accept connection...\n"); - if ((accfd = libzt.zts_accept(fd, IntPtr.Zero, IntPtr.Zero)) < 0) - { - Console.Write("error accepting incoming connection\n"); - } - Console.Write("accepted connection!\n"); - - - // Read message - byte[] msgBuf = new byte[32]; - int buflen = 32; - Console.Write("reading from client...\n"); - if ((err = libzt.zts_read(accfd, msgBuf, buflen)) < 0) - { - Console.Write("error reading from remote client\n"); - } - Console.Write("read " + err + " bytes from client\n"); - string msgStr = System.Text.Encoding.UTF8.GetString(msgBuf, 0, msgBuf.Length); - Console.Write("msg from client = " + msgStr + "\n"); - - libzt.zts_close(fd); - libzt.zts_close(accfd); - Marshal.FreeHGlobal(addrPtr); - } - - Console.Write("fd=" + fd); - Console.Write("wrote=" + err); - - libzt.zts_stop(); - } - } -} diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Properties/AssemblyInfo.cs b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Properties/AssemblyInfo.cs deleted file mode 100644 index 86e2265..0000000 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ExampleWindowsCSharpApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ExampleWindowsCSharpApp")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("74f548e3-64fd-41ff-9416-0ae1fc24e8be")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs deleted file mode 100644 index d1683e7..0000000 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using System.Runtime.InteropServices; - -namespace ZeroTier -{ - static class libzt - { - public enum SockAddrFamily - { - Inet = 2, - Inet6 = 10 - } - - [StructLayout(LayoutKind.Sequential)] - public struct SockAddr - { - public ushort Family; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] - public byte[] Data; - }; - - [StructLayout(LayoutKind.Sequential)] - public struct SockAddrIn - { - byte len; // unique to lwIP - public byte Family; - public Int16 Port; - public uint Addr; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public byte[] Zero; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SockAddrIn6 - { - public ushort Family; - public ushort Port; - public uint FlowInfo; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] Addr; - public uint ScopeId; - }; - - /****************************************************************************/ - /* ZeroTier Service Controls */ - /****************************************************************************/ - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_start(string path); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_startjoin(string path, ulong nwid); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_stop(); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_join(ulong nwid); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_leave(ulong nwid); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_get_homepath(string homePath, int len); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern Int64 zts_get_node_id(); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_running(); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_has_address(ulong nwid); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_get_address(ulong nwid, IntPtr addr, int address_family); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_get_6plane_addr(IntPtr addr, string nwid, string nodeId); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_get_rfc4193_addr(IntPtr addr, string nwid, string nodeId); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern long zts_get_peer_count(); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_get_peer_address(string peer, ulong nodeId); - - /****************************************************************************/ - /* Socket-like API */ - /****************************************************************************/ - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_socket(int socket_family, int socket_type, int protocol); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_connect(int fd, IntPtr addr, int addrlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_bind(int fd, IntPtr addr, int addrlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_listen(int fd, int backlog); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_accept(int fd, IntPtr addr, IntPtr addrlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_setsockopt(int fd, int level, int optname, IntPtr optval, int optlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_getsockopt(int fd, int level, int optname, IntPtr optval, IntPtr optlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_getsockname(int fd, IntPtr addr, IntPtr addrlen); - - /* - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_getpeername(int fd, System.IntPtr addr, IntPtr addrlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_gethostname(string name, int len); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_sethostname(string name, int len); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - unsafe public static extern IntPtr *zts_gethostbyname(string name); - */ - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_close(int fd); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_select(int nfds, IntPtr readfds, IntPtr writefds, IntPtr exceptfds, IntPtr timeout); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_fcntl(int fd, int cmd, int flags); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_ioctl(int fd, ulong request, IntPtr argp); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_send(int fd, byte[] buf, int len, int flags); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_sendto(int fd, byte[] buf, int len, int flags, IntPtr addr, int addrlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_sendmsg(int fd, byte[] msg, int flags); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_recv(int fd, byte[] buf, int len, int flags); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_recvfrom(int fd, byte[] buf, int len, int flags, IntPtr addr, IntPtr addrlen); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_recvmsg(int fd, byte[] msg, int flags); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_read(int fd, byte[] buf, int len); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_write(int fd, byte[] buf, int len); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_shutdown(int fd, int how); - -/* - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_add_dns_nameserver(System.IntPtr addr); - - [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_del_dns_nameserver(System.IntPtr addr); -*/ - } -} diff --git a/examples/java/ExampleApp.java b/examples/java/ExampleApp.java deleted file mode 100644 index 245e194..0000000 --- a/examples/java/ExampleApp.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -// Simple Java example for libzt using JNI - -import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZTSocketAddress; -import com.zerotier.libzt.ZTFDSet; - -import java.lang.Thread; - -public class ExampleApp { - - static { System.loadLibrary("zt"); } // load libzt.dylib or libzt.so - - static void sleep(int ms) - { - try { Thread.sleep(ms); } - catch (InterruptedException e) { e.printStackTrace(); } - } - - public static void main(String[] args) - { - - final ZeroTier zt = new ZeroTier(); - - new Thread(new Runnable() - { - public void run() - { - String path = "/Users/joseph/op/zt/libzt/ztjni"; // Where node's config files are stored - long nwid = 0xa09acf7233e4b071L; - - // Test modes - boolean blocking_start_call = true; - boolean client_mode = false; - boolean tcp = false; - boolean loop = true; // RX/TX multiple times - boolean idle = false; // Idle loop after node comes online. For testing reachability - boolean use_select = true; - - int fd = -1, client_fd = -1, err, r, w, lengthToRead = 0, flags = 0; - byte[] rxBuffer; - byte[] txBuffer = "welcome to the machine".getBytes(); - String remoteAddrStr = "11.7.7.107"; - String localAddrStr = "0.0.0.0"; - int portNo = 4040; - - ZTSocketAddress remoteAddr, localAddr; - ZTSocketAddress sockname = new ZTSocketAddress(); - ZTSocketAddress addr = new ZTSocketAddress(); - - // METHOD 1 (easy) - // Blocking call that waits for all components of the service to start - System.out.println("Starting ZT service..."); - if (blocking_start_call) { - zt.startjoin(path, nwid); - } - // METHOD 2 - // Optional. Non-blocking call to start service. You'll have to use the below process to determine - // when you are allowed to start making socket calls. - if (!blocking_start_call) { - zt.start(path, true); - while(!zt.ready()) { - try { // Wait for core service to start - Thread.sleep(250); - } - catch(InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - System.out.println("Core started. Networks can be joined after this point"); - zt.join(nwid); - // Wait for userspace stack to start, we trigger this by joining a network - while(!zt.stack_running()) { - try { - Thread.sleep(1000); - } - catch(InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - System.out.println("ZT service ready."); - // Device/Node address info - System.out.println("path=" + zt.get_path()); - long nodeId = zt.get_node_id(); - System.out.println("nodeId=" + Long.toHexString(nodeId)); - int numAddresses = zt.get_num_assigned_addresses(nwid); - System.out.println("this node has (" + numAddresses + ") assigned addresses on network " + Long.toHexString(nwid)); - for (int i=0; i 0) { - System.out.println("select detected something to read on"); - for (int i = 0; i < nfds; i++) - { - if (master_set.ISSET(i)) - { - System.out.println("attempting to read from: " + i); - r = zt.recvfrom(fd, rxBuffer, flags, remoteAddr); - System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer)); - } - } - } - } - } - if (!use_select) - { - while(true) { - addr = new ZTSocketAddress(); - r = zt.recvfrom(fd, rxBuffer, flags, remoteAddr); - System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer)); - } - } - } - } - - zt.close(client_fd); - zt.close(fd); - } - }).start(); - - while(true) - { - try { Thread.sleep(3000); } - catch (InterruptedException e) { e.printStackTrace(); } - } - } -} \ No newline at end of file diff --git a/examples/java/README.md b/examples/java/README.md deleted file mode 100644 index c5472b9..0000000 --- a/examples/java/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## ZeroTier with Java via JNI -*** - -### ExampleApp - -Copy `zt.jar` file into this directory -Extract shared library from JAR file: `jar xf zt.jar libzt.dylib` -Build ExampleApp: `javac -cp ".:zt.jar" ExampleApp.java` \ No newline at end of file diff --git a/examples/java/com/zerotier/libzt/ZTFDSet.java b/examples/java/com/zerotier/libzt/ZTFDSet.java deleted file mode 100644 index cf5bd7b..0000000 --- a/examples/java/com/zerotier/libzt/ZTFDSet.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -public class ZTFDSet -{ - byte[] fds_bits = new byte[1024]; - - public void CLR(int fd) - { - fds_bits[fd] = 0x00; - } - - public boolean ISSET(int fd) - { - return fds_bits[fd] == 0x01; - } - - public void SET(int fd) - { - fds_bits[fd] = 0x01; - } - - public void ZERO() - { - for (int i=0; i<1024; i++) { - fds_bits[i] = 0x00; - } - } -} \ No newline at end of file diff --git a/examples/java/com/zerotier/libzt/ZTSocketAddress.java b/examples/java/com/zerotier/libzt/ZTSocketAddress.java deleted file mode 100644 index c922251..0000000 --- a/examples/java/com/zerotier/libzt/ZTSocketAddress.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; - -import java.net.InetAddress; - -// Designed to transport address information across the JNI boundary -public class ZTSocketAddress -{ - public byte[] _ip6 = new byte[16]; - public byte[] _ip4 = new byte[4]; - - public int _family; - public int _port; // Also reused for netmask or prefix - - public ZTSocketAddress() {} - - public ZTSocketAddress(String ipStr, int port) - { - if(ipStr.contains(":")) { - _family = ZeroTier.AF_INET6; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip6 = ip.getAddress(); - } - catch (Exception e) { } - } - else if(ipStr.contains(".")) { - _family = ZeroTier.AF_INET; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip4 = ip.getAddress(); - } - catch (Exception e) { } - } - _port = port; - } - - public int getPort() { return _port; } - public int getNetmask() { return _port; } - public int getPrefix() { return _port; } - - private String ipString() - { - if (_family == ZeroTier.AF_INET) { - try { - InetAddress inet = InetAddress.getByAddress(_ip4); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - if (_family == ZeroTier.AF_INET6) { - try { - InetAddress inet = InetAddress.getByAddress(_ip6); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - return ""; - } - - public String toString() { return ipString() + ":" + _port; } - public String toCIDR() { return ipString() + "/" + _port; } -} diff --git a/examples/java/com/zerotier/libzt/ZeroTier.java b/examples/java/com/zerotier/libzt/ZeroTier.java deleted file mode 100644 index 26e337b..0000000 --- a/examples/java/com/zerotier/libzt/ZeroTier.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -import java.net.*; - -public class ZeroTier { - - public static int AF_INET = 2; - public static int AF_INET6 = 30; - public static int SOCK_STREAM = 1; - public static int SOCK_DGRAM = 2; - public static int O_APPEND = 1024; - public static int O_NONBLOCK = 2048; - public static int O_ASYNC = 8192; - public static int O_DIRECT = 65536; - public static int O_NOATIME = 262144; - public static int F_GETFL = 3; - public static int F_SETFL = 4; - - public native void start(String homePath, boolean blocking); - public native void startjoin(String homePath, long nwid); - public native void stop(); - public native boolean core_running(); - public native boolean stack_running(); - public native boolean ready(); - public native int join(long nwid); - public native int leave(long nwid); - public native String get_path(); - public native long get_node_id(); - public native int get_num_assigned_addresses(long nwid); - public native boolean get_address_at_index(long nwid, int index, ZTSocketAddress addr); - public native boolean has_address(long nwid); - public native boolean get_address(long nwid, int address_family, ZTSocketAddress addr); - public native void get_6plane_addr(long nwid, long nodeId, ZTSocketAddress addr); - public native void get_rfc4193_addr(long nwid, long nodeId, ZTSocketAddress addr); - - public native int socket(int family, int type, int protocol); - public native int connect(int fd, ZTSocketAddress addr); - public native int bind(int fd, ZTSocketAddress addr); - public native int listen(int fd, int backlog); - public native int accept(int fd, ZTSocketAddress addr); - public native int accept4(int fd, String addr, int port); - public native int close(int fd); - public native int setsockopt(int fd, int level, int optname, int optval, int optlen); - public native int getsockopt(int fd, int level, int optname, int optval, int optlen); - public native int sendto(int fd, byte[] buf, int flags, ZTSocketAddress addr); - public native int send(int fd, byte[] buf, int flags); - public native int recv(int fd, byte[] buf, int flags); - public native int recvfrom(int fd, byte[] buf, int flags, ZTSocketAddress addr); - public native int read(int fd, byte[] buf); - public native int write(int fd, byte[] buf); - public native int shutdown(int fd, int how); - public native boolean getsockname(int fd, ZTSocketAddress addr); - public native int getpeername(int fd, ZTSocketAddress addr); - public native int fcntl(int sock, int cmd, int flag); - public native int select(int nfds, ZTFDSet readfds, ZTFDSet writefds, ZTFDSet exceptfds, int timeout_sec, int timeout_usec); -} \ No newline at end of file diff --git a/examples/layer2/layer2.cpp b/examples/layer2/layer2.cpp deleted file mode 100644 index 50b82ce..0000000 --- a/examples/layer2/layer2.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// This file is built with libzt.a via `make tests` - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#if defined(__APPLE__) -#include -#endif -#if defined(__linux__) -#include -#include -#include -#include -#endif - -#include "libzt.h" - -unsigned short csum(unsigned short *buf, int nwords) -{ - unsigned long sum; - for(sum=0; nwords>0; nwords--) - sum += *buf++; - sum = (sum >> 16) + (sum &0xffff); - sum += (sum >> 16); - return (unsigned short)(~sum); -} - -int main(int argc , char *argv[]) -{ - if (argc < 3) { - fprintf(stderr, "usage: layer2 \n"); - return 1; - } - - // initialize library - printf("Starting libzt...\n"); - zts_startjoin(argv[1], strtoull(argv[2], NULL, 16)); - uint64_t device_id = zts_get_node_id(); - fprintf(stderr, "Complete. I am %llx\n", device_id); - - // create socket - int fd; - if ((fd = zts_socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) { - printf("There was a problem creating the raw socket\n"); - exit(-1); - } - fprintf(stderr, "Created raw socket (%d)\n", fd); - -#if defined(__APPLE__) - fprintf(stderr, "SOCK_RAW not supported on mac builds yet. exiting"); - exit(0); -#endif -#if defined(__linux__) // The rest of this file isn't yet supported on non-linux platforms - // get interface index to bind on - struct ifreq if_idx; - memset(&if_idx, 0, sizeof(struct ifreq)); - strncpy(if_idx.ifr_name, "libzt0", IFNAMSIZ-1); - if (zts_ioctl(fd, SIOCGIFINDEX, &if_idx) < 0) { - perror("SIOCGIFINDEX"); - exit(-1); - } - fprintf(stderr, "if_idx.ifr_ifindex=%d\n", if_idx.ifr_ifindex); - - // get MAC address of interface to send on - struct ifreq if_mac; - memset(&if_mac, 0, sizeof(struct ifreq)); - strncpy(if_mac.ifr_name, "libzt0", IFNAMSIZ-1); - if (zts_ioctl(fd, SIOCGIFHWADDR, &if_mac) < 0) { - perror("SIOCGIFHWADDR"); - exit(-1); - } - const unsigned char* mac=(unsigned char*)if_mac.ifr_hwaddr.sa_data; - fprintf(stderr, "hwaddr=%02X:%02X:%02X:%02X:%02X:%02X\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); - - // get IP address of interface to send on - struct ifreq if_ip; - memset(&if_ip, 0, sizeof(struct ifreq)); - strncpy(if_ip.ifr_name, "libzt0", IFNAMSIZ-1); - if (zts_ioctl(fd, SIOCGIFADDR, &if_ip) < 0) { - perror("SIOCGIFADDR"); - exit(-1); - } - char ipv4_str[INET_ADDRSTRLEN]; - struct sockaddr_in *in4 = (struct sockaddr_in *)&if_ip.ifr_addr; - inet_ntop(AF_INET, (const void *)&in4->sin_addr.s_addr, ipv4_str, INET_ADDRSTRLEN); - fprintf(stderr, "addr=%s", ipv4_str); - - // construct ethernet header - int tx_len = 0; - char sendbuf[1024]; - struct ether_header *eh = (struct ether_header *) sendbuf; - memset(sendbuf, 0, 1024); - - // Ethernet header - eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; - eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; - eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; - eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; - eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; - eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; - - // set destination MAC - int MY_DEST_MAC0 = 0x72; - int MY_DEST_MAC1 = 0x92; - int MY_DEST_MAC2 = 0xd4; - int MY_DEST_MAC3 = 0xfd; - int MY_DEST_MAC4 = 0x43; - int MY_DEST_MAC5 = 0x45; - - eh->ether_dhost[0] = MY_DEST_MAC0; - eh->ether_dhost[1] = MY_DEST_MAC1; - eh->ether_dhost[2] = MY_DEST_MAC2; - eh->ether_dhost[3] = MY_DEST_MAC3; - eh->ether_dhost[4] = MY_DEST_MAC4; - eh->ether_dhost[5] = MY_DEST_MAC5; - eh->ether_type = htons(ETH_P_IP); - tx_len += sizeof(struct ether_header); - - - // Construct the IP header - int ttl = 64; - struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header)); - iph->ihl = 5; - iph->version = 4; - iph->tos = 16; // Low delay - iph->id = htons(54321); - iph->ttl = ttl; // hops - iph->protocol = 17; // UDP - // Source IP address, can be spoofed - iph->saddr = inet_addr(inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr)); - // iph->saddr = inet_addr("192.168.0.112"); - // Destination IP address - iph->daddr = inet_addr("10.7.7.1"); - tx_len += sizeof(struct iphdr); - - // Construct UDP header - struct udphdr *udph = (struct udphdr *) (sendbuf + sizeof(struct iphdr) + sizeof(struct ether_header)); - udph->source = htons(3423); - udph->dest = htons(5342); - udph->check = 0; // skip - tx_len += sizeof(struct udphdr); - - // Fill in UDP payload - sendbuf[tx_len++] = 0xde; - sendbuf[tx_len++] = 0xad; - sendbuf[tx_len++] = 0xbe; - sendbuf[tx_len++] = 0xef; - - // Fill in remaining header info - // Length of UDP payload and header - udph->len = htons(tx_len - sizeof(struct ether_header) - sizeof(struct iphdr)); - // Length of IP payload and header - iph->tot_len = htons(tx_len - sizeof(struct ether_header)); - // Calculate IP checksum on completed header - iph->check = csum((unsigned short *)(sendbuf+sizeof(struct ether_header)), sizeof(struct iphdr)/2); - - // Send packet - // Destination address - struct sockaddr_ll socket_address; - // Index of the network device - socket_address.sll_ifindex = if_idx.ifr_ifindex; - // Address length - socket_address.sll_halen = ETH_ALEN; - // Destination MAC - socket_address.sll_addr[0] = MY_DEST_MAC0; - socket_address.sll_addr[1] = MY_DEST_MAC1; - socket_address.sll_addr[2] = MY_DEST_MAC2; - socket_address.sll_addr[3] = MY_DEST_MAC3; - socket_address.sll_addr[4] = MY_DEST_MAC4; - socket_address.sll_addr[5] = MY_DEST_MAC5; - - while(1) - { - usleep(10000); - // Send packet - if (zts_sendto(fd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0) - fprintf(stderr, "Send failed\n"); - } - - // dismantle all zt virtual taps - zts_stop(); -#endif - return 0; -} \ No newline at end of file diff --git a/examples/scala/ExampleApp.scala b/examples/scala/ExampleApp.scala deleted file mode 100644 index d774169..0000000 --- a/examples/scala/ExampleApp.scala +++ /dev/null @@ -1,36 +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. - */ - -import zerotier.ZeroTier - -object ExampleApp extends App { - // load libzt.dylib or libzt.so - System.loadLibrary("zt") - val libzt = new ZeroTier - libzt.startjoin("/Users/joseph/op/zt/libzt/ztjni", 0xa09acf0232a930f7L) - val fd = libzt.socket(2, 1, 0) - println(s"libzt.socket(): $fd") -} \ No newline at end of file diff --git a/examples/scala/Makefile b/examples/scala/Makefile deleted file mode 100644 index 5c18202..0000000 --- a/examples/scala/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -OSTYPE=$(shell uname -s | tr '[A-Z]' '[a-z]') -BUILD=build/$(OSTYPE) - -ifeq ($(OSTYPE),darwin) -SHARED_LIB=libzt.dylib -endif -ifeq ($(OSTYPE),linux) -SHARED_LIB=libzt.so -endif - -example_scala_app: - scalac *.scala - -copy_dynamic_lib: - cp ../../../$(BUILD)/$(SHARED_LIB) . - -clean: - -find . -type f \( -name '*.class' \) -delete \ No newline at end of file diff --git a/examples/scala/README.md b/examples/scala/README.md deleted file mode 100644 index 08c1d99..0000000 --- a/examples/scala/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## ZeroTier with Scala via JNI -*** - -To get this example project to work, do the following: - -- From libzt main directory, build shared library: `make shared_jni_lib` -- Copy the resultant dynamic library (`*.so` or `*.dylib`) from `build/` to this current directory -- Change to this directory and `make example_scala_app` -- Run: `scala -Djava.library.path=$(pwd) -cp "." ExampleApp` - - -Notes: - -Upon execution, it will load the libzt dynamic library via the `loadLibrary` method and begin generating an identity. \ No newline at end of file diff --git a/examples/scala/libzt.scala b/examples/scala/libzt.scala deleted file mode 100644 index 4ee304c..0000000 --- a/examples/scala/libzt.scala +++ /dev/null @@ -1,76 +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. - */ - -package zerotier; - -class ZeroTier { - - // socket families - // socket types - // basic service controls - @native def start(path: String, blocking: Boolean): Int - @native def startjoin(path: String, nwid: Long): Int - @native def stop(): Unit - @native def running(): Int - @native def join(nwid: Long): Unit - @native def leave(nwid: Long): Unit - // advanced service controls - //@native def get_path(): Unit - @native def get_node_id(): Long - //@native def get_6plane_addr(): Unit - //@native def get_rfc4193_addr(): Unit - // socket API - @native def socket(socket_family: Int, socket_type: Int, protocol: Int): Int - @native def connect(fd: Int, addr: String, port: Int): Int - @native def bind(fd: Int, addr: String, port: Int): Int - @native def listen(fd: Int, backlog: Int): Int - @native def accept(fd: Int, addr: Object, addrlen: Int): Int - @native def accept4(fd: Int, addr: Object, addrlen: Int, flags: Int): Int - @native def close(fd: Int): Int - @native def setsockopt(fd: Int, level: Int, optname: Int, optval: Object, optlen: Int): Int - @native def getsockopt(fd: Int, level: Int, optname: Int, optval: Object, optlen: Int): Int - @native def read(fd: Int, buf: Object, len: Int): Int - @native def write(fd: Int, buf: Object, len: Int): Int - @native def send(fd: Int, buf: Object, len: Int, flags: Int): Int - @native def sendto(fd: Int, buf: Object, len: Int, addr: Object, addrlen: Int): Int - @native def sendmsg(fd: Int, msg: Object, flags: Int): Int - @native def recv(fd: Int, buf: Object, len: Int, flags: Int): Int - @native def recvfrom(fd: Int, buf: Object, len: Int, addr: Object, addrlen: Int): Int - @native def recvmsg(fd: Int, msg: Object, flags: Int): Int - @native def shutdown(fd: Int, how: Int): Int - //@native def getsockname(): Int - //@native def getpeername(): Int - //@native def gethostname(): Int - //@native def sethostname(): Int - //@native def gethostbyname(): Object - //@native def poll(): Int - //@native def select(): Int - @native def fcntl(fd: Int, cmd: Int, flags: Int): Int - @native def ioctl(fd: Int, request: Long, argp: Object): Int - // stack controls - //@native def add_dns(): Int - //@native def del_dns(): Int -} diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.pbxproj b/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.pbxproj deleted file mode 100644 index b840018..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,374 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 7C6D474121126417004C82ED /* libzt-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7CC090842112516900AB1506 /* libzt-static.a */; }; - 7CC0908021124A1200AB1506 /* wrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0907E21124A1200AB1506 /* wrapper.cpp */; }; - 7CC0908221124F8900AB1506 /* Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0908121124F8900AB1506 /* Example.swift */; }; - 7CFEEDAA21123E550071915A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CFEEDA921123E550071915A /* AppDelegate.swift */; }; - 7CFEEDAC21123E550071915A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CFEEDAB21123E550071915A /* ViewController.swift */; }; - 7CFEEDAF21123E550071915A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7CFEEDAD21123E550071915A /* Main.storyboard */; }; - 7CFEEDB121123E560071915A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7CFEEDB021123E560071915A /* Assets.xcassets */; }; - 7CFEEDB421123E560071915A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7CFEEDB221123E560071915A /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 7CC0907D21124A1100AB1506 /* ExampleSwiftApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleSwiftApp-Bridging-Header.h"; sourceTree = ""; }; - 7CC0907E21124A1200AB1506 /* wrapper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrapper.cpp; sourceTree = ""; }; - 7CC0907F21124A1200AB1506 /* wrapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = wrapper.hpp; sourceTree = ""; }; - 7CC0908121124F8900AB1506 /* Example.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example.swift; sourceTree = ""; }; - 7CC090842112516900AB1506 /* libzt-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libzt-static.a"; path = "../../../bin/lib/Debug/libzt-static.a"; sourceTree = ""; }; - 7CFEEDA621123E550071915A /* ExampleSwiftApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleSwiftApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 7CFEEDA921123E550071915A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7CFEEDAB21123E550071915A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 7CFEEDAE21123E550071915A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 7CFEEDB021123E560071915A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 7CFEEDB321123E560071915A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 7CFEEDB521123E560071915A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 7CFEEDA321123E550071915A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 7C6D474121126417004C82ED /* libzt-static.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 7CC090832112516800AB1506 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 7CC090842112516900AB1506 /* libzt-static.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - 7CFEED9D21123E550071915A = { - isa = PBXGroup; - children = ( - 7CFEEDA821123E550071915A /* ExampleSwiftApp */, - 7CFEEDA721123E550071915A /* Products */, - 7CC090832112516800AB1506 /* Frameworks */, - ); - sourceTree = ""; - }; - 7CFEEDA721123E550071915A /* Products */ = { - isa = PBXGroup; - children = ( - 7CFEEDA621123E550071915A /* ExampleSwiftApp.app */, - ); - name = Products; - sourceTree = ""; - }; - 7CFEEDA821123E550071915A /* ExampleSwiftApp */ = { - isa = PBXGroup; - children = ( - 7CFEEDA921123E550071915A /* AppDelegate.swift */, - 7CFEEDAB21123E550071915A /* ViewController.swift */, - 7CFEEDAD21123E550071915A /* Main.storyboard */, - 7CFEEDB021123E560071915A /* Assets.xcassets */, - 7CFEEDB221123E560071915A /* LaunchScreen.storyboard */, - 7CFEEDB521123E560071915A /* Info.plist */, - 7CC0907E21124A1200AB1506 /* wrapper.cpp */, - 7CC0907F21124A1200AB1506 /* wrapper.hpp */, - 7CC0907D21124A1100AB1506 /* ExampleSwiftApp-Bridging-Header.h */, - 7CC0908121124F8900AB1506 /* Example.swift */, - ); - path = ExampleSwiftApp; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7CFEEDA521123E550071915A /* ExampleSwiftApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7CFEEDB821123E560071915A /* Build configuration list for PBXNativeTarget "ExampleSwiftApp" */; - buildPhases = ( - 7CFEEDA221123E550071915A /* Sources */, - 7CFEEDA321123E550071915A /* Frameworks */, - 7CFEEDA421123E550071915A /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = ExampleSwiftApp; - productName = ExampleSwiftApp; - productReference = 7CFEEDA621123E550071915A /* ExampleSwiftApp.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7CFEED9E21123E550071915A /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0940; - LastUpgradeCheck = 0940; - ORGANIZATIONNAME = ZeroTier; - TargetAttributes = { - 7CFEEDA521123E550071915A = { - CreatedOnToolsVersion = 9.4.1; - LastSwiftMigration = 0940; - }; - }; - }; - buildConfigurationList = 7CFEEDA121123E550071915A /* Build configuration list for PBXProject "ExampleSwiftApp" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 7CFEED9D21123E550071915A; - productRefGroup = 7CFEEDA721123E550071915A /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7CFEEDA521123E550071915A /* ExampleSwiftApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7CFEEDA421123E550071915A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7CFEEDB421123E560071915A /* LaunchScreen.storyboard in Resources */, - 7CFEEDB121123E560071915A /* Assets.xcassets in Resources */, - 7CFEEDAF21123E550071915A /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7CFEEDA221123E550071915A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7CC0908221124F8900AB1506 /* Example.swift in Sources */, - 7CFEEDAC21123E550071915A /* ViewController.swift in Sources */, - 7CFEEDAA21123E550071915A /* AppDelegate.swift in Sources */, - 7CC0908021124A1200AB1506 /* wrapper.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 7CFEEDAD21123E550071915A /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 7CFEEDAE21123E550071915A /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 7CFEEDB221123E560071915A /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 7CFEEDB321123E560071915A /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 7CFEEDB621123E560071915A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.4; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 7CFEEDB721123E560071915A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.4; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7CFEEDB921123E560071915A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 57AG88JR8A; - INFOPLIST_FILE = ExampleSwiftApp/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - "LIBRARY_SEARCH_PATHS[arch=*]" = /Users/joseph/op/zt/libzt_new/bin/lib/Debug; - PRODUCT_BUNDLE_IDENTIFIER = zerotier.ExampleSwiftApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = "ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7CFEEDBA21123E560071915A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 57AG88JR8A; - INFOPLIST_FILE = ExampleSwiftApp/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = zerotier.ExampleSwiftApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = "ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h"; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7CFEEDA121123E550071915A /* Build configuration list for PBXProject "ExampleSwiftApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7CFEEDB621123E560071915A /* Debug */, - 7CFEEDB721123E560071915A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7CFEEDB821123E560071915A /* Build configuration list for PBXNativeTarget "ExampleSwiftApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7CFEEDB921123E560071915A /* Debug */, - 7CFEEDBA21123E560071915A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7CFEED9E21123E550071915A /* Project object */; -} diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index accca7f..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/xcuserdata/joseph.xcuserdatad/xcschemes/xcschememanagement.plist b/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/xcuserdata/joseph.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 967e6fd..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp.xcodeproj/xcuserdata/joseph.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - SchemeUserState - - ExampleSwiftApp.xcscheme - - orderHint - 0 - - - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/AppDelegate.swift b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/AppDelegate.swift deleted file mode 100644 index 5602efc..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/AppDelegate.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// AppDelegate.swift -// ExampleSwiftApp -// -// Created by Joseph Henry on 8/1/18. -// Copyright © 2018 ZeroTier. All rights reserved. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - var window: UIWindow? - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - return true - } - - func applicationWillResignActive(_ application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. - } - - func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. - } - - func applicationWillEnterForeground(_ application: UIApplication) { - // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. - } - - func applicationDidBecomeActive(_ application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillTerminate(_ application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. - } - - -} - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d8db8d6..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" - }, - { - "idiom" : "ios-marketing", - "size" : "1024x1024", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/Contents.json b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/Contents.json deleted file mode 100644 index da4a164..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/LaunchScreen.storyboard b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f83f6fd..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/Main.storyboard b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/Main.storyboard deleted file mode 100644 index 03c13c2..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Example.swift b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Example.swift deleted file mode 100644 index 3635613..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Example.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// Example.swift -// ExampleSwiftApp -// -// Created by Joseph Henry on 8/1/18. -// Copyright © 2018 ZeroTier. All rights reserved. -// - -import Foundation -import UIKit - -class MyApplication: UIResponder, UIApplicationDelegate { - static func libzt_example_function() - { - var fd: Int32 = -1; - var err: Int32 = -1; - let clientMode = true; - let remotePort = 4545; - let remoteAddress = "192.168.195.1"; - let appDir = String(NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0]) - - // Start up and create socket - print("starting..."); - zts_startjoin(appDir, 0x1c33c1ceb0aa9251); - print("I am ", NSString(format:"%llx", zts_get_node_id())); - fd = zts_socket(2, 1, 0); - if(fd < 0) { - print("error creating socket"); - } - print("fd = ", fd); - - // Remote address - var in4 = sockaddr_in(sin_len: UInt8(MemoryLayout.size), - sin_family: UInt8(AF_INET), - sin_port: UInt16(remotePort).bigEndian, - sin_addr: in_addr(s_addr: 0), - sin_zero: (0,0,0,0,0,0,0,0)) - inet_pton(AF_INET, remoteAddress, &(in4.sin_addr)); - - // CLIENT - if (clientMode) - { - print("connecting..."); - let addrlen = socklen_t(MemoryLayout.size(ofValue: in4)) - let a = withUnsafeMutablePointer(to: &in4) { - $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { - err = zts_connect(fd, $0, addrlen) - } - } - if(err < 0) { - print("error connecting to remote server"); - } - print("connected"); - - print("sending message to server"); - var msg: String = "Hello from Swift!"; - err = zts_write(fd, msg, msg.count) - if(err < 0) { - print("error creating socket"); - } - print("wrote ", err, " bytes"); - zts_close(fd); - } - else // SERVER - { - - } - - zts_stop(); - } -} - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h deleted file mode 100644 index d74b530..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/ExampleSwiftApp-Bridging-Header.h +++ /dev/null @@ -1,71 +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. - */ - -#ifndef LIBZT_BRIDGING_HEADER_H -#define LIBZT_BRIDGING_HEADER_H - -#include -#include "/Users/joseph/op/zt/libzt_new/include/libzt.h" - -// ZT SERVICE CONTROLS -int zts_start(const char *path, int blocking); -int zts_startjoin(const char *path, const uint64_t nwid); -void zts_stop(); -int zts_core_running(); -int zts_stack_running(); -int zts_ready(); -int zts_join(uint64_t nwid); -int zts_leave(uint64_t nwid); -uint64_t zts_get_node_id(); -// SOCKET API -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_accept(int fd, struct sockaddr *addr, socklen_t *addrlen); -int zts_listen(int fd, int backlog); -int zts_socket(int socket_family, int socket_type, int protocol); -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_close(int fd); -int zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen); -int zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen); -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_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); -int zts_fcntl(int fd, int cmd, int flags); -int zts_ioctl(int fd, unsigned long request, void *argp); - -#endif /* LIBZT_BRIDGING_HEADER_H */ - - - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Info.plist b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Info.plist deleted file mode 100644 index 16be3b6..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/ViewController.swift b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/ViewController.swift deleted file mode 100644 index f265acd..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/ViewController.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// ViewController.swift -// ExampleSwiftApp -// -// Created by Joseph Henry on 8/1/18. -// Copyright © 2018 ZeroTier. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - - MyApplication.libzt_example_function(); - - // Do any additional setup after loading the view, typically from a nib. - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - -} - diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.cpp b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.cpp deleted file mode 100644 index 51326d8..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// wrapper.cpp -// ExampleSwiftApp -// -// Created by Joseph Henry on 8/1/18. -// Copyright © 2018 ZeroTier. All rights reserved. -// - -#include "wrapper.hpp" -#include "/Users/joseph/op/zt/libzt_new/include/libzt.h" - -#ifdef __cplusplus -extern "C" { -#endif - - // Nothing, implementation is in src/libzt.cpp - -#ifdef __cplusplus -} -#endif diff --git a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.hpp b/examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.hpp deleted file mode 100644 index 2cfc87d..0000000 --- a/examples/swift/ExampleSwiftApp/ExampleSwiftApp/wrapper.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// wrapper.hpp -// ExampleSwiftApp -// -// Created by Joseph Henry on 8/1/18. -// Copyright © 2018 ZeroTier. All rights reserved. -// - -#ifndef wrapper_hpp -#define wrapper_hpp - -#include - -#endif /* wrapper_hpp */ diff --git a/examples/ztproxy/ztproxy.cpp b/examples/ztproxy/ztproxy.cpp deleted file mode 100644 index 5203851..0000000 --- a/examples/ztproxy/ztproxy.cpp +++ /dev/null @@ -1,406 +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(__linux__) || defined(__APPLE__) -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libzt.h" - -#include "RingBuffer.h" -#include "ztproxy.hpp" - -#if defined(_WIN32) -#include -void sleep(unsigned long ms) -{ - Sleep(ms); -} -#endif - -namespace ZeroTier { - - typedef void PhySocket; - - ZTProxy::ZTProxy(int proxy_listen_port, std::string nwid, std::string path, std::string internal_addr, - int internal_port, std::string dns_nameserver) - : - _enabled(true), - _run(true), - _proxy_listen_port(proxy_listen_port), - _internal_port(internal_port), - _nwid(nwid), - _internal_addr(internal_addr), - _dns_nameserver(dns_nameserver), - _phy(this,false,true) - { - // Set up TCP listen sockets - // IPv4 - struct sockaddr_in in4; - memset(&in4,0,sizeof(in4)); - in4.sin_family = AF_INET; - in4.sin_addr.s_addr = Utils::hton((uint32_t)(0x7f000001)); // listen for TCP @127.0.0.1 - in4.sin_port = Utils::hton((uint16_t)proxy_listen_port); - _tcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this); - if (!_tcpListenSocket) { - DEBUG_ERROR("Error binding on port %d for IPv4 HTTP listen socket", proxy_listen_port); - } - // IPv6 - /* - struct sockaddr_in6 in6; - memset((void *)&in6,0,sizeof(in6)); - in6.sin6_family = AF_INET6; - in6.sin6_port = in4.sin_port; - in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1 - in6.sin6_port = Utils::hton((uint16_t)proxy_listen_port); - _tcpListenSocket6 = _phy.tcpListen((const struct sockaddr *)&in6,this); - */ - /* - if (!_tcpListenSocket6) { - DEBUG_ERROR("Error binding on port %d for IPv6 HTTP listen socket", proxy_listen_port); - } - */ - _thread = Thread::start(this); - } - - ZTProxy::~ZTProxy() - { - _run = false; - _phy.whack(); - Thread::join(_thread); - _phy.close(_tcpListenSocket,false); - _phy.close(_tcpListenSocket6,false); - } - - void ZTProxy::threadMain() - throw() - { - // Add DNS nameserver - if (_dns_nameserver.length() > 0) { - DEBUG_INFO("setting DNS nameserver (%s)", _dns_nameserver.c_str()); - struct sockaddr_in dns_address; - dns_address.sin_addr.s_addr = inet_addr(_dns_nameserver.c_str()); - zts_add_dns_nameserver((struct sockaddr*)&dns_address); - } - - TcpConnection *conn = NULL; - uint32_t msecs = 1; - struct timeval tv; - tv.tv_sec = msecs / 1000; - tv.tv_usec = (msecs % 1000) * 1000; - int ret = 0; - // Main I/O loop - // Moves data between client application socket and libzt VirtualSocket - while(_run) { - - _phy.poll(1); - - conn_m.lock(); - // build fd_sets to select upon - FD_ZERO(&read_set); - FD_ZERO(&write_set); - nfds = 0; - for (size_t i=0; izfd, &read_set); - FD_SET(clist[i]->zfd, &write_set); - nfds = clist[i]->zfd > nfds ? clist[i]->zfd : nfds; - } - - ret = zts_select(nfds + 1, &read_set, &write_set, NULL, &tv); - if (ret > 0) { - for (int fd_i=0; fd_irx_m.lock(); - if (conn->RXbuf->count() > 0) { - //DEBUG_INFO("libzt has incoming data on fd=%d, RXing via conn=%p, sock=%p", - // conn->zfd, conn, conn->client_sock); - } - if ((rd = zts_read(conn->zfd, conn->RXbuf->get_buf(),ZT_MAX_MTU)) < 0) { - DEBUG_ERROR("error while reading data from libzt, err=%d", rd); - } - else { - //DEBUG_INFO("LIBZT -> RXBUFFER = %d bytes", rd); - conn->RXbuf->produce(rd); - } - // attempt to write data to client from buffer - if ((wr = _phy.streamSend(conn->client_sock, conn->RXbuf->get_buf(), conn->RXbuf->count())) < 0) { - DEBUG_ERROR("error while writing the data from the RXbuf to the client PhySocket, err=%d", wr); - } - else { - //DEBUG_INFO("RXBUFFER -> CLIENT = %d bytes", wr); - conn->RXbuf->consume(wr); - } - conn->rx_m.unlock(); - } - - // TX, Handle data outgoing from client to libzt - if (FD_ISSET(fd_i, &write_set)) { - int wr = 0; - conn = zmap[fd_i]; - if (conn == NULL) { - DEBUG_ERROR("invalid conn, possibly closed before transmit was possible"); - } - // read data from client and place it on ring buffer - conn->tx_m.lock(); - if (conn->TXbuf->count() > 0) { - // DEBUG_INFO("client has outgoing data of len=%d on fd=%d, TXing via conn=%p, sock=%p", - // conn->TXbuf->count(), conn->zfd, conn, conn->client_sock); - if ((wr = zts_write(conn->zfd, conn->TXbuf->get_buf(), conn->TXbuf->count())) < 0) { - DEBUG_ERROR("error while sending the data over libzt, err=%d", wr); - } - else { - //DEBUG_INFO("TXBUFFER -> LIBZT = %d bytes", wr); - conn->TXbuf->consume(wr); // data is presumed sent, mark it as such in the ringbuffer - } - } - conn->tx_m.unlock(); - } - } - } - conn_m.unlock(); - } - } - - bool isValidIPAddress(const char *ip) - { - struct sockaddr_in sa; - return inet_pton(AF_INET, ip, &(sa.sin_addr)) == 1; - } - - void ZTProxy::phyOnTcpData(PhySocket *sock, void **uptr, void *data, unsigned long len) - { - int wr = 0, zfd = -1, err = 0; - DEBUG_EXTRA("sock=%p, len=%lu", sock, len); - std::string host = _internal_addr; - TcpConnection *conn = cmap[sock]; - if (conn == NULL) { - DEBUG_ERROR("invalid conn"); - exit(0); - } - if (conn->zfd < 0) { // no connection yet - if (host == "") { - DEBUG_ERROR("invalid hostname or address (empty)"); - return; - } - DEBUG_INFO("establishing proxy connection..."); - - uint16_t dest_port, ipv; - dest_port = _internal_port; - host = _internal_addr; - - if (isValidIPAddress(host.c_str()) == false) { - // try to resolve this if it isn't an IP address - struct hostent *h = zts_gethostbyname(host.c_str()); - if (h == NULL) { - DEBUG_ERROR("unable to resolve hostname (%s) (errno=%d)", host.c_str(), errno); - return; - } - // TODO - // host = h->h_addr_list[0]; - } - - // determine address type - ipv = host.find(":") != std::string::npos ? 6 : 4; - - // connect to remote host - if (ipv == 4) { - DEBUG_INFO("attempting to proxy [0.0.0.0:%d -> %s:%d]", _proxy_listen_port, host.c_str(), dest_port); - struct sockaddr_in in4; - memset(&in4,0,sizeof(in4)); - in4.sin_family = AF_INET; - in4.sin_addr.s_addr = inet_addr(host.c_str()); - in4.sin_port = Utils::hton(dest_port); - if ((zfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) { - DEBUG_ERROR("unable to create socket (errno=%d)", errno); - return; - } - if ((err = zts_connect(zfd, (const struct sockaddr *)&in4, sizeof(in4))) < 0) { - DEBUG_ERROR("unable to connect to remote host (errno=%d)", errno); - return; - } - } - if (ipv == 6) { - //DEBUG_INFO("attempting to proxy [0.0.0.0:%d -> %s:%d]", _proxy_listen_port, host.c_str(), dest_port); - /* - struct sockaddr_in6 in6; - memset(&in6,0,sizeof(in6)); - in6.sin6_family = AF_INET; - struct hostent *server; - server = gethostbyname2((char*)host.c_str(),AF_INET6); - memmove((char *) &in6.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length); - in6.sin6_port = Utils::hton(dest_port); - zfd = zts_socket(AF_INET, SOCK_STREAM, 0); - err = zts_connect(zfd, (const struct sockaddr *)&in6, sizeof(in6)); - */ - } - if (zfd < 0 || err < 0) { - // now release TX buffer contents we previously saved, since we can't connect - DEBUG_ERROR("error while connecting to remote host (zfd=%d, err=%d)", zfd, err); - conn->tx_m.lock(); - conn->TXbuf->reset(); - conn->tx_m.unlock(); - return; - } - else { - DEBUG_INFO("successfully connected to remote host"); - } - - conn_m.lock(); - // on success, add connection entry to map, set physock for later - clist.push_back(conn); - conn->zfd = zfd; - conn->client_sock = sock; - cmap[conn->client_sock] = conn; - zmap[zfd] = conn; - conn_m.unlock(); - } - // Write data coming from client TCP connection to its TX buffer, later emptied into libzt by threadMain I/O loop - conn->tx_m.lock(); - if ((wr = conn->TXbuf->write((const char *)data, len)) < 0) { - DEBUG_ERROR("there was an error while writing data from client to tx buffer, err=%d", wr); - } - else { - // DEBUG_INFO("CLIENT -> TXBUFFER = %d bytes", wr); - } - conn->tx_m.unlock(); - } - - void ZTProxy::phyOnTcpAccept(PhySocket *sockL, PhySocket *sockN, void **uptrL, void **uptrN, - const struct sockaddr *from) - { - DEBUG_INFO("sockL=%p, sockN=%p", sockL, sockN); - TcpConnection *conn = new TcpConnection(); - conn->client_sock = sockN; - cmap[sockN]=conn; - } - - void ZTProxy::phyOnTcpClose(PhySocket *sock, void **uptr) - { - DEBUG_INFO("sock=%p", sock); - conn_m.lock(); - TcpConnection *conn = cmap[sock]; - if (conn) { - conn->client_sock=NULL; - if (conn->zfd >= 0) { - zts_close(conn->zfd); - } - cmap.erase(sock); - for (size_t i=0; izfd] = NULL; - delete conn; - conn = NULL; - } -#if defined(_WIN32) - closesocket(_phy.getDescriptor(sock)); -#else - close(_phy.getDescriptor(sock)); -#endif - conn_m.unlock(); - } - - void ZTProxy::phyOnDatagram(PhySocket *sock, void **uptr, const struct sockaddr *localAddr, - const struct sockaddr *from, void *data, unsigned long len) { - DEBUG_INFO(); - } - void ZTProxy::phyOnTcpWritable(PhySocket *sock, void **uptr) { - DEBUG_INFO(); - } - void ZTProxy::phyOnFileDescriptorActivity(PhySocket *sock, void **uptr, bool readable, bool writable) { - DEBUG_INFO("sock=%p", sock); - } - void ZTProxy::phyOnTcpConnect(PhySocket *sock, void **uptr, bool success) { - DEBUG_INFO("sock=%p", sock); - } - void ZTProxy::phyOnUnixClose(PhySocket *sock, void **uptr) { - DEBUG_INFO("sock=%p", sock); - } - void ZTProxy::phyOnUnixData(PhySocket *sock,void **uptr,void *data,ssize_t len) { - DEBUG_INFO("sock=%p, len=%lu", sock, len); - } - void ZTProxy::phyOnUnixWritable(PhySocket *sock, void **uptr, bool lwip_invoked) { - DEBUG_INFO("sock=%p", sock); - } -} - -int main(int argc, char **argv) -{ - if (argc < 6 || argc > 7) { - printf("\nZeroTier TCP Proxy Service\n"); - printf("ztproxy [config_file_path] [local_listen_port] [nwid] [zt_host_addr] [zt_resource_port] [optional_dns_nameserver]\n"); - exit(0); - } - std::string path = argv[1]; - int proxy_listen_port = atoi(argv[2]); - std::string nwidstr = argv[3]; - std::string internal_addr = argv[4]; - int internal_port = atoi(argv[5]); - std::string dns_nameserver= "";//argv[6]; - - // Start ZeroTier Node - // Join Network which contains resources we need to proxy - DEBUG_INFO("waiting for libzt to come online"); - uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); - zts_startjoin(path.c_str(), nwid); - - ZeroTier::ZTProxy *proxy = new ZeroTier::ZTProxy(proxy_listen_port, nwidstr, path, internal_addr, internal_port, dns_nameserver); - - if (proxy) { - printf("\nZTProxy started. Listening on %d\n", proxy_listen_port); - printf("Traffic will be proxied to and from %s:%d on network %s\n", internal_addr.c_str(), internal_port, nwidstr.c_str()); - printf("Proxy Node config files and key stored in: %s/\n\n", path.c_str()); - while(1) { - sleep(1); - } - } - else { - printf("unable to create proxy\n"); - } - return 0; -} diff --git a/examples/ztproxy/ztproxy.hpp b/examples/ztproxy/ztproxy.hpp deleted file mode 100644 index 9bbfa21..0000000 --- a/examples/ztproxy/ztproxy.hpp +++ /dev/null @@ -1,132 +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. - */ - -#ifndef ZT_ZTPROXY_HPP -#define ZT_ZTPROXY_HPP - -#include "Constants.hpp" -#include "Thread.hpp" -#include "InetAddress.hpp" -#include "Mutex.hpp" -#include "Phy.hpp" -#include "OSUtils.hpp" - -#if defined(__linux__) || defined(__APPLE__) - #include -#endif - -#include -#include -#include - -#define BUF_SZ 1024*1024 - -namespace ZeroTier { - - typedef void PhySocket; - class ZTProxy; - - class TcpConnection - { - public: - int zfd; - PhySocket *client_sock; - RingBuffer *TXbuf, *RXbuf; - Mutex tx_m, rx_m; - - TcpConnection() { - zfd = -1; - TXbuf = new RingBuffer(BUF_SZ); - RXbuf = new RingBuffer(BUF_SZ); - } - - ~TcpConnection() { - delete TXbuf; - delete RXbuf; - client_sock = NULL; - TXbuf = NULL; - RXbuf = NULL; - } - }; - - class ZTProxy - { - friend class Phy; - - public: - ZTProxy(int proxy_listen_port, std::string nwid, std::string path, std::string internal_addr, int internal_port, std::string _dns_nameserver); - ~ZTProxy(); - - // Send incoming data to intended host - void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len); - void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len); - void phyOnTcpWritable(PhySocket *sock,void **uptr); - void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable); - // Establish outgoing connection to intended host - void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success); - // Accept connection - void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from); - // Handle the closure of a Unix Domain socket - void phyOnUnixClose(PhySocket *sock,void **uptr); - void phyOnUnixData(PhySocket *sock,void **uptr,void *data,ssize_t len); - void phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_invoked); - // Handle the closure of a TCP connection - void phyOnTcpClose(PhySocket *sock,void **uptr); - - void threadMain() - throw(); - - TcpConnection *getConnection(PhySocket *sock); - - private: - volatile bool _enabled; - volatile bool _run; - - Mutex conn_m; - fd_set read_set, write_set; - int nfds; - - int _proxy_listen_port; - int _internal_port; - std::string _nwid; - std::string _internal_addr; - std::string _dns_nameserver; - - Thread _thread; - Phy _phy; - PhySocket *_tcpListenSocket; - PhySocket *_tcpListenSocket6; - - // mapping from ZeroTier VirtualSocket fd to TcpConnection pointer - std::map zmap; - // mapping from ZeroTier PhySocket to TcpConnection pointer - std::map cmap; - - std::vector clist; - }; -} - -#endif \ No newline at end of file diff --git a/ext/ZeroTierOne.patch b/ext/ZeroTierOne.patch index 4094e39..dbae021 100644 --- a/ext/ZeroTierOne.patch +++ b/ext/ZeroTierOne.patch @@ -36,29 +36,3 @@ index 74c22d33..58979e26 100644 if (i < nqcb->oldQueues.size()) { if (nqcb->oldQueues[i]->byteLength > maxQueueLength) { maxQueueLength = nqcb->oldQueues[i]->byteLength; -diff --git a/service/OneService.cpp b/service/OneService.cpp -index a1c53764..e3034059 100644 ---- a/service/OneService.cpp -+++ b/service/OneService.cpp -@@ -625,6 +625,8 @@ public: - break; - if (!pkt) - break; -+ if (!_run) -+ break; - - const ZT_ResultCode rc = _node->processWirePacket(nullptr,pkt->now,pkt->sock,&(pkt->from),pkt->data,pkt->size,&_nextBackgroundTaskDeadline); - { -@@ -2244,6 +2246,12 @@ public: - #endif - syncManagedStuff(n,true,true); - n.tap->setMtu(nwc->mtu); -+#if defined(ZT_SDK) -+ // Inform the virtual tap of the update -+ if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE) { -+ n.tap->lastConfigUpdate(OSUtils::now()); -+ } -+#endif - } else { - _nets.erase(nwid); - return -999; // tap init failed diff --git a/ext/concurrentqueue/LICENSE.md b/ext/concurrentqueue/LICENSE.md new file mode 100644 index 0000000..c4e7588 --- /dev/null +++ b/ext/concurrentqueue/LICENSE.md @@ -0,0 +1,61 @@ +This license file applies to everything in this repository except that which +is explicitly annotated as being written by other authors, i.e. the Boost +queue (included in the benchmarks for comparison), Intel's TBB library (ditto), +the CDSChecker tool (used for verification), the Relacy model checker (ditto), +and Jeff Preshing's semaphore implementation (used in the blocking queue) which +has a zlib license (embedded in blockingconcurrentqueue.h). + +--- + +Simplified BSD License: + +Copyright (c) 2013-2016, Cameron Desrochers. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this list of +conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, this list of +conditions and the following disclaimer in the documentation and/or other materials +provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + +I have also chosen to dual-license under the Boost Software License as an alternative to +the Simplified BSD license above: + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/ext/concurrentqueue/concurrentqueue.h b/ext/concurrentqueue/concurrentqueue.h new file mode 100644 index 0000000..09e810f --- /dev/null +++ b/ext/concurrentqueue/concurrentqueue.h @@ -0,0 +1,3635 @@ +// Provides a C++11 implementation of a multi-producer, multi-consumer lock-free queue. +// An overview, including benchmark results, is provided here: +// http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++ +// The full design is also described in excruciating detail at: +// http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue + +// Simplified BSD license: +// Copyright (c) 2013-2016, Cameron Desrochers. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#pragma once + +#if defined(__GNUC__) +// Disable -Wconversion warnings (spuriously triggered when Traits::size_t and +// Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings +// upon assigning any computed values) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" + +#ifdef MCDBGQ_USE_RELACY +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" +#endif +#endif + +#if defined(__APPLE__) +#include "TargetConditionals.h" +#endif + +#ifdef MCDBGQ_USE_RELACY +#include "relacy/relacy_std.hpp" +#include "relacy_shims.h" +// We only use malloc/free anyway, and the delete macro messes up `= delete` method declarations. +// We'll override the default trait malloc ourselves without a macro. +#undef new +#undef delete +#undef malloc +#undef free +#else +#include // Requires C++11. Sorry VS2010. +#include +#endif +#include // for max_align_t +#include +#include +#include +#include +#include +#include +#include // for CHAR_BIT +#include +#include // partly for __WINPTHREADS_VERSION if on MinGW-w64 w/ POSIX threading + +// Platform-specific definitions of a numeric thread ID type and an invalid value +namespace moodycamel { namespace details { + template struct thread_id_converter { + typedef thread_id_t thread_id_numeric_size_t; + typedef thread_id_t thread_id_hash_t; + static thread_id_hash_t prehash(thread_id_t const& x) { return x; } + }; +} } +#if defined(MCDBGQ_USE_RELACY) +namespace moodycamel { namespace details { + typedef std::uint32_t thread_id_t; + static const thread_id_t invalid_thread_id = 0xFFFFFFFFU; + static const thread_id_t invalid_thread_id2 = 0xFFFFFFFEU; + static inline thread_id_t thread_id() { return rl::thread_index(); } +} } +#elif defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__) +// No sense pulling in windows.h in a header, we'll manually declare the function +// we use and rely on backwards-compatibility for this not to break +extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); +namespace moodycamel { namespace details { + static_assert(sizeof(unsigned long) == sizeof(std::uint32_t), "Expected size of unsigned long to be 32 bits on Windows"); + typedef std::uint32_t thread_id_t; + static const thread_id_t invalid_thread_id = 0; // See http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx + static const thread_id_t invalid_thread_id2 = 0xFFFFFFFFU; // Not technically guaranteed to be invalid, but is never used in practice. Note that all Win32 thread IDs are presently multiples of 4. + static inline thread_id_t thread_id() { return static_cast(::GetCurrentThreadId()); } +} } +#elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE) +namespace moodycamel { namespace details { + static_assert(sizeof(std::thread::id) == 4 || sizeof(std::thread::id) == 8, "std::thread::id is expected to be either 4 or 8 bytes"); + + typedef std::thread::id thread_id_t; + static const thread_id_t invalid_thread_id; // Default ctor creates invalid ID + + // Note we don't define a invalid_thread_id2 since std::thread::id doesn't have one; it's + // only used if MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is defined anyway, which it won't + // be. + static inline thread_id_t thread_id() { return std::this_thread::get_id(); } + + template struct thread_id_size { }; + template<> struct thread_id_size<4> { typedef std::uint32_t numeric_t; }; + template<> struct thread_id_size<8> { typedef std::uint64_t numeric_t; }; + + template<> struct thread_id_converter { + typedef thread_id_size::numeric_t thread_id_numeric_size_t; +#ifndef __APPLE__ + typedef std::size_t thread_id_hash_t; +#else + typedef thread_id_numeric_size_t thread_id_hash_t; +#endif + + static thread_id_hash_t prehash(thread_id_t const& x) + { +#ifndef __APPLE__ + return std::hash()(x); +#else + return *reinterpret_cast(&x); +#endif + } + }; +} } +#else +// Use a nice trick from this answer: http://stackoverflow.com/a/8438730/21475 +// In order to get a numeric thread ID in a platform-independent way, we use a thread-local +// static variable's address as a thread identifier :-) +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define MOODYCAMEL_THREADLOCAL __thread +#elif defined(_MSC_VER) +#define MOODYCAMEL_THREADLOCAL __declspec(thread) +#else +// Assume C++11 compliant compiler +#define MOODYCAMEL_THREADLOCAL thread_local +#endif +namespace moodycamel { namespace details { + typedef std::uintptr_t thread_id_t; + static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr + static const thread_id_t invalid_thread_id2 = 1; // Member accesses off a null pointer are also generally invalid. Plus it's not aligned. + static inline thread_id_t thread_id() { static MOODYCAMEL_THREADLOCAL int x; return reinterpret_cast(&x); } +} } +#endif + +// Exceptions +#ifndef MOODYCAMEL_EXCEPTIONS_ENABLED +#if (defined(_MSC_VER) && defined(_CPPUNWIND)) || (defined(__GNUC__) && defined(__EXCEPTIONS)) || (!defined(_MSC_VER) && !defined(__GNUC__)) +#define MOODYCAMEL_EXCEPTIONS_ENABLED +#endif +#endif +#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED +#define MOODYCAMEL_TRY try +#define MOODYCAMEL_CATCH(...) catch(__VA_ARGS__) +#define MOODYCAMEL_RETHROW throw +#define MOODYCAMEL_THROW(expr) throw (expr) +#else +#define MOODYCAMEL_TRY if (true) +#define MOODYCAMEL_CATCH(...) else if (false) +#define MOODYCAMEL_RETHROW +#define MOODYCAMEL_THROW(expr) +#endif + +#ifndef MOODYCAMEL_NOEXCEPT +#if !defined(MOODYCAMEL_EXCEPTIONS_ENABLED) +#define MOODYCAMEL_NOEXCEPT +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) true +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) true +#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1800 +// VS2012's std::is_nothrow_[move_]constructible is broken and returns true when it shouldn't :-( +// We have to assume *all* non-trivial constructors may throw on VS2012! +#define MOODYCAMEL_NOEXCEPT _NOEXCEPT +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value : std::is_trivially_copy_constructible::value) +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) +#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1900 +#define MOODYCAMEL_NOEXCEPT _NOEXCEPT +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value || std::is_nothrow_move_constructible::value : std::is_trivially_copy_constructible::value || std::is_nothrow_copy_constructible::value) +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) +#else +#define MOODYCAMEL_NOEXCEPT noexcept +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) noexcept(expr) +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) noexcept(expr) +#endif +#endif + +#ifndef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED +#ifdef MCDBGQ_USE_RELACY +#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED +#else +// VS2013 doesn't support `thread_local`, and MinGW-w64 w/ POSIX threading has a crippling bug: http://sourceforge.net/p/mingw-w64/bugs/445 +// g++ <=4.7 doesn't support thread_local either. +// Finally, iOS/ARM doesn't have support for it either, and g++/ARM allows it to compile but it's unconfirmed to actually work +#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && (!defined(__MINGW32__) && !defined(__MINGW64__) || !defined(__WINPTHREADS_VERSION)) && (!defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && (!defined(__APPLE__) || !TARGET_OS_IPHONE) && !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__) +// Assume `thread_local` is fully supported in all other C++11 compilers/platforms +//#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED // always disabled for now since several users report having problems with it on +#endif +#endif +#endif + +// VS2012 doesn't support deleted functions. +// In this case, we declare the function normally but don't define it. A link error will be generated if the function is called. +#ifndef MOODYCAMEL_DELETE_FUNCTION +#if defined(_MSC_VER) && _MSC_VER < 1800 +#define MOODYCAMEL_DELETE_FUNCTION +#else +#define MOODYCAMEL_DELETE_FUNCTION = delete +#endif +#endif + +// Compiler-specific likely/unlikely hints +namespace moodycamel { namespace details { +#if defined(__GNUC__) + static inline bool (likely)(bool x) { return __builtin_expect((x), true); } + static inline bool (unlikely)(bool x) { return __builtin_expect((x), false); } +#else + static inline bool (likely)(bool x) { return x; } + static inline bool (unlikely)(bool x) { return x; } +#endif +} } + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG +#include "internal/concurrentqueue_internal_debug.h" +#endif + +namespace moodycamel { +namespace details { + template + struct const_numeric_max { + static_assert(std::is_integral::value, "const_numeric_max can only be used with integers"); + static const T value = std::numeric_limits::is_signed + ? (static_cast(1) << (sizeof(T) * CHAR_BIT - 1)) - static_cast(1) + : static_cast(-1); + }; + +#if defined(__GLIBCXX__) + typedef ::max_align_t std_max_align_t; // libstdc++ forgot to add it to std:: for a while +#else + typedef std::max_align_t std_max_align_t; // Others (e.g. MSVC) insist it can *only* be accessed via std:: +#endif + + // Some platforms have incorrectly set max_align_t to a type with <8 bytes alignment even while supporting + // 8-byte aligned scalar values (*cough* 32-bit iOS). Work around this with our own union. See issue #64. + typedef union { + std_max_align_t x; + long long y; + void* z; + } max_align_t; +} + +// Default traits for the ConcurrentQueue. To change some of the +// traits without re-implementing all of them, inherit from this +// struct and shadow the declarations you wish to be different; +// since the traits are used as a template type parameter, the +// shadowed declarations will be used where defined, and the defaults +// otherwise. +struct ConcurrentQueueDefaultTraits +{ + // General-purpose size type. std::size_t is strongly recommended. + typedef std::size_t size_t; + + // The type used for the enqueue and dequeue indices. Must be at least as + // large as size_t. Should be significantly larger than the number of elements + // you expect to hold at once, especially if you have a high turnover rate; + // for example, on 32-bit x86, if you expect to have over a hundred million + // elements or pump several million elements through your queue in a very + // short space of time, using a 32-bit type *may* trigger a race condition. + // A 64-bit int type is recommended in that case, and in practice will + // prevent a race condition no matter the usage of the queue. Note that + // whether the queue is lock-free with a 64-int type depends on the whether + // std::atomic is lock-free, which is platform-specific. + typedef std::size_t index_t; + + // Internally, all elements are enqueued and dequeued from multi-element + // blocks; this is the smallest controllable unit. If you expect few elements + // but many producers, a smaller block size should be favoured. For few producers + // and/or many elements, a larger block size is preferred. A sane default + // is provided. Must be a power of 2. + static const size_t BLOCK_SIZE = 32; + + // For explicit producers (i.e. when using a producer token), the block is + // checked for being empty by iterating through a list of flags, one per element. + // For large block sizes, this is too inefficient, and switching to an atomic + // counter-based approach is faster. The switch is made for block sizes strictly + // larger than this threshold. + static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 32; + + // How many full blocks can be expected for a single explicit producer? This should + // reflect that number's maximum for optimal performance. Must be a power of 2. + static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 32; + + // How many full blocks can be expected for a single implicit producer? This should + // reflect that number's maximum for optimal performance. Must be a power of 2. + static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 32; + + // The initial size of the hash table mapping thread IDs to implicit producers. + // Note that the hash is resized every time it becomes half full. + // Must be a power of two, and either 0 or at least 1. If 0, implicit production + // (using the enqueue methods without an explicit producer token) is disabled. + static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 32; + + // Controls the number of items that an explicit consumer (i.e. one with a token) + // must consume before it causes all consumers to rotate and move on to the next + // internal queue. + static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256; + + // The maximum number of elements (inclusive) that can be enqueued to a sub-queue. + // Enqueue operations that would cause this limit to be surpassed will fail. Note + // that this limit is enforced at the block level (for performance reasons), i.e. + // it's rounded up to the nearest block size. + static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max::value; + + +#ifndef MCDBGQ_USE_RELACY + // Memory allocation can be customized if needed. + // malloc should return nullptr on failure, and handle alignment like std::malloc. +#if defined(malloc) || defined(free) + // Gah, this is 2015, stop defining macros that break standard code already! + // Work around malloc/free being special macros: + static inline void* WORKAROUND_malloc(size_t size) { return malloc(size); } + static inline void WORKAROUND_free(void* ptr) { return free(ptr); } + static inline void* (malloc)(size_t size) { return WORKAROUND_malloc(size); } + static inline void (free)(void* ptr) { return WORKAROUND_free(ptr); } +#else + static inline void* malloc(size_t size) { return std::malloc(size); } + static inline void free(void* ptr) { return std::free(ptr); } +#endif +#else + // Debug versions when running under the Relacy race detector (ignore + // these in user code) + static inline void* malloc(size_t size) { return rl::rl_malloc(size, $); } + static inline void free(void* ptr) { return rl::rl_free(ptr, $); } +#endif +}; + + +// When producing or consuming many elements, the most efficient way is to: +// 1) Use one of the bulk-operation methods of the queue with a token +// 2) Failing that, use the bulk-operation methods without a token +// 3) Failing that, create a token and use that with the single-item methods +// 4) Failing that, use the single-parameter methods of the queue +// Having said that, don't create tokens willy-nilly -- ideally there should be +// a maximum of one token per thread (of each kind). +struct ProducerToken; +struct ConsumerToken; + +template class ConcurrentQueue; +template class BlockingConcurrentQueue; +class ConcurrentQueueTests; + + +namespace details +{ + struct ConcurrentQueueProducerTypelessBase + { + ConcurrentQueueProducerTypelessBase* next; + std::atomic inactive; + ProducerToken* token; + + ConcurrentQueueProducerTypelessBase() + : next(nullptr), inactive(false), token(nullptr) + { + } + }; + + template struct _hash_32_or_64 { + static inline std::uint32_t hash(std::uint32_t h) + { + // MurmurHash3 finalizer -- see https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp + // Since the thread ID is already unique, all we really want to do is propagate that + // uniqueness evenly across all the bits, so that we can use a subset of the bits while + // reducing collisions significantly + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + return h ^ (h >> 16); + } + }; + template<> struct _hash_32_or_64<1> { + static inline std::uint64_t hash(std::uint64_t h) + { + h ^= h >> 33; + h *= 0xff51afd7ed558ccd; + h ^= h >> 33; + h *= 0xc4ceb9fe1a85ec53; + return h ^ (h >> 33); + } + }; + template struct hash_32_or_64 : public _hash_32_or_64<(size > 4)> { }; + + static inline size_t hash_thread_id(thread_id_t id) + { + static_assert(sizeof(thread_id_t) <= 8, "Expected a platform where thread IDs are at most 64-bit values"); + return static_cast(hash_32_or_64::thread_id_hash_t)>::hash( + thread_id_converter::prehash(id))); + } + + template + static inline bool circular_less_than(T a, T b) + { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4554) +#endif + static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "circular_less_than is intended to be used only with unsigned integer types"); + return static_cast(a - b) > static_cast(static_cast(1) << static_cast(sizeof(T) * CHAR_BIT - 1)); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + } + + template + static inline char* align_for(char* ptr) + { + const std::size_t alignment = std::alignment_of::value; + return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment; + } + + template + static inline T ceil_to_pow_2(T x) + { + static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "ceil_to_pow_2 is intended to be used only with unsigned integer types"); + + // Adapted from http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + for (std::size_t i = 1; i < sizeof(T); i <<= 1) { + x |= x >> (i << 3); + } + ++x; + return x; + } + + template + static inline void swap_relaxed(std::atomic& left, std::atomic& right) + { + T temp = std::move(left.load(std::memory_order_relaxed)); + left.store(std::move(right.load(std::memory_order_relaxed)), std::memory_order_relaxed); + right.store(std::move(temp), std::memory_order_relaxed); + } + + template + static inline T const& nomove(T const& x) + { + return x; + } + + template + struct nomove_if + { + template + static inline T const& eval(T const& x) + { + return x; + } + }; + + template<> + struct nomove_if + { + template + static inline auto eval(U&& x) + -> decltype(std::forward(x)) + { + return std::forward(x); + } + }; + + template + static inline auto deref_noexcept(It& it) MOODYCAMEL_NOEXCEPT -> decltype(*it) + { + return *it; + } + +#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + template struct is_trivially_destructible : std::is_trivially_destructible { }; +#else + template struct is_trivially_destructible : std::has_trivial_destructor { }; +#endif + +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED +#ifdef MCDBGQ_USE_RELACY + typedef RelacyThreadExitListener ThreadExitListener; + typedef RelacyThreadExitNotifier ThreadExitNotifier; +#else + struct ThreadExitListener + { + typedef void (*callback_t)(void*); + callback_t callback; + void* userData; + + ThreadExitListener* next; // reserved for use by the ThreadExitNotifier + }; + + + class ThreadExitNotifier + { + public: + static void subscribe(ThreadExitListener* listener) + { + auto& tlsInst = instance(); + listener->next = tlsInst.tail; + tlsInst.tail = listener; + } + + static void unsubscribe(ThreadExitListener* listener) + { + auto& tlsInst = instance(); + ThreadExitListener** prev = &tlsInst.tail; + for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) { + if (ptr == listener) { + *prev = ptr->next; + break; + } + prev = &ptr->next; + } + } + + private: + ThreadExitNotifier() : tail(nullptr) { } + ThreadExitNotifier(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; + ThreadExitNotifier& operator=(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; + + ~ThreadExitNotifier() + { + // This thread is about to exit, let everyone know! + assert(this == &instance() && "If this assert fails, you likely have a buggy compiler! Change the preprocessor conditions such that MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is no longer defined."); + for (auto ptr = tail; ptr != nullptr; ptr = ptr->next) { + ptr->callback(ptr->userData); + } + } + + // Thread-local + static inline ThreadExitNotifier& instance() + { + static thread_local ThreadExitNotifier notifier; + return notifier; + } + + private: + ThreadExitListener* tail; + }; +#endif +#endif + + template struct static_is_lock_free_num { enum { value = 0 }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_CHAR_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_SHORT_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_INT_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_LONG_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_LLONG_LOCK_FREE }; }; + template struct static_is_lock_free : static_is_lock_free_num::type> { }; + template<> struct static_is_lock_free { enum { value = ATOMIC_BOOL_LOCK_FREE }; }; + template struct static_is_lock_free { enum { value = ATOMIC_POINTER_LOCK_FREE }; }; +} + + +struct ProducerToken +{ + template + explicit ProducerToken(ConcurrentQueue& queue); + + template + explicit ProducerToken(BlockingConcurrentQueue& queue); + + ProducerToken(ProducerToken&& other) MOODYCAMEL_NOEXCEPT + : producer(other.producer) + { + other.producer = nullptr; + if (producer != nullptr) { + producer->token = this; + } + } + + inline ProducerToken& operator=(ProducerToken&& other) MOODYCAMEL_NOEXCEPT + { + swap(other); + return *this; + } + + void swap(ProducerToken& other) MOODYCAMEL_NOEXCEPT + { + std::swap(producer, other.producer); + if (producer != nullptr) { + producer->token = this; + } + if (other.producer != nullptr) { + other.producer->token = &other; + } + } + + // A token is always valid unless: + // 1) Memory allocation failed during construction + // 2) It was moved via the move constructor + // (Note: assignment does a swap, leaving both potentially valid) + // 3) The associated queue was destroyed + // Note that if valid() returns true, that only indicates + // that the token is valid for use with a specific queue, + // but not which one; that's up to the user to track. + inline bool valid() const { return producer != nullptr; } + + ~ProducerToken() + { + if (producer != nullptr) { + producer->token = nullptr; + producer->inactive.store(true, std::memory_order_release); + } + } + + // Disable copying and assignment + ProducerToken(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; + ProducerToken& operator=(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; + +private: + template friend class ConcurrentQueue; + friend class ConcurrentQueueTests; + +protected: + details::ConcurrentQueueProducerTypelessBase* producer; +}; + + +struct ConsumerToken +{ + template + explicit ConsumerToken(ConcurrentQueue& q); + + template + explicit ConsumerToken(BlockingConcurrentQueue& q); + + ConsumerToken(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT + : initialOffset(other.initialOffset), lastKnownGlobalOffset(other.lastKnownGlobalOffset), itemsConsumedFromCurrent(other.itemsConsumedFromCurrent), currentProducer(other.currentProducer), desiredProducer(other.desiredProducer) + { + } + + inline ConsumerToken& operator=(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT + { + swap(other); + return *this; + } + + void swap(ConsumerToken& other) MOODYCAMEL_NOEXCEPT + { + std::swap(initialOffset, other.initialOffset); + std::swap(lastKnownGlobalOffset, other.lastKnownGlobalOffset); + std::swap(itemsConsumedFromCurrent, other.itemsConsumedFromCurrent); + std::swap(currentProducer, other.currentProducer); + std::swap(desiredProducer, other.desiredProducer); + } + + // Disable copying and assignment + ConsumerToken(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; + ConsumerToken& operator=(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; + +private: + template friend class ConcurrentQueue; + friend class ConcurrentQueueTests; + +private: // but shared with ConcurrentQueue + std::uint32_t initialOffset; + std::uint32_t lastKnownGlobalOffset; + std::uint32_t itemsConsumedFromCurrent; + details::ConcurrentQueueProducerTypelessBase* currentProducer; + details::ConcurrentQueueProducerTypelessBase* desiredProducer; +}; + +// Need to forward-declare this swap because it's in a namespace. +// See http://stackoverflow.com/questions/4492062/why-does-a-c-friend-class-need-a-forward-declaration-only-in-other-namespaces +template +inline void swap(typename ConcurrentQueue::ImplicitProducerKVP& a, typename ConcurrentQueue::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT; + + +template +class ConcurrentQueue +{ +public: + typedef ::moodycamel::ProducerToken producer_token_t; + typedef ::moodycamel::ConsumerToken consumer_token_t; + + typedef typename Traits::index_t index_t; + typedef typename Traits::size_t size_t; + + static const size_t BLOCK_SIZE = static_cast(Traits::BLOCK_SIZE); + static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = static_cast(Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD); + static const size_t EXPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::EXPLICIT_INITIAL_INDEX_SIZE); + static const size_t IMPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::IMPLICIT_INITIAL_INDEX_SIZE); + static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = static_cast(Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE); + static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = static_cast(Traits::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE); +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4307) // + integral constant overflow (that's what the ternary expression is for!) +#pragma warning(disable: 4309) // static_cast: Truncation of constant value +#endif + static const size_t MAX_SUBQUEUE_SIZE = (details::const_numeric_max::value - static_cast(Traits::MAX_SUBQUEUE_SIZE) < BLOCK_SIZE) ? details::const_numeric_max::value : ((static_cast(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE - 1)) / BLOCK_SIZE * BLOCK_SIZE); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::size_t must be an unsigned integral type"); + static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::index_t must be an unsigned integral type"); + static_assert(sizeof(index_t) >= sizeof(size_t), "Traits::index_t must be at least as wide as Traits::size_t"); + static_assert((BLOCK_SIZE > 1) && !(BLOCK_SIZE & (BLOCK_SIZE - 1)), "Traits::BLOCK_SIZE must be a power of 2 (and at least 2)"); + static_assert((EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD > 1) && !(EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD & (EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD - 1)), "Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD must be a power of 2 (and greater than 1)"); + static_assert((EXPLICIT_INITIAL_INDEX_SIZE > 1) && !(EXPLICIT_INITIAL_INDEX_SIZE & (EXPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::EXPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); + static_assert((IMPLICIT_INITIAL_INDEX_SIZE > 1) && !(IMPLICIT_INITIAL_INDEX_SIZE & (IMPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::IMPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); + static_assert((INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) || !(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE & (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE - 1)), "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be a power of 2"); + static_assert(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0 || INITIAL_IMPLICIT_PRODUCER_HASH_SIZE >= 1, "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be at least 1 (or 0 to disable implicit enqueueing)"); + +public: + // Creates a queue with at least `capacity` element slots; note that the + // actual number of elements that can be inserted without additional memory + // allocation depends on the number of producers and the block size (e.g. if + // the block size is equal to `capacity`, only a single block will be allocated + // up-front, which means only a single producer will be able to enqueue elements + // without an extra allocation -- blocks aren't shared between producers). + // This method is not thread safe -- it is up to the user to ensure that the + // queue is fully constructed before it starts being used by other threads (this + // includes making the memory effects of construction visible, possibly with a + // memory barrier). + explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE) + : producerListTail(nullptr), + producerCount(0), + initialBlockPoolIndex(0), + nextExplicitConsumerId(0), + globalExplicitConsumerOffset(0) + { + implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); + populate_initial_implicit_producer_hash(); + populate_initial_block_list(capacity / BLOCK_SIZE + ((capacity & (BLOCK_SIZE - 1)) == 0 ? 0 : 1)); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + // Track all the producers using a fully-resolved typed list for + // each kind; this makes it possible to debug them starting from + // the root queue object (otherwise wacky casts are needed that + // don't compile in the debugger's expression evaluator). + explicitProducers.store(nullptr, std::memory_order_relaxed); + implicitProducers.store(nullptr, std::memory_order_relaxed); +#endif + } + + // Computes the correct amount of pre-allocated blocks for you based + // on the minimum number of elements you want available at any given + // time, and the maximum concurrent number of each type of producer. + ConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers) + : producerListTail(nullptr), + producerCount(0), + initialBlockPoolIndex(0), + nextExplicitConsumerId(0), + globalExplicitConsumerOffset(0) + { + implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); + populate_initial_implicit_producer_hash(); + size_t blocks = (((minCapacity + BLOCK_SIZE - 1) / BLOCK_SIZE) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers + maxImplicitProducers); + populate_initial_block_list(blocks); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + explicitProducers.store(nullptr, std::memory_order_relaxed); + implicitProducers.store(nullptr, std::memory_order_relaxed); +#endif + } + + // Note: The queue should not be accessed concurrently while it's + // being deleted. It's up to the user to synchronize this. + // This method is not thread safe. + ~ConcurrentQueue() + { + // Destroy producers + auto ptr = producerListTail.load(std::memory_order_relaxed); + while (ptr != nullptr) { + auto next = ptr->next_prod(); + if (ptr->token != nullptr) { + ptr->token->producer = nullptr; + } + destroy(ptr); + ptr = next; + } + + // Destroy implicit producer hash tables + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE != 0) { + auto hash = implicitProducerHash.load(std::memory_order_relaxed); + while (hash != nullptr) { + auto prev = hash->prev; + if (prev != nullptr) { // The last hash is part of this object and was not allocated dynamically + for (size_t i = 0; i != hash->capacity; ++i) { + hash->entries[i].~ImplicitProducerKVP(); + } + hash->~ImplicitProducerHash(); + (Traits::free)(hash); + } + hash = prev; + } + } + + // Destroy global free list + auto block = freeList.head_unsafe(); + while (block != nullptr) { + auto next = block->freeListNext.load(std::memory_order_relaxed); + if (block->dynamicallyAllocated) { + destroy(block); + } + block = next; + } + + // Destroy initial free list + destroy_array(initialBlockPool, initialBlockPoolSize); + } + + // Disable copying and copy assignment + ConcurrentQueue(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; + ConcurrentQueue& operator=(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; + + // Moving is supported, but note that it is *not* a thread-safe operation. + // Nobody can use the queue while it's being moved, and the memory effects + // of that move must be propagated to other threads before they can use it. + // Note: When a queue is moved, its tokens are still valid but can only be + // used with the destination queue (i.e. semantically they are moved along + // with the queue itself). + ConcurrentQueue(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT + : producerListTail(other.producerListTail.load(std::memory_order_relaxed)), + producerCount(other.producerCount.load(std::memory_order_relaxed)), + initialBlockPoolIndex(other.initialBlockPoolIndex.load(std::memory_order_relaxed)), + initialBlockPool(other.initialBlockPool), + initialBlockPoolSize(other.initialBlockPoolSize), + freeList(std::move(other.freeList)), + nextExplicitConsumerId(other.nextExplicitConsumerId.load(std::memory_order_relaxed)), + globalExplicitConsumerOffset(other.globalExplicitConsumerOffset.load(std::memory_order_relaxed)) + { + // Move the other one into this, and leave the other one as an empty queue + implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); + populate_initial_implicit_producer_hash(); + swap_implicit_producer_hashes(other); + + other.producerListTail.store(nullptr, std::memory_order_relaxed); + other.producerCount.store(0, std::memory_order_relaxed); + other.nextExplicitConsumerId.store(0, std::memory_order_relaxed); + other.globalExplicitConsumerOffset.store(0, std::memory_order_relaxed); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + explicitProducers.store(other.explicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); + other.explicitProducers.store(nullptr, std::memory_order_relaxed); + implicitProducers.store(other.implicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); + other.implicitProducers.store(nullptr, std::memory_order_relaxed); +#endif + + other.initialBlockPoolIndex.store(0, std::memory_order_relaxed); + other.initialBlockPoolSize = 0; + other.initialBlockPool = nullptr; + + reown_producers(); + } + + inline ConcurrentQueue& operator=(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT + { + return swap_internal(other); + } + + // Swaps this queue's state with the other's. Not thread-safe. + // Swapping two queues does not invalidate their tokens, however + // the tokens that were created for one queue must be used with + // only the swapped queue (i.e. the tokens are tied to the + // queue's movable state, not the object itself). + inline void swap(ConcurrentQueue& other) MOODYCAMEL_NOEXCEPT + { + swap_internal(other); + } + +private: + ConcurrentQueue& swap_internal(ConcurrentQueue& other) + { + if (this == &other) { + return *this; + } + + details::swap_relaxed(producerListTail, other.producerListTail); + details::swap_relaxed(producerCount, other.producerCount); + details::swap_relaxed(initialBlockPoolIndex, other.initialBlockPoolIndex); + std::swap(initialBlockPool, other.initialBlockPool); + std::swap(initialBlockPoolSize, other.initialBlockPoolSize); + freeList.swap(other.freeList); + details::swap_relaxed(nextExplicitConsumerId, other.nextExplicitConsumerId); + details::swap_relaxed(globalExplicitConsumerOffset, other.globalExplicitConsumerOffset); + + swap_implicit_producer_hashes(other); + + reown_producers(); + other.reown_producers(); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + details::swap_relaxed(explicitProducers, other.explicitProducers); + details::swap_relaxed(implicitProducers, other.implicitProducers); +#endif + + return *this; + } + +public: + // Enqueues a single item (by copying it). + // Allocates memory if required. Only fails if memory allocation fails (or implicit + // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, + // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). + // Thread-safe. + inline bool enqueue(T const& item) + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; + return inner_enqueue(item); + } + + // Enqueues a single item (by moving it, if possible). + // Allocates memory if required. Only fails if memory allocation fails (or implicit + // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, + // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). + // Thread-safe. + inline bool enqueue(T&& item) + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; + return inner_enqueue(std::move(item)); + } + + // Enqueues a single item (by copying it) using an explicit producer token. + // Allocates memory if required. Only fails if memory allocation fails (or + // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). + // Thread-safe. + inline bool enqueue(producer_token_t const& token, T const& item) + { + return inner_enqueue(token, item); + } + + // Enqueues a single item (by moving it, if possible) using an explicit producer token. + // Allocates memory if required. Only fails if memory allocation fails (or + // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). + // Thread-safe. + inline bool enqueue(producer_token_t const& token, T&& item) + { + return inner_enqueue(token, std::move(item)); + } + + // Enqueues several items. + // Allocates memory if required. Only fails if memory allocation fails (or + // implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE + // is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). + // Note: Use std::make_move_iterator if the elements should be moved instead of copied. + // Thread-safe. + template + bool enqueue_bulk(It itemFirst, size_t count) + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; + return inner_enqueue_bulk(itemFirst, count); + } + + // Enqueues several items using an explicit producer token. + // Allocates memory if required. Only fails if memory allocation fails + // (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). + // Note: Use std::make_move_iterator if the elements should be moved + // instead of copied. + // Thread-safe. + template + bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) + { + return inner_enqueue_bulk(token, itemFirst, count); + } + + // Enqueues a single item (by copying it). + // Does not allocate memory. Fails if not enough room to enqueue (or implicit + // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE + // is 0). + // Thread-safe. + inline bool try_enqueue(T const& item) + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; + return inner_enqueue(item); + } + + // Enqueues a single item (by moving it, if possible). + // Does not allocate memory (except for one-time implicit producer). + // Fails if not enough room to enqueue (or implicit production is + // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0). + // Thread-safe. + inline bool try_enqueue(T&& item) + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; + return inner_enqueue(std::move(item)); + } + + // Enqueues a single item (by copying it) using an explicit producer token. + // Does not allocate memory. Fails if not enough room to enqueue. + // Thread-safe. + inline bool try_enqueue(producer_token_t const& token, T const& item) + { + return inner_enqueue(token, item); + } + + // Enqueues a single item (by moving it, if possible) using an explicit producer token. + // Does not allocate memory. Fails if not enough room to enqueue. + // Thread-safe. + inline bool try_enqueue(producer_token_t const& token, T&& item) + { + return inner_enqueue(token, std::move(item)); + } + + // Enqueues several items. + // Does not allocate memory (except for one-time implicit producer). + // Fails if not enough room to enqueue (or implicit production is + // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0). + // Note: Use std::make_move_iterator if the elements should be moved + // instead of copied. + // Thread-safe. + template + bool try_enqueue_bulk(It itemFirst, size_t count) + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; + return inner_enqueue_bulk(itemFirst, count); + } + + // Enqueues several items using an explicit producer token. + // Does not allocate memory. Fails if not enough room to enqueue. + // Note: Use std::make_move_iterator if the elements should be moved + // instead of copied. + // Thread-safe. + template + bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) + { + return inner_enqueue_bulk(token, itemFirst, count); + } + + + + // Attempts to dequeue from the queue. + // Returns false if all producer streams appeared empty at the time they + // were checked (so, the queue is likely but not guaranteed to be empty). + // Never allocates. Thread-safe. + template + bool try_dequeue(U& item) + { + // Instead of simply trying each producer in turn (which could cause needless contention on the first + // producer), we score them heuristically. + size_t nonEmptyCount = 0; + ProducerBase* best = nullptr; + size_t bestSize = 0; + for (auto ptr = producerListTail.load(std::memory_order_acquire); nonEmptyCount < 3 && ptr != nullptr; ptr = ptr->next_prod()) { + auto size = ptr->size_approx(); + if (size > 0) { + if (size > bestSize) { + bestSize = size; + best = ptr; + } + ++nonEmptyCount; + } + } + + // If there was at least one non-empty queue but it appears empty at the time + // we try to dequeue from it, we need to make sure every queue's been tried + if (nonEmptyCount > 0) { + if ((details::likely)(best->dequeue(item))) { + return true; + } + for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + if (ptr != best && ptr->dequeue(item)) { + return true; + } + } + } + return false; + } + + // Attempts to dequeue from the queue. + // Returns false if all producer streams appeared empty at the time they + // were checked (so, the queue is likely but not guaranteed to be empty). + // This differs from the try_dequeue(item) method in that this one does + // not attempt to reduce contention by interleaving the order that producer + // streams are dequeued from. So, using this method can reduce overall throughput + // under contention, but will give more predictable results in single-threaded + // consumer scenarios. This is mostly only useful for internal unit tests. + // Never allocates. Thread-safe. + template + bool try_dequeue_non_interleaved(U& item) + { + for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + if (ptr->dequeue(item)) { + return true; + } + } + return false; + } + + // Attempts to dequeue from the queue using an explicit consumer token. + // Returns false if all producer streams appeared empty at the time they + // were checked (so, the queue is likely but not guaranteed to be empty). + // Never allocates. Thread-safe. + template + bool try_dequeue(consumer_token_t& token, U& item) + { + // The idea is roughly as follows: + // Every 256 items from one producer, make everyone rotate (increase the global offset) -> this means the highest efficiency consumer dictates the rotation speed of everyone else, more or less + // If you see that the global offset has changed, you must reset your consumption counter and move to your designated place + // If there's no items where you're supposed to be, keep moving until you find a producer with some items + // If the global offset has not changed but you've run out of items to consume, move over from your current position until you find an producer with something in it + + if (token.desiredProducer == nullptr || token.lastKnownGlobalOffset != globalExplicitConsumerOffset.load(std::memory_order_relaxed)) { + if (!update_current_producer_after_rotation(token)) { + return false; + } + } + + // If there was at least one non-empty queue but it appears empty at the time + // we try to dequeue from it, we need to make sure every queue's been tried + if (static_cast(token.currentProducer)->dequeue(item)) { + if (++token.itemsConsumedFromCurrent == EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE) { + globalExplicitConsumerOffset.fetch_add(1, std::memory_order_relaxed); + } + return true; + } + + auto tail = producerListTail.load(std::memory_order_acquire); + auto ptr = static_cast(token.currentProducer)->next_prod(); + if (ptr == nullptr) { + ptr = tail; + } + while (ptr != static_cast(token.currentProducer)) { + if (ptr->dequeue(item)) { + token.currentProducer = ptr; + token.itemsConsumedFromCurrent = 1; + return true; + } + ptr = ptr->next_prod(); + if (ptr == nullptr) { + ptr = tail; + } + } + return false; + } + + // Attempts to dequeue several elements from the queue. + // Returns the number of items actually dequeued. + // Returns 0 if all producer streams appeared empty at the time they + // were checked (so, the queue is likely but not guaranteed to be empty). + // Never allocates. Thread-safe. + template + size_t try_dequeue_bulk(It itemFirst, size_t max) + { + size_t count = 0; + for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + count += ptr->dequeue_bulk(itemFirst, max - count); + if (count == max) { + break; + } + } + return count; + } + + // Attempts to dequeue several elements from the queue using an explicit consumer token. + // Returns the number of items actually dequeued. + // Returns 0 if all producer streams appeared empty at the time they + // were checked (so, the queue is likely but not guaranteed to be empty). + // Never allocates. Thread-safe. + template + size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max) + { + if (token.desiredProducer == nullptr || token.lastKnownGlobalOffset != globalExplicitConsumerOffset.load(std::memory_order_relaxed)) { + if (!update_current_producer_after_rotation(token)) { + return 0; + } + } + + size_t count = static_cast(token.currentProducer)->dequeue_bulk(itemFirst, max); + if (count == max) { + if ((token.itemsConsumedFromCurrent += static_cast(max)) >= EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE) { + globalExplicitConsumerOffset.fetch_add(1, std::memory_order_relaxed); + } + return max; + } + token.itemsConsumedFromCurrent += static_cast(count); + max -= count; + + auto tail = producerListTail.load(std::memory_order_acquire); + auto ptr = static_cast(token.currentProducer)->next_prod(); + if (ptr == nullptr) { + ptr = tail; + } + while (ptr != static_cast(token.currentProducer)) { + auto dequeued = ptr->dequeue_bulk(itemFirst, max); + count += dequeued; + if (dequeued != 0) { + token.currentProducer = ptr; + token.itemsConsumedFromCurrent = static_cast(dequeued); + } + if (dequeued == max) { + break; + } + max -= dequeued; + ptr = ptr->next_prod(); + if (ptr == nullptr) { + ptr = tail; + } + } + return count; + } + + + + // Attempts to dequeue from a specific producer's inner queue. + // If you happen to know which producer you want to dequeue from, this + // is significantly faster than using the general-case try_dequeue methods. + // Returns false if the producer's queue appeared empty at the time it + // was checked (so, the queue is likely but not guaranteed to be empty). + // Never allocates. Thread-safe. + template + inline bool try_dequeue_from_producer(producer_token_t const& producer, U& item) + { + return static_cast(producer.producer)->dequeue(item); + } + + // Attempts to dequeue several elements from a specific producer's inner queue. + // Returns the number of items actually dequeued. + // If you happen to know which producer you want to dequeue from, this + // is significantly faster than using the general-case try_dequeue methods. + // Returns 0 if the producer's queue appeared empty at the time it + // was checked (so, the queue is likely but not guaranteed to be empty). + // Never allocates. Thread-safe. + template + inline size_t try_dequeue_bulk_from_producer(producer_token_t const& producer, It itemFirst, size_t max) + { + return static_cast(producer.producer)->dequeue_bulk(itemFirst, max); + } + + + // Returns an estimate of the total number of elements currently in the queue. This + // estimate is only accurate if the queue has completely stabilized before it is called + // (i.e. all enqueue and dequeue operations have completed and their memory effects are + // visible on the calling thread, and no further operations start while this method is + // being called). + // Thread-safe. + size_t size_approx() const + { + size_t size = 0; + for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + size += ptr->size_approx(); + } + return size; + } + + + // Returns true if the underlying atomic variables used by + // the queue are lock-free (they should be on most platforms). + // Thread-safe. + static bool is_lock_free() + { + return + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::thread_id_numeric_size_t>::value == 2; + } + + +private: + friend struct ProducerToken; + friend struct ConsumerToken; + struct ExplicitProducer; + friend struct ExplicitProducer; + struct ImplicitProducer; + friend struct ImplicitProducer; + friend class ConcurrentQueueTests; + + enum AllocationMode { CanAlloc, CannotAlloc }; + + + /////////////////////////////// + // Queue methods + /////////////////////////////// + + template + inline bool inner_enqueue(producer_token_t const& token, U&& element) + { + return static_cast(token.producer)->ConcurrentQueue::ExplicitProducer::template enqueue(std::forward(element)); + } + + template + inline bool inner_enqueue(U&& element) + { + auto producer = get_or_add_implicit_producer(); + return producer == nullptr ? false : producer->ConcurrentQueue::ImplicitProducer::template enqueue(std::forward(element)); + } + + template + inline bool inner_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) + { + return static_cast(token.producer)->ConcurrentQueue::ExplicitProducer::template enqueue_bulk(itemFirst, count); + } + + template + inline bool inner_enqueue_bulk(It itemFirst, size_t count) + { + auto producer = get_or_add_implicit_producer(); + return producer == nullptr ? false : producer->ConcurrentQueue::ImplicitProducer::template enqueue_bulk(itemFirst, count); + } + + inline bool update_current_producer_after_rotation(consumer_token_t& token) + { + // Ah, there's been a rotation, figure out where we should be! + auto tail = producerListTail.load(std::memory_order_acquire); + if (token.desiredProducer == nullptr && tail == nullptr) { + return false; + } + auto prodCount = producerCount.load(std::memory_order_relaxed); + auto globalOffset = globalExplicitConsumerOffset.load(std::memory_order_relaxed); + if ((details::unlikely)(token.desiredProducer == nullptr)) { + // Aha, first time we're dequeueing anything. + // Figure out our local position + // Note: offset is from start, not end, but we're traversing from end -- subtract from count first + std::uint32_t offset = prodCount - 1 - (token.initialOffset % prodCount); + token.desiredProducer = tail; + for (std::uint32_t i = 0; i != offset; ++i) { + token.desiredProducer = static_cast(token.desiredProducer)->next_prod(); + if (token.desiredProducer == nullptr) { + token.desiredProducer = tail; + } + } + } + + std::uint32_t delta = globalOffset - token.lastKnownGlobalOffset; + if (delta >= prodCount) { + delta = delta % prodCount; + } + for (std::uint32_t i = 0; i != delta; ++i) { + token.desiredProducer = static_cast(token.desiredProducer)->next_prod(); + if (token.desiredProducer == nullptr) { + token.desiredProducer = tail; + } + } + + token.lastKnownGlobalOffset = globalOffset; + token.currentProducer = token.desiredProducer; + token.itemsConsumedFromCurrent = 0; + return true; + } + + + /////////////////////////// + // Free list + /////////////////////////// + + template + struct FreeListNode + { + FreeListNode() : freeListRefs(0), freeListNext(nullptr) { } + + std::atomic freeListRefs; + std::atomic freeListNext; + }; + + // A simple CAS-based lock-free free list. Not the fastest thing in the world under heavy contention, but + // simple and correct (assuming nodes are never freed until after the free list is destroyed), and fairly + // speedy under low contention. + template // N must inherit FreeListNode or have the same fields (and initialization of them) + struct FreeList + { + FreeList() : freeListHead(nullptr) { } + FreeList(FreeList&& other) : freeListHead(other.freeListHead.load(std::memory_order_relaxed)) { other.freeListHead.store(nullptr, std::memory_order_relaxed); } + void swap(FreeList& other) { details::swap_relaxed(freeListHead, other.freeListHead); } + + FreeList(FreeList const&) MOODYCAMEL_DELETE_FUNCTION; + FreeList& operator=(FreeList const&) MOODYCAMEL_DELETE_FUNCTION; + + inline void add(N* node) + { +#if MCDBGQ_NOLOCKFREE_FREELIST + debug::DebugLock lock(mutex); +#endif + // We know that the should-be-on-freelist bit is 0 at this point, so it's safe to + // set it using a fetch_add + if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST, std::memory_order_acq_rel) == 0) { + // Oh look! We were the last ones referencing this node, and we know + // we want to add it to the free list, so let's do it! + add_knowing_refcount_is_zero(node); + } + } + + inline N* try_get() + { +#if MCDBGQ_NOLOCKFREE_FREELIST + debug::DebugLock lock(mutex); +#endif + auto head = freeListHead.load(std::memory_order_acquire); + while (head != nullptr) { + auto prevHead = head; + auto refs = head->freeListRefs.load(std::memory_order_relaxed); + if ((refs & REFS_MASK) == 0 || !head->freeListRefs.compare_exchange_strong(refs, refs + 1, std::memory_order_acquire, std::memory_order_relaxed)) { + head = freeListHead.load(std::memory_order_acquire); + continue; + } + + // Good, reference count has been incremented (it wasn't at zero), which means we can read the + // next and not worry about it changing between now and the time we do the CAS + auto next = head->freeListNext.load(std::memory_order_relaxed); + if (freeListHead.compare_exchange_strong(head, next, std::memory_order_acquire, std::memory_order_relaxed)) { + // Yay, got the node. This means it was on the list, which means shouldBeOnFreeList must be false no + // matter the refcount (because nobody else knows it's been taken off yet, it can't have been put back on). + assert((head->freeListRefs.load(std::memory_order_relaxed) & SHOULD_BE_ON_FREELIST) == 0); + + // Decrease refcount twice, once for our ref, and once for the list's ref + head->freeListRefs.fetch_sub(2, std::memory_order_release); + return head; + } + + // OK, the head must have changed on us, but we still need to decrease the refcount we increased. + // Note that we don't need to release any memory effects, but we do need to ensure that the reference + // count decrement happens-after the CAS on the head. + refs = prevHead->freeListRefs.fetch_sub(1, std::memory_order_acq_rel); + if (refs == SHOULD_BE_ON_FREELIST + 1) { + add_knowing_refcount_is_zero(prevHead); + } + } + + return nullptr; + } + + // Useful for traversing the list when there's no contention (e.g. to destroy remaining nodes) + N* head_unsafe() const { return freeListHead.load(std::memory_order_relaxed); } + + private: + inline void add_knowing_refcount_is_zero(N* node) + { + // Since the refcount is zero, and nobody can increase it once it's zero (except us, and we run + // only one copy of this method per node at a time, i.e. the single thread case), then we know + // we can safely change the next pointer of the node; however, once the refcount is back above + // zero, then other threads could increase it (happens under heavy contention, when the refcount + // goes to zero in between a load and a refcount increment of a node in try_get, then back up to + // something non-zero, then the refcount increment is done by the other thread) -- so, if the CAS + // to add the node to the actual list fails, decrease the refcount and leave the add operation to + // the next thread who puts the refcount back at zero (which could be us, hence the loop). + auto head = freeListHead.load(std::memory_order_relaxed); + while (true) { + node->freeListNext.store(head, std::memory_order_relaxed); + node->freeListRefs.store(1, std::memory_order_release); + if (!freeListHead.compare_exchange_strong(head, node, std::memory_order_release, std::memory_order_relaxed)) { + // Hmm, the add failed, but we can only try again when the refcount goes back to zero + if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST - 1, std::memory_order_release) == 1) { + continue; + } + } + return; + } + } + + private: + // Implemented like a stack, but where node order doesn't matter (nodes are inserted out of order under contention) + std::atomic freeListHead; + + static const std::uint32_t REFS_MASK = 0x7FFFFFFF; + static const std::uint32_t SHOULD_BE_ON_FREELIST = 0x80000000; + +#if MCDBGQ_NOLOCKFREE_FREELIST + debug::DebugMutex mutex; +#endif + }; + + + /////////////////////////// + // Block + /////////////////////////// + + enum InnerQueueContext { implicit_context = 0, explicit_context = 1 }; + + struct Block + { + Block() + : next(nullptr), elementsCompletelyDequeued(0), freeListRefs(0), freeListNext(nullptr), shouldBeOnFreeList(false), dynamicallyAllocated(true) + { +#if MCDBGQ_TRACKMEM + owner = nullptr; +#endif + } + + template + inline bool is_empty() const + { + if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { + // Check flags + for (size_t i = 0; i < BLOCK_SIZE; ++i) { + if (!emptyFlags[i].load(std::memory_order_relaxed)) { + return false; + } + } + + // Aha, empty; make sure we have all other memory effects that happened before the empty flags were set + std::atomic_thread_fence(std::memory_order_acquire); + return true; + } + else { + // Check counter + if (elementsCompletelyDequeued.load(std::memory_order_relaxed) == BLOCK_SIZE) { + std::atomic_thread_fence(std::memory_order_acquire); + return true; + } + assert(elementsCompletelyDequeued.load(std::memory_order_relaxed) <= BLOCK_SIZE); + return false; + } + } + + // Returns true if the block is now empty (does not apply in explicit context) + template + inline bool set_empty(index_t i) + { + if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { + // Set flag + assert(!emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].load(std::memory_order_relaxed)); + emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].store(true, std::memory_order_release); + return false; + } + else { + // Increment counter + auto prevVal = elementsCompletelyDequeued.fetch_add(1, std::memory_order_release); + assert(prevVal < BLOCK_SIZE); + return prevVal == BLOCK_SIZE - 1; + } + } + + // Sets multiple contiguous item statuses to 'empty' (assumes no wrapping and count > 0). + // Returns true if the block is now empty (does not apply in explicit context). + template + inline bool set_many_empty(index_t i, size_t count) + { + if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { + // Set flags + std::atomic_thread_fence(std::memory_order_release); + i = BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1)) - count + 1; + for (size_t j = 0; j != count; ++j) { + assert(!emptyFlags[i + j].load(std::memory_order_relaxed)); + emptyFlags[i + j].store(true, std::memory_order_relaxed); + } + return false; + } + else { + // Increment counter + auto prevVal = elementsCompletelyDequeued.fetch_add(count, std::memory_order_release); + assert(prevVal + count <= BLOCK_SIZE); + return prevVal + count == BLOCK_SIZE; + } + } + + template + inline void set_all_empty() + { + if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { + // Set all flags + for (size_t i = 0; i != BLOCK_SIZE; ++i) { + emptyFlags[i].store(true, std::memory_order_relaxed); + } + } + else { + // Reset counter + elementsCompletelyDequeued.store(BLOCK_SIZE, std::memory_order_relaxed); + } + } + + template + inline void reset_empty() + { + if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { + // Reset flags + for (size_t i = 0; i != BLOCK_SIZE; ++i) { + emptyFlags[i].store(false, std::memory_order_relaxed); + } + } + else { + // Reset counter + elementsCompletelyDequeued.store(0, std::memory_order_relaxed); + } + } + + inline T* operator[](index_t idx) MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); } + inline T const* operator[](index_t idx) const MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); } + + private: + // IMPORTANT: This must be the first member in Block, so that if T depends on the alignment of + // addresses returned by malloc, that alignment will be preserved. Apparently clang actually + // generates code that uses this assumption for AVX instructions in some cases. Ideally, we + // should also align Block to the alignment of T in case it's higher than malloc's 16-byte + // alignment, but this is hard to do in a cross-platform way. Assert for this case: + static_assert(std::alignment_of::value <= std::alignment_of::value, "The queue does not support super-aligned types at this time"); + // Additionally, we need the alignment of Block itself to be a multiple of max_align_t since + // otherwise the appropriate padding will not be added at the end of Block in order to make + // arrays of Blocks all be properly aligned (not just the first one). We use a union to force + // this. + union { + char elements[sizeof(T) * BLOCK_SIZE]; + details::max_align_t dummy; + }; + public: + Block* next; + std::atomic elementsCompletelyDequeued; + std::atomic emptyFlags[BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD ? BLOCK_SIZE : 1]; + public: + std::atomic freeListRefs; + std::atomic freeListNext; + std::atomic shouldBeOnFreeList; + bool dynamicallyAllocated; // Perhaps a better name for this would be 'isNotPartOfInitialBlockPool' + +#if MCDBGQ_TRACKMEM + void* owner; +#endif + }; + static_assert(std::alignment_of::value >= std::alignment_of::value, "Internal error: Blocks must be at least as aligned as the type they are wrapping"); + + +#if MCDBGQ_TRACKMEM +public: + struct MemStats; +private: +#endif + + /////////////////////////// + // Producer base + /////////////////////////// + + struct ProducerBase : public details::ConcurrentQueueProducerTypelessBase + { + ProducerBase(ConcurrentQueue* parent_, bool isExplicit_) : + tailIndex(0), + headIndex(0), + dequeueOptimisticCount(0), + dequeueOvercommit(0), + tailBlock(nullptr), + isExplicit(isExplicit_), + parent(parent_) + { + } + + virtual ~ProducerBase() { }; + + template + inline bool dequeue(U& element) + { + if (isExplicit) { + return static_cast(this)->dequeue(element); + } + else { + return static_cast(this)->dequeue(element); + } + } + + template + inline size_t dequeue_bulk(It& itemFirst, size_t max) + { + if (isExplicit) { + return static_cast(this)->dequeue_bulk(itemFirst, max); + } + else { + return static_cast(this)->dequeue_bulk(itemFirst, max); + } + } + + inline ProducerBase* next_prod() const { return static_cast(next); } + + inline size_t size_approx() const + { + auto tail = tailIndex.load(std::memory_order_relaxed); + auto head = headIndex.load(std::memory_order_relaxed); + return details::circular_less_than(head, tail) ? static_cast(tail - head) : 0; + } + + inline index_t getTail() const { return tailIndex.load(std::memory_order_relaxed); } + protected: + std::atomic tailIndex; // Where to enqueue to next + std::atomic headIndex; // Where to dequeue from next + + std::atomic dequeueOptimisticCount; + std::atomic dequeueOvercommit; + + Block* tailBlock; + + public: + bool isExplicit; + ConcurrentQueue* parent; + + protected: +#if MCDBGQ_TRACKMEM + friend struct MemStats; +#endif + }; + + + /////////////////////////// + // Explicit queue + /////////////////////////// + + struct ExplicitProducer : public ProducerBase + { + explicit ExplicitProducer(ConcurrentQueue* parent) : + ProducerBase(parent, true), + blockIndex(nullptr), + pr_blockIndexSlotsUsed(0), + pr_blockIndexSize(EXPLICIT_INITIAL_INDEX_SIZE >> 1), + pr_blockIndexFront(0), + pr_blockIndexEntries(nullptr), + pr_blockIndexRaw(nullptr) + { + size_t poolBasedIndexSize = details::ceil_to_pow_2(parent->initialBlockPoolSize) >> 1; + if (poolBasedIndexSize > pr_blockIndexSize) { + pr_blockIndexSize = poolBasedIndexSize; + } + + new_block_index(0); // This creates an index with double the number of current entries, i.e. EXPLICIT_INITIAL_INDEX_SIZE + } + + ~ExplicitProducer() + { + // Destruct any elements not yet dequeued. + // Since we're in the destructor, we can assume all elements + // are either completely dequeued or completely not (no halfways). + if (this->tailBlock != nullptr) { // Note this means there must be a block index too + // First find the block that's partially dequeued, if any + Block* halfDequeuedBlock = nullptr; + if ((this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) != 0) { + // The head's not on a block boundary, meaning a block somewhere is partially dequeued + // (or the head block is the tail block and was fully dequeued, but the head/tail are still not on a boundary) + size_t i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & (pr_blockIndexSize - 1); + while (details::circular_less_than(pr_blockIndexEntries[i].base + BLOCK_SIZE, this->headIndex.load(std::memory_order_relaxed))) { + i = (i + 1) & (pr_blockIndexSize - 1); + } + assert(details::circular_less_than(pr_blockIndexEntries[i].base, this->headIndex.load(std::memory_order_relaxed))); + halfDequeuedBlock = pr_blockIndexEntries[i].block; + } + + // Start at the head block (note the first line in the loop gives us the head from the tail on the first iteration) + auto block = this->tailBlock; + do { + block = block->next; + if (block->ConcurrentQueue::Block::template is_empty()) { + continue; + } + + size_t i = 0; // Offset into block + if (block == halfDequeuedBlock) { + i = static_cast(this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)); + } + + // Walk through all the items in the block; if this is the tail block, we need to stop when we reach the tail index + auto lastValidIndex = (this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) == 0 ? BLOCK_SIZE : static_cast(this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)); + while (i != BLOCK_SIZE && (block != this->tailBlock || i != lastValidIndex)) { + (*block)[i++]->~T(); + } + } while (block != this->tailBlock); + } + + // Destroy all blocks that we own + if (this->tailBlock != nullptr) { + auto block = this->tailBlock; + do { + auto nextBlock = block->next; + if (block->dynamicallyAllocated) { + destroy(block); + } + else { + this->parent->add_block_to_free_list(block); + } + block = nextBlock; + } while (block != this->tailBlock); + } + + // Destroy the block indices + auto header = static_cast(pr_blockIndexRaw); + while (header != nullptr) { + auto prev = static_cast(header->prev); + header->~BlockIndexHeader(); + (Traits::free)(header); + header = prev; + } + } + + template + inline bool enqueue(U&& element) + { + index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed); + index_t newTailIndex = 1 + currentTailIndex; + if ((currentTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { + // We reached the end of a block, start a new one + auto startBlock = this->tailBlock; + auto originalBlockIndexSlotsUsed = pr_blockIndexSlotsUsed; + if (this->tailBlock != nullptr && this->tailBlock->next->ConcurrentQueue::Block::template is_empty()) { + // We can re-use the block ahead of us, it's empty! + this->tailBlock = this->tailBlock->next; + this->tailBlock->ConcurrentQueue::Block::template reset_empty(); + + // We'll put the block on the block index (guaranteed to be room since we're conceptually removing the + // last block from it first -- except instead of removing then adding, we can just overwrite). + // Note that there must be a valid block index here, since even if allocation failed in the ctor, + // it would have been re-attempted when adding the first block to the queue; since there is such + // a block, a block index must have been successfully allocated. + } + else { + // Whatever head value we see here is >= the last value we saw here (relatively), + // and <= its current value. Since we have the most recent tail, the head must be + // <= to it. + auto head = this->headIndex.load(std::memory_order_relaxed); + assert(!details::circular_less_than(currentTailIndex, head)); + if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) + || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) { + // We can't enqueue in another block because there's not enough leeway -- the + // tail could surpass the head by the time the block fills up! (Or we'll exceed + // the size limit, if the second part of the condition was true.) + return false; + } + // We're going to need a new block; check that the block index has room + if (pr_blockIndexRaw == nullptr || pr_blockIndexSlotsUsed == pr_blockIndexSize) { + // Hmm, the circular block index is already full -- we'll need + // to allocate a new index. Note pr_blockIndexRaw can only be nullptr if + // the initial allocation failed in the constructor. + + if (allocMode == CannotAlloc || !new_block_index(pr_blockIndexSlotsUsed)) { + return false; + } + } + + // Insert a new block in the circular linked list + auto newBlock = this->parent->ConcurrentQueue::template requisition_block(); + if (newBlock == nullptr) { + return false; + } +#if MCDBGQ_TRACKMEM + newBlock->owner = this; +#endif + newBlock->ConcurrentQueue::Block::template reset_empty(); + if (this->tailBlock == nullptr) { + newBlock->next = newBlock; + } + else { + newBlock->next = this->tailBlock->next; + this->tailBlock->next = newBlock; + } + this->tailBlock = newBlock; + ++pr_blockIndexSlotsUsed; + } + + if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { + // The constructor may throw. We want the element not to appear in the queue in + // that case (without corrupting the queue): + MOODYCAMEL_TRY { + new ((*this->tailBlock)[currentTailIndex]) T(std::forward(element)); + } + MOODYCAMEL_CATCH (...) { + // Revert change to the current block, but leave the new block available + // for next time + pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; + this->tailBlock = startBlock == nullptr ? this->tailBlock : startBlock; + MOODYCAMEL_RETHROW; + } + } + else { + (void)startBlock; + (void)originalBlockIndexSlotsUsed; + } + + // Add block to block index + auto& entry = blockIndex.load(std::memory_order_relaxed)->entries[pr_blockIndexFront]; + entry.base = currentTailIndex; + entry.block = this->tailBlock; + blockIndex.load(std::memory_order_relaxed)->front.store(pr_blockIndexFront, std::memory_order_release); + pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1); + + if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { + this->tailIndex.store(newTailIndex, std::memory_order_release); + return true; + } + } + + // Enqueue + new ((*this->tailBlock)[currentTailIndex]) T(std::forward(element)); + + this->tailIndex.store(newTailIndex, std::memory_order_release); + return true; + } + + template + bool dequeue(U& element) + { + auto tail = this->tailIndex.load(std::memory_order_relaxed); + auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); + if (details::circular_less_than(this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit, tail)) { + // Might be something to dequeue, let's give it a try + + // Note that this if is purely for performance purposes in the common case when the queue is + // empty and the values are eventually consistent -- we may enter here spuriously. + + // Note that whatever the values of overcommit and tail are, they are not going to change (unless we + // change them) and must be the same value at this point (inside the if) as when the if condition was + // evaluated. + + // We insert an acquire fence here to synchronize-with the release upon incrementing dequeueOvercommit below. + // This ensures that whatever the value we got loaded into overcommit, the load of dequeueOptisticCount in + // the fetch_add below will result in a value at least as recent as that (and therefore at least as large). + // Note that I believe a compiler (signal) fence here would be sufficient due to the nature of fetch_add (all + // read-modify-write operations are guaranteed to work on the latest value in the modification order), but + // unfortunately that can't be shown to be correct using only the C++11 standard. + // See http://stackoverflow.com/questions/18223161/what-are-the-c11-memory-ordering-guarantees-in-this-corner-case + std::atomic_thread_fence(std::memory_order_acquire); + + // Increment optimistic counter, then check if it went over the boundary + auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(1, std::memory_order_relaxed); + + // Note that since dequeueOvercommit must be <= dequeueOptimisticCount (because dequeueOvercommit is only ever + // incremented after dequeueOptimisticCount -- this is enforced in the `else` block below), and since we now + // have a version of dequeueOptimisticCount that is at least as recent as overcommit (due to the release upon + // incrementing dequeueOvercommit and the acquire above that synchronizes with it), overcommit <= myDequeueCount. + // However, we can't assert this since both dequeueOptimisticCount and dequeueOvercommit may (independently) + // overflow; in such a case, though, the logic still holds since the difference between the two is maintained. + + // Note that we reload tail here in case it changed; it will be the same value as before or greater, since + // this load is sequenced after (happens after) the earlier load above. This is supported by read-read + // coherency (as defined in the standard), explained here: http://en.cppreference.com/w/cpp/atomic/memory_order + tail = this->tailIndex.load(std::memory_order_acquire); + if ((details::likely)(details::circular_less_than(myDequeueCount - overcommit, tail))) { + // Guaranteed to be at least one element to dequeue! + + // Get the index. Note that since there's guaranteed to be at least one element, this + // will never exceed tail. We need to do an acquire-release fence here since it's possible + // that whatever condition got us to this point was for an earlier enqueued element (that + // we already see the memory effects for), but that by the time we increment somebody else + // has incremented it, and we need to see the memory effects for *that* element, which is + // in such a case is necessarily visible on the thread that incremented it in the first + // place with the more current condition (they must have acquired a tail that is at least + // as recent). + auto index = this->headIndex.fetch_add(1, std::memory_order_acq_rel); + + + // Determine which block the element is in + + auto localBlockIndex = blockIndex.load(std::memory_order_acquire); + auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire); + + // We need to be careful here about subtracting and dividing because of index wrap-around. + // When an index wraps, we need to preserve the sign of the offset when dividing it by the + // block size (in order to get a correct signed block count offset in all cases): + auto headBase = localBlockIndex->entries[localBlockIndexHead].base; + auto blockBaseIndex = index & ~static_cast(BLOCK_SIZE - 1); + auto offset = static_cast(static_cast::type>(blockBaseIndex - headBase) / BLOCK_SIZE); + auto block = localBlockIndex->entries[(localBlockIndexHead + offset) & (localBlockIndex->size - 1)].block; + + // Dequeue + auto& el = *((*block)[index]); + if (!MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, element = std::move(el))) { + // Make sure the element is still fully dequeued and destroyed even if the assignment + // throws + struct Guard { + Block* block; + index_t index; + + ~Guard() + { + (*block)[index]->~T(); + block->ConcurrentQueue::Block::template set_empty(index); + } + } guard = { block, index }; + + element = std::move(el); + } + else { + element = std::move(el); + el.~T(); + block->ConcurrentQueue::Block::template set_empty(index); + } + + return true; + } + else { + // Wasn't anything to dequeue after all; make the effective dequeue count eventually consistent + this->dequeueOvercommit.fetch_add(1, std::memory_order_release); // Release so that the fetch_add on dequeueOptimisticCount is guaranteed to happen before this write + } + } + + return false; + } + + template + bool enqueue_bulk(It itemFirst, size_t count) + { + // First, we need to make sure we have enough room to enqueue all of the elements; + // this means pre-allocating blocks and putting them in the block index (but only if + // all the allocations succeeded). + index_t startTailIndex = this->tailIndex.load(std::memory_order_relaxed); + auto startBlock = this->tailBlock; + auto originalBlockIndexFront = pr_blockIndexFront; + auto originalBlockIndexSlotsUsed = pr_blockIndexSlotsUsed; + + Block* firstAllocatedBlock = nullptr; + + // Figure out how many blocks we'll need to allocate, and do so + size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1)); + index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); + if (blockBaseDiff > 0) { + // Allocate as many blocks as possible from ahead + while (blockBaseDiff > 0 && this->tailBlock != nullptr && this->tailBlock->next != firstAllocatedBlock && this->tailBlock->next->ConcurrentQueue::Block::template is_empty()) { + blockBaseDiff -= static_cast(BLOCK_SIZE); + currentTailIndex += static_cast(BLOCK_SIZE); + + this->tailBlock = this->tailBlock->next; + firstAllocatedBlock = firstAllocatedBlock == nullptr ? this->tailBlock : firstAllocatedBlock; + + auto& entry = blockIndex.load(std::memory_order_relaxed)->entries[pr_blockIndexFront]; + entry.base = currentTailIndex; + entry.block = this->tailBlock; + pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1); + } + + // Now allocate as many blocks as necessary from the block pool + while (blockBaseDiff > 0) { + blockBaseDiff -= static_cast(BLOCK_SIZE); + currentTailIndex += static_cast(BLOCK_SIZE); + + auto head = this->headIndex.load(std::memory_order_relaxed); + assert(!details::circular_less_than(currentTailIndex, head)); + bool full = !details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head)); + if (pr_blockIndexRaw == nullptr || pr_blockIndexSlotsUsed == pr_blockIndexSize || full) { + if (allocMode == CannotAlloc || full || !new_block_index(originalBlockIndexSlotsUsed)) { + // Failed to allocate, undo changes (but keep injected blocks) + pr_blockIndexFront = originalBlockIndexFront; + pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; + this->tailBlock = startBlock == nullptr ? firstAllocatedBlock : startBlock; + return false; + } + + // pr_blockIndexFront is updated inside new_block_index, so we need to + // update our fallback value too (since we keep the new index even if we + // later fail) + originalBlockIndexFront = originalBlockIndexSlotsUsed; + } + + // Insert a new block in the circular linked list + auto newBlock = this->parent->ConcurrentQueue::template requisition_block(); + if (newBlock == nullptr) { + pr_blockIndexFront = originalBlockIndexFront; + pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; + this->tailBlock = startBlock == nullptr ? firstAllocatedBlock : startBlock; + return false; + } + +#if MCDBGQ_TRACKMEM + newBlock->owner = this; +#endif + newBlock->ConcurrentQueue::Block::template set_all_empty(); + if (this->tailBlock == nullptr) { + newBlock->next = newBlock; + } + else { + newBlock->next = this->tailBlock->next; + this->tailBlock->next = newBlock; + } + this->tailBlock = newBlock; + firstAllocatedBlock = firstAllocatedBlock == nullptr ? this->tailBlock : firstAllocatedBlock; + + ++pr_blockIndexSlotsUsed; + + auto& entry = blockIndex.load(std::memory_order_relaxed)->entries[pr_blockIndexFront]; + entry.base = currentTailIndex; + entry.block = this->tailBlock; + pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1); + } + + // Excellent, all allocations succeeded. Reset each block's emptiness before we fill them up, and + // publish the new block index front + auto block = firstAllocatedBlock; + while (true) { + block->ConcurrentQueue::Block::template reset_empty(); + if (block == this->tailBlock) { + break; + } + block = block->next; + } + + if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) { + blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release); + } + } + + // Enqueue, one block at a time + index_t newTailIndex = startTailIndex + static_cast(count); + currentTailIndex = startTailIndex; + auto endBlock = this->tailBlock; + this->tailBlock = startBlock; + assert((startTailIndex & static_cast(BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock != nullptr || count == 0); + if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0 && firstAllocatedBlock != nullptr) { + this->tailBlock = firstAllocatedBlock; + } + while (true) { + auto stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + if (details::circular_less_than(newTailIndex, stopIndex)) { + stopIndex = newTailIndex; + } + if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) { + while (currentTailIndex != stopIndex) { + new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++); + } + } + else { + MOODYCAMEL_TRY { + while (currentTailIndex != stopIndex) { + // Must use copy constructor even if move constructor is available + // because we may have to revert if there's an exception. + // Sorry about the horrible templated next line, but it was the only way + // to disable moving *at compile time*, which is important because a type + // may only define a (noexcept) move constructor, and so calls to the + // cctor will not compile, even if they are in an if branch that will never + // be executed + new ((*this->tailBlock)[currentTailIndex]) T(details::nomove_if<(bool)!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))>::eval(*itemFirst)); + ++currentTailIndex; + ++itemFirst; + } + } + MOODYCAMEL_CATCH (...) { + // Oh dear, an exception's been thrown -- destroy the elements that + // were enqueued so far and revert the entire bulk operation (we'll keep + // any allocated blocks in our linked list for later, though). + auto constructedStopIndex = currentTailIndex; + auto lastBlockEnqueued = this->tailBlock; + + pr_blockIndexFront = originalBlockIndexFront; + pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; + this->tailBlock = startBlock == nullptr ? firstAllocatedBlock : startBlock; + + if (!details::is_trivially_destructible::value) { + auto block = startBlock; + if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { + block = firstAllocatedBlock; + } + currentTailIndex = startTailIndex; + while (true) { + stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + if (details::circular_less_than(constructedStopIndex, stopIndex)) { + stopIndex = constructedStopIndex; + } + while (currentTailIndex != stopIndex) { + (*block)[currentTailIndex++]->~T(); + } + if (block == lastBlockEnqueued) { + break; + } + block = block->next; + } + } + MOODYCAMEL_RETHROW; + } + } + + if (this->tailBlock == endBlock) { + assert(currentTailIndex == newTailIndex); + break; + } + this->tailBlock = this->tailBlock->next; + } + + if (!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst))) && firstAllocatedBlock != nullptr) { + blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release); + } + + this->tailIndex.store(newTailIndex, std::memory_order_release); + return true; + } + + template + size_t dequeue_bulk(It& itemFirst, size_t max) + { + auto tail = this->tailIndex.load(std::memory_order_relaxed); + auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); + auto desiredCount = static_cast(tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit)); + if (details::circular_less_than(0, desiredCount)) { + desiredCount = desiredCount < max ? desiredCount : max; + std::atomic_thread_fence(std::memory_order_acquire); + + auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed);; + + tail = this->tailIndex.load(std::memory_order_acquire); + auto actualCount = static_cast(tail - (myDequeueCount - overcommit)); + if (details::circular_less_than(0, actualCount)) { + actualCount = desiredCount < actualCount ? desiredCount : actualCount; + if (actualCount < desiredCount) { + this->dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release); + } + + // Get the first index. Note that since there's guaranteed to be at least actualCount elements, this + // will never exceed tail. + auto firstIndex = this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel); + + // Determine which block the first element is in + auto localBlockIndex = blockIndex.load(std::memory_order_acquire); + auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire); + + auto headBase = localBlockIndex->entries[localBlockIndexHead].base; + auto firstBlockBaseIndex = firstIndex & ~static_cast(BLOCK_SIZE - 1); + auto offset = static_cast(static_cast::type>(firstBlockBaseIndex - headBase) / BLOCK_SIZE); + auto indexIndex = (localBlockIndexHead + offset) & (localBlockIndex->size - 1); + + // Iterate the blocks and dequeue + auto index = firstIndex; + do { + auto firstIndexInBlock = index; + auto endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; + auto block = localBlockIndex->entries[indexIndex].block; + if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, details::deref_noexcept(itemFirst) = std::move((*(*block)[index])))) { + while (index != endIndex) { + auto& el = *((*block)[index]); + *itemFirst++ = std::move(el); + el.~T(); + ++index; + } + } + else { + MOODYCAMEL_TRY { + while (index != endIndex) { + auto& el = *((*block)[index]); + *itemFirst = std::move(el); + ++itemFirst; + el.~T(); + ++index; + } + } + MOODYCAMEL_CATCH (...) { + // It's too late to revert the dequeue, but we can make sure that all + // the dequeued objects are properly destroyed and the block index + // (and empty count) are properly updated before we propagate the exception + do { + block = localBlockIndex->entries[indexIndex].block; + while (index != endIndex) { + (*block)[index++]->~T(); + } + block->ConcurrentQueue::Block::template set_many_empty(firstIndexInBlock, static_cast(endIndex - firstIndexInBlock)); + indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1); + + firstIndexInBlock = index; + endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; + } while (index != firstIndex + actualCount); + + MOODYCAMEL_RETHROW; + } + } + block->ConcurrentQueue::Block::template set_many_empty(firstIndexInBlock, static_cast(endIndex - firstIndexInBlock)); + indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1); + } while (index != firstIndex + actualCount); + + return actualCount; + } + else { + // Wasn't anything to dequeue after all; make the effective dequeue count eventually consistent + this->dequeueOvercommit.fetch_add(desiredCount, std::memory_order_release); + } + } + + return 0; + } + + private: + struct BlockIndexEntry + { + index_t base; + Block* block; + }; + + struct BlockIndexHeader + { + size_t size; + std::atomic front; // Current slot (not next, like pr_blockIndexFront) + BlockIndexEntry* entries; + void* prev; + }; + + + bool new_block_index(size_t numberOfFilledSlotsToExpose) + { + auto prevBlockSizeMask = pr_blockIndexSize - 1; + + // Create the new block + pr_blockIndexSize <<= 1; + auto newRawPtr = static_cast((Traits::malloc)(sizeof(BlockIndexHeader) + std::alignment_of::value - 1 + sizeof(BlockIndexEntry) * pr_blockIndexSize)); + if (newRawPtr == nullptr) { + pr_blockIndexSize >>= 1; // Reset to allow graceful retry + return false; + } + + auto newBlockIndexEntries = reinterpret_cast(details::align_for(newRawPtr + sizeof(BlockIndexHeader))); + + // Copy in all the old indices, if any + size_t j = 0; + if (pr_blockIndexSlotsUsed != 0) { + auto i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & prevBlockSizeMask; + do { + newBlockIndexEntries[j++] = pr_blockIndexEntries[i]; + i = (i + 1) & prevBlockSizeMask; + } while (i != pr_blockIndexFront); + } + + // Update everything + auto header = new (newRawPtr) BlockIndexHeader; + header->size = pr_blockIndexSize; + header->front.store(numberOfFilledSlotsToExpose - 1, std::memory_order_relaxed); + header->entries = newBlockIndexEntries; + header->prev = pr_blockIndexRaw; // we link the new block to the old one so we can free it later + + pr_blockIndexFront = j; + pr_blockIndexEntries = newBlockIndexEntries; + pr_blockIndexRaw = newRawPtr; + blockIndex.store(header, std::memory_order_release); + + return true; + } + + private: + std::atomic blockIndex; + + // To be used by producer only -- consumer must use the ones in referenced by blockIndex + size_t pr_blockIndexSlotsUsed; + size_t pr_blockIndexSize; + size_t pr_blockIndexFront; // Next slot (not current) + BlockIndexEntry* pr_blockIndexEntries; + void* pr_blockIndexRaw; + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + public: + ExplicitProducer* nextExplicitProducer; + private: +#endif + +#if MCDBGQ_TRACKMEM + friend struct MemStats; +#endif + }; + + + ////////////////////////////////// + // Implicit queue + ////////////////////////////////// + + struct ImplicitProducer : public ProducerBase + { + ImplicitProducer(ConcurrentQueue* parent) : + ProducerBase(parent, false), + nextBlockIndexCapacity(IMPLICIT_INITIAL_INDEX_SIZE), + blockIndex(nullptr) + { + new_block_index(); + } + + ~ImplicitProducer() + { + // Note that since we're in the destructor we can assume that all enqueue/dequeue operations + // completed already; this means that all undequeued elements are placed contiguously across + // contiguous blocks, and that only the first and last remaining blocks can be only partially + // empty (all other remaining blocks must be completely full). + +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED + // Unregister ourselves for thread termination notification + if (!this->inactive.load(std::memory_order_relaxed)) { + details::ThreadExitNotifier::unsubscribe(&threadExitListener); + } +#endif + + // Destroy all remaining elements! + auto tail = this->tailIndex.load(std::memory_order_relaxed); + auto index = this->headIndex.load(std::memory_order_relaxed); + Block* block = nullptr; + assert(index == tail || details::circular_less_than(index, tail)); + bool forceFreeLastBlock = index != tail; // If we enter the loop, then the last (tail) block will not be freed + while (index != tail) { + if ((index & static_cast(BLOCK_SIZE - 1)) == 0 || block == nullptr) { + if (block != nullptr) { + // Free the old block + this->parent->add_block_to_free_list(block); + } + + block = get_block_index_entry_for_index(index)->value.load(std::memory_order_relaxed); + } + + ((*block)[index])->~T(); + ++index; + } + // Even if the queue is empty, there's still one block that's not on the free list + // (unless the head index reached the end of it, in which case the tail will be poised + // to create a new block). + if (this->tailBlock != nullptr && (forceFreeLastBlock || (tail & static_cast(BLOCK_SIZE - 1)) != 0)) { + this->parent->add_block_to_free_list(this->tailBlock); + } + + // Destroy block index + auto localBlockIndex = blockIndex.load(std::memory_order_relaxed); + if (localBlockIndex != nullptr) { + for (size_t i = 0; i != localBlockIndex->capacity; ++i) { + localBlockIndex->index[i]->~BlockIndexEntry(); + } + do { + auto prev = localBlockIndex->prev; + localBlockIndex->~BlockIndexHeader(); + (Traits::free)(localBlockIndex); + localBlockIndex = prev; + } while (localBlockIndex != nullptr); + } + } + + template + inline bool enqueue(U&& element) + { + index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed); + index_t newTailIndex = 1 + currentTailIndex; + if ((currentTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { + // We reached the end of a block, start a new one + auto head = this->headIndex.load(std::memory_order_relaxed); + assert(!details::circular_less_than(currentTailIndex, head)); + if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) { + return false; + } +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + debug::DebugLock lock(mutex); +#endif + // Find out where we'll be inserting this block in the block index + BlockIndexEntry* idxEntry; + if (!insert_block_index_entry(idxEntry, currentTailIndex)) { + return false; + } + + // Get ahold of a new block + auto newBlock = this->parent->ConcurrentQueue::template requisition_block(); + if (newBlock == nullptr) { + rewind_block_index_tail(); + idxEntry->value.store(nullptr, std::memory_order_relaxed); + return false; + } +#if MCDBGQ_TRACKMEM + newBlock->owner = this; +#endif + newBlock->ConcurrentQueue::Block::template reset_empty(); + + if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { + // May throw, try to insert now before we publish the fact that we have this new block + MOODYCAMEL_TRY { + new ((*newBlock)[currentTailIndex]) T(std::forward(element)); + } + MOODYCAMEL_CATCH (...) { + rewind_block_index_tail(); + idxEntry->value.store(nullptr, std::memory_order_relaxed); + this->parent->add_block_to_free_list(newBlock); + MOODYCAMEL_RETHROW; + } + } + + // Insert the new block into the index + idxEntry->value.store(newBlock, std::memory_order_relaxed); + + this->tailBlock = newBlock; + + if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { + this->tailIndex.store(newTailIndex, std::memory_order_release); + return true; + } + } + + // Enqueue + new ((*this->tailBlock)[currentTailIndex]) T(std::forward(element)); + + this->tailIndex.store(newTailIndex, std::memory_order_release); + return true; + } + + template + bool dequeue(U& element) + { + // See ExplicitProducer::dequeue for rationale and explanation + index_t tail = this->tailIndex.load(std::memory_order_relaxed); + index_t overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); + if (details::circular_less_than(this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit, tail)) { + std::atomic_thread_fence(std::memory_order_acquire); + + index_t myDequeueCount = this->dequeueOptimisticCount.fetch_add(1, std::memory_order_relaxed); + tail = this->tailIndex.load(std::memory_order_acquire); + if ((details::likely)(details::circular_less_than(myDequeueCount - overcommit, tail))) { + index_t index = this->headIndex.fetch_add(1, std::memory_order_acq_rel); + + // Determine which block the element is in + auto entry = get_block_index_entry_for_index(index); + + // Dequeue + auto block = entry->value.load(std::memory_order_relaxed); + auto& el = *((*block)[index]); + + if (!MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, element = std::move(el))) { +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + // Note: Acquiring the mutex with every dequeue instead of only when a block + // is released is very sub-optimal, but it is, after all, purely debug code. + debug::DebugLock lock(producer->mutex); +#endif + struct Guard { + Block* block; + index_t index; + BlockIndexEntry* entry; + ConcurrentQueue* parent; + + ~Guard() + { + (*block)[index]->~T(); + if (block->ConcurrentQueue::Block::template set_empty(index)) { + entry->value.store(nullptr, std::memory_order_relaxed); + parent->add_block_to_free_list(block); + } + } + } guard = { block, index, entry, this->parent }; + + element = std::move(el); + } + else { + element = std::move(el); + el.~T(); + + if (block->ConcurrentQueue::Block::template set_empty(index)) { + { +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + debug::DebugLock lock(mutex); +#endif + // Add the block back into the global free pool (and remove from block index) + entry->value.store(nullptr, std::memory_order_relaxed); + } + this->parent->add_block_to_free_list(block); // releases the above store + } + } + + return true; + } + else { + this->dequeueOvercommit.fetch_add(1, std::memory_order_release); + } + } + + return false; + } + + template + bool enqueue_bulk(It itemFirst, size_t count) + { + // First, we need to make sure we have enough room to enqueue all of the elements; + // this means pre-allocating blocks and putting them in the block index (but only if + // all the allocations succeeded). + + // Note that the tailBlock we start off with may not be owned by us any more; + // this happens if it was filled up exactly to the top (setting tailIndex to + // the first index of the next block which is not yet allocated), then dequeued + // completely (putting it on the free list) before we enqueue again. + + index_t startTailIndex = this->tailIndex.load(std::memory_order_relaxed); + auto startBlock = this->tailBlock; + Block* firstAllocatedBlock = nullptr; + auto endBlock = this->tailBlock; + + // Figure out how many blocks we'll need to allocate, and do so + size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1)); + index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); + if (blockBaseDiff > 0) { +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + debug::DebugLock lock(mutex); +#endif + do { + blockBaseDiff -= static_cast(BLOCK_SIZE); + currentTailIndex += static_cast(BLOCK_SIZE); + + // Find out where we'll be inserting this block in the block index + BlockIndexEntry* idxEntry = nullptr; // initialization here unnecessary but compiler can't always tell + Block* newBlock; + bool indexInserted = false; + auto head = this->headIndex.load(std::memory_order_relaxed); + assert(!details::circular_less_than(currentTailIndex, head)); + bool full = !details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head)); + if (full || !(indexInserted = insert_block_index_entry(idxEntry, currentTailIndex)) || (newBlock = this->parent->ConcurrentQueue::template requisition_block()) == nullptr) { + // Index allocation or block allocation failed; revert any other allocations + // and index insertions done so far for this operation + if (indexInserted) { + rewind_block_index_tail(); + idxEntry->value.store(nullptr, std::memory_order_relaxed); + } + currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); + for (auto block = firstAllocatedBlock; block != nullptr; block = block->next) { + currentTailIndex += static_cast(BLOCK_SIZE); + idxEntry = get_block_index_entry_for_index(currentTailIndex); + idxEntry->value.store(nullptr, std::memory_order_relaxed); + rewind_block_index_tail(); + } + this->parent->add_blocks_to_free_list(firstAllocatedBlock); + this->tailBlock = startBlock; + + return false; + } + +#if MCDBGQ_TRACKMEM + newBlock->owner = this; +#endif + newBlock->ConcurrentQueue::Block::template reset_empty(); + newBlock->next = nullptr; + + // Insert the new block into the index + idxEntry->value.store(newBlock, std::memory_order_relaxed); + + // Store the chain of blocks so that we can undo if later allocations fail, + // and so that we can find the blocks when we do the actual enqueueing + if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock != nullptr) { + assert(this->tailBlock != nullptr); + this->tailBlock->next = newBlock; + } + this->tailBlock = newBlock; + endBlock = newBlock; + firstAllocatedBlock = firstAllocatedBlock == nullptr ? newBlock : firstAllocatedBlock; + } while (blockBaseDiff > 0); + } + + // Enqueue, one block at a time + index_t newTailIndex = startTailIndex + static_cast(count); + currentTailIndex = startTailIndex; + this->tailBlock = startBlock; + assert((startTailIndex & static_cast(BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock != nullptr || count == 0); + if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0 && firstAllocatedBlock != nullptr) { + this->tailBlock = firstAllocatedBlock; + } + while (true) { + auto stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + if (details::circular_less_than(newTailIndex, stopIndex)) { + stopIndex = newTailIndex; + } + if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) { + while (currentTailIndex != stopIndex) { + new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++); + } + } + else { + MOODYCAMEL_TRY { + while (currentTailIndex != stopIndex) { + new ((*this->tailBlock)[currentTailIndex]) T(details::nomove_if<(bool)!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))>::eval(*itemFirst)); + ++currentTailIndex; + ++itemFirst; + } + } + MOODYCAMEL_CATCH (...) { + auto constructedStopIndex = currentTailIndex; + auto lastBlockEnqueued = this->tailBlock; + + if (!details::is_trivially_destructible::value) { + auto block = startBlock; + if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { + block = firstAllocatedBlock; + } + currentTailIndex = startTailIndex; + while (true) { + stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + if (details::circular_less_than(constructedStopIndex, stopIndex)) { + stopIndex = constructedStopIndex; + } + while (currentTailIndex != stopIndex) { + (*block)[currentTailIndex++]->~T(); + } + if (block == lastBlockEnqueued) { + break; + } + block = block->next; + } + } + + currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); + for (auto block = firstAllocatedBlock; block != nullptr; block = block->next) { + currentTailIndex += static_cast(BLOCK_SIZE); + auto idxEntry = get_block_index_entry_for_index(currentTailIndex); + idxEntry->value.store(nullptr, std::memory_order_relaxed); + rewind_block_index_tail(); + } + this->parent->add_blocks_to_free_list(firstAllocatedBlock); + this->tailBlock = startBlock; + MOODYCAMEL_RETHROW; + } + } + + if (this->tailBlock == endBlock) { + assert(currentTailIndex == newTailIndex); + break; + } + this->tailBlock = this->tailBlock->next; + } + this->tailIndex.store(newTailIndex, std::memory_order_release); + return true; + } + + template + size_t dequeue_bulk(It& itemFirst, size_t max) + { + auto tail = this->tailIndex.load(std::memory_order_relaxed); + auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); + auto desiredCount = static_cast(tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit)); + if (details::circular_less_than(0, desiredCount)) { + desiredCount = desiredCount < max ? desiredCount : max; + std::atomic_thread_fence(std::memory_order_acquire); + + auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed); + + tail = this->tailIndex.load(std::memory_order_acquire); + auto actualCount = static_cast(tail - (myDequeueCount - overcommit)); + if (details::circular_less_than(0, actualCount)) { + actualCount = desiredCount < actualCount ? desiredCount : actualCount; + if (actualCount < desiredCount) { + this->dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release); + } + + // Get the first index. Note that since there's guaranteed to be at least actualCount elements, this + // will never exceed tail. + auto firstIndex = this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel); + + // Iterate the blocks and dequeue + auto index = firstIndex; + BlockIndexHeader* localBlockIndex; + auto indexIndex = get_block_index_index_for_index(index, localBlockIndex); + do { + auto blockStartIndex = index; + auto endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; + + auto entry = localBlockIndex->index[indexIndex]; + auto block = entry->value.load(std::memory_order_relaxed); + if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, details::deref_noexcept(itemFirst) = std::move((*(*block)[index])))) { + while (index != endIndex) { + auto& el = *((*block)[index]); + *itemFirst++ = std::move(el); + el.~T(); + ++index; + } + } + else { + MOODYCAMEL_TRY { + while (index != endIndex) { + auto& el = *((*block)[index]); + *itemFirst = std::move(el); + ++itemFirst; + el.~T(); + ++index; + } + } + MOODYCAMEL_CATCH (...) { + do { + entry = localBlockIndex->index[indexIndex]; + block = entry->value.load(std::memory_order_relaxed); + while (index != endIndex) { + (*block)[index++]->~T(); + } + + if (block->ConcurrentQueue::Block::template set_many_empty(blockStartIndex, static_cast(endIndex - blockStartIndex))) { +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + debug::DebugLock lock(mutex); +#endif + entry->value.store(nullptr, std::memory_order_relaxed); + this->parent->add_block_to_free_list(block); + } + indexIndex = (indexIndex + 1) & (localBlockIndex->capacity - 1); + + blockStartIndex = index; + endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; + } while (index != firstIndex + actualCount); + + MOODYCAMEL_RETHROW; + } + } + if (block->ConcurrentQueue::Block::template set_many_empty(blockStartIndex, static_cast(endIndex - blockStartIndex))) { + { +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + debug::DebugLock lock(mutex); +#endif + // Note that the set_many_empty above did a release, meaning that anybody who acquires the block + // we're about to free can use it safely since our writes (and reads!) will have happened-before then. + entry->value.store(nullptr, std::memory_order_relaxed); + } + this->parent->add_block_to_free_list(block); // releases the above store + } + indexIndex = (indexIndex + 1) & (localBlockIndex->capacity - 1); + } while (index != firstIndex + actualCount); + + return actualCount; + } + else { + this->dequeueOvercommit.fetch_add(desiredCount, std::memory_order_release); + } + } + + return 0; + } + + private: + // The block size must be > 1, so any number with the low bit set is an invalid block base index + static const index_t INVALID_BLOCK_BASE = 1; + + struct BlockIndexEntry + { + std::atomic key; + std::atomic value; + }; + + struct BlockIndexHeader + { + size_t capacity; + std::atomic tail; + BlockIndexEntry* entries; + BlockIndexEntry** index; + BlockIndexHeader* prev; + }; + + template + inline bool insert_block_index_entry(BlockIndexEntry*& idxEntry, index_t blockStartIndex) + { + auto localBlockIndex = blockIndex.load(std::memory_order_relaxed); // We're the only writer thread, relaxed is OK + if (localBlockIndex == nullptr) { + return false; // this can happen if new_block_index failed in the constructor + } + auto newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1); + idxEntry = localBlockIndex->index[newTail]; + if (idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE || + idxEntry->value.load(std::memory_order_relaxed) == nullptr) { + + idxEntry->key.store(blockStartIndex, std::memory_order_relaxed); + localBlockIndex->tail.store(newTail, std::memory_order_release); + return true; + } + + // No room in the old block index, try to allocate another one! + if (allocMode == CannotAlloc || !new_block_index()) { + return false; + } + localBlockIndex = blockIndex.load(std::memory_order_relaxed); + newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1); + idxEntry = localBlockIndex->index[newTail]; + assert(idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE); + idxEntry->key.store(blockStartIndex, std::memory_order_relaxed); + localBlockIndex->tail.store(newTail, std::memory_order_release); + return true; + } + + inline void rewind_block_index_tail() + { + auto localBlockIndex = blockIndex.load(std::memory_order_relaxed); + localBlockIndex->tail.store((localBlockIndex->tail.load(std::memory_order_relaxed) - 1) & (localBlockIndex->capacity - 1), std::memory_order_relaxed); + } + + inline BlockIndexEntry* get_block_index_entry_for_index(index_t index) const + { + BlockIndexHeader* localBlockIndex; + auto idx = get_block_index_index_for_index(index, localBlockIndex); + return localBlockIndex->index[idx]; + } + + inline size_t get_block_index_index_for_index(index_t index, BlockIndexHeader*& localBlockIndex) const + { +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + debug::DebugLock lock(mutex); +#endif + index &= ~static_cast(BLOCK_SIZE - 1); + localBlockIndex = blockIndex.load(std::memory_order_acquire); + auto tail = localBlockIndex->tail.load(std::memory_order_acquire); + auto tailBase = localBlockIndex->index[tail]->key.load(std::memory_order_relaxed); + assert(tailBase != INVALID_BLOCK_BASE); + // Note: Must use division instead of shift because the index may wrap around, causing a negative + // offset, whose negativity we want to preserve + auto offset = static_cast(static_cast::type>(index - tailBase) / BLOCK_SIZE); + size_t idx = (tail + offset) & (localBlockIndex->capacity - 1); + assert(localBlockIndex->index[idx]->key.load(std::memory_order_relaxed) == index && localBlockIndex->index[idx]->value.load(std::memory_order_relaxed) != nullptr); + return idx; + } + + bool new_block_index() + { + auto prev = blockIndex.load(std::memory_order_relaxed); + size_t prevCapacity = prev == nullptr ? 0 : prev->capacity; + auto entryCount = prev == nullptr ? nextBlockIndexCapacity : prevCapacity; + auto raw = static_cast((Traits::malloc)( + sizeof(BlockIndexHeader) + + std::alignment_of::value - 1 + sizeof(BlockIndexEntry) * entryCount + + std::alignment_of::value - 1 + sizeof(BlockIndexEntry*) * nextBlockIndexCapacity)); + if (raw == nullptr) { + return false; + } + + auto header = new (raw) BlockIndexHeader; + auto entries = reinterpret_cast(details::align_for(raw + sizeof(BlockIndexHeader))); + auto index = reinterpret_cast(details::align_for(reinterpret_cast(entries) + sizeof(BlockIndexEntry) * entryCount)); + if (prev != nullptr) { + auto prevTail = prev->tail.load(std::memory_order_relaxed); + auto prevPos = prevTail; + size_t i = 0; + do { + prevPos = (prevPos + 1) & (prev->capacity - 1); + index[i++] = prev->index[prevPos]; + } while (prevPos != prevTail); + assert(i == prevCapacity); + } + for (size_t i = 0; i != entryCount; ++i) { + new (entries + i) BlockIndexEntry; + entries[i].key.store(INVALID_BLOCK_BASE, std::memory_order_relaxed); + index[prevCapacity + i] = entries + i; + } + header->prev = prev; + header->entries = entries; + header->index = index; + header->capacity = nextBlockIndexCapacity; + header->tail.store((prevCapacity - 1) & (nextBlockIndexCapacity - 1), std::memory_order_relaxed); + + blockIndex.store(header, std::memory_order_release); + + nextBlockIndexCapacity <<= 1; + + return true; + } + + private: + size_t nextBlockIndexCapacity; + std::atomic blockIndex; + +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED + public: + details::ThreadExitListener threadExitListener; + private: +#endif + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + public: + ImplicitProducer* nextImplicitProducer; + private: +#endif + +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX + mutable debug::DebugMutex mutex; +#endif +#if MCDBGQ_TRACKMEM + friend struct MemStats; +#endif + }; + + + ////////////////////////////////// + // Block pool manipulation + ////////////////////////////////// + + void populate_initial_block_list(size_t blockCount) + { + initialBlockPoolSize = blockCount; + if (initialBlockPoolSize == 0) { + initialBlockPool = nullptr; + return; + } + + initialBlockPool = create_array(blockCount); + if (initialBlockPool == nullptr) { + initialBlockPoolSize = 0; + } + for (size_t i = 0; i < initialBlockPoolSize; ++i) { + initialBlockPool[i].dynamicallyAllocated = false; + } + } + + inline Block* try_get_block_from_initial_pool() + { + if (initialBlockPoolIndex.load(std::memory_order_relaxed) >= initialBlockPoolSize) { + return nullptr; + } + + auto index = initialBlockPoolIndex.fetch_add(1, std::memory_order_relaxed); + + return index < initialBlockPoolSize ? (initialBlockPool + index) : nullptr; + } + + inline void add_block_to_free_list(Block* block) + { +#if MCDBGQ_TRACKMEM + block->owner = nullptr; +#endif + freeList.add(block); + } + + inline void add_blocks_to_free_list(Block* block) + { + while (block != nullptr) { + auto next = block->next; + add_block_to_free_list(block); + block = next; + } + } + + inline Block* try_get_block_from_free_list() + { + return freeList.try_get(); + } + + // Gets a free block from one of the memory pools, or allocates a new one (if applicable) + template + Block* requisition_block() + { + auto block = try_get_block_from_initial_pool(); + if (block != nullptr) { + return block; + } + + block = try_get_block_from_free_list(); + if (block != nullptr) { + return block; + } + + if (canAlloc == CanAlloc) { + return create(); + } + + return nullptr; + } + + +#if MCDBGQ_TRACKMEM + public: + struct MemStats { + size_t allocatedBlocks; + size_t usedBlocks; + size_t freeBlocks; + size_t ownedBlocksExplicit; + size_t ownedBlocksImplicit; + size_t implicitProducers; + size_t explicitProducers; + size_t elementsEnqueued; + size_t blockClassBytes; + size_t queueClassBytes; + size_t implicitBlockIndexBytes; + size_t explicitBlockIndexBytes; + + friend class ConcurrentQueue; + + private: + static MemStats getFor(ConcurrentQueue* q) + { + MemStats stats = { 0 }; + + stats.elementsEnqueued = q->size_approx(); + + auto block = q->freeList.head_unsafe(); + while (block != nullptr) { + ++stats.allocatedBlocks; + ++stats.freeBlocks; + block = block->freeListNext.load(std::memory_order_relaxed); + } + + for (auto ptr = q->producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + bool implicit = dynamic_cast(ptr) != nullptr; + stats.implicitProducers += implicit ? 1 : 0; + stats.explicitProducers += implicit ? 0 : 1; + + if (implicit) { + auto prod = static_cast(ptr); + stats.queueClassBytes += sizeof(ImplicitProducer); + auto head = prod->headIndex.load(std::memory_order_relaxed); + auto tail = prod->tailIndex.load(std::memory_order_relaxed); + auto hash = prod->blockIndex.load(std::memory_order_relaxed); + if (hash != nullptr) { + for (size_t i = 0; i != hash->capacity; ++i) { + if (hash->index[i]->key.load(std::memory_order_relaxed) != ImplicitProducer::INVALID_BLOCK_BASE && hash->index[i]->value.load(std::memory_order_relaxed) != nullptr) { + ++stats.allocatedBlocks; + ++stats.ownedBlocksImplicit; + } + } + stats.implicitBlockIndexBytes += hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry); + for (; hash != nullptr; hash = hash->prev) { + stats.implicitBlockIndexBytes += sizeof(typename ImplicitProducer::BlockIndexHeader) + hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry*); + } + } + for (; details::circular_less_than(head, tail); head += BLOCK_SIZE) { + //auto block = prod->get_block_index_entry_for_index(head); + ++stats.usedBlocks; + } + } + else { + auto prod = static_cast(ptr); + stats.queueClassBytes += sizeof(ExplicitProducer); + auto tailBlock = prod->tailBlock; + bool wasNonEmpty = false; + if (tailBlock != nullptr) { + auto block = tailBlock; + do { + ++stats.allocatedBlocks; + if (!block->ConcurrentQueue::Block::template is_empty() || wasNonEmpty) { + ++stats.usedBlocks; + wasNonEmpty = wasNonEmpty || block != tailBlock; + } + ++stats.ownedBlocksExplicit; + block = block->next; + } while (block != tailBlock); + } + auto index = prod->blockIndex.load(std::memory_order_relaxed); + while (index != nullptr) { + stats.explicitBlockIndexBytes += sizeof(typename ExplicitProducer::BlockIndexHeader) + index->size * sizeof(typename ExplicitProducer::BlockIndexEntry); + index = static_cast(index->prev); + } + } + } + + auto freeOnInitialPool = q->initialBlockPoolIndex.load(std::memory_order_relaxed) >= q->initialBlockPoolSize ? 0 : q->initialBlockPoolSize - q->initialBlockPoolIndex.load(std::memory_order_relaxed); + stats.allocatedBlocks += freeOnInitialPool; + stats.freeBlocks += freeOnInitialPool; + + stats.blockClassBytes = sizeof(Block) * stats.allocatedBlocks; + stats.queueClassBytes += sizeof(ConcurrentQueue); + + return stats; + } + }; + + // For debugging only. Not thread-safe. + MemStats getMemStats() + { + return MemStats::getFor(this); + } + private: + friend struct MemStats; +#endif + + + ////////////////////////////////// + // Producer list manipulation + ////////////////////////////////// + + ProducerBase* recycle_or_create_producer(bool isExplicit) + { + bool recycled; + return recycle_or_create_producer(isExplicit, recycled); + } + + ProducerBase* recycle_or_create_producer(bool isExplicit, bool& recycled) + { +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH + debug::DebugLock lock(implicitProdMutex); +#endif + // Try to re-use one first + for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + if (ptr->inactive.load(std::memory_order_relaxed) && ptr->isExplicit == isExplicit) { + bool expected = true; + if (ptr->inactive.compare_exchange_strong(expected, /* desired */ false, std::memory_order_acquire, std::memory_order_relaxed)) { + // We caught one! It's been marked as activated, the caller can have it + recycled = true; + return ptr; + } + } + } + + recycled = false; + return add_producer(isExplicit ? static_cast(create(this)) : create(this)); + } + + ProducerBase* add_producer(ProducerBase* producer) + { + // Handle failed memory allocation + if (producer == nullptr) { + return nullptr; + } + + producerCount.fetch_add(1, std::memory_order_relaxed); + + // Add it to the lock-free list + auto prevTail = producerListTail.load(std::memory_order_relaxed); + do { + producer->next = prevTail; + } while (!producerListTail.compare_exchange_weak(prevTail, producer, std::memory_order_release, std::memory_order_relaxed)); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + if (producer->isExplicit) { + auto prevTailExplicit = explicitProducers.load(std::memory_order_relaxed); + do { + static_cast(producer)->nextExplicitProducer = prevTailExplicit; + } while (!explicitProducers.compare_exchange_weak(prevTailExplicit, static_cast(producer), std::memory_order_release, std::memory_order_relaxed)); + } + else { + auto prevTailImplicit = implicitProducers.load(std::memory_order_relaxed); + do { + static_cast(producer)->nextImplicitProducer = prevTailImplicit; + } while (!implicitProducers.compare_exchange_weak(prevTailImplicit, static_cast(producer), std::memory_order_release, std::memory_order_relaxed)); + } +#endif + + return producer; + } + + void reown_producers() + { + // After another instance is moved-into/swapped-with this one, all the + // producers we stole still think their parents are the other queue. + // So fix them up! + for (auto ptr = producerListTail.load(std::memory_order_relaxed); ptr != nullptr; ptr = ptr->next_prod()) { + ptr->parent = this; + } + } + + + ////////////////////////////////// + // Implicit producer hash + ////////////////////////////////// + + struct ImplicitProducerKVP + { + std::atomic key; + ImplicitProducer* value; // No need for atomicity since it's only read by the thread that sets it in the first place + + ImplicitProducerKVP() : value(nullptr) { } + + ImplicitProducerKVP(ImplicitProducerKVP&& other) MOODYCAMEL_NOEXCEPT + { + key.store(other.key.load(std::memory_order_relaxed), std::memory_order_relaxed); + value = other.value; + } + + inline ImplicitProducerKVP& operator=(ImplicitProducerKVP&& other) MOODYCAMEL_NOEXCEPT + { + swap(other); + return *this; + } + + inline void swap(ImplicitProducerKVP& other) MOODYCAMEL_NOEXCEPT + { + if (this != &other) { + details::swap_relaxed(key, other.key); + std::swap(value, other.value); + } + } + }; + + template + friend void moodycamel::swap(typename ConcurrentQueue::ImplicitProducerKVP&, typename ConcurrentQueue::ImplicitProducerKVP&) MOODYCAMEL_NOEXCEPT; + + struct ImplicitProducerHash + { + size_t capacity; + ImplicitProducerKVP* entries; + ImplicitProducerHash* prev; + }; + + inline void populate_initial_implicit_producer_hash() + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return; + + implicitProducerHashCount.store(0, std::memory_order_relaxed); + auto hash = &initialImplicitProducerHash; + hash->capacity = INITIAL_IMPLICIT_PRODUCER_HASH_SIZE; + hash->entries = &initialImplicitProducerHashEntries[0]; + for (size_t i = 0; i != INITIAL_IMPLICIT_PRODUCER_HASH_SIZE; ++i) { + initialImplicitProducerHashEntries[i].key.store(details::invalid_thread_id, std::memory_order_relaxed); + } + hash->prev = nullptr; + implicitProducerHash.store(hash, std::memory_order_relaxed); + } + + void swap_implicit_producer_hashes(ConcurrentQueue& other) + { + if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return; + + // Swap (assumes our implicit producer hash is initialized) + initialImplicitProducerHashEntries.swap(other.initialImplicitProducerHashEntries); + initialImplicitProducerHash.entries = &initialImplicitProducerHashEntries[0]; + other.initialImplicitProducerHash.entries = &other.initialImplicitProducerHashEntries[0]; + + details::swap_relaxed(implicitProducerHashCount, other.implicitProducerHashCount); + + details::swap_relaxed(implicitProducerHash, other.implicitProducerHash); + if (implicitProducerHash.load(std::memory_order_relaxed) == &other.initialImplicitProducerHash) { + implicitProducerHash.store(&initialImplicitProducerHash, std::memory_order_relaxed); + } + else { + ImplicitProducerHash* hash; + for (hash = implicitProducerHash.load(std::memory_order_relaxed); hash->prev != &other.initialImplicitProducerHash; hash = hash->prev) { + continue; + } + hash->prev = &initialImplicitProducerHash; + } + if (other.implicitProducerHash.load(std::memory_order_relaxed) == &initialImplicitProducerHash) { + other.implicitProducerHash.store(&other.initialImplicitProducerHash, std::memory_order_relaxed); + } + else { + ImplicitProducerHash* hash; + for (hash = other.implicitProducerHash.load(std::memory_order_relaxed); hash->prev != &initialImplicitProducerHash; hash = hash->prev) { + continue; + } + hash->prev = &other.initialImplicitProducerHash; + } + } + + // Only fails (returns nullptr) if memory allocation fails + ImplicitProducer* get_or_add_implicit_producer() + { + // Note that since the data is essentially thread-local (key is thread ID), + // there's a reduced need for fences (memory ordering is already consistent + // for any individual thread), except for the current table itself. + + // Start by looking for the thread ID in the current and all previous hash tables. + // If it's not found, it must not be in there yet, since this same thread would + // have added it previously to one of the tables that we traversed. + + // Code and algorithm adapted from http://preshing.com/20130605/the-worlds-simplest-lock-free-hash-table + +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH + debug::DebugLock lock(implicitProdMutex); +#endif + + auto id = details::thread_id(); + auto hashedId = details::hash_thread_id(id); + + auto mainHash = implicitProducerHash.load(std::memory_order_acquire); + for (auto hash = mainHash; hash != nullptr; hash = hash->prev) { + // Look for the id in this hash + auto index = hashedId; + while (true) { // Not an infinite loop because at least one slot is free in the hash table + index &= hash->capacity - 1; + + auto probedKey = hash->entries[index].key.load(std::memory_order_relaxed); + if (probedKey == id) { + // Found it! If we had to search several hashes deep, though, we should lazily add it + // to the current main hash table to avoid the extended search next time. + // Note there's guaranteed to be room in the current hash table since every subsequent + // table implicitly reserves space for all previous tables (there's only one + // implicitProducerHashCount). + auto value = hash->entries[index].value; + if (hash != mainHash) { + index = hashedId; + while (true) { + index &= mainHash->capacity - 1; + probedKey = mainHash->entries[index].key.load(std::memory_order_relaxed); + auto empty = details::invalid_thread_id; +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED + auto reusable = details::invalid_thread_id2; + if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed)) || + (probedKey == reusable && mainHash->entries[index].key.compare_exchange_strong(reusable, id, std::memory_order_acquire, std::memory_order_acquire))) { +#else + if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed))) { +#endif + mainHash->entries[index].value = value; + break; + } + ++index; + } + } + + return value; + } + if (probedKey == details::invalid_thread_id) { + break; // Not in this hash table + } + ++index; + } + } + + // Insert! + auto newCount = 1 + implicitProducerHashCount.fetch_add(1, std::memory_order_relaxed); + while (true) { + if (newCount >= (mainHash->capacity >> 1) && !implicitProducerHashResizeInProgress.test_and_set(std::memory_order_acquire)) { + // We've acquired the resize lock, try to allocate a bigger hash table. + // Note the acquire fence synchronizes with the release fence at the end of this block, and hence when + // we reload implicitProducerHash it must be the most recent version (it only gets changed within this + // locked block). + mainHash = implicitProducerHash.load(std::memory_order_acquire); + if (newCount >= (mainHash->capacity >> 1)) { + auto newCapacity = mainHash->capacity << 1; + while (newCount >= (newCapacity >> 1)) { + newCapacity <<= 1; + } + auto raw = static_cast((Traits::malloc)(sizeof(ImplicitProducerHash) + std::alignment_of::value - 1 + sizeof(ImplicitProducerKVP) * newCapacity)); + if (raw == nullptr) { + // Allocation failed + implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed); + implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); + return nullptr; + } + + auto newHash = new (raw) ImplicitProducerHash; + newHash->capacity = newCapacity; + newHash->entries = reinterpret_cast(details::align_for(raw + sizeof(ImplicitProducerHash))); + for (size_t i = 0; i != newCapacity; ++i) { + new (newHash->entries + i) ImplicitProducerKVP; + newHash->entries[i].key.store(details::invalid_thread_id, std::memory_order_relaxed); + } + newHash->prev = mainHash; + implicitProducerHash.store(newHash, std::memory_order_release); + implicitProducerHashResizeInProgress.clear(std::memory_order_release); + mainHash = newHash; + } + else { + implicitProducerHashResizeInProgress.clear(std::memory_order_release); + } + } + + // If it's < three-quarters full, add to the old one anyway so that we don't have to wait for the next table + // to finish being allocated by another thread (and if we just finished allocating above, the condition will + // always be true) + if (newCount < (mainHash->capacity >> 1) + (mainHash->capacity >> 2)) { + bool recycled; + auto producer = static_cast(recycle_or_create_producer(false, recycled)); + if (producer == nullptr) { + implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed); + return nullptr; + } + if (recycled) { + implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed); + } + +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED + producer->threadExitListener.callback = &ConcurrentQueue::implicit_producer_thread_exited_callback; + producer->threadExitListener.userData = producer; + details::ThreadExitNotifier::subscribe(&producer->threadExitListener); +#endif + + auto index = hashedId; + while (true) { + index &= mainHash->capacity - 1; + auto probedKey = mainHash->entries[index].key.load(std::memory_order_relaxed); + + auto empty = details::invalid_thread_id; +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED + auto reusable = details::invalid_thread_id2; + if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed)) || + (probedKey == reusable && mainHash->entries[index].key.compare_exchange_strong(reusable, id, std::memory_order_acquire, std::memory_order_acquire))) { +#else + if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed))) { +#endif + mainHash->entries[index].value = producer; + break; + } + ++index; + } + return producer; + } + + // Hmm, the old hash is quite full and somebody else is busy allocating a new one. + // We need to wait for the allocating thread to finish (if it succeeds, we add, if not, + // we try to allocate ourselves). + mainHash = implicitProducerHash.load(std::memory_order_acquire); + } + } + +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED + void implicit_producer_thread_exited(ImplicitProducer* producer) + { + // Remove from thread exit listeners + details::ThreadExitNotifier::unsubscribe(&producer->threadExitListener); + + // Remove from hash +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH + debug::DebugLock lock(implicitProdMutex); +#endif + auto hash = implicitProducerHash.load(std::memory_order_acquire); + assert(hash != nullptr); // The thread exit listener is only registered if we were added to a hash in the first place + auto id = details::thread_id(); + auto hashedId = details::hash_thread_id(id); + details::thread_id_t probedKey; + + // We need to traverse all the hashes just in case other threads aren't on the current one yet and are + // trying to add an entry thinking there's a free slot (because they reused a producer) + for (; hash != nullptr; hash = hash->prev) { + auto index = hashedId; + do { + index &= hash->capacity - 1; + probedKey = hash->entries[index].key.load(std::memory_order_relaxed); + if (probedKey == id) { + hash->entries[index].key.store(details::invalid_thread_id2, std::memory_order_release); + break; + } + ++index; + } while (probedKey != details::invalid_thread_id); // Can happen if the hash has changed but we weren't put back in it yet, or if we weren't added to this hash in the first place + } + + // Mark the queue as being recyclable + producer->inactive.store(true, std::memory_order_release); + } + + static void implicit_producer_thread_exited_callback(void* userData) + { + auto producer = static_cast(userData); + auto queue = producer->parent; + queue->implicit_producer_thread_exited(producer); + } +#endif + + ////////////////////////////////// + // Utility functions + ////////////////////////////////// + + template + static inline U* create_array(size_t count) + { + assert(count > 0); + auto p = static_cast((Traits::malloc)(sizeof(U) * count)); + if (p == nullptr) { + return nullptr; + } + + for (size_t i = 0; i != count; ++i) { + new (p + i) U(); + } + return p; + } + + template + static inline void destroy_array(U* p, size_t count) + { + if (p != nullptr) { + assert(count > 0); + for (size_t i = count; i != 0; ) { + (p + --i)->~U(); + } + (Traits::free)(p); + } + } + + template + static inline U* create() + { + auto p = (Traits::malloc)(sizeof(U)); + return p != nullptr ? new (p) U : nullptr; + } + + template + static inline U* create(A1&& a1) + { + auto p = (Traits::malloc)(sizeof(U)); + return p != nullptr ? new (p) U(std::forward(a1)) : nullptr; + } + + template + static inline void destroy(U* p) + { + if (p != nullptr) { + p->~U(); + } + (Traits::free)(p); + } + +private: + std::atomic producerListTail; + std::atomic producerCount; + + std::atomic initialBlockPoolIndex; + Block* initialBlockPool; + size_t initialBlockPoolSize; + +#if !MCDBGQ_USEDEBUGFREELIST + FreeList freeList; +#else + debug::DebugFreeList freeList; +#endif + + std::atomic implicitProducerHash; + std::atomic implicitProducerHashCount; // Number of slots logically used + ImplicitProducerHash initialImplicitProducerHash; + std::array initialImplicitProducerHashEntries; + std::atomic_flag implicitProducerHashResizeInProgress; + + std::atomic nextExplicitConsumerId; + std::atomic globalExplicitConsumerOffset; + +#if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH + debug::DebugMutex implicitProdMutex; +#endif + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + std::atomic explicitProducers; + std::atomic implicitProducers; +#endif +}; + + +template +ProducerToken::ProducerToken(ConcurrentQueue& queue) + : producer(queue.recycle_or_create_producer(true)) +{ + if (producer != nullptr) { + producer->token = this; + } +} + +template +ProducerToken::ProducerToken(BlockingConcurrentQueue& queue) + : producer(reinterpret_cast*>(&queue)->recycle_or_create_producer(true)) +{ + if (producer != nullptr) { + producer->token = this; + } +} + +template +ConsumerToken::ConsumerToken(ConcurrentQueue& queue) + : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr) +{ + initialOffset = queue.nextExplicitConsumerId.fetch_add(1, std::memory_order_release); + lastKnownGlobalOffset = -1; +} + +template +ConsumerToken::ConsumerToken(BlockingConcurrentQueue& queue) + : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr) +{ + initialOffset = reinterpret_cast*>(&queue)->nextExplicitConsumerId.fetch_add(1, std::memory_order_release); + lastKnownGlobalOffset = -1; +} + +template +inline void swap(ConcurrentQueue& a, ConcurrentQueue& b) MOODYCAMEL_NOEXCEPT +{ + a.swap(b); +} + +inline void swap(ProducerToken& a, ProducerToken& b) MOODYCAMEL_NOEXCEPT +{ + a.swap(b); +} + +inline void swap(ConsumerToken& a, ConsumerToken& b) MOODYCAMEL_NOEXCEPT +{ + a.swap(b); +} + +template +inline void swap(typename ConcurrentQueue::ImplicitProducerKVP& a, typename ConcurrentQueue::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT +{ + a.swap(b); +} + +} + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif diff --git a/ext/lwip-contrib.patch b/ext/lwip-contrib.patch deleted file mode 100644 index 8d80f11..0000000 --- a/ext/lwip-contrib.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/ports/unix/port/include/arch/cc.h b/ports/unix/port/include/arch/cc.h -index 80b37d8..ae46d76 100644 ---- a/ports/unix/port/include/arch/cc.h -+++ b/ports/unix/port/include/arch/cc.h -@@ -32,6 +32,8 @@ - #ifndef LWIP_ARCH_CC_H - #define LWIP_ARCH_CC_H - -+#include "include/Debug.hpp" // libzt -+ - /* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ - #if defined __ANDROID__ - #define LWIP_UNIX_ANDROID -@@ -65,7 +67,7 @@ - #endif - - #if defined(LWIP_UNIX_ANDROID) && defined(FD_SET) --typedef __kernel_fd_set fd_set; -+//typedef __kernel_fd_set fd_set; - #endif - - #if defined(LWIP_UNIX_MACH) -@@ -81,6 +83,9 @@ typedef struct sio_status_s sio_status_t; - #define sio_fd_t sio_status_t* - #define __sio_fd_t_defined - -+// Comment out the following line to use lwIP's default diagnostic printing routine -+#define LWIP_PLATFORM_DIAG(x) do {DEBUG_INFO x;} while(0) -+ - typedef unsigned int sys_prot_t; - - #endif /* LWIP_ARCH_CC_H */ diff --git a/ext/lwipopts.h b/ext/lwipopts.h deleted file mode 100644 index b018998..0000000 --- a/ext/lwipopts.h +++ /dev/null @@ -1,2 +0,0 @@ -// Refers to the actual lwIP stack driver location -#include "../include/lwipopts.h" \ No newline at end of file diff --git a/include/Constants.hpp b/include/Constants.hpp deleted file mode 100644 index f511004..0000000 --- a/include/Constants.hpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2019 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. - */ - -/** - * @file - * - * Useful constants - */ - -#ifndef LIBZT_CONSTANTS_HPP -#define LIBZT_CONSTANTS_HPP - -////////////////////////////////////////////////////////////////////////////// -// Callbacks // -////////////////////////////////////////////////////////////////////////////// - -#define ZTS_NODE_CALLBACKS 1 -#define ZTS_NETWORK_CALLBACKS 1 -#define ZTS_NETIF_CALLBACKS 1 -#define ZTS_PEER_CALLBACKS 1 - -#define ZTS_CALLBACK_PROCESSING_INTERVAL ZTS_WRAPPER_CHECK_INTERVAL // 100 // ms -#define ZTS_CALLBACK_MSG_QUEUE_LEN 256 - -////////////////////////////////////////////////////////////////////////////// -// Error codes returned by ZeroTier and the libzt API // -// See ext/ZeroTierOne/include/ZeroTierOne.h // -////////////////////////////////////////////////////////////////////////////// - -typedef int zts_err_t; - -#define ZTS_ERR_OK 0 // Everything is ok -#define ZTS_ERR_INVALID_ARG -1 // A parameter provided by the user application is invalid (e.g. our of range, NULL, etc) -#define ZTS_ERR_SERVICE -2 // The service isn't initialized or is for some other reason currently unavailable -#define ZTS_ERR_INVALID_OP -3 // For some reason this API operation is not permitted (perhaps the service is still starting?) - -#define ZTS_EVENT_NONE 0x00000000 -// Node-specific events -#define ZTS_EVENT_NODE_ONLINE 0x00000001 // Node is online -#define ZTS_EVENT_NODE_OFFLINE 0x00000002 // Node is offline -#define ZTS_EVENT_NODE_DOWN 0x00000004 // Node is shutting down -#define ZTS_EVENT_NODE_IDENTITY_COLLISION 0x00000008 // Identity collision - check for duplicate instances -#define ZTS_EVENT_NODE_UNRECOVERABLE_ERROR 0x00000010 // Something is seriously wrong -#define ZTS_EVENT_NODE_NORMAL_TERMINATION 0x00000020 // Service thread has stopped -// Network-specific events -#define ZTS_EVENT_NETWORK_NOT_FOUND 0x00000080 -#define ZTS_EVENT_NETWORK_CLIENT_TOO_OLD 0x00000100 -#define ZTS_EVENT_NETWORK_REQUESTING_CONFIG 0x00000200 -#define ZTS_EVENT_NETWORK_OK 0x00000400 -#define ZTS_EVENT_NETWORK_ACCESS_DENIED 0x00000800 -#define ZTS_EVENT_NETWORK_READY_IP4 0x00001000 -#define ZTS_EVENT_NETWORK_READY_IP6 0x00002000 -#define ZTS_EVENT_NETWORK_DOWN 0x00004000 -#define ZTS_EVENT_NETWORK_STATUS_CHANGE ZTS_EVENT_NETWORK_NOT_FOUND | ZTS_EVENT_NETWORK_CLIENT_TOO_OLD | ZTS_EVENT_NETWORK_REQUESTING_CONFIG | ZTS_EVENT_NETWORK_OK | ZTS_EVENT_NETWORK_ACCESS_DENIED -// lwIP netif events -#define ZTS_EVENT_NETIF_UP_IP4 0x00100000 -#define ZTS_EVENT_NETIF_UP_IP6 0x00200000 -#define ZTS_EVENT_NETIF_DOWN_IP4 0x00400000 -#define ZTS_EVENT_NETIF_DOWN_IP6 0x00800000 -#define ZTS_EVENT_NETIF_REMOVED 0x01000000 -#define ZTS_EVENT_NETIF_LINK_UP 0x02000000 -#define ZTS_EVENT_NETIF_LINK_DOWN 0x04000000 -#define ZTS_EVENT_NETIF_NEW_ADDRESS 0x08000000 -#define ZTS_EVENT_NETIF_STATUS_CHANGE ZTS_EVENT_NETIF_UP_IP4 | ZTS_EVENT_NETIF_UP_IP6 | ZTS_EVENT_NETIF_DOWN_IP4 | ZTS_EVENT_NETIF_DOWN_IP6 | ZTS_EVENT_NETIF_LINK_UP | ZTS_EVENT_NETIF_LINK_DOWN -// -#define ZTS_EVENT_GENERIC_DOWN ZTS_EVENT_NETWORK_DOWN | ZTS_EVENT_NETIF_DOWN_IP4 | ZTS_EVENT_NETIF_DOWN_IP6 | ZTS_EVENT_NETIF_LINK_DOWN -// Peer events -#define ZTS_EVENT_PEER_P2P 0x20000000 -#define ZTS_EVENT_PEER_RELAY 0x40000000 -#define ZTS_EVENT_PEER_UNREACHABLE 0x80000000 // Not yet supported - -////////////////////////////////////////////////////////////////////////////// -// libzt config // -////////////////////////////////////////////////////////////////////////////// - -/** - * Default port that libzt will use to support all virtual communication - */ -#define ZTS_DEFAULT_PORT 9994 - -/** - * Maximum port number allowed - */ -#define ZTS_MAX_PORT 65535 - -/** - * For layer-2 only (this will omit all user-space network stack code) - */ -#define ZTS_NO_STACK 0 - -/** - * How fast service states are re-checked (in milliseconds) - */ -#define ZTS_WRAPPER_CHECK_INTERVAL 50 - -/** - * By how much thread I/O and callback loop delays are multiplied (unitless) - */ -#define ZTS_HIBERNATION_MULTIPLIER 50 - -/** - * Maximum allowed number of networks joined to concurrently - */ -#define ZTS_MAX_JOINED_NETWORKS 64 - -/** - * Maximum address assignments per network - */ -#define ZTS_MAX_ASSIGNED_ADDRESSES 16 - -/** - * Maximum routes per network - */ -#define ZTS_MAX_NETWORK_ROUTES 32 - -/** - * Length of buffer required to hold a ztAddress/nodeID - */ -#define ZTS_ID_LEN 16 - -/** - * Polling interval (in ms) for file descriptors wrapped in the Phy I/O loop (for raw drivers only) - */ -#define ZTS_PHY_POLL_INTERVAL 1 - -/** - * Maximum length of libzt/ZeroTier home path (where keys, and config files are stored) - */ -#define ZTS_HOME_PATH_MAX_LEN 256 - -/** - * Length of human-readable MAC address string - */ -#define ZTS_MAC_ADDRSTRLEN 18 - -/** - * Interval (in ms) for performing background tasks - */ -#define ZTS_HOUSEKEEPING_INTERVAL 1000 - -/** - * Name of the service thread (for debug purposes only) - */ -#define ZTS_SERVICE_THREAD_NAME "ZeroTierServiceThread" - -/** - * Name of the callback monitor thread (for debug purposes only) - */ -#define ZTS_EVENT_CALLBACK_THREAD_NAME "ZeroTierEventCallbackThread" - -////////////////////////////////////////////////////////////////////////////// -// lwIP driver config // -// For more LWIP configuration options see: include/lwipopts.h // -////////////////////////////////////////////////////////////////////////////// - -/* - * The following three quantities are related and govern how incoming frames are fed into the - * network stack's core: - - * Every LWIP_GUARDED_BUF_CHECK_INTERVAL milliseconds, a callback will be called from the core and - * will input a maximum of LWIP_FRAMES_HANDLED_PER_CORE_CALL frames before returning control back - * to the core. Meanwhile, incoming frames from the ZeroTier wire will be allocated and their - * pointers will be cached in the receive frame buffer of the size LWIP_MAX_GUARDED_RX_BUF_SZ to - * await the next callback from the core - */ - -#define LWIP_GUARDED_BUF_CHECK_INTERVAL 5 // in ms -#define LWIP_MAX_GUARDED_RX_BUF_SZ 1024 // number of frame pointers that can be cached waiting for receipt into core -#define LWIP_FRAMES_HANDLED_PER_CORE_CALL 16 // How many frames are handled per call from core - -typedef signed char err_t; - -#define ND6_DISCOVERY_INTERVAL 1000 -#define ARP_DISCOVERY_INTERVAL ARP_TMR_INTERVAL - -////////////////////////////////////////////////////////////////////////////// -// Subset of: ZeroTierOne.h and Constants.hpp // -// We redefine a few ZT structures here so that we don't need to drag the // -// entire ZeroTierOne.h file into the user application // -////////////////////////////////////////////////////////////////////////////// - -/** - * Maximum MTU size for ZeroTier - */ -#define ZT_MAX_MTU 10000 - -/** - * Maximum number of direct network paths to a given peer - */ -#define ZT_MAX_PEER_NETWORK_PATHS 16 - -// -// This include file also auto-detects and canonicalizes some environment -// information defines: -// -// __LINUX__ -// __APPLE__ -// __BSD__ (OSX also defines this) -// __UNIX_LIKE__ (Linux, BSD, etc.) -// __WINDOWS__ -// -// Also makes sure __BYTE_ORDER is defined reasonably. -// - -// Hack: make sure __GCC__ is defined on old GCC compilers -#ifndef __GCC__ -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) -#define __GCC__ -#endif -#endif - -#if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) -#ifndef __LINUX__ -#define __LINUX__ -#endif -#ifndef __UNIX_LIKE__ -#define __UNIX_LIKE__ -#endif -#include -#endif - -#ifdef __APPLE__ -#define likely(x) __builtin_expect((x),1) -#define unlikely(x) __builtin_expect((x),0) -#include -#ifndef __UNIX_LIKE__ -#define __UNIX_LIKE__ -#endif -#ifndef __BSD__ -#define __BSD__ -#endif -#include -#endif - -// Defined this macro to disable "type punning" on a number of targets that -// have issues with unaligned memory access. -#if defined(__arm__) || defined(__ARMEL__) || (defined(__APPLE__) && ( (defined(TARGET_OS_IPHONE) && (TARGET_OS_IPHONE != 0)) || (defined(TARGET_OS_WATCH) && (TARGET_OS_WATCH != 0)) || (defined(TARGET_IPHONE_SIMULATOR) && (TARGET_IPHONE_SIMULATOR != 0)) ) ) -#ifndef ZT_NO_TYPE_PUNNING -#define ZT_NO_TYPE_PUNNING -#endif -#endif - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -#ifndef __UNIX_LIKE__ -#define __UNIX_LIKE__ -#endif -#ifndef __BSD__ -#define __BSD__ -#endif -#include -#ifndef __BYTE_ORDER -#define __BYTE_ORDER _BYTE_ORDER -#define __LITTLE_ENDIAN _LITTLE_ENDIAN -#define __BIG_ENDIAN _BIG_ENDIAN -#endif -#endif - -#if defined(_WIN32) || defined(_WIN64) -#ifndef __WINDOWS__ -#define __WINDOWS__ -#endif -#ifndef NOMINMAX -#define NOMINMAX -#endif -#pragma warning(disable : 4290) -#pragma warning(disable : 4996) -#pragma warning(disable : 4101) -#undef __UNIX_LIKE__ -#undef __BSD__ -#define ZT_PATH_SEPARATOR '\\' -#define ZT_PATH_SEPARATOR_S "\\" -#define ZT_EOL_S "\r\n" -#include -#include -#endif - -// Assume little endian if not defined -#if (defined(__APPLE__) || defined(__WINDOWS__)) && (!defined(__BYTE_ORDER)) -#undef __BYTE_ORDER -#undef __LITTLE_ENDIAN -#undef __BIG_ENDIAN -#define __BIG_ENDIAN 4321 -#define __LITTLE_ENDIAN 1234 -#define __BYTE_ORDER 1234 -#endif - -#ifdef __UNIX_LIKE__ -#define ZT_PATH_SEPARATOR '/' -#define ZT_PATH_SEPARATOR_S "/" -#define ZT_EOL_S "\n" -#endif - -#ifndef __BYTE_ORDER -#include -#endif - -#ifdef __NetBSD__ -#define RTF_MULTICAST 0x20000000 -#endif - -#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) -#ifndef likely -#define likely(x) __builtin_expect((x),1) -#endif -#ifndef unlikely -#define unlikely(x) __builtin_expect((x),0) -#endif -#else -#ifndef likely -#define likely(x) (x) -#endif -#ifndef unlikely -#define unlikely(x) (x) -#endif -#endif - -#ifdef __WINDOWS__ -#define ZT_PACKED_STRUCT(D) __pragma(pack(push,1)) D __pragma(pack(pop)) -#else -#define ZT_PACKED_STRUCT(D) D __attribute__((packed)) -#endif - -#endif // _H \ No newline at end of file diff --git a/include/Defs.hpp b/include/Defs.hpp deleted file mode 100644 index 39a8162..0000000 --- a/include/Defs.hpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2019 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. - */ - -/** - * @file - * - * Management of virtual tap interfaces - */ - -#ifndef LIBZT_DEFS_HPP -#define LIBZT_DEFS_HPP - -#include "Constants.hpp" - -#ifndef _USING_LWIP_DEFINITIONS_ -#include -#endif - -namespace ZeroTier { - -////////////////////////////////////////////////////////////////////////////// -// Subset of: ZeroTierOne.h // -// We redefine a few ZT structures here so that we don't need to drag the // -// entire ZeroTierOne.h file into the user application // -////////////////////////////////////////////////////////////////////////////// - -/** - * What trust hierarchy role does this peer have? - */ -enum zts_peer_role -{ - ZTS_PEER_ROLE_LEAF = 0, // ordinary node - ZTS_PEER_ROLE_MOON = 1, // moon root - ZTS_PEER_ROLE_PLANET = 2 // planetary root -}; - -/** - * A structure used to represent a virtual network route - */ -struct zts_virtual_network_route -{ - /** - * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default - */ - struct sockaddr_storage target; - - /** - * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) - */ - struct sockaddr_storage via; - - /** - * Route flags - */ - uint16_t flags; - - /** - * Route metric (not currently used) - */ - uint16_t metric; -}; - -/** - * A structure used to convey network-specific details to the user application - */ -struct zts_network_details -{ - /** - * Network ID - */ - uint64_t nwid; - - /** - * Maximum Transmission Unit size for this network - */ - int mtu; - - /** - * Number of addresses (actually) assigned to the node on this network - */ - short num_addresses; - - /** - * Array of IPv4 and IPv6 addresses assigned to the node on this network - */ - struct sockaddr_storage addr[ZTS_MAX_ASSIGNED_ADDRESSES]; - - /** - * Number of routes - */ - unsigned int num_routes; - - /** - * Array of IPv4 and IPv6 addresses assigned to the node on this network - */ - struct zts_virtual_network_route routes[ZTS_MAX_NETWORK_ROUTES]; -}; - -/** - * Physical network path to a peer - */ -struct zts_physical_path -{ - /** - * Address of endpoint - */ - struct sockaddr_storage address; - - /** - * Time of last send in milliseconds or 0 for never - */ - uint64_t lastSend; - - /** - * Time of last receive in milliseconds or 0 for never - */ - uint64_t lastReceive; - - /** - * Is this a trusted path? If so this will be its nonzero ID. - */ - uint64_t trustedPathId; - - /** - * Is path expired? - */ - int expired; - - /** - * Is path preferred? - */ - int preferred; -}; - -/** - * Peer status result buffer - */ -struct zts_peer_details -{ - /** - * ZeroTier address (40 bits) - */ - uint64_t address; - - /** - * Remote major version or -1 if not known - */ - int versionMajor; - - /** - * Remote minor version or -1 if not known - */ - int versionMinor; - - /** - * Remote revision or -1 if not known - */ - int versionRev; - - /** - * Last measured latency in milliseconds or -1 if unknown - */ - int latency; - - /** - * What trust hierarchy role does this device have? - */ - enum zts_peer_role role; - - /** - * Number of paths (size of paths[]) - */ - unsigned int pathCount; - - /** - * Known network paths to peer - */ - zts_physical_path paths[ZT_MAX_PEER_NETWORK_PATHS]; -}; - -/** - * List of peers - */ -struct zts_peer_list -{ - zts_peer_details *peers; - unsigned long peerCount; -}; - -} // namespace ZeroTier - -#endif // _H \ No newline at end of file diff --git a/include/RingBuffer.h b/include/RingBuffer.h deleted file mode 100644 index e143584..0000000 --- a/include/RingBuffer.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2019 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. - */ - -/** - * @file - * - * Ring buffer implementation for network stack drivers - */ - -#ifndef ZT_RINGBUFFER_H -#define ZT_RINGBUFFER_H - -#include -#include - -typedef char bufElementType; - -class RingBuffer -{ -private: - bufElementType * buf; - size_t size; - size_t begin; - size_t end; - bool wrap; - -public: - /** - * create a RingBuffer with space for up to size elements. - */ - explicit RingBuffer(size_t size) - : size(size), - begin(0), - end(0), - wrap(false) - { - buf = new bufElementType[size]; - } -/* - RingBuffer(const RingBuffer & ring) - { - this(ring.size); - begin = ring.begin; - end = ring.end; - memcpy(buf, ring.buf, sizeof(T) * size); - } -*/ - ~RingBuffer() - { - delete[] buf; - } - - // get a reference to the underlying buffer - bufElementType* get_buf(); - - // adjust buffer index pointer as if we copied data in - size_t produce(size_t n); - - // merely reset the buffer pointer, doesn't erase contents - void reset(); - - // adjust buffer index pointer as if we copied data out - size_t consume(size_t n); - - size_t write(const bufElementType * data, size_t n); - - size_t read(bufElementType * dest, size_t n); - - size_t count(); - - size_t getFree(); -}; - -#endif // _H diff --git a/include/ServiceControls.hpp b/include/ServiceControls.hpp deleted file mode 100644 index 9ceca6c..0000000 --- a/include/ServiceControls.hpp +++ /dev/null @@ -1,393 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2019 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. - */ - -/** - * @file - * - * Header for ZeroTier service controls - */ - -#ifndef LIBZT_SERVICE_CONTROLS_HPP -#define LIBZT_SERVICE_CONTROLS_HPP - -#include "Constants.hpp" - -namespace ZeroTier { - -#ifdef _WIN32 - #ifdef ADD_EXPORTS - #define ZT_SOCKET_API __declspec(dllexport) - #else - #define ZT_SOCKET_API __declspec(dllimport) - #endif - #define ZTCALL __cdecl -#else - #define ZT_SOCKET_API - #define ZTCALL -#endif - -////////////////////////////////////////////////////////////////////////////// -// ZeroTier Service Controls // -////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief (optional) Sets the port for the background libzt service. If this function is called - * with a port number between 1-65535 it will attempt to bind to that port. If it is called with - * a port number of 0 it will attempt to randomly search for an available port. If this function - * is never called, the service will try to bind on LIBZT_DEFAULT_PORT which is 9994. - * - * @usage Should be called at the beginning of your application before `zts_startjoin()` - * @param portno Port number - * @return 0 if successful; or -1 if failed - */ -ZT_SOCKET_API int ZTCALL zts_set_service_port(int portno); - -/** - * @brief (optional) Returns the port number used by the ZeroTier service - * @usage Can be called if a port number was previously assigned - * @return the port number used by the ZeroTier service - */ -ZT_SOCKET_API int ZTCALL zts_get_service_port(); - -/** - * @brief Starts the ZeroTier service - * - * @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met: - * - ZeroTier core service has been initialized - * - Cryptographic identity has been generated or loaded from directory specified by `path` - * - Virtual network is successfully joined - * - IP address is assigned by network controller service - * @param path path directory where cryptographic identities and network configuration files are stored and retrieved - * (`identity.public`, `identity.secret`) - * @param blocking whether or not this call will block until the entire service is up and running - * @return 0 if successful; or 1 if failed - */ -ZT_SOCKET_API int ZTCALL zts_start(const char *path, int blocking); - -/** - * @brief Starts the ZeroTier service and notifies user application of events via callback - * - * @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met: - * - ZeroTier core service has been initialized - * - Cryptographic identity has been generated or loaded from directory specified by `path` - * - Virtual network is successfully joined - * - IP address is assigned by network controller service - * @param path path directory where cryptographic identities and network configuration files are stored and retrieved - * (`identity.public`, `identity.secret`) - * @param userCallbackFunc User-specified callback for ZeroTier events - * @param blocking whether or not this call will block until the entire service is up and running - * @return 0 if successful; or 1 if failed - */ -ZT_SOCKET_API int ZTCALL zts_start_with_callback(const char *path, void (*userCallbackFunc)(uint64_t, int), int blocking); - -/** - * @brief Starts the ZeroTier service - * - * @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met: - * - ZeroTier core service has been initialized - * - Cryptographic identity has been generated or loaded from directory specified by `path` - * - Virtual network is successfully joined - * - IP address is assigned by network controller service - * @param path path directory where cryptographic identities and network configuration files are stored and retrieved - * (`identity.public`, `identity.secret`) - * @param nwid A 16-digit hexidecimal network identifier (e.g. Earth: `8056c2e21c000001`) - * @return 0 if successful; or 1 if failed - */ -ZT_SOCKET_API int ZTCALL zts_startjoin(const char *path, const uint64_t nwid); - -/** - * @brief Stops the ZeroTier service, brings down all virtual interfaces in order to stop all traffic processing. - * - * @usage This should be called when the application anticipates not needing any sort of traffic processing for a - * prolonged period of time. The stack driver (with associated timers) will remain active in case future traffic - * processing is required. Note that the application must tolerate a multi-second startup time if zts_start() - * zts_startjoin() is called again. To stop this background thread and free all resources use zts_free() instead. - * @param blocking whether or not this call will block until the entire service is torn down - * @return Returns 0 on success, -1 on failure - */ -ZT_SOCKET_API int ZTCALL zts_stop(int blocking = 1); - -/** - * @brief Stops all background services, brings down all interfaces, frees all resources. After calling this function - * an application restart will be required before the library can be used again. This is a blocking call. - * - * @usage This should be called at the end of your program or when you do not anticipate communicating over ZeroTier - * @return Returns 0 on success, -1 on failure - */ -ZT_SOCKET_API int ZTCALL zts_free(); - -/** - * @brief Return whether the ZeroTier service is currently running - * - * @usage Call this after zts_start() - * @return 1 if running, 0 if not running - */ -ZT_SOCKET_API int ZTCALL zts_core_running(); - -/** - * @brief Return whether libzt is ready to handle socket API calls. Alternatively you could - * have just called zts_startjoin(path, nwid) - * - * @usage Call this after zts_start() - * @return 1 if running, 0 if not running - */ -ZT_SOCKET_API int ZTCALL zts_ready(); - -/** - * @brief Return the number of networks currently joined by this node - * - * @usage Call this after zts_start(), zts_startjoin() and/or zts_join() - * @return Number of networks joined by this node - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_get_num_joined_networks(); - -/** - * @brief Populates a structure with details for a given network - * - * @usage Call this from the application thread any time after the node has joined a network - * @param nwid A 16-digit hexidecimal virtual network ID - * @param nd Pointer to a zts_network_details structure to populate - * @return ZTS_ERR_SERVICE if failed, 0 if otherwise - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_get_network_details(uint64_t nwid, struct zts_network_details *nd); - -/** - * @brief Populates an array of structures with details for any given number of networks - * - * @usage Call this from the application thread any time after the node has joined a network - * @param nds Pointer to an array of zts_network_details structures to populate - * @param num Number of zts_network_details structures available to copy data into, will be updated - * to reflect number of structures that were actually populated - * @return ZTS_ERR_SERVICE if failed, 0 if otherwise - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_get_all_network_details(struct zts_network_details *nds, int *num); - -/** - * @brief Join a network - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param nwid A 16-digit hexidecimal virtual network ID - * @return 0 if successful, -1 for any failure - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_join(const uint64_t nwid, int blocking = 1); - -/** - * @brief Leave a network - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param nwid A 16-digit hexidecimal virtual network ID - * @return 0 if successful, -1 for any failure - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_leave(const uint64_t nwid, int blocking = 1); - - -/** - * @brief Leaves all networks - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param nwid A 16-digit hexidecimal virtual network ID - * @return 0 if successful, -1 for any failure - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_leave_all(int blocking = 1); - -/** - * @brief Orbits a given moon (user-defined root server) - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param moonWorldId A 16-digit hexidecimal world ID - * @param moonSeed A 16-digit hexidecimal seed ID - * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed); - -/** - * @brief De-orbits a given moon (user-defined root server) - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param moonWorldId A 16-digit hexidecimal world ID - * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_deorbit(uint64_t moonWorldId); - -/** - * @brief Copies the configuration path used by ZeroTier into the provided buffer - * - * @usage Use this to determine where ZeroTier is storing identity files - * @param homePath Path to ZeroTier configuration files - * @param len Length of destination buffer - * @return 0 if no error, -1 if invalid argument was supplied - */ -ZT_SOCKET_API zts_err_t ZTCALL zts_get_path(char *homePath, size_t *len); - -/** - * @brief Returns the node ID of this instance - * - * @usage Call this after zts_start() and/or when zts_running() returns true - * @return - */ -ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id(); - -/** - * @brief Returns whether any address has been assigned to the SockTap for this network - * - * @usage This is used as an indicator of readiness for service for the ZeroTier core and stack - * @param nwid Network ID - * @return - */ -ZT_SOCKET_API int ZTCALL zts_has_address(const uint64_t nwid); - - -/** - * @brief Returns the number of addresses assigned to this node for the given nwid - * - * @param nwid Network ID - * @return The number of addresses assigned - */ -ZT_SOCKET_API int ZTCALL zts_get_num_assigned_addresses(const uint64_t nwid); - -/** - * @brief Returns the assigned address located at the given index - * - * @usage The indices of each assigned address are not guaranteed and should only - * be used for iterative purposes. - * @param nwid Network ID - * @param index location of assigned address - * @return The number of addresses assigned - */ -ZT_SOCKET_API int ZTCALL zts_get_address_at_index( - const uint64_t nwid, const int index, struct sockaddr *addr, socklen_t *addrlen); - -/** - * @brief Get IP address for this device on a given network - * - * @usage FIXME: Only returns first address found, good enough for most cases - * @param nwid Network ID - * @param addr Destination structure for address - * @param addrlen size of destination address buffer, will be changed to size of returned address - * @return 0 if an address was successfully found, -1 if failure - */ -ZT_SOCKET_API int ZTCALL zts_get_address( - const uint64_t nwid, struct sockaddr_storage *addr, const int address_family); - -/** - * @brief Computes a 6PLANE IPv6 address for the given Network ID and Node ID - * - * @usage Can call any time - * @param addr Destination structure for address - * @param nwid Network ID - * @param nodeId Node ID - * @return - */ -ZT_SOCKET_API void ZTCALL zts_get_6plane_addr( - struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); - -/** - * @brief Computes a RFC4193 IPv6 address for the given Network ID and Node ID - * - * @usage Can call any time - * @param addr Destination structure for address - * @param nwid Network ID - * @param nodeId Node ID - * @return - */ -ZT_SOCKET_API void ZTCALL zts_get_rfc4193_addr( - struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); - -/** - * @brief Return the number of peers - * - * @usage Call this after zts_start() has succeeded - * @return - */ -ZT_SOCKET_API zts_err_t zts_get_peer_count(); - -ZT_SOCKET_API zts_err_t zts_get_peers(struct zts_peer_details *pds, int *num); - -/** - * @brief Enables the HTTP backplane management system - * - * @usage Call this after zts_start() has succeeded - * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE if otherwise - */ -ZT_SOCKET_API zts_err_t zts_enable_http_backplane_mgmt(); - -/** - * @brief Disables the HTTP backplane management system - * - * @usage Call this after zts_start() has succeeded - * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_OP if otherwise - */ -ZT_SOCKET_API zts_err_t zts_disable_http_backplane_mgmt(); - - -/** - * @brief Starts a ZeroTier service in the background - * - * @usage For internal use only. - * @param - * @return - */ -#if defined(_WIN32) -DWORD WINAPI _zts_start_service(LPVOID thread_id); -#else -void *_zts_start_service(void *thread_id); -#endif - -/** - * @brief [Should not be called from user application] This function must be surrounded by - * ZT service locks. It will determine if it is currently safe and allowed to operate on - * the service. - * @usage Can be called at any time - * @return 1 or 0 - */ -int _zts_can_perform_service_operation(); - -/** - * @brief [Should not be called from user application] Returns whether or not the node is - * online. - * @usage Can be called at any time - * @return 1 or 0 - */ -int _zts_node_online(); - -/** - * @brief [Should not be called from user application] Adjusts the delay multiplier for the - * network stack driver thread. - * @usage Can be called at any time - */ -void _hibernate_if_needed(); - -#ifdef __cplusplus -} -#endif - -} // namespace ZeroTier - -#endif // _H \ No newline at end of file diff --git a/include/libzt.h b/include/libzt.h index 2f75735..950ce60 100644 --- a/include/libzt.h +++ b/include/libzt.h @@ -63,22 +63,86 @@ typedef int socklen_t; #include #endif +/* #ifdef _USING_LWIP_DEFINITIONS_ #include "lwip/sockets.h" #endif - -#include "Constants.hpp" -#include "Defs.hpp" -#include "ServiceControls.hpp" - -class InetAddress; -class VirtualTap; +*/ #if defined(_MSC_VER) #include typedef SSIZE_T ssize_t; #endif +namespace ZeroTier { + +#ifdef __cplusplus +extern "C" { +#endif + +// Custom errno to prevent conflicts with platform's own errno +extern int zts_errno; +typedef int zts_err_t; + +#ifdef __cplusplus +} +#endif + +/** + * The system port upon which ZT traffic is sent and received + */ +#define ZTS_DEFAULT_PORT 9994 + +////////////////////////////////////////////////////////////////////////////// +// Control API error codes // +////////////////////////////////////////////////////////////////////////////// + +#define ZTS_ERR_OK 0 // Everything is ok +#define ZTS_ERR_INVALID_ARG -1 // A parameter provided by the user application is invalid (e.g. our of range, NULL, etc) +#define ZTS_ERR_SERVICE -2 // The service isn't initialized or is for some other reason currently unavailable +#define ZTS_ERR_INVALID_OP -3 // For some reason this API operation is not permitted (perhaps the service is still starting?) + +////////////////////////////////////////////////////////////////////////////// +// Control API event codes // +////////////////////////////////////////////////////////////////////////////// + +#define ZTS_EVENT_NONE -1 +#define ZTS_EVENT_NODE_UP 0 +// Standard node events +#define ZTS_EVENT_NODE_OFFLINE 1 +#define ZTS_EVENT_NODE_ONLINE 2 +#define ZTS_EVENT_NODE_DOWN 3 +#define ZTS_EVENT_NODE_IDENTITY_COLLISION 4 +// libzt node events +#define ZTS_EVENT_NODE_UNRECOVERABLE_ERROR 16 +#define ZTS_EVENT_NODE_NORMAL_TERMINATION 17 +// Network-specific events +#define ZTS_EVENT_NETWORK_NOT_FOUND 32 +#define ZTS_EVENT_NETWORK_CLIENT_TOO_OLD 33 +#define ZTS_EVENT_NETWORK_REQUESTING_CONFIG 34 +#define ZTS_EVENT_NETWORK_OK 35 +#define ZTS_EVENT_NETWORK_ACCESS_DENIED 36 +#define ZTS_EVENT_NETWORK_READY_IP4 37 +#define ZTS_EVENT_NETWORK_READY_IP6 38 +#define ZTS_EVENT_NETWORK_DOWN 39 +// +#define ZTS_EVENT_NETWORK_STACK_UP 48 +#define ZTS_EVENT_NETWORK_STACK_DOWN 49 + +// lwIP netif events +#define ZTS_EVENT_NETIF_UP_IP4 64 +#define ZTS_EVENT_NETIF_UP_IP6 65 +#define ZTS_EVENT_NETIF_DOWN_IP4 66 +#define ZTS_EVENT_NETIF_DOWN_IP6 67 +#define ZTS_EVENT_NETIF_REMOVED 68 +#define ZTS_EVENT_NETIF_LINK_UP 69 +#define ZTS_EVENT_NETIF_LINK_DOWN 70 +#define ZTS_EVENT_NETIF_NEW_ADDRESS 71 +// Peer events +#define ZTS_EVENT_PEER_P2P 96 +#define ZTS_EVENT_PEER_RELAY 97 +#define ZTS_EVENT_PEER_UNREACHABLE 98 + ////////////////////////////////////////////////////////////////////////////// // Common definitions and structures for interacting with the ZT socket API // // This is a subset of lwip/sockets.h, lwip/arch.h, and lwip/inet.h // @@ -196,7 +260,7 @@ typedef SSIZE_T ssize_t; #error "external ZTS_FD_SETSIZE too small for number of sockets" #endif // FD_SET -#if !defined(_USING_LWIP_DEFINITIONS_) +#if defined(_USING_LWIP_DEFINITIONS_) #ifdef __cplusplus extern "C" { @@ -322,15 +386,454 @@ struct sockaddr_ll { #endif ////////////////////////////////////////////////////////////////////////////// -// Socket API // +// Subset of: ZeroTierOne.h // +// We redefine a few ZT structures here so that we don't need to drag the // +// entire ZeroTierOne.h file into the user application // +////////////////////////////////////////////////////////////////////////////// + +/** + * Maximum address assignments per network + */ +#define ZTS_MAX_ASSIGNED_ADDRESSES 16 + +/** + * Maximum routes per network + */ +#define ZTS_MAX_NETWORK_ROUTES 32 + +/** + * Maximum number of direct network paths to a given peer + */ +#define ZT_MAX_PEER_NETWORK_PATHS 16 + +/** + * What trust hierarchy role does this peer have? + */ +enum zts_peer_role +{ + ZTS_PEER_ROLE_LEAF = 0, // ordinary node + ZTS_PEER_ROLE_MOON = 1, // moon root + ZTS_PEER_ROLE_PLANET = 2 // planetary root +}; + +/** + * A structure used to represent a virtual network route + */ +struct zts_virtual_network_route +{ + /** + * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default + */ + struct sockaddr_storage target; + + /** + * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) + */ + struct sockaddr_storage via; + + /** + * Route flags + */ + uint16_t flags; + + /** + * Route metric (not currently used) + */ + uint16_t metric; +}; + +/** + * A structure used to convey network-specific details to the user application + */ +struct zts_network_details +{ + /** + * Network ID + */ + uint64_t nwid; + + /** + * Maximum Transmission Unit size for this network + */ + int mtu; + + /** + * Number of addresses (actually) assigned to the node on this network + */ + short num_addresses; + + /** + * Array of IPv4 and IPv6 addresses assigned to the node on this network + */ + struct sockaddr_storage addr[ZTS_MAX_ASSIGNED_ADDRESSES]; + + /** + * Number of routes + */ + unsigned int num_routes; + + /** + * Array of IPv4 and IPv6 addresses assigned to the node on this network + */ + struct zts_virtual_network_route routes[ZTS_MAX_NETWORK_ROUTES]; +}; + +/** + * Physical network path to a peer + */ +struct zts_physical_path +{ + /** + * Address of endpoint + */ + struct sockaddr_storage address; + + /** + * Time of last send in milliseconds or 0 for never + */ + uint64_t lastSend; + + /** + * Time of last receive in milliseconds or 0 for never + */ + uint64_t lastReceive; + + /** + * Is this a trusted path? If so this will be its nonzero ID. + */ + uint64_t trustedPathId; + + /** + * Is path expired? + */ + int expired; + + /** + * Is path preferred? + */ + int preferred; +}; + +/** + * Peer status result buffer + */ +struct zts_peer_details +{ + /** + * ZeroTier address (40 bits) + */ + uint64_t address; + + /** + * Remote major version or -1 if not known + */ + int versionMajor; + + /** + * Remote minor version or -1 if not known + */ + int versionMinor; + + /** + * Remote revision or -1 if not known + */ + int versionRev; + + /** + * Last measured latency in milliseconds or -1 if unknown + */ + int latency; + + /** + * What trust hierarchy role does this device have? + */ + enum zts_peer_role role; + + /** + * Number of paths (size of paths[]) + */ + unsigned int pathCount; + + /** + * Known network paths to peer + */ + zts_physical_path paths[ZT_MAX_PEER_NETWORK_PATHS]; +}; + +/** + * List of peers + */ +struct zts_peer_list +{ + zts_peer_details *peers; + unsigned long peerCount; +}; + +////////////////////////////////////////////////////////////////////////////// +// ZeroTier Service Controls // ////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus extern "C" { #endif -// Custom errno to prevent conflicts with platform's own errno -extern int zts_errno; +/** + * @brief Starts the ZeroTier service and notifies user application of events via callback + * + * @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met: + * - ZeroTier core service has been initialized + * - Cryptographic identity has been generated or loaded from directory specified by `path` + * - Virtual network is successfully joined + * - IP address is assigned by network controller service + * @param path path directory where cryptographic identities and network configuration files are stored and retrieved + * (`identity.public`, `identity.secret`) + * @param userCallbackFunc User-specified callback for ZeroTier events + * @return 0 if successful; or 1 if failed + */ +ZT_SOCKET_API int ZTCALL zts_start(const char *path, void (*userCallbackFunc)(uint64_t, int), int port = ZTS_DEFAULT_PORT); + +/** + * @brief Stops the ZeroTier service, brings down all virtual interfaces in order to stop all traffic processing. + * + * @usage This should be called when the application anticipates not needing any sort of traffic processing for a + * prolonged period of time. The stack driver (with associated timers) will remain active in case future traffic + * processing is required. Note that the application must tolerate a multi-second startup time if zts_start() + * zts_startjoin() is called again. To stop this background thread and free all resources use zts_free() instead. + * @return Returns 0 on success, -1 on failure + */ +ZT_SOCKET_API int ZTCALL zts_stop(); + +/** + * @brief Stops all background services, brings down all interfaces, frees all resources. After calling this function + * an application restart will be required before the library can be used again. This is a blocking call. + * + * @usage This should be called at the end of your program or when you do not anticipate communicating over ZeroTier + * @return Returns 0 on success, -1 on failure + */ +ZT_SOCKET_API int ZTCALL zts_free(); + +/** + * @brief Return whether the ZeroTier service is currently running + * + * @usage Call this after zts_start() + * @return 1 if running, 0 if not running + */ +ZT_SOCKET_API int ZTCALL zts_core_running(); + +/** + * @brief Return the number of networks currently joined by this node + * + * @usage Call this after zts_start(), zts_startjoin() and/or zts_join() + * @return Number of networks joined by this node + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_get_num_joined_networks(); + +/** + * @brief Populates a structure with details for a given network + * + * @usage Call this from the application thread any time after the node has joined a network + * @param nwid A 16-digit hexidecimal virtual network ID + * @param nd Pointer to a zts_network_details structure to populate + * @return ZTS_ERR_SERVICE if failed, 0 if otherwise + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_get_network_details(uint64_t nwid, struct zts_network_details *nd); + +/** + * @brief Populates an array of structures with details for any given number of networks + * + * @usage Call this from the application thread any time after the node has joined a network + * @param nds Pointer to an array of zts_network_details structures to populate + * @param num Number of zts_network_details structures available to copy data into, will be updated + * to reflect number of structures that were actually populated + * @return ZTS_ERR_SERVICE if failed, 0 if otherwise + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_get_all_network_details(struct zts_network_details *nds, int *num); + +/** + * @brief Join a network + * + * @usage Call this from application thread. Only after zts_start() has succeeded + * @param nwid A 16-digit hexidecimal virtual network ID + * @return 0 if successful, -1 for any failure + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_join(const uint64_t nwid); + +/** + * @brief Leave a network + * + * @usage Call this from application thread. Only after zts_start() has succeeded + * @param nwid A 16-digit hexidecimal virtual network ID + * @return 0 if successful, -1 for any failure + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_leave(const uint64_t nwid); + + +/** + * @brief Leaves all networks + * + * @usage Call this from application thread. Only after zts_start() has succeeded + * @return 0 if successful, -1 for any failure + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_leave_all(); + +/** + * @brief Orbits a given moon (user-defined root server) + * + * @usage Call this from application thread. Only after zts_start() has succeeded + * @param moonWorldId A 16-digit hexidecimal world ID + * @param moonSeed A 16-digit hexidecimal seed ID + * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed); + +/** + * @brief De-orbits a given moon (user-defined root server) + * + * @usage Call this from application thread. Only after zts_start() has succeeded + * @param moonWorldId A 16-digit hexidecimal world ID + * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_deorbit(uint64_t moonWorldId); + +/** + * @brief Copies the configuration path used by ZeroTier into the provided buffer + * + * @usage Use this to determine where ZeroTier is storing identity files + * @param homePath Path to ZeroTier configuration files + * @param len Length of destination buffer + * @return 0 if no error, -1 if invalid argument was supplied + */ +ZT_SOCKET_API zts_err_t ZTCALL zts_get_path(char *homePath, size_t *len); + +/** + * @brief Returns the node ID of this instance + * + * @usage Call this after zts_start() and/or when zts_running() returns true + * @return + */ +ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id(); + +/** + * @brief Returns whether any address has been assigned to the SockTap for this network + * + * @usage This is used as an indicator of readiness for service for the ZeroTier core and stack + * @param nwid Network ID + * @return + */ +ZT_SOCKET_API int ZTCALL zts_has_address(const uint64_t nwid); + + +/** + * @brief Returns the number of addresses assigned to this node for the given nwid + * + * @param nwid Network ID + * @return The number of addresses assigned + */ +ZT_SOCKET_API int ZTCALL zts_get_num_assigned_addresses(const uint64_t nwid); + +/** + * @brief Returns the assigned address located at the given index + * + * @usage The indices of each assigned address are not guaranteed and should only + * be used for iterative purposes. + * @param nwid Network ID + * @param index location of assigned address + * @return The number of addresses assigned + */ +ZT_SOCKET_API int ZTCALL zts_get_address_at_index( + const uint64_t nwid, const int index, struct sockaddr *addr, socklen_t *addrlen); + +/** + * @brief Get IP address for this device on a given network + * + * @usage FIXME: Only returns first address found, good enough for most cases + * @param nwid Network ID + * @param addr Destination structure for address + * @param addrlen size of destination address buffer, will be changed to size of returned address + * @return 0 if an address was successfully found, -1 if failure + */ +ZT_SOCKET_API int ZTCALL zts_get_address( + const uint64_t nwid, struct sockaddr_storage *addr, const int address_family); + +/** + * @brief Computes a 6PLANE IPv6 address for the given Network ID and Node ID + * + * @usage Can call any time + * @param addr Destination structure for address + * @param nwid Network ID + * @param nodeId Node ID + * @return + */ +ZT_SOCKET_API void ZTCALL zts_get_6plane_addr( + struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); + +/** + * @brief Computes a RFC4193 IPv6 address for the given Network ID and Node ID + * + * @usage Can call any time + * @param addr Destination structure for address + * @param nwid Network ID + * @param nodeId Node ID + * @return + */ +ZT_SOCKET_API void ZTCALL zts_get_rfc4193_addr( + struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); + +/** + * @brief Return the number of peers + * + * @usage Call this after zts_start() has succeeded + * @return + */ +ZT_SOCKET_API zts_err_t zts_get_peer_count(); + +ZT_SOCKET_API zts_err_t zts_get_peers(struct zts_peer_details *pds, int *num); + +/** + * @brief Determines whether a peer is reachable via a P2P connection + * or is being relayed via roots. + * + * @usage + * @param nodeId The ID of the peer to check + * @return The status of a peer + */ +ZT_SOCKET_API zts_err_t zts_get_peer_status(uint64_t nodeId); + +/** + * @brief Starts a ZeroTier service in the background + * + * @usage For internal use only. + * @param + * @return + */ +#if defined(_WIN32) +DWORD WINAPI _zts_start_service(LPVOID thread_id); +#else +void *_zts_start_service(void *thread_id); +#endif + +/** + * @brief [Should not be called from user application] This function must be surrounded by + * ZT service locks. It will determine if it is currently safe and allowed to operate on + * the service. + * @usage Can be called at any time + * @return 1 or 0 + */ +int _zts_can_perform_service_operation(); + +/** + * @brief [Should not be called from user application] Returns whether or not the node is + * online. + * @usage Can be called at any time + * @return 1 or 0 + */ +int _zts_node_online(); + +int zts_ready(); + +////////////////////////////////////////////////////////////////////////////// +// Socket API // +////////////////////////////////////////////////////////////////////////////// /** * @brief Create a socket @@ -679,4 +1182,6 @@ ZT_SOCKET_API zts_err_t ZTCALL zts_del_dns_nameserver(struct sockaddr *addr); } // extern "C" #endif +} // namespace ZeroTier + #endif // _H diff --git a/packages/PyPI/bdist.bat b/packages/PyPI/bdist.bat deleted file mode 100644 index 28fb8cb..0000000 --- a/packages/PyPI/bdist.bat +++ /dev/null @@ -1,7 +0,0 @@ -cd ../../ -cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=DEBUG -cmake --build build -copy bin\lib\Debug\*.lib packages\pypi -cd packages\pypi -pip3 install wheel twine -py setup.py bdist_wheel \ No newline at end of file diff --git a/packages/README.md b/packages/README.md deleted file mode 100644 index 8a2d93b..0000000 --- a/packages/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### Projects and scripts for building various packages - -Pre-built binaries [here](https://download.zerotier.com/RELEASES/) - -*** - -### To build entire distribution package: - -Step 1: On a Windows host, run `make dist`. Outputs will be copied to `prebuilt/(debug|release)/(win32/win64)` -Step 2: On a Linux host, run `make dist`. Outputs will be copied to `prebuilt/linux-$ARCH` -Step 3: On a macOS host, run `make dist`. Outputs will be copied to `prebuilt/macos-$ARCH` -Step 4: Perform any necessary modifications to the generated projects (such as Xcode projects) -Step 5: Re-run `make dist` -Step 6: On a Unix-like host, run `make package`. This will zip everything up into a pair of `tar.gz` files in `products` - -*** - -### iOS - - - In `packages/xcode_ios`, change SDK from `macOS` to `iOS` - - Build - -### Android - -This project is not currently generated by CMake, but does utilize the `CMakeLists.txt` and generates a `.aar` Android Archive which can be imported into an Android Studio project as a library. An example of this library's usage can be found in [examples/android](examples/android). Further examples of the libzt JNI API can be seen in [examples/java](examples/java). diff --git a/packages/android/.gitignore b/packages/android/.gitignore deleted file mode 100644 index 5edb4ee..0000000 --- a/packages/android/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -.DS_Store -/build -/captures -.externalNativeBuild diff --git a/packages/android/.project b/packages/android/.project new file mode 100644 index 0000000..3964dd3 --- /dev/null +++ b/packages/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/packages/android/app/.gitignore b/packages/android/app/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/packages/android/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/packages/android/app/build.gradle b/packages/android/app/build.gradle deleted file mode 100644 index b52d99b..0000000 --- a/packages/android/app/build.gradle +++ /dev/null @@ -1,42 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion 28 - defaultConfig { - minSdkVersion 21 - targetSdkVersion 28 - versionCode 1 - versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - externalNativeBuild { - cmake { - cppFlags "" - } - } - ndk { - // Tells Gradle to build outputs for the following ABIs and package - // them into your APK. - abiFilters 'armeabi-v7a' - } - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - externalNativeBuild { - cmake { - path "../../../CMakeLists.txt" - } - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' - implementation 'com.android.support.constraint:constraint-layout:1.1.2' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' -} \ No newline at end of file diff --git a/packages/android/app/proguard-rules.pro b/packages/android/app/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/packages/android/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/packages/android/app/src/androidTest/java/com/example/zerotier/ExampleInstrumentedTest.java b/packages/android/app/src/androidTest/java/com/example/zerotier/ExampleInstrumentedTest.java deleted file mode 100644 index fe8e36c..0000000 --- a/packages/android/app/src/androidTest/java/com/example/zerotier/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.zerotier; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.example.zerotier", appContext.getPackageName()); - } -} diff --git a/packages/android/app/src/main/AndroidManifest.xml b/packages/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 42365c2..0000000 --- a/packages/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/packages/android/app/src/main/java/ZTFDSet.java b/packages/android/app/src/main/java/ZTFDSet.java deleted file mode 100644 index cf5bd7b..0000000 --- a/packages/android/app/src/main/java/ZTFDSet.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -public class ZTFDSet -{ - byte[] fds_bits = new byte[1024]; - - public void CLR(int fd) - { - fds_bits[fd] = 0x00; - } - - public boolean ISSET(int fd) - { - return fds_bits[fd] == 0x01; - } - - public void SET(int fd) - { - fds_bits[fd] = 0x01; - } - - public void ZERO() - { - for (int i=0; i<1024; i++) { - fds_bits[i] = 0x00; - } - } -} \ No newline at end of file diff --git a/packages/android/app/src/main/java/ZTSocketAddress.java b/packages/android/app/src/main/java/ZTSocketAddress.java deleted file mode 100644 index b86a985..0000000 --- a/packages/android/app/src/main/java/ZTSocketAddress.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -import com.zerotier.libzt.ZeroTier; - -import java.net.InetAddress; - -// Designed to transport address information across the JNI boundary -public class ZTSocketAddress -{ - public byte[] _ip6 = new byte[16]; - public byte[] _ip4 = new byte[4]; - - public int _family; - public int _port; // Also reused for netmask or prefix - - public ZTSocketAddress() {} - - public ZTSocketAddress(String ipStr, int port) - { - if(ipStr.contains(":")) { - _family = ZeroTier.AF_INET6; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip6 = ip.getAddress(); - } - catch (Exception e) { } - } - else if(ipStr.contains(".")) { - _family = ZeroTier.AF_INET; - try { - InetAddress ip = InetAddress.getByName(ipStr); - _ip4 = ip.getAddress(); - } - catch (Exception e) { } - } - _port = port; - } - - public int getPort() { return _port; } - public int getNetmask() { return _port; } - public int getPrefix() { return _port; } - - private String ipString() - { - if (_family == ZeroTier.AF_INET) { - try { - InetAddress inet = InetAddress.getByAddress(_ip4); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - if (_family == ZeroTier.AF_INET6) { - try { - InetAddress inet = InetAddress.getByAddress(_ip6); - return "" + inet.getHostAddress(); - } catch (Exception e) { - System.out.println(e); - } - } - return ""; - } - - public String toString() { return ipString() + ":" + _port; } - public String toCIDR() { return ipString() + "/" + _port; } -} diff --git a/packages/android/app/src/main/java/ZeroTier.java b/packages/android/app/src/main/java/ZeroTier.java deleted file mode 100644 index 26e337b..0000000 --- a/packages/android/app/src/main/java/ZeroTier.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ZeroTier SDK - Network Virtualization Everywhere - * Copyright (C) 2011-2018 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. - */ - -package com.zerotier.libzt; - -import java.net.*; - -public class ZeroTier { - - public static int AF_INET = 2; - public static int AF_INET6 = 30; - public static int SOCK_STREAM = 1; - public static int SOCK_DGRAM = 2; - public static int O_APPEND = 1024; - public static int O_NONBLOCK = 2048; - public static int O_ASYNC = 8192; - public static int O_DIRECT = 65536; - public static int O_NOATIME = 262144; - public static int F_GETFL = 3; - public static int F_SETFL = 4; - - public native void start(String homePath, boolean blocking); - public native void startjoin(String homePath, long nwid); - public native void stop(); - public native boolean core_running(); - public native boolean stack_running(); - public native boolean ready(); - public native int join(long nwid); - public native int leave(long nwid); - public native String get_path(); - public native long get_node_id(); - public native int get_num_assigned_addresses(long nwid); - public native boolean get_address_at_index(long nwid, int index, ZTSocketAddress addr); - public native boolean has_address(long nwid); - public native boolean get_address(long nwid, int address_family, ZTSocketAddress addr); - public native void get_6plane_addr(long nwid, long nodeId, ZTSocketAddress addr); - public native void get_rfc4193_addr(long nwid, long nodeId, ZTSocketAddress addr); - - public native int socket(int family, int type, int protocol); - public native int connect(int fd, ZTSocketAddress addr); - public native int bind(int fd, ZTSocketAddress addr); - public native int listen(int fd, int backlog); - public native int accept(int fd, ZTSocketAddress addr); - public native int accept4(int fd, String addr, int port); - public native int close(int fd); - public native int setsockopt(int fd, int level, int optname, int optval, int optlen); - public native int getsockopt(int fd, int level, int optname, int optval, int optlen); - public native int sendto(int fd, byte[] buf, int flags, ZTSocketAddress addr); - public native int send(int fd, byte[] buf, int flags); - public native int recv(int fd, byte[] buf, int flags); - public native int recvfrom(int fd, byte[] buf, int flags, ZTSocketAddress addr); - public native int read(int fd, byte[] buf); - public native int write(int fd, byte[] buf); - public native int shutdown(int fd, int how); - public native boolean getsockname(int fd, ZTSocketAddress addr); - public native int getpeername(int fd, ZTSocketAddress addr); - public native int fcntl(int sock, int cmd, int flag); - public native int select(int nfds, ZTFDSet readfds, ZTFDSet writefds, ZTFDSet exceptfds, int timeout_sec, int timeout_usec); -} \ No newline at end of file diff --git a/packages/android/app/src/main/java/com/example/zerotier/MainActivity.java b/packages/android/app/src/main/java/com/example/zerotier/MainActivity.java deleted file mode 100644 index 66ee81b..0000000 --- a/packages/android/app/src/main/java/com/example/zerotier/MainActivity.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.example.zerotier; - -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.widget.TextView; - -import com.zerotier.libzt.ZeroTier; -import com.zerotier.libzt.ZTSocketAddress; -import com.zerotier.libzt.ZTFDSet; - -public class MainActivity extends AppCompatActivity { - - // Used to load the 'native-lib' library on application startup. - static { - System.loadLibrary("zt"); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - - final ZeroTier libzt = new ZeroTier(); - - new Thread(new Runnable() { - public void run() { - final String path = getApplicationContext().getFilesDir() + "/zerotier"; - long nwid = 0xac9afb023544b071L; - - // Test modes - boolean blocking_start_call = true; - boolean client_mode = false; - boolean tcp = false; - boolean loop = true; - - int fd = -1, client_fd = -1, err, r, w, length = 0, flags = 0; - byte[] rxBuffer; - byte[] txBuffer = "welcome to the machine".getBytes(); - String remoteAddrStr = "11.7.7.224"; - String localAddrStr = "1.2.3.4"; - int portNo = 4040; - - ZTSocketAddress remoteAddr, localAddr; - ZTSocketAddress sockname = new ZTSocketAddress(); - ZTSocketAddress addr = new ZTSocketAddress(); - - // METHOD 1 (easy) - // Blocking call that waits for all components of the service to start - System.out.println("Starting ZT service..."); - if (blocking_start_call) { - libzt.startjoin(path, nwid); - } - System.out.println("ZT service ready."); - - // Device/Node address info - System.out.println("path=" + libzt.get_path()); - long nodeId = libzt.get_node_id(); - System.out.println("nodeId=" + Long.toHexString(nodeId)); - int numAddresses = libzt.get_num_assigned_addresses(nwid); - System.out.println("this node has (" + numAddresses + ") assigned addresses on network " + Long.toHexString(nwid)); - for (int i=0; i - - - - - - - - - - diff --git a/packages/android/app/src/main/res/drawable/ic_launcher_background.xml b/packages/android/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index d5fccc5..0000000 --- a/packages/android/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/android/app/src/main/res/layout/activity_main.xml b/packages/android/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 7d8d24e..0000000 --- a/packages/android/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cf..0000000 --- a/packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cf..0000000 --- a/packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/packages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a2f5908281d070150700378b64a84c7db1f97aa1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3056 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 axPAxe%7rDusX+w*00006jj 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⁣ zwiG+x#%j}{0gU~J8;<|!B1@-XaB@{KORFwrYg_8rOv({b0EO#DbeQRm;B6_9=mXGf z-x|VL{zd`)#@yN}HkCSJbjbNlE|zL3Wm9Q8HY`sV)}3%pgN>cL^67{Z;PPL(*wT8N zUjXU{@|*hvm}({wsAC=x0^ok0%UAz0;sogW{B!nDqk|JJ5x~4NfTDgP49^zeu`csl?5mY@JdQdISc zFs!E{^grmkLnUk9 zny~m)1vws@5BFI<-0Tuo2JWX(0v`W|t(wg;s--L47WTvTMz-8l#TL^=OJNRS2?_Qj z3AKT+gvbyBi#H*-tJ%tWD|>EV3wy|8qxfzS!5RW;Jpl5*zo&^UBU=fG#2}UvRyNkK zA06Dy9;K1ca@r2T>yThYgI!ont$(G{6q#2QT+00r_x0(b)gsE`lBB?2gr55gq^D3Fi&p%E(p9>U%bv zkg1Jco(RbyTX7FDHOnl7-O@ zI$AaIl?9NJKPm(WiBP`1-#CB1QzU>&hKm)fpa5DKE{2$X0hGz-0uZ?cyTk(YC!Y&| zL=1VrNERSA5NA2jq7FACfX4JfPyj5XXl1yv0>~s;eF7L2$>&oMqeTFT2m$y7FlkON z_yurD1yIOvA;5C6016pyxBznGUt0kJ&k5r#;&>Jow`r)sp9R~PmK~lz$3xH%LT*1U zJdOyABZ3!FvNoR*vN$5ykHS8f`jA4zV+|L}i1C4`B2c{R0;UdYxaU|H)2avz@ z=mEYc|2S<+(B2Tj+FkX+2D+yFI!k9lWMA61DJ{)e;lum$(;O87?vGJJe!KtK04+N_ zI*P~t@dUb>9Xh{dbyl{-ZQ(UMgz7$|QfL5XSPkskt^NgctYC#;4WcZB1@%@wy@2t3 z2z0DI7&%b$*Aw~abe?GxE`ez@+6hOh-6*8fHRV{1os$EL@}uUZeG4h1&Be`98q*7j z=3-v+lhIjfWVo12!<>%V^a6lTgW3+_#W6n|p*~==zOH7z$0{LSZk(Tpd7EaD04hnA zL;#fxS0aD{`5^&D`}>0Uq?byDD-l2=!wm_bLcUl4gc(% za1p|itVANvFF>hghAS07Im1;IK;|b*W)}VDyI;BIp2=K*yu2a)j?B|f<44NI$NbmJ z#dE0>jI$fMr&@>4kN8MLFb4&2O9fEKaQg%(QO$4_1rVQywG^CmBLh#}_7gKW3vd?| z2?1^&KWq8}8I^_S0|)MowU_pw$q@nl@Nkn$z>BQq_KA^9yaR`(R3u{{Ig;cwt z@AJ^{ODQCm^neroM9nKNUAXi9RCK`OsP_LuR0PUR(YZCCX5dNF6VzcoK&=b^r`W?ltt|*F zpkoae%ZT{C1h~EcFui~b7fF`vb<<~j_VquuUA$}QqIKYELPp#;{u?q8Dz}WAG-(3; zjrm$i%7UbyZMM(Y{>!uJ#vNB?R~B{6Htp=>e*<{fQQ5W7V(1coCWlOON!MzZxhum| ztZBQpGR z;~#ur^&PockKdV{Q6R>o`Pl{0x!DEbpZ7y9Y;*ZvE!*gU`V1W3znva{f=?WO5I&>B z&hw6}tjECtaghm5z|C#%M;Yf_*pI^};h}Vl=^r9EN=tVDj86D;C$jIJ?K7VP+00000NkvXXu0mjf D5i!M* diff --git a/packages/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/packages/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 459ca609d3ae0d3943ab44cdc27feef9256dc6d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7098 zcmV;r8%5-aP)U(QdAI7f)tS=AhH53iU?Q%B}x&gA$2B`o|*LCD1jhW zSQpS0{*?u3iXtkY?&2<)$@#zc%$?qDlF1T~d7k&lWaiv^&wbx>zVm(GIrof<%iY)A zm%|rhEg~Z$Te<*wd9Cb1SB{RkOI$-=MBtc%k*xtvYC~Uito}R@3fRUqJvco z|Bt2r9pSOcJocAEd)UN^Tz-82GUZlqsU;wb|2Q_1!4Rms&HO1Xyquft~#6lJoR z`$|}VSy@{k6U652FJ~bnD9(X%>CS6Wp6U>sn;f}te}%WL`rg)qE4Q=4OOhk^@ykw( ziKr^LHnAd4M?#&SQhw8zaC05q#Mc66K^mxY!dZ=W+#Bq1B}cQ6Y8FWd(n>#%{8Di_8$CHibtvP z-x#-g;~Q?y0vJA*8TW>ZxF?fAy1DuFy7%O1ylLF(t=ah7LjZ$=p!;8(ZLjXAhwEkCR{wF`L=hwm>|vLK2=gR&KM1ZEG9R~53yNCZdabQoQ%VsolX zS#WlesPcpJ)7XLo6>Ly$im38oxyiizP&&>***e@KqUk3q3y+LQN^-v?ZmO>9O{Oq@ z{{He$*Z=Kf_FPR>El3iB*FULYFMnLa#Fl^l&|bFg$Omlh{xVVJ7uHm=4WE6)NflH6 z=>z4w{GV&8#MNnEY3*B7pXU!$9v-tZvdjO}9O=9r{3Wxq2QB}(n%%YI$)pS~NEd}U z)n#nv-V)K}kz9M0$hogDLsa<(OS0Hf5^WUKO-%WbR1W1ID$NpAegxHH;em?U$Eyn1 zU{&J2@WqSUn0tav=jR&&taR9XbV+Izb*PwFn|?cv0mksBdOWeGxNb~oR;`~>#w3bp zrOrEQ+BiW_*f&GARyW|nE}~oh0R>>AOH^>NHNKe%%sXLgWRu1Sy3yW0Q#L{8Y6=3d zKd=By=Nb8?#W6|LrpZm>8Ro)`@cLmU;D`d64nKT~6Z!aLOS{m`@oYwD`9yily@}%yr0A>P!6O4G|ImNbBzI`LJ0@=TfLt^f`M07vw_PvXvN{nx%4 zD8vS>8*2N}`lD>M{`v?2!nYnf%+`GRK3`_i+yq#1a1Yx~_1o~-$2@{=r~q11r0oR* zqBhFFVZFx!U0!2CcItqLs)C;|hZ|9zt3k^(2g32!KB-|(RhKbq-vh|uT>jT@tX8dN zH`TT5iytrZT#&8u=9qt=oV`NjC)2gWl%KJ;n63WwAe%-)iz&bK{k`lTSAP`hr)H$Q`Yq8-A4PBBuP*-G#hSKrnmduy6}G zrc+mcVrrxM0WZ__Y#*1$mVa2y=2I`TQ%3Vhk&=y!-?<4~iq8`XxeRG!q?@l&cG8;X zQ(qH=@6{T$$qk~l?Z0@I4HGeTG?fWL67KN#-&&CWpW0fUm}{sBGUm)Xe#=*#W{h_i zohQ=S{=n3jDc1b{h6oTy=gI!(N%ni~O$!nBUig}9u1b^uI8SJ9GS7L#s!j;Xy*CO>N(o6z){ND5WTew%1lr? znp&*SAdJb5{L}y7q#NHbY;N_1vn!a^3TGRzCKjw?i_%$0d2%AR73CwHf z`h4QFmE-7G=psYnw)B!_Cw^{=!UNZeR{(s47|V$`3;-*gneX=;O+eN@+Efd_Zt=@H3T@v&o^%H z7QgDF8g>X~$4t9pv35G{a_8Io>#>uGRHV{2PSk#Ea~^V8!n@9C)ZH#87~ z#{~PUaRR~4K*m4*PI16)rvzdaP|7sE8SyMQYI6!t(%JNebR%?lc$={$s?VBI0Qk!A zvrE4|#asTZA|5tB{>!7BcxOezR?QIo4U_LU?&9Im-liGSc|TrJ>;1=;W?gG)0pQaw z|6o7&I&PH!*Z=c7pNPkp)1(4W`9Z01*QKv44FkvF^2Kdz3gDNpV=A6R;Q}~V-_sZY zB9DB)F8%iFEjK?Gf4$Cwu_hA$98&pkrJM!7{l+}osR_aU2PEx!1CRCKsS`0v$LlKq z{Pg#ZeoBMv@6BcmK$-*|S9nv50or*2&EV`L7PfW$2J7R1!9Q(1SSe42eSWZ5sYU?g z2v{_QB^^jfh$)L?+|M`u-E7D=Hb?7@9O89!bRUSI7uD?Mxh63j5!4e(v)Kc&TUEqy z8;f`#(hwrIeW);FA0CK%YHz6;(WfJz^<&W#y0N3O2&Qh_yxHu?*8z1y9Ua}rECL!5 z7L1AEXx83h^}+)cY*Ko{`^0g3GtTuMP>b$kq;Aqo+2d&+48mc#DP;Sv z*UL^nR*K7J968xR0_eTaZ`N`u_c#9bFUjTj-}0+_57(gtEJT|7PA12W=2Z>#_a z&Wg@_b=$d~wonN3h~?)gS`qxx<4J&`dI*rH9!mTSiQj(0rF-{YoNJRnOqd5IbP7p} ztDaPu$A;#osxf=z2zVe4>tpa(knS_Mp67nKcE<>Cj$G2orP(Z$Oc4;4DPwbXYZsS^ z;b>59s(LgYmx|tkRD?U{+9VZ$T}{S}L6>lQNR^a|&5joAFXtOrI07Do!vk(e$mu@Y zNdN!djB`Hq1*T8mrC@S)MLwZ`&8aM8YYtVj7i)IY{g&D1sJaY`3e=1DSFnjO+jEHH zj+|@r$$4RtpuJ!8=C`n5X;5BjU2slP9VV&m0gr+{O(I}9pYF32AMU?n$k$=x;X^E# zOb-x}p1_`@IOXAj3>HFxnmvBV9M^^9CfD7UlfuH*y^aOD?X6D82p_r*c>DF)m=9>o zgv_SDeSF6WkoVOI<_mX};FlW9rk3WgQP|vr-eVo8!wH!TiX)aiw+I|dBWJX=H6zxx z_tSI2$ChOM+?XlJwEz3!juYU6Z_b+vP-Y|m1!|ahw>Kpjrii-M_wmO@f@7;aK(I;p zqWgn+X^onc-*f)V9Vfu?AHLHHK!p2|M`R&@4H0x4hD5#l1##Plb8KsgqGZ{`d+1Ns zQ7N(V#t49wYIm9drzw`;WSa|+W+VW8Zbbx*Z+aXHSoa!c!@3F_yVww58NPH2->~Ls z2++`lSrKF(rBZLZ5_ts6_LbZG-W-3fDq^qI>|rzbc@21?)H>!?7O*!D?dKlL z6J@yulp7;Yk6Bdytq*J1JaR1!pXZz4aXQ{qfLu0;TyPWebr3|*EzCk5%ImpjUI4cP z7A$bJvo4(n2km-2JTfRKBjI9$mnJG@)LjjE9dnG&O=S;fC)@nq9K&eUHAL%yAPX7OFuD$pb_H9nhd{iE0OiI4#F-);A|&YT z|A3tvFLfR`5NYUkE?Rfr&PyUeFX-VHzcss2i*w06vn4{k1R%1_1+Ygx2oFt*HwfT> zd=PFdfFtrP1+YRs0AVr{YVp4Bnw2HQX-|P$M^9&P7pY6XSC-8;O2Ia4c{=t{NRD=z z0DeYUO3n;p%k zNEmBntbNac&5o#&fkY1QSYA4tKqBb=w~c6yktzjyk_Po)A|?nn8>HdA31amaOf7jX z2qillM8t8V#qv5>19Cg_X`mlU*O5|C#X-kfAXAHAD*q%6+z%IK(*H6olm-N4%Ic)5 zL`?wQgXfD&qQRxWskoO^Ylb>`jelq;*~ZIwKw|#BQjOSLkgc2uy7|oFEVhC?pcnU+ z^7qz}Z2%F!WOp%JO3y*&_7t;uRfU>)drR1q)c7lX?;A1-TuLTR zyr(`7O19`eW{ev;L%`;BvOzh?m|)Rh?W8&I$KVvUTo?@f@K!du&vf=o6kKb?hA z%e6$T0jWS7doVkN%^_k3QOksfV?aC$Ge$a)z(!C@UVs*@qzDw*OFd*JfX#>5LCXjE z_vfUrLF7D`K$U2Ld#OCnh9U!;r7%GlKo$e__Il-oba06ER{H&f#J&W@x^^5j;y$0` zs2`m6pf+{UiDb{Mjsb$rH+MCM6G_wX92so96`ODFYKD>!Xz^0y@U7Tc1uON4L<>2f-oPe%FRPEZ@S#-yd7Md-i?v z)$Kgtq;%4g@>Kap3Nl2I&jnCIfGmRmcF4CXfF1H}3SfhLg8=!a0ucGaUk&c3*Ykgl z2X_L84cs+FD#cjf-nMJkVDH%XzOoh5!X-Q$K5VZx-hGF7MQ=XKBjhZZQ@1Sh zO^vY`WQ`zi21z-+01na%<^niMFIWm-n|!?hm4X2HEHkba4YS|+HRoIR=`#Xck@PFXaPjnP z=hC4A*0lumS+gpK=TUN!G;{WqICbMz-V=-lTP^@a#C|E!qH;T00SZh7u#?+?08g0< zV1s%-U-`T@8wGh!3pO^`zUIY{nAED7kBqg!qi&GfOp>57f2PGTV19m z0qU@1PYkf%4z_%;Sq4IY94rS+ie~pwT@O3+tg?#k_=5PIk6tV@< zwLoqM0wBVLkI#`|1w=eYMnc^aRR!t?lnUng>WekR#X!!9mYXL3g^gC7`)S7mmo{y} z9*N!d$s32Nu{cZp#O|UxEZK7eY<7hGcI=lc;HrSVL|HA|S$rhhu_DBT&l+`75d`Sj3LaM~H)P zZuk2&jor6yipafklSsPL-vMo?0yAYXpH3=LveBhkno-3{4VLWL16I-@!RM$Po>&}} zm&PX3-$i>$*yx-THZmvK2q`8Qm7B`(NMR;>VSgoGw}W|G6Xd6v04Zf;HIZ0DZU?@- z39vPe0N8w(9kl$2?eG4T?tLgY5V&aFl%~g;2)aSpi!dl?{hDgsz|3<-M(gPtwP_!n z2aB4tV?d0k+>X`+(HMYfK@qtfDK|mIJeg+A<_i-n+5wkrexFs#V0N&~+{+qJ(wggC*52o2daaRwcu7r;S!!KwguB3!Ei7?IEY ze4V$m{8B4Q^(VK4~Ea!V@@}Gs0HGbR5 zy~WI*21hZuoiK`=O$2a|Uce-Zi2%A*pB|?{gv)n8+_B+i&u8Ys)ePY+UwhBDlzbC& z+N00*-?a8DTC26*(3pKgeMO`fOau^-+c6Qqq}3-dpTsEEH}ds! zT^}8XAWO>c5%+qF%#M8#x_0gC+N%q8h6-%w;qidS%gai<T)vpfYuCHXRx6O-TbC|fnj87X zBESvn(9XlXFMj6%{&BaNQ&;xixaKP)+jJ|%u&?HXvYficY}{%hf?0rNDS-X-0_Jcr zjfj~n?T;~RL#sd4ZED2Jf{*Vj+*1eP9-H+~8X^#Jb?HHabLY)EH{QD@Yh-$M`XXt@3_f-L8nBo~*C?L4~n6M92PCuzX=KFgM*j!B66er$F! z+*M(Wkk`UI@uhrL#IUz-C{K@@xtd&n-PQz%kc}7YeE{{&$?}-*yW$eG*E4jp>B_U!2`2oZuvvitN& z%RN>tE$+Yhtqb1q+xQHbp=W4uKSiIj_LZppR0=hEiVj>P0^Vcr^hu2+#Hqum+}zzo znqZ|M4oD|qd=y&JX-qob`=uqt?o%FJPIVY2w0M7BH>#sx>s#OM#9JF1(3LxMAe-vi ztJeU*G)aksP`5sP9_%|~>Pp{NmMMcay>&D+cI%H}$uSx{Su(yz$)2e$*pS%*+!Zo>DNp(P7 zI%w^D2ceEFUGCtQPKfsKr`x%^dy;Rh>lMKuhA^btz=071W=vV`_xz&m;cvd0`|!3+ z2M6uga6CNvy)%Pjw_X}5+xf###jc+?=>6chZI{BMH=haH^7ipT>(?9{weF3apk<4; z_nZFsi`@oFBXCZE^k9B1x+cH2)~9d(MnfEm;GJxG*IB zU@ly{cOTWk*K1ryX+T7m!6A>VwB-*qfH;b>`AUP19lLSA9HbfppW!={L0K)??SymOCA^V>=tOBLn2c5e ksm9QK-qMKdW>5J419kFO%DdQj-T(jq07*qoM6N<$f+5oB`~Uy| diff --git a/packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 8ca12fe024be86e868d14e91120a6902f8e88ac6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6464 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 B0*L?s diff --git a/packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 8e19b410a1b15ff180f3dacac19395fe3046cdec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10676 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 diff --git a/packages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/packages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 4c19a13c239cb67b8a2134ddd5f325db1d2d5bee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15523 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 BIP(Ai diff --git a/packages/android/app/src/main/res/values/colors.xml b/packages/android/app/src/main/res/values/colors.xml deleted file mode 100644 index 3ab3e9c..0000000 --- a/packages/android/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #3F51B5 - #303F9F - #FF4081 - diff --git a/packages/android/app/src/main/res/values/strings.xml b/packages/android/app/src/main/res/values/strings.xml deleted file mode 100644 index 87c6cc8..0000000 --- a/packages/android/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - ZeroTier - diff --git a/packages/android/app/src/main/res/values/styles.xml b/packages/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 5885930..0000000 --- a/packages/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/packages/android/app/src/test/java/com/example/zerotier/ExampleUnitTest.java b/packages/android/app/src/test/java/com/example/zerotier/ExampleUnitTest.java deleted file mode 100644 index f0aee30..0000000 --- a/packages/android/app/src/test/java/com/example/zerotier/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.zerotier; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/packages/android/build.gradle b/packages/android/build.gradle deleted file mode 100644 index 43c0708..0000000 --- a/packages/android/build.gradle +++ /dev/null @@ -1,27 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - - repositories { - google() - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:3.1.3' - - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/packages/android/gradle.properties b/packages/android/gradle.properties deleted file mode 100644 index b2b3bb2..0000000 --- a/packages/android/gradle.properties +++ /dev/null @@ -1,13 +0,0 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file diff --git a/packages/android/gradle/wrapper/gradle-wrapper.jar b/packages/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7a3265ee94c0ab25cf079ac8ccdf87f41d455d42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54708 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