diff --git a/.travis.yml b/.travis.yml index ff4ccdb96..192bd8b7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,10 @@ matrix: os: osx osx_image: xcode10.2 env: BUILD_TYPE=Release PATH="/usr/local/opt/ccache/libexec:$PATH" + - name: "make iOS" + os: osx + osx_image: xcode10.2 + env: MAKE_TARGET=ios PATH="/usr/local/opt/ccache/libexec:$PATH" - name: "make windows (macOS)" os: osx osx_image: xcode10.2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 71882d928..dd9567a1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,22 +42,7 @@ endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") -# Basic definitions -set(LIB lokinet) -set(SHARED_LIB ${LIB}-shared) -set(STATIC_LIB ${LIB}-static) -set(CRYPTOGRAPHY_LIB ${LIB}-cryptography) -set(UTIL_LIB ${LIB}-util) -set(PLATFORM_LIB ${LIB}-platform) -set(ANDROID_LIB ${LIB}android) -set(ABYSS libabyss) -set(ABYSS_LIB abyss) -set(ABYSS_EXE ${ABYSS_LIB}-main) -get_filename_component(TT_ROOT "vendor/libtuntap-master" ABSOLUTE) -add_definitions(-D${CMAKE_SYSTEM_NAME}) - -get_filename_component(CORE_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/include" ABSOLUTE) -get_filename_component(ABYSS_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include" ABSOLUTE) +include(cmake/basic_definitions.cmake) if(MSVC_VERSION) enable_language(ASM_MASM) @@ -118,6 +103,11 @@ endif(WITH_SHELLHOOKS) # Always build PIC set(CMAKE_POSITION_INDEPENDENT_CODE ON) +if(TRACY_ROOT) + include_directories(${TRACY_ROOT}) + add_definitions(-DTRACY_ENABLE) +endif() + set(ABSEIL_DIR vendor/abseil-cpp) include_directories(SYSTEM ${ABSEIL_DIR}) add_subdirectory(vendor/cxxopts) @@ -211,17 +201,9 @@ if(NOT GIT_VERSION) string(STRIP "${GIT_VERSION_UNSTRIP}" GIT_VERSION) endif(NOT GIT_VERSION) -string(REGEX REPLACE ^fatal.*$ nogit GIT_VERSION_REAL "${GIT_VERSION}") +string(REGEX REPLACE "^fatal.*$" nogit GIT_VERSION_REAL "${GIT_VERSION}") add_definitions("-DGIT_REV=\"${GIT_VERSION_REAL}\"") -set(EXE lokinet) -set(EXE_SRC daemon/main.cpp) -if(TRACY_ROOT) - include_directories(${TRACY_ROOT}) - add_definitions(-DTRACY_ENABLE) - list(APPEND EXE_SRC ${TRACY_ROOT}/TracyClient.cpp) -endif() - # HeapAlloc(2) on Windows was significantly revamped in 2009 # but the old algorithm isn't too bad either # this is _the_ system allocator on BSD UNIX @@ -237,17 +219,6 @@ if(ANDROID) set(ANDROID_PLATFORM_SRC android/ifaddrs.c) endif(ANDROID) -set(LIBTUNTAP_SRC_BASE - ${TT_ROOT}/tuntap.cpp - ${TT_ROOT}/tuntap_log.cpp - ${LIBTUNTAP_IMPL}) - -if(UNIX) - set(LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix.c ${LIBTUNTAP_SRC_BASE}) -else() - set(LIBTUNTAP_SRC ${LIBTUNTAP_SRC_BASE}) -endif() - set(LIBS ${MALLOC_LIB} ${FS_LIB} ${LIBUV_LIBRARY}) if(TRACY_ROOT) list(APPEND LIBS -ldl) @@ -256,85 +227,16 @@ endif() add_subdirectory(crypto) add_subdirectory(llarp) add_subdirectory(libabyss) +add_subdirectory(daemon) -if (NOT WIN32) - add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp) - target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} Threads::Threads ${LIBS}) -elseif(NOT MSVC_VERSION) - add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp llarp/win32/abyss.rc) - target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} ${STATIC_LIB} ws2_32) -else() - add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp) - target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} ${STATIC_LIB} ws2_32) -endif(NOT WIN32) - - -# Why does abyss not inherit the existing include folders? -target_include_directories(${ABYSS_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include" llarp vendor/nlohmann/include include crypto/include) -target_include_directories(${ABYSS_EXE} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include" llarp vendor/nlohmann/include include crypto/include) - -# for freebsd -if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - target_link_directories(${ABYSS_EXE} PRIVATE /usr/local/lib) - target_include_directories(${ABYSS_LIB} SYSTEM PUBLIC /usr/local/include) -endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") -add_log_tag(${ABYSS_EXE}) -add_log_tag(${ABYSS_LIB}) - - -if(SHADOW) - set(LOKINET_SHADOW shadow-plugin-${SHARED_LIB}) - set(LOKINET_SHADOW_LIBS ${SHARED_LIB}) - add_shadow_plugin(${LOKINET_SHADOW} ${EXE_SRC}) - target_link_libraries(${LOKINET_SHADOW} ${LOKINET_SHADOW_LIBS}) - target_include_directories(${LOKINET_SHADOW} PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/llarp ${PROJECT_SOURCE_DIR}/crypto/include) -else() - if(NOT WIN32) - add_executable(${EXE} ${EXE_SRC}) - if(TRACY_ROOT) - add_executable(lokinet-rcutil daemon/rcutil.cpp ${TRACY_ROOT}/TracyClient.cpp) - else() - add_executable(lokinet-rcutil daemon/rcutil.cpp) - endif() - elseif(NOT MSVC_VERSION) - add_executable(${EXE} ${EXE_SRC} llarp/win32/version.rc) - add_executable(lokinet-rcutil daemon/rcutil.cpp llarp/win32/version.rc) - else() - add_executable(${EXE} ${EXE_SRC}) - add_executable(lokinet-rcutil daemon/rcutil.cpp) - endif(NOT WIN32) - - add_log_tag(${EXE}) - add_log_tag(lokinet-rcutil) - - install(TARGETS ${EXE} RUNTIME DESTINATION bin) - install(TARGETS lokinet-rcutil RUNTIME DESTINATION bin) - if(WIN32) - install(PROGRAMS ${CMAKE_SOURCE_DIR}/lokinet-bootstrap.exe DESTINATION bin) - else() - install(PROGRAMS ${CMAKE_SOURCE_DIR}/lokinet-bootstrap DESTINATION bin) - endif() - - if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - install(CODE "execute_process(COMMAND setcap cap_net_admin,cap_net_bind_service=+eip ${CMAKE_INSTALL_PREFIX}/bin/lokinet)") - endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - target_link_directories(${EXE} PRIVATE /usr/local/lib) - target_link_directories(lokinet-rcutil PRIVATE /usr/local/lib) - endif() - target_link_libraries(${EXE} PUBLIC ${EXE_LIBS} ${LIBS}) - target_link_libraries(lokinet-rcutil PUBLIC ${EXE_LIBS} ${LIBS}) +enable_testing() +if (NOT SHADOW) + add_subdirectory(test) if(ANDROID) add_library(${ANDROID_LIB} SHARED jni/lokinet_android.cpp) set_property(TARGET ${ANDROID_LIB} PROPERTY CXX_STANDARD 14) add_log_tag(${ANDROID_LIB}) target_link_libraries(${ANDROID_LIB} ${STATIC_LIB} ${LIBS}) endif(ANDROID) -endif(SHADOW) - -enable_testing() - -if (NOT SHADOW) - add_subdirectory(test) endif() diff --git a/Makefile b/Makefile index 4fd99230d..ef30a2522 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,7 @@ endif TARGETS = $(REPO)/lokinet SIGS = $(TARGETS:=.sig) -EXE = $(BUILD_ROOT)/lokinet +EXE = $(BUILD_ROOT)/daemon/lokinet TEST_EXE = $(BUILD_ROOT)/test/testAll ABYSS_EXE = $(BUILD_ROOT)/abyss-main @@ -208,6 +208,10 @@ $(LIBUV_PREFIX): mkdir -p $(BUILD_ROOT) git clone -b "$(LIBUV_VERSION)" https://github.com/libuv/libuv "$(LIBUV_PREFIX)" +ios: + cmake -S ui-ios -B build -G Xcode -DCMAKE_TOOLCHAIN_FILE=$(shell pwd)/ui-ios/ios-toolchain.cmake -DCMAKE_SYSTEM_NAME=iOS "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES + cmake --build build + android-gradle-prepare: $(LIBUV_PREFIX) rm -f $(ANDROID_PROPS) rm -f $(ANDROID_LOCAL_PROPS) diff --git a/cmake/add_log_tag.cmake b/cmake/add_log_tag.cmake index 77f1de1cf..c91fc809f 100644 --- a/cmake/add_log_tag.cmake +++ b/cmake/add_log_tag.cmake @@ -1,6 +1,8 @@ function(add_log_tag target) - get_target_property(TARGET_SRCS ${target} SOURCES) - foreach(F ${TARGET_SRCS}) - set_source_files_properties(${F} PROPERTIES COMPILE_FLAGS -DLOG_TAG=\\\"${F}\\\") - endforeach(F) + if(TARGET ${target}) + get_target_property(TARGET_SRCS ${target} SOURCES) + foreach(F ${TARGET_SRCS}) + set_source_files_properties(${F} PROPERTIES COMPILE_FLAGS -DLOG_TAG=\\\"${F}\\\") + endforeach(F) + endif() endfunction() diff --git a/cmake/basic_definitions.cmake b/cmake/basic_definitions.cmake new file mode 100644 index 000000000..7362e70ca --- /dev/null +++ b/cmake/basic_definitions.cmake @@ -0,0 +1,20 @@ +# Basic definitions +set(LIB lokinet) +set(SHARED_LIB ${LIB}-shared) +set(STATIC_LIB ${LIB}-static) +set(CRYPTOGRAPHY_LIB ${LIB}-cryptography) +set(UTIL_LIB ${LIB}-util) +set(PLATFORM_LIB ${LIB}-platform) +set(ANDROID_LIB ${LIB}android) +set(ABYSS libabyss) +set(ABYSS_LIB abyss) +set(ABYSS_EXE ${ABYSS_LIB}-main) +get_filename_component(TT_ROOT "${CMAKE_CURRENT_LIST_DIR}/../vendor/libtuntap-master" ABSOLUTE) +add_definitions(-D${CMAKE_SYSTEM_NAME}) + +get_filename_component(CORE_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/include" ABSOLUTE) +get_filename_component(ABYSS_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include" ABSOLUTE) + +set(LIBTUNTAP_SRC + ${TT_ROOT}/tuntap.cpp + ${TT_ROOT}/tuntap_log.cpp) diff --git a/cmake/unix.cmake b/cmake/unix.cmake index 817adc79f..ebca06117 100644 --- a/cmake/unix.cmake +++ b/cmake/unix.cmake @@ -7,6 +7,7 @@ include(CheckLibraryExists) add_definitions(-DUNIX) add_definitions(-DPOSIX) +list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix.c) if (STATIC_LINK_RUNTIME OR STATIC_LINK) set(LIBUV_USE_STATIC ON) @@ -18,7 +19,7 @@ if(LIBUV_ROOT) set(LIBUV_LIBRARY uv_a) add_definitions(-D_LARGEFILE_SOURCE) add_definitions(-D_FILE_OFFSET_BITS=64) -else() +elseif(NOT LIBUV_IN_SOURCE) find_package(LibUV 1.28.0 REQUIRED) endif() @@ -30,7 +31,7 @@ endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(FS_LIB stdc++fs) - get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-linux.c ABSOLUTE) + list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-linux.c) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android") find_library(FS_LIB NAMES c++fs c++experimental stdc++fs) if(FS_LIB STREQUAL FS_LIB-NOTFOUND) @@ -38,24 +39,24 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android") add_definitions(-DLOKINET_USE_CPPBACKPORT) set(FS_LIB cppbackport) endif() - get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-linux.c ABSOLUTE) + list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-linux.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") - set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-openbsd.c ${TT_ROOT}/tuntap-unix-bsd.c) + list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-openbsd.c ${TT_ROOT}/tuntap-unix-bsd.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") - set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-netbsd.c ${TT_ROOT}/tuntap-unix-bsd.c) + list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-netbsd.c ${TT_ROOT}/tuntap-unix-bsd.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") find_library(FS_LIB NAMES c++experimental) - set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR ${CMAKE_SYSTEM_NAME} MATCHES "iOS") find_library(FS_LIB NAMES c++fs c++experimental stdc++fs) if(FS_LIB STREQUAL FS_LIB-NOTFOUND) include_directories("${CMAKE_CURRENT_LIST_DIR}/../vendor/cppbackport-master/lib") add_definitions(-DLOKINET_USE_CPPBACKPORT) set(FS_LIB cppbackport) endif() - set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c) + list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-sunos.c) + list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-sunos.c) # Apple C++ screws up name decorations in stdc++fs, causing link to fail # Samsung does not build c++experimental or c++fs in their Apple libc++ pkgsrc build if (LIBUV_USE_STATIC) @@ -69,7 +70,7 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") set(FS_LIB stdc++fs) endif() else() - message(FATAL_ERROR "Your operating system is not supported yet") + message(FATAL_ERROR "Your operating system - ${CMAKE_SYSTEM_NAME} is not supported yet") endif() diff --git a/cmake/win32.cmake b/cmake/win32.cmake index a875a189a..05dbd7f40 100644 --- a/cmake/win32.cmake +++ b/cmake/win32.cmake @@ -21,17 +21,17 @@ if(NOT MSVC_VERSION) # to .r[o]data section one after the other! add_compile_options(-fno-ident -Wa,-mbig-obj) link_libraries( -lws2_32 -liphlpapi -lshlwapi -ldbghelp ) - add_definitions(-DWINVER=0x0500 -D_WIN32_WINNT=0x0500) - # Wait a minute, if we're not Microsoft C++, nor a Clang paired with Microsoft C++, - # then the only possible option has to be GNU or a GNU-linked Clang! + add_definitions(-DWINVER=0x0500 -D_WIN32_WINNT=0x0500) + # Wait a minute, if we're not Microsoft C++, nor a Clang paired with Microsoft C++, + # then the only possible option has to be GNU or a GNU-linked Clang! set(FS_LIB stdc++fs) endif() - -if(EMBEDDED_CFG) - link_libatomic() + +if(EMBEDDED_CFG) + link_libatomic() endif() - -get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c ABSOLUTE) + +list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-windows.c) get_filename_component(EV_SRC "llarp/ev/ev_win32.cpp" ABSOLUTE) add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32 -DWINVER=0x0500) set(EXE_LIBS ${STATIC_LIB} ${FS_LIB} ws2_32 iphlpapi) diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt new file mode 100644 index 000000000..fb45a29d2 --- /dev/null +++ b/daemon/CMakeLists.txt @@ -0,0 +1,45 @@ +set(EXE lokinet) +set(EXE_SRC main.cpp) + +if(TRACY_ROOT) + list(APPEND EXE_SRC ${TRACY_ROOT}/TracyClient.cpp) +endif() + +if(SHADOW) + set(LOKINET_SHADOW shadow-plugin-${SHARED_LIB}) + set(LOKINET_SHADOW_LIBS ${SHARED_LIB}) + add_shadow_plugin(${LOKINET_SHADOW} ${EXE_SRC}) + target_link_libraries(${LOKINET_SHADOW} ${LOKINET_SHADOW_LIBS}) + target_include_directories(${LOKINET_SHADOW} PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/llarp ${PROJECT_SOURCE_DIR}/crypto/include) +else() + if(NOT WIN32) + add_executable(${EXE} ${EXE_SRC}) + add_executable(lokinet-rcutil rcutil.cpp) + elseif(NOT MSVC_VERSION) + add_executable(${EXE} ${EXE_SRC} llarp/win32/version.rc) + add_executable(lokinet-rcutil rcutil.cpp llarp/win32/version.rc) + else() + add_executable(${EXE} ${EXE_SRC}) + add_executable(lokinet-rcutil rcutil.cpp) + endif(NOT WIN32) + + add_log_tag(${EXE}) + add_log_tag(lokinet-rcutil) + + install(TARGETS ${EXE} RUNTIME DESTINATION bin) + install(TARGETS lokinet-rcutil RUNTIME DESTINATION bin) + if(WIN32) + install(PROGRAMS ${CMAKE_SOURCE_DIR}/lokinet-bootstrap.exe DESTINATION bin) + else() + install(PROGRAMS ${CMAKE_SOURCE_DIR}/lokinet-bootstrap DESTINATION bin) + endif() + + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + install(CODE "execute_process(COMMAND setcap cap_net_admin,cap_net_bind_service=+eip ${CMAKE_INSTALL_PREFIX}/bin/lokinet)") + elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + target_link_directories(${EXE} PRIVATE /usr/local/lib) + target_link_directories(lokinet-rcutil PRIVATE /usr/local/lib) + endif() + target_link_libraries(${EXE} PUBLIC ${EXE_LIBS} ${LIBS}) + target_link_libraries(lokinet-rcutil PUBLIC ${EXE_LIBS} ${LIBS}) +endif(SHADOW) diff --git a/daemon/main.cpp b/daemon/main.cpp index d2a489e0e..5061be47c 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -1,4 +1,5 @@ #include // for ensure_config +#include #include #include #include @@ -84,7 +85,7 @@ resolvePath(std::string conffname) /// this sets up, configures and runs the main context static void -run_main_context(std::string conffname, bool multiThreaded, bool debugMode) +run_main_context(std::string conffname, bool multiThreaded, bool backgroundMode) { // this is important, can downgrade from Info though llarp::LogDebug("Running from: ", fs::current_path().string()); @@ -98,10 +99,10 @@ run_main_context(std::string conffname, bool multiThreaded, bool debugMode) #ifndef _WIN32 signal(SIGHUP, handle_signal); #endif - code = llarp_main_setup(ctx, debugMode); + code = llarp_main_setup(ctx); llarp::util::SetThreadName("llarp-mainloop"); if(code == 0) - code = llarp_main_run(ctx); + code = llarp_main_run(ctx, backgroundMode); llarp_main_free(ctx); } exit_code.set_value(code); @@ -136,20 +137,21 @@ main(int argc, char *argv[]) options.add_options() ("v,verbose", "Verbose", cxxopts::value()) ("h,help", "help", cxxopts::value()) + ("version", "version", cxxopts::value()) ("g,generate", "generate client config", cxxopts::value()) ("r,router", "generate router config", cxxopts::value()) ("f,force", "overwrite", cxxopts::value()) ("c,colour", "colour output", cxxopts::value()->default_value("true")) - ("d,debug", "debug mode - UNENCRYPTED TRAFFIC", cxxopts::value()) + ("b,background", "background mode (start, but do not connect to the network)", cxxopts::value()) ("config","path to configuration file", cxxopts::value()); options.parse_positional("config"); // clang-format on - bool genconfigOnly = false; - bool asRouter = false; - bool overWrite = false; - bool debugMode = false; + bool genconfigOnly = false; + bool asRouter = false; + bool overWrite = false; + bool backgroundMode = false; std::string conffname; // suggestions: confFName? conf_fname? try @@ -174,14 +176,20 @@ main(int argc, char *argv[]) return 0; } + if(result.count("version")) + { + std::cout << LLARP_VERSION << std::endl; + return 0; + } + if(result.count("generate") > 0) { genconfigOnly = true; } - if(result.count("debug") > 0) + if(result.count("background") > 0) { - debugMode = true; + backgroundMode = true; } if(result.count("force") > 0) @@ -313,7 +321,7 @@ main(int argc, char *argv[]) } std::thread main_thread{ - std::bind(&run_main_context, conffname, multiThreaded, debugMode)}; + std::bind(&run_main_context, conffname, multiThreaded, backgroundMode)}; auto ftr = exit_code.get_future(); do { diff --git a/docker/compose/compose-base.Dockerfile b/docker/compose/compose-base.Dockerfile index 208b1bced..07caebd24 100644 --- a/docker/compose/compose-base.Dockerfile +++ b/docker/compose/compose-base.Dockerfile @@ -12,5 +12,5 @@ RUN make NINJA=ninja STATIC_LINK=ON BUILD_TYPE=Release FROM alpine:latest -COPY --from=builder /src/build/lokinet / -COPY --from=builder /src/build/lokinet-rcutil / +COPY --from=builder /src/build/daemon/lokinet / +COPY --from=builder /src/build/daemon/lokinet-rcutil / diff --git a/docker/router.Dockerfile b/docker/router.Dockerfile index 33c913bdf..1b933046e 100644 --- a/docker/router.Dockerfile +++ b/docker/router.Dockerfile @@ -13,7 +13,7 @@ RUN ./lokinet-bootstrap ${bootstrap} FROM alpine:latest COPY lokinet-docker.ini /root/.lokinet/lokinet.ini -COPY --from=builder /src/build/lokinet . +COPY --from=builder /src/build/daemon/lokinet . COPY --from=builder /root/.lokinet/bootstrap.signed /root/.lokinet/ CMD ["./lokinet"] diff --git a/include/llarp.h b/include/llarp.h index 24779c17d..72f4856d5 100644 --- a/include/llarp.h +++ b/include/llarp.h @@ -41,11 +41,11 @@ extern "C" /// setup main context, returns 0 on success int - llarp_main_setup(struct llarp_main *ptr, bool debugMode); + llarp_main_setup(struct llarp_main *ptr); /// run main context, returns 0 on success, blocks until program end int - llarp_main_run(struct llarp_main *ptr); + llarp_main_run(struct llarp_main *ptr, bool backgroundMode); /// free main context and end all operations void diff --git a/include/llarp.hpp b/include/llarp.hpp index d380350eb..9f34e22bf 100644 --- a/include/llarp.hpp +++ b/include/llarp.hpp @@ -81,10 +81,10 @@ namespace llarp GetDatabase(const byte_t *pk); int - Setup(bool debug = false); + Setup(); int - Run(); + Run(bool daemonMode); void HandleSignal(int sig); diff --git a/include/tuntap.h b/include/tuntap.h index 6cc444a70..5981793f6 100644 --- a/include/tuntap.h +++ b/include/tuntap.h @@ -42,6 +42,8 @@ #endif #if defined Linux #include +#elif defined(iOS) +#include #else #include #endif diff --git a/libabyss/CMakeLists.txt b/libabyss/CMakeLists.txt index 7a7f71b2f..f013d14a0 100644 --- a/libabyss/CMakeLists.txt +++ b/libabyss/CMakeLists.txt @@ -4,6 +4,25 @@ add_library(${ABYSS_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/src/md5.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/server.cpp") target_include_directories(${ABYSS_LIB} PUBLIC include) -if(NOT WIN32) - target_link_libraries(${ABYSS_LIB} PUBLIC ${PLATFORM_LIB} ${LIBUV_LIBRARY}) +target_link_libraries(${ABYSS_LIB} PUBLIC ${PLATFORM_LIB}) + +if(NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL iOS) + target_link_libraries(${ABYSS_LIB} PUBLIC ${LIBUV_LIBRARY}) + add_executable(${ABYSS_EXE} main.cpp) + target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} Threads::Threads ${LIBS}) +elseif(MSVC_VERSION) + add_executable(${ABYSS_EXE} main.cpp) + target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} ${STATIC_LIB} ws2_32) +elseif(NOT CMAKE_SYSTEM_NAME STREQUAL iOS) + add_executable(${ABYSS_EXE} main.cpp llarp/win32/abyss.rc) + target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} ${STATIC_LIB} ws2_32) endif() + +# for freebsd +if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + target_link_directories(${ABYSS_EXE} PRIVATE /usr/local/lib) + target_include_directories(${ABYSS_LIB} SYSTEM PUBLIC /usr/local/include) +endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + +add_log_tag(${ABYSS_EXE}) +add_log_tag(${ABYSS_LIB}) diff --git a/llarp/context.cpp b/llarp/context.cpp index 894454602..e26ab6277 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -193,39 +193,13 @@ __ ___ ____ _ _ ___ _ _ ____ } int - Context::Setup(bool debug) + Context::Setup() { llarp::LogInfo(LLARP_VERSION, " ", LLARP_RELEASE_MOTTO); llarp::LogInfo("starting up"); mainloop = llarp_make_ev_loop(); - if(debug) - { - static std::string WARNING = R"( -__ ___ ____ _ _ ___ _ _ ____ -\ \ / / \ | _ \| \ | |_ _| \ | |/ ___| - \ \ /\ / / _ \ | |_) | \| || || \| | | _ - \ V V / ___ \| _ <| |\ || || |\ | |_| | - \_/\_/_/ \_\_| \_\_| \_|___|_| \_|\____| - -This Lokinet session is not private!! - -Sending traffic unencrypted!! -__ ___ ____ _ _ ___ _ _ ____ -\ \ / / \ | _ \| \ | |_ _| \ | |/ ___| - \ \ /\ / / _ \ | |_) | \| || || \| | | _ - \ V V / ___ \| _ <| |\ || || |\ | |_| | - \_/\_/_/ \_\_| \_\_| \_|___|_| \_|\____| - - )"; - - std::cerr << WARNING << '\n'; - crypto = std::make_unique< NoOpCrypto >(); - } - else - { - crypto = std::make_unique< sodium::CryptoLibSodium >(); - } + crypto = std::make_unique< sodium::CryptoLibSodium >(); cryptoManager = std::make_unique< CryptoManager >(crypto.get()); router = std::make_unique< Router >(worker, mainloop, logic); @@ -248,7 +222,7 @@ __ ___ ____ _ _ ___ _ _ ____ } int - Context::Run() + Context::Run(bool backgroundMode) { if(router == nullptr) { @@ -259,9 +233,15 @@ __ ___ ____ _ _ ___ _ _ ____ if(!WritePIDFile()) return 1; // run - if(!router->Run(nodedb.get())) + if(!router->StartJsonRpc()) return 1; + if(!backgroundMode) + { + if(!router->Run()) + return 2; + } + // run net io thread llarp::LogInfo("running mainloop"); llarp_ev_loop_run_single_process(mainloop, logic); @@ -438,20 +418,20 @@ extern "C" } int - llarp_main_setup(struct llarp_main *ptr, bool debug) + llarp_main_setup(struct llarp_main *ptr) { - return ptr->ctx->Setup(debug); + return ptr->ctx->Setup(); } int - llarp_main_run(struct llarp_main *ptr) + llarp_main_run(struct llarp_main *ptr, bool backgroundMode) { if(!ptr) { llarp::LogError("No ptr passed in"); return 1; } - return ptr->ctx->Run(); + return ptr->ctx->Run(backgroundMode); } void diff --git a/llarp/router/abstractrouter.hpp b/llarp/router/abstractrouter.hpp index ad2891834..08fbf449e 100644 --- a/llarp/router/abstractrouter.hpp +++ b/llarp/router/abstractrouter.hpp @@ -127,7 +127,10 @@ namespace llarp Configure(Config *conf, llarp_nodedb *nodedb) = 0; virtual bool - Run(struct llarp_nodedb *nodedb) = 0; + StartJsonRpc() = 0; + + virtual bool + Run() = 0; /// stop running the router logic gracefully virtual void diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index cef9d608e..5a36e0ce6 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -110,11 +110,19 @@ namespace llarp util::StatusObject Router::ExtractStatus() const { - return util::StatusObject{ - {"dht", _dht->impl->ExtractStatus()}, - {"services", _hiddenServiceContext.ExtractStatus()}, - {"exit", _exitContext.ExtractStatus()}, - {"links", _linkManager.ExtractStatus()}}; + if(_running) + { + return util::StatusObject{ + {"running", true}, + {"dht", _dht->impl->ExtractStatus()}, + {"services", _hiddenServiceContext.ExtractStatus()}, + {"exit", _exitContext.ExtractStatus()}, + {"links", _linkManager.ExtractStatus()}}; + } + else + { + return util::StatusObject{{"running", false}}; + } } bool @@ -836,11 +844,10 @@ namespace llarp } bool - Router::Run(struct llarp_nodedb *nodedb) + Router::StartJsonRpc() { if(_running || _stopping) return false; - this->_nodedb = nodedb; if(enableRPCServer) { @@ -860,6 +867,16 @@ namespace llarp } LogInfo("Bound RPC server to ", rpcBindAddr); } + + return true; + } + + bool + Router::Run() + { + if(_running || _stopping) + return false; + if(whitelistRouters) { rpcCaller = std::make_unique< rpc::Caller >(this); @@ -1012,8 +1029,10 @@ namespace llarp _dht->impl->Nodes()->PutNode(rc); } - LogInfo("have ", nodedb->num_loaded(), " routers"); + LogInfo("have ", _nodedb->num_loaded(), " routers"); + _netloop->add_ticker(std::bind(&Router::PumpLL, this)); + ScheduleTicker(1000); _running.store(true); _startedAt = Now(); diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index dce19004f..e2d94536e 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -327,7 +327,10 @@ namespace llarp Configure(Config *conf, llarp_nodedb *nodedb = nullptr) override; bool - Run(struct llarp_nodedb *nodedb) override; + StartJsonRpc() override; + + bool + Run() override; /// stop running the router logic gracefully void diff --git a/llarp/rpc/rpc.cpp b/llarp/rpc/rpc.cpp index e2830389b..12cc3725c 100644 --- a/llarp/rpc/rpc.cpp +++ b/llarp/rpc/rpc.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -194,6 +195,13 @@ namespace llarp ~Handler() override = default; + Response + StartRouter() const + { + const bool rc = router->Run(); + return Response{{"status", rc}}; + } + Response DumpState() const { @@ -259,10 +267,21 @@ namespace llarp return resp; } + Response + DumpVersion() const + { + const Response resp{{"version", LLARP_VERSION}}; + return resp; + } + absl::optional< Response > HandleJSONRPC(Method_t method, ABSL_ATTRIBUTE_UNUSED const Params& params) override { + if(method == "llarp.admin.wakeup") + { + return StartRouter(); + } if(method == "llarp.admin.link.neighboors") { return ListNeighboors(); @@ -279,6 +298,10 @@ namespace llarp { return DumpStatus(); } + if(method == "llarp.version") + { + return DumpVersion(); + } return false; } }; diff --git a/ui-ios/CMakeLists.txt b/ui-ios/CMakeLists.txt new file mode 100644 index 000000000..8e1a98e67 --- /dev/null +++ b/ui-ios/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 3.14) +set(PROJECT_NAME lokinet) +project(${PROJECT_NAME} C CXX Swift) + +get_filename_component(LOKINET_ROOT .. ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}") + +include("${LOKINET_ROOT}/cmake/target_link_libraries_system.cmake") +include("${LOKINET_ROOT}/cmake/add_import_library.cmake") +include("${LOKINET_ROOT}/cmake/add_log_tag.cmake") +include("${LOKINET_ROOT}/cmake/libatomic.cmake") + +if (STATIC_LINK AND STATIC_LINK_RUNTIME) + message(FATAL "Cannot set both STATIC_LINK and STATIC_LINK_RUNTIME") +endif() + +set(CMAKE_Swift_LANGUAGE_VERSION 5.0) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +list(APPEND CMAKE_MODULE_PATH "${LOKINET_ROOT}/cmake") + +include(FetchContent) +FetchContent_Declare( + libuv + GIT_REPOSITORY https://github.com/libuv/libuv.git + GIT_TAG v1.32.0 +) +FetchContent_Populate(libuv) +add_subdirectory(${libuv_SOURCE_DIR} ${libuv_BINARY_DIR}) + +include("${LOKINET_ROOT}/cmake/basic_definitions.cmake") +set(LIBUV_IN_SOURCE ON) +set(LIBUV_LIBRARY uv_a) +include("${LOKINET_ROOT}/cmake/unix.cmake") +unset(LIBTUNTAP_SRC) + +find_package(Threads REQUIRED) + +set(ABSEIL_DIR "${LOKINET_ROOT}/vendor/abseil-cpp") + +macro(add_loki_dir name) + add_subdirectory("${LOKINET_ROOT}/${name}" "${name}") +endmacro() + +include_directories(SYSTEM ${ABSEIL_DIR}) +add_loki_dir(vendor/cxxopts) +add_loki_dir(vendor/nlohmann) +include_directories(SYSTEM "${LOKINET_ROOT}/vendor/cxxopts/include") +include_directories("${LOKINET_ROOT}/include") +include_directories("${libuv_SOURCE_DIR}/include") + +add_loki_dir(vendor/gtest) +add_subdirectory(${ABSEIL_DIR} "vendor/abseil-cpp") + +if (FS_LIB STREQUAL "cppbackport") + add_loki_dir(vendor) +endif() + +add_loki_dir(crypto) +add_loki_dir(llarp) +add_loki_dir(libabyss) + +add_subdirectory(lokinet) diff --git a/ui-ios/ios-toolchain.cmake b/ui-ios/ios-toolchain.cmake new file mode 100644 index 000000000..8d36fe7fc --- /dev/null +++ b/ui-ios/ios-toolchain.cmake @@ -0,0 +1,4 @@ +set(CMAKE_MACOSX_BUNDLE YES) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED NO) +set(CMAKE_OSX_SYSROOT iphoneos) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "") diff --git a/ui-ios/lokinet/AppDelegate.swift b/ui-ios/lokinet/AppDelegate.swift new file mode 100644 index 000000000..dbb3fcde6 --- /dev/null +++ b/ui-ios/lokinet/AppDelegate.swift @@ -0,0 +1,92 @@ +// +// AppDelegate.swift +// lokinet +// +// Copyright © 2019 Loki. All rights reserved. +// + +import UIKit +import CoreData + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 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:. + // Saves changes in the application's managed object context before the application terminates. + self.saveContext() + } + + // MARK: - Core Data stack + + lazy var persistentContainer: NSPersistentContainer = { + /* + The persistent container for the application. This implementation + creates and returns a container, having loaded the store for the + application to it. This property is optional since there are legitimate + error conditions that could cause the creation of the store to fail. + */ + let container = NSPersistentContainer(name: "lokinet") + container.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error as NSError? { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + /* + Typical reasons for an error here include: + * The parent directory does not exist, cannot be created, or disallows writing. + * The persistent store is not accessible, due to permissions or data protection when the device is locked. + * The device is out of space. + * The store could not be migrated to the current model version. + Check the error message to determine what the actual problem was. + */ + fatalError("Unresolved error \(error), \(error.userInfo)") + } + }) + return container + }() + + // MARK: - Core Data Saving support + + func saveContext () { + let context = persistentContainer.viewContext + if context.hasChanges { + do { + try context.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nserror = error as NSError + fatalError("Unresolved error \(nserror), \(nserror.userInfo)") + } + } + } + +} + diff --git a/ui-ios/lokinet/Assets.xcassets/AppIcon.appiconset/Contents.json b/ui-ios/lokinet/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d8db8d65f --- /dev/null +++ b/ui-ios/lokinet/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "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/ui-ios/lokinet/Assets.xcassets/Contents.json b/ui-ios/lokinet/Assets.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/ui-ios/lokinet/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ui-ios/lokinet/Base.lproj/LaunchScreen.storyboard b/ui-ios/lokinet/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..bfa361294 --- /dev/null +++ b/ui-ios/lokinet/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ios/lokinet/Base.lproj/Main.storyboard b/ui-ios/lokinet/Base.lproj/Main.storyboard new file mode 100644 index 000000000..f1bcf3840 --- /dev/null +++ b/ui-ios/lokinet/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ios/lokinet/CMakeLists.txt b/ui-ios/lokinet/CMakeLists.txt new file mode 100644 index 000000000..35fa08bd5 --- /dev/null +++ b/ui-ios/lokinet/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(lokinet AppDelegate.swift ViewController.swift) diff --git a/ui-ios/lokinet/Info.plist b/ui-ios/lokinet/Info.plist new file mode 100644 index 000000000..16be3b681 --- /dev/null +++ b/ui-ios/lokinet/Info.plist @@ -0,0 +1,45 @@ + + + + + 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/ui-ios/lokinet/ViewController.swift b/ui-ios/lokinet/ViewController.swift new file mode 100644 index 000000000..26e307e09 --- /dev/null +++ b/ui-ios/lokinet/ViewController.swift @@ -0,0 +1,19 @@ +// +// ViewController.swift +// lokinet +// +// Copyright © 2019 Loki. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} + diff --git a/ui-ios/lokinet/lokinet.entitlements b/ui-ios/lokinet/lokinet.entitlements new file mode 100644 index 000000000..8f2ff3f1e --- /dev/null +++ b/ui-ios/lokinet/lokinet.entitlements @@ -0,0 +1,15 @@ + + + + + com.apple.developer.networking.networkextension + + dns-proxy + packet-tunnel-provider + + com.apple.developer.networking.vpn.api + + allow-vpn + + + diff --git a/ui-ios/lokinet/lokinet.xcdatamodeld/.xccurrentversion b/ui-ios/lokinet/lokinet.xcdatamodeld/.xccurrentversion new file mode 100644 index 000000000..bf2d08f0a --- /dev/null +++ b/ui-ios/lokinet/lokinet.xcdatamodeld/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + lokinet.xcdatamodel + + diff --git a/ui-ios/lokinet/lokinet.xcdatamodeld/lokinet.xcdatamodel/contents b/ui-ios/lokinet/lokinet.xcdatamodeld/lokinet.xcdatamodel/contents new file mode 100644 index 000000000..476e5b6cf --- /dev/null +++ b/ui-ios/lokinet/lokinet.xcdatamodeld/lokinet.xcdatamodel/contents @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/vendor/cxxopts/test/options.cpp b/vendor/cxxopts/test/options.cpp index d110e0125..d3d3c7a69 100644 --- a/vendor/cxxopts/test/options.cpp +++ b/vendor/cxxopts/test/options.cpp @@ -9,7 +9,7 @@ class Argv { Argv(std::initializer_list args) : m_argv(new char*[args.size()]) - , m_argc(args.size()) + , m_argc(static_cast(args.size())) { int i = 0; auto iter = args.begin();