diff --git a/CMakeLists.txt b/CMakeLists.txt index a095deedb..be03d9830 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,6 +416,7 @@ else() 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) diff --git a/Makefile b/Makefile index 5336a9439..5b78594ec 100644 --- a/Makefile +++ b/Makefile @@ -185,6 +185,7 @@ android-gradle-prepare: echo "#auto generated don't modify kthnx" >> $(ANDROID_PROPS) echo "lokinetCMake=$(REPO)/CMakeLists.txt" >> $(ANDROID_PROPS) echo "org.gradle.parallel=true" >> $(ANDROID_PROPS) + echo "org.gradle.jvmargs=-Xmx1536M" >> $(ANDROID_PROPS) echo "#auto generated don't modify kthnx" >> $(ANDROID_LOCAL_PROPS) echo "sdk.dir=$(ANDROID_SDK)" >> $(ANDROID_LOCAL_PROPS) echo "ndk.dir=$(ANDROID_NDK)" >> $(ANDROID_LOCAL_PROPS) diff --git a/android/build.gradle b/android/build.gradle index 9cd1597bf..d2d496e4f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -24,17 +24,17 @@ android { defaultConfig { applicationId "network.loki.lokinet" targetSdkVersion 28 - minSdkVersion 14 + minSdkVersion 23 versionCode 1 versionName "0.4.0" ndk { - abiFilters 'armeabi' + abiFilters 'armeabi' } externalNativeBuild { cmake { targets "lokinetandroid" - arguments "-DANDROID=ON", "-DANDROID_STL=c++_static" - cppFlags "-fexceptions" + arguments "-DANDROID=ON", "-DANDROID_STL=c++_static", "-DANDROID_ARM_NEON=TRUE" + cppFlags "-fexceptions -std=c++14 -frtti" } } packagingOptions{ diff --git a/android/src/network/loki/lokinet/Lokinet_JNI.java b/android/src/network/loki/lokinet/Lokinet_JNI.java index eb3a2ebba..a5d3cda40 100644 --- a/android/src/network/loki/lokinet/Lokinet_JNI.java +++ b/android/src/network/loki/lokinet/Lokinet_JNI.java @@ -29,10 +29,11 @@ public class Lokinet_JNI { public static native void onNetworkStateChanged(boolean isConnected); /** - * set vpn network interface fd - * @param fd the file descriptor of the vpn interface + * set vpn network interface fd pair + * @param rfd the file descriptor of read end + * @param wfd the file descriptor of the write end */ - public static native void setVPNFileDescriptor(int fd); + public static native void setVPNFileDescriptor(int rfd, int wfd); /** * load jni libraries diff --git a/crypto/libntrup/src/avx/dec.c b/crypto/libntrup/src/avx/dec.c index 8b1d0034d..817b22a84 100644 --- a/crypto/libntrup/src/avx/dec.c +++ b/crypto/libntrup/src/avx/dec.c @@ -1,15 +1,15 @@ #ifdef KAT #include #endif +#include +#include +#include #include "params.h" #include "small.h" #include "mod3.h" #include "rq.h" #include "r3.h" -#include -#include -#include int crypto_kem_dec_avx2(unsigned char *k, const unsigned char *cstr, diff --git a/crypto/libntrup/src/ref/dec.c b/crypto/libntrup/src/ref/dec.c index f489a89a3..c110465b2 100644 --- a/crypto/libntrup/src/ref/dec.c +++ b/crypto/libntrup/src/ref/dec.c @@ -1,15 +1,15 @@ #ifdef KAT #include #endif +#include +#include +#include #include "params.h" #include "small.h" #include "mod3.h" #include "rq.h" #include "r3.h" -#include -#include -#include int crypto_kem_dec_ref(unsigned char *k, const unsigned char *cstr, diff --git a/include/llarp.h b/include/llarp.h index eefb1cc65..45f8d6c37 100644 --- a/include/llarp.h +++ b/include/llarp.h @@ -35,9 +35,9 @@ extern "C" void llarp_main_signal(struct llarp_main *ptr, int sig); - /// give main context a vpn file descriptor (android/ios) + /// give main context a vpn file descriptor pair (android/ios) void - llarp_main_inject_vpn_fd(struct llarp_main *m, int fd); + llarp_main_inject_vpn_fd(struct llarp_main *m, int rfd, int wfd); /// setup main context, returns 0 on success int diff --git a/jni/lokinet_android.cpp b/jni/lokinet_android.cpp index 1ca398695..ba79378d8 100755 --- a/jni/lokinet_android.cpp +++ b/jni/lokinet_android.cpp @@ -97,10 +97,10 @@ struct AndroidMain } void - SetVPN_FD(int fd) + SetVPN_FD(int rfd, int wfd) { if(m_impl) - llarp_main_inject_vpn_fd(m_impl, fd); + llarp_main_inject_vpn_fd(m_impl, rfd, wfd); } /// stop daemon thread @@ -120,7 +120,7 @@ struct AndroidMain typedef std::unique_ptr< AndroidMain > Ptr; }; -static AndroidMain::Ptr daemon(new AndroidMain()); +static AndroidMain::Ptr daemon_ptr(new AndroidMain()); extern "C" { @@ -135,7 +135,7 @@ extern "C" Java_network_loki_lokinet_Lokinet_1JNI_startLokinet(JNIEnv* env, jclass, jstring configfile) { - if(daemon->Running()) + if(daemon_ptr->Running()) return env->NewStringUTF("already running"); std::string conf; fs::path basepath; @@ -145,9 +145,9 @@ extern "C" env->ReleaseStringUTFChars(configfile, nativeString); basepath = fs::path(conf).parent_path(); } - if(daemon->Configure(conf.c_str(), basepath.string().c_str())) + if(daemon_ptr->Configure(conf.c_str(), basepath.string().c_str())) { - if(daemon->Start()) + if(daemon_ptr->Start()) return env->NewStringUTF("ok"); else return env->NewStringUTF("failed to start daemon"); @@ -159,24 +159,25 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet(JNIEnv*, jclass) { - if(daemon->Running()) + if(daemon_ptr->Running()) { - daemon->Stop(); + daemon_ptr->Stop(); } } JNIEXPORT void JNICALL Java_network_loki_lokinet_Lokinet_1JNI_setVPNFileDescriptor(JNIEnv*, jclass, - jint fd) + jint rfd, + jint wfd) { - daemon->SetVPN_FD(fd); + daemon_ptr->SetVPN_FD(rfd, wfd); } JNIEXPORT jstring JNICALL Java_network_loki_lokinet_Lokinet_1JNI_getIfAddr(JNIEnv* env, jclass) { - if(daemon) - return env->NewStringUTF(daemon->GetIfAddr()); + if(daemon_ptr) + return env->NewStringUTF(daemon_ptr->GetIfAddr()); else return env->NewStringUTF(""); } @@ -184,8 +185,8 @@ extern "C" JNIEXPORT jint JNICALL Java_network_loki_lokinet_Lokinet_1JNI_getIfRange(JNIEnv*, jclass) { - if(daemon) - return daemon->GetIfRange(); + if(daemon_ptr) + return daemon_ptr->GetIfRange(); else return -1; } @@ -196,17 +197,17 @@ extern "C" { if(isConnected) { - if(!daemon->Running()) + if(!daemon_ptr->Running()) { - if(!daemon->Start()) + if(!daemon_ptr->Start()) { // TODO: do some kind of callback here } } } - else if(daemon->Running()) + else if(daemon_ptr->Running()) { - daemon->Stop(); + daemon_ptr->Stop(); } } } diff --git a/jni/network_loki_lokinet_Lokinet_JNI.h b/jni/network_loki_lokinet_Lokinet_JNI.h index 035c4e248..94b8d964b 100644 --- a/jni/network_loki_lokinet_Lokinet_JNI.h +++ b/jni/network_loki_lokinet_Lokinet_JNI.h @@ -5,48 +5,52 @@ #ifndef _Included_network_loki_lokinet_Lokinet_JNI #define _Included_network_loki_lokinet_Lokinet_JNI #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/* - * Class: network_loki_lokinet_Lokinet_JNI - * Method: getABICompiledWith - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_network_loki_lokinet_Lokinet_1JNI_getABICompiledWith - (JNIEnv *, jclass); - -/* - * Class: network_loki_lokinet_Lokinet_JNI - * Method: startLokinet - * Signature: (Ljava/lang/String;)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_network_loki_lokinet_Lokinet_1JNI_startLokinet - (JNIEnv *, jclass, jstring); - -JNIEXPORT jstring JNICALL Java_network_loki_lokinet_Lokinet_1JNI_getIfAddr - (JNIEnv *, jclass); - -JNIEXPORT jint JNICALL Java_network_loki_lokinet_Lokinet_1JNI_getIfRange - (JNIEnv *, jclass); - -/* - * Class: network_loki_lokinet_Lokinet_JNI - * Method: stopLokinet - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_network_loki_lokinet_Lokinet_1JNI_setVPNFileDescriptor - (JNIEnv *, jclass, jint); - -/* - * Class: network_loki_lokinet_Lokinet_JNI - * Method: onNetworkStateChanged - * Signature: (Z)V - */ -JNIEXPORT void JNICALL Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged - (JNIEnv *, jclass, jboolean); + /* + * Class: network_loki_lokinet_Lokinet_JNI + * Method: getABICompiledWith + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL + Java_network_loki_lokinet_Lokinet_1JNI_getABICompiledWith(JNIEnv *, jclass); + + /* + * Class: network_loki_lokinet_Lokinet_JNI + * Method: startLokinet + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL + Java_network_loki_lokinet_Lokinet_1JNI_startLokinet(JNIEnv *, jclass, + jstring); + + JNIEXPORT jstring JNICALL + Java_network_loki_lokinet_Lokinet_1JNI_getIfAddr(JNIEnv *, jclass); + + JNIEXPORT jint JNICALL + Java_network_loki_lokinet_Lokinet_1JNI_getIfRange(JNIEnv *, jclass); + + /* + * Class: network_loki_lokinet_Lokinet_JNI + * Method: stopLokinet + * Signature: ()V + */ + JNIEXPORT void JNICALL + Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet(JNIEnv *, jclass); + + JNIEXPORT void JNICALL + Java_network_loki_lokinet_Lokinet_1JNI_setVPNFileDescriptor(JNIEnv *, jclass, + jint, jint); + + /* + * Class: network_loki_lokinet_Lokinet_JNI + * Method: onNetworkStateChanged + * Signature: (Z)V + */ + JNIEXPORT void JNICALL + Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged(JNIEnv *, jclass, + jboolean); #ifdef __cplusplus } diff --git a/llarp/context.cpp b/llarp/context.cpp index 0dfab6152..ac3a34c06 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -414,7 +414,7 @@ extern "C" } void - llarp_main_inject_vpn_fd(struct llarp_main *ptr, int fd) + llarp_main_inject_vpn_fd(struct llarp_main *ptr, int rfd, int wfd) { llarp::handlers::TunEndpoint *tun = ptr->ctx->router->hiddenServiceContext().getFirstTun(); @@ -422,7 +422,7 @@ extern "C" return; if(!tun->Promise) return; - tun->Promise->Set(fd); + tun->Promise->Set({rfd, wfd}); } int diff --git a/llarp/ev/ev.cpp b/llarp/ev/ev.cpp index 67cfbcd7c..1bdef1c07 100644 --- a/llarp/ev/ev.cpp +++ b/llarp/ev/ev.cpp @@ -40,12 +40,6 @@ llarp_make_ev_loop() return r; } -int -llarp_fd_promise_wait_for_value(struct llarp_fd_promise *p) -{ - return p->Get(); -} - void llarp_ev_loop_run_single_process(llarp_ev_loop_ptr ev, struct llarp_threadpool *tp, diff --git a/llarp/ev/ev.hpp b/llarp/ev/ev.hpp index d915b0e7e..79532e421 100644 --- a/llarp/ev/ev.hpp +++ b/llarp/ev/ev.hpp @@ -660,7 +660,7 @@ namespace llarp struct llarp_fd_promise { void - Set(int) + Set(std::pair< int, int >) { } @@ -673,18 +673,19 @@ struct llarp_fd_promise #else struct llarp_fd_promise { - llarp_fd_promise(std::promise< int >* p) : _impl(p) + using promise_val_t = std::pair< int, int >; + llarp_fd_promise(std::promise< promise_val_t >* p) : _impl(p) { } - std::promise< int >* _impl; + std::promise< promise_val_t >* _impl; void - Set(int fd) + Set(promise_val_t fds) { - _impl->set_value(fd); + _impl->set_value(fds); } - int + promise_val_t Get() { auto future = _impl->get_future(); diff --git a/llarp/ev/ev_epoll.cpp b/llarp/ev/ev_epoll.cpp index d75250407..9f92bf4b5 100644 --- a/llarp/ev/ev_epoll.cpp +++ b/llarp/ev/ev_epoll.cpp @@ -1,10 +1,5 @@ #include -#ifdef ANDROID -/** TODO: correct this value */ -#define SOCK_NONBLOCK (0) -#endif - namespace llarp { int @@ -191,6 +186,14 @@ namespace llarp return ret; } + ssize_t + tun::do_write(void* buf, size_t sz) + { + if(writefd != -1) // case of android + return ::write(writefd, buf, sz); + return ev_io::do_write(buf, sz); + } + int tun::wait_for_fd_promise(struct device* dev) { @@ -199,7 +202,14 @@ namespace llarp { struct llarp_fd_promise* promise = t->t->get_fd_promise(t->t); if(promise) - return llarp_fd_promise_wait_for_value(promise); + { + // get promise + auto p = promise->Get(); + // set write fd + t->writefd = p.second; + // return read fd + return p.first; + } } return -1; } diff --git a/llarp/ev/ev_epoll.hpp b/llarp/ev/ev_epoll.hpp index c055f1029..2fbb97ec9 100644 --- a/llarp/ev/ev_epoll.hpp +++ b/llarp/ev/ev_epoll.hpp @@ -18,11 +18,6 @@ #include #include -#ifdef ANDROID -/** TODO: correct this value */ -#define SOCK_NONBLOCK (0) -#endif - namespace llarp { struct udp_listener : public ev_io @@ -36,22 +31,24 @@ namespace llarp } bool - tick(); + tick() override; int - read(byte_t* buf, size_t sz); + read(byte_t* buf, size_t sz) override; int - sendto(const sockaddr* to, const void* data, size_t sz); + sendto(const sockaddr* to, const void* data, size_t sz) override; }; struct tun : public ev_io { llarp_tun_io* t; + int writefd; device* tunif; tun(llarp_tun_io* tio, llarp_ev_loop_ptr l) : ev_io(-1, new LossyWriteQueue_t("tun_write_queue", l, l)) , t(tio) + , writefd(-1) , tunif(tuntap_init()) { @@ -59,16 +56,19 @@ namespace llarp }; int - sendto(const sockaddr* to, const void* data, size_t sz); + sendto(const sockaddr* to, const void* data, size_t sz) override; bool - tick(); + tick() override; void - flush_write(); + flush_write() override; + + ssize_t + do_write(void* buf, size_t sz) override; int - read(byte_t* buf, size_t sz); + read(byte_t* buf, size_t sz) override; static int wait_for_fd_promise(struct device* dev); @@ -84,8 +84,9 @@ namespace llarp }; }; // namespace llarp -struct llarp_epoll_loop : public llarp_ev_loop, - public std::enable_shared_from_this< llarp_ev_loop > +struct llarp_epoll_loop + : public llarp_ev_loop, + public std::enable_shared_from_this< llarp_epoll_loop > { int epollfd; diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 2e5ad0f3b..f9bfee2ea 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -212,7 +212,7 @@ namespace llarp #ifndef WIN32 /// handles fd injection force android - std::promise< int > m_VPNPromise; + std::promise< std::pair< int, int > > m_VPNPromise; #endif /// our dns resolver diff --git a/vendor/abseil-cpp/CMakeLists.txt b/vendor/abseil-cpp/CMakeLists.txt index 097b46f4f..7a5fefbf7 100644 --- a/vendor/abseil-cpp/CMakeLists.txt +++ b/vendor/abseil-cpp/CMakeLists.txt @@ -49,7 +49,7 @@ if (MSVC) /D_ENABLE_EXTENDED_ALIGNED_STORAGE ) else() - set(ABSL_STD_CXX_FLAG "-std=c++11" CACHE STRING "c++ std flag (default: c++11)") + set(ABSL_STD_CXX_FLAG "-std=c++17" CACHE STRING "c++ std flag (default: c++11)") endif() diff --git a/vendor/abseil-cpp/absl/base/internal/spinlock_wait.cc b/vendor/abseil-cpp/absl/base/internal/spinlock_wait.cc index fda55ca55..583df2f9e 100644 --- a/vendor/abseil-cpp/absl/base/internal/spinlock_wait.cc +++ b/vendor/abseil-cpp/absl/base/internal/spinlock_wait.cc @@ -23,7 +23,7 @@ #if defined(_WIN32) && defined(_MSC_VER) #include "absl/base/internal/spinlock_win32.inc" -#elif defined(__linux__) +#elif defined(__linux__) && !defined(ANDROID) #include "absl/base/internal/spinlock_linux.inc" #elif defined(__akaros__) #include "absl/base/internal/spinlock_akaros.inc" @@ -63,11 +63,11 @@ int SpinLockSuggestedDelayNS(int loop) { // Weak pseudo-random number generator to get some spread between threads // when many are spinning. uint64_t r = delay_rand.load(std::memory_order_relaxed); - r = 0x5deece66dLL * r + 0xb; // numbers from nrand48() + r = 0x5deece66dLL * r + 0xb; // numbers from nrand48() delay_rand.store(r, std::memory_order_relaxed); - r <<= 16; // 48-bit random number now in top 48-bits. - if (loop < 0 || loop > 32) { // limit loop to 0..32 + r <<= 16; // 48-bit random number now in top 48-bits. + if (loop < 0 || loop > 32) { // limit loop to 0..32 loop = 32; } // loop>>3 cannot exceed 4 because loop cannot exceed 32. @@ -80,5 +80,5 @@ int SpinLockSuggestedDelayNS(int loop) { } } // namespace base_internal -} // inline namespace lts_2018_12_18 +} // namespace lts_2018_12_18 } // namespace absl