diff --git a/CMakeLists.txt b/CMakeLists.txt index ed9a69cfd..29b38ff15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,10 +311,7 @@ else() target_link_libraries(lokinet-rcutil PUBLIC ${EXE_LIBS} ${LIBS}) 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}) + add_subdirectory(jni) endif(ANDROID) endif(SHADOW) diff --git a/daemon/main.cpp b/daemon/main.cpp index 61aa78440..fd6e9ea74 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -149,9 +149,9 @@ main(int argc, char *argv[]) options.parse_positional("config"); // clang-format on - bool genconfigOnly = false; - bool asRouter = false; - bool overWrite = false; + bool genconfigOnly = false; + bool asRouter = false; + bool overWrite = false; std::string conffname; // suggestions: confFName? conf_fname? try { @@ -319,8 +319,7 @@ main(int argc, char *argv[]) return 0; } - std::thread main_thread{ - std::bind(&run_main_context, conffname, opts)}; + std::thread main_thread{std::bind(&run_main_context, conffname, opts)}; auto ftr = exit_code.get_future(); do { diff --git a/include/llarp.h b/include/llarp.h index cb4bca0c2..f1dd044c7 100644 --- a/include/llarp.h +++ b/include/llarp.h @@ -35,6 +35,10 @@ extern "C" struct llarp_config * llarp_default_config(); + /// free previously allocated configuration + void + llarp_config_free(struct llarp_config *); + /// packet writer to send packets to lokinet internals struct llarp_vpn_writer_pipe; /// packet reader to recv packets from lokinet internals @@ -68,8 +72,8 @@ extern "C" char ifname[64]; /// interface's address as string char ifaddr[128]; - /// netmask bits - unsigned char netmask; + /// netmask number of bits set + uint8_t netmask; }; /// initialize llarp_vpn_io private implementation @@ -132,10 +136,19 @@ extern "C" } /// load config from file by name + /// allocates new config and puts it into c + /// return false on failure + bool + llarp_config_load_file(const char *fname, struct llarp_config **c); + + /// loads config from file by name + /// uses already allocated config + /// return false on failure bool - llarp_config_load_file(const char *fname, struct llarp_config **config); + llarp_config_read_file(struct llarp_config *c, const char *f); /// make a main context from configuration + /// copies config contents struct llarp_main * llarp_main_init_from_config(struct llarp_config *conf); @@ -143,25 +156,41 @@ extern "C" static struct llarp_main * llarp_main_init(const char *fname) { + struct llarp_main *m = 0; struct llarp_config *conf = 0; if(!llarp_config_load_file(fname, &conf)) return 0; if(conf == NULL) return 0; - return llarp_main_init_from_config(conf); + m = llarp_main_init_from_config(conf); + llarp_config_free(conf); + return m; } /// initialize applicatin context with all defaults static struct llarp_main * llarp_main_default_init() { + struct llarp_main *m; struct llarp_config *conf; conf = llarp_default_config(); if(conf == 0) return 0; - return llarp_main_init_from_config(conf); + m = llarp_main_init_from_config(conf); + llarp_config_free(conf); + return m; } + /// (re)configure main context + /// return true if (re)configuration was successful + bool + llarp_main_configure(struct llarp_main *ptr, struct llarp_config *conf); + + /// return true if this main context is running + /// return false otherwise + bool + llarp_main_is_running(struct llarp_main *ptr); + /// handle signal for main context void llarp_main_signal(struct llarp_main *ptr, int sig); @@ -174,6 +203,11 @@ extern "C" int llarp_main_run(struct llarp_main *ptr, struct llarp_main_runtime_opts opts); + /// tell main context to stop and wait for complete stop + /// after calling this you can call llarp_main_free safely + void + llarp_main_stop(struct llarp_main *ptr); + /// free main context and end all operations void llarp_main_free(struct llarp_main *ptr); @@ -182,6 +216,14 @@ extern "C" const char * llarp_version(); + /// return sizeof(llarp_main); for jni + size_t + llarp_main_size(); + + /// return sizeof(llarp_config); for jni + size_t + llarp_config_size(); + #ifdef __cplusplus } #endif diff --git a/jni/CMakeLists.txt b/jni/CMakeLists.txt new file mode 100644 index 000000000..d6cf96b53 --- /dev/null +++ b/jni/CMakeLists.txt @@ -0,0 +1,10 @@ + + set(ANDROID_SRC + jni/lokinet_config.cpp + jni/lokinet_daemon.cpp + jni/lokinet_vnp.cpp + ) + add_library(${ANDROID_LIB} SHARED ${ANDROID_SRC}) + set_property(TARGET ${ANDROID_LIB} PROPERTY CXX_STANDARD 14) + add_log_tag(${ANDROID_LIB}) + target_link_libraries(${ANDROID_LIB} ${STATIC_LIB} ${LIBS}) \ No newline at end of file diff --git a/jni/lokinet_config.cpp b/jni/lokinet_config.cpp new file mode 100644 index 000000000..8cf59e10b --- /dev/null +++ b/jni/lokinet_config.cpp @@ -0,0 +1,38 @@ +#include "network_loki_lokinet_LokinetConfig.h" +#include +#include "lokinet_jni_common.hpp" + +extern "C +{ + JNIEXPORT jobject JNICALL + Java_network_loki_lokinet_LokinetConfig_Obtain(JNIEnv* env, jclass* c) + { + llarp_config* conf = llarp_default_config(); + if(conf == nullptr) + return nullptr; + return env->NewDirectByteBuffer(conf, llarp_config_size()); + } + + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetConfig_Free(JNIEnv* env, jclass c, + jobject buf) + { + llarp_config_free(FromBuffer< llarp_config >(env, buf)); + } + + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetConfig_Load(JNIEnv* env, jobject self, + jstring fname) + { + llarp_config* conf = FromObjectMember< llarp_config >(env, self, "impl"); + if(conf == nullptr) + return JNI_FALSE; + return VisitStringAsStringView< jboolean >( + env, fname, [conf](llarp::string_view val) -> jboolean { + const auto filename = llarp::string_view_string(val); + if(llarp_config_read_file(conf, filename.c_str())) + return JNI_TRUE; + return JNI_FALSE; + }); + } +} \ No newline at end of file diff --git a/jni/lokinet_daemon.cpp b/jni/lokinet_daemon.cpp new file mode 100644 index 000000000..8a542bbcc --- /dev/null +++ b/jni/lokinet_daemon.cpp @@ -0,0 +1,82 @@ +#include "network_loki_lokinet_LokinetDaemon.h" +#include "lokinet_jni_common.hpp" +#include "lokinet_jni_vpnio.hpp" +#include + +extern "C" +{ + JNIEXPORT jobject JNICALL + Java_network_loki_lokinet_LokinetDaemon_Obtain(JNIEnv *env, jclass) + { + llarp_main *ptr = llarp_main_default_init(); + if(ptr == nullptr) + return nullptr; + return env->NewDirectByteBuffer(ptr, llarp_main_size()); + } + + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetDaemon_Free(JNIEnv *env, jclass, jobject buf) + { + llarp_main *ptr = FromBuffer< llarp_main >(env, buf); + llarp_main_free(ptr); + } + + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_Configure(JNIEnv *env, jobject self, + jobject conf) + { + llarp_main *ptr = FromObjectMember< llarp_main >(env, self, "impl"); + llarp_config *config = FromObjectMember< llarp_config >(env, conf, "impl"); + if(ptr == nullptr || config == nullptr) + return JNI_FALSE; + if(llarp_main_configure(ptr, config)) + return JNI_TRUE; + return JNI_FALSE; + } + + JNIEXPORT jint JNICALL + Java_network_loki_lokinet_LokinetDaemon_Mainloop(JNIEnv *env, jobject self) + { + static llarp_main_runtime_opts opts; + llarp_main *ptr = FromObjectMember< llarp_main >(env, self, "impl"); + if(ptr == nullptr) + return -1; + return llarp_main_run(ptr, opts); + } + + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_IsRunning(JNIEnv *env, jobject self) + { + llarp_main *ptr = FromObjectMember< llarp_main >(env, self, "impl"); + return (ptr != nullptr && llarp_main_is_running(ptr)) ? JNI_TRUE + : JNI_FALSE; + } + + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_Stop(JNIEnv *env, jobject self) + { + llarp_main *ptr = FromObjectMember< llarp_main >(env, self, "impl"); + if(ptr == nullptr) + return JNI_FALSE; + if(not llarp_main_is_running(ptr)) + return JNI_FALSE; + llarp_main_stop(ptr); + return llarp_main_is_running(ptr) ? JNI_FALSE : JNI_TRUE; + } + + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_InjectVPN(JNIEnv *env, jobject self, + jobject vpn) + { + llarp_main *ptr = FromObjectMember< llarp_main >(env, self, "impl"); + lokinet_jni_vpnio *impl = + FromObjectMember< lokinet_jni_vpnio >(env, vpn, "impl"); + if(ptr == nullptr || impl == nullptr) + return JNI_FALSE; + if(not impl->Init(ptr)) + return JNI_FASE; + return llarp_main_inject_default_vpn(ptr, &impl->io, impl->info) + ? JNI_TRUE + : JNI_FALSE; + } +} \ No newline at end of file diff --git a/jni/lokinet_jni_common.hpp b/jni/lokinet_jni_common.hpp new file mode 100644 index 000000000..79e8e0b13 --- /dev/null +++ b/jni/lokinet_jni_common.hpp @@ -0,0 +1,77 @@ +#ifndef LOKINET_JNI_COMMON_HPP +#define LOKINET_JNI_COMMON_HPP + +#include +#include +#include + +/// visit string as native bytes +template < typename T, typename V > +static T +VisitStringAsStringView(JNIEnv* env, jobject str, V visit) +{ + const jclass stringClass = env->GetObjectClass(str); + const jmethodID getBytes = + env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B"); + + const jstring charsetName = env->NewStringUTF("UTF-8"); + const jbyteArray stringJbytes = + (jbyteArray)env->CallObjectMethod(str, getBytes, charsetName); + env->DeleteLocalRef(charsetName); + + const jsize length = env->GetArrayLength(stringJbytes); + const jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL); + + T result = visit(llarp::string_view(bBytes, length)); + + env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT); + env->DeleteLocalRef(stringJbytes); + + return std::move(result); +} + +/// cast jni buffer to T * +template < typename T > +static T* +FromBuffer(JNIEnv* env, jobject o) +{ + if(o == nullptr) + return nullptr; + return static_cast< T* >(env->GetDirectBufferAddress(o)); +} + +/// get T * from object member called membername +template < typename T > +static T* +FromObjectMember(JNIEnv* env, jobject self, const char* membername) +{ + jclass cl = env->GetObjectClass(self); + jfieldID name = env->GetFieldID(cl, membername, "Ljava/nio/Buffer;"); + jobject buffer = env->GetObjectField(self, name); + return FromBuffer< T >(env, buffer); +} + +/// visit object string member called membername as bytes +template < typename T, typename V > +static T +VisitObjectMemberStringAsStringView(JNIEnv* env, jobject self, + const char* membername, V v) +{ + jclass cl = env->GetObjectClass(self); + jfieldID name = env->GetFieldID(cl, membername, "Ljava/lang/String;"); + jobject str = env->GetObjectField(self, name); + return VisitStringAsStringView(env, str, v); +} + +/// get object member int called membername +template < typename Int_t > +void +GetObjectMemberAsInt(JNIEnv* env, jobject self, const char* membername, + Int_t& result) +{ + jclass cl = env->GetObjectClass(self); + jfieldID name = env->GetFieldID(cl, membername, "I"); + result = env->GetIntField(self, name); +} + +#endif \ No newline at end of file diff --git a/jni/lokinet_jni_vpnio.hpp b/jni/lokinet_jni_vpnio.hpp new file mode 100644 index 000000000..f0b981cc5 --- /dev/null +++ b/jni/lokinet_jni_vpnio.hpp @@ -0,0 +1,141 @@ +#ifndef LOKINET_JNI_VPNIO_HPP +#define LOKINET_JNI_VPNIO_HPP + +#include +#include +#include +#include +#include + +namespace lokinet +{ + struct VPNIO + { + static VPNIO * + Get(llarp_vpn_io *vpn) + { + return static_cast< VPNIO * >(vpn->user); + } + + virtual ~VPNIO() = default; + + llarp_vpn_io io; + llarp_vpn_ifaddr_info info{{0}, {0}, 0}; + std::unique_ptr< std::promise< void > > closeWaiter; + + void + Closed() + { + if(closeWaiter) + closeWaiter->get_future().set_value(); + } + + virtual void + InjectSuccess() = 0; + + virtual void + InjectFail() = 0; + + virtual void + Tick() = 0; + + VPNIO() + { + io.impl = nullptr; + io.user = this; + io.closed = [](llarp_vpn_io *vpn) { VPNIO::Get(vpn)->Closed(); }; + io.injected = [](llarp_vpn_io *vpn, bool good) { + VPNIO *ptr = VPNIO::Get(vpn); + if(good) + ptr->InjectSuccess(); + else + ptr->InjectFail(); + }; + io.tick = [](llarp_vpn_io *vpn) { VPNIO::Get(vpn)->Tick(); }; + } + + bool + Init(llarp_main *ptr) + { + return llarp_vpn_io_init(ptr, &io); + } + + void + Close() + { + if(io.impl == nullptr) + return; + if(closeWaiter) + return; + closerWaiter = std::make_unique< std::promise< void > >(); + llarp_vpn_io_close_async(&io); + closeWaiter->wait(); + closeWaiter.reset(); + io.impl = nullptr; + } + + llarp_vpn_pkt_reader * + Reader() + { + return llarp_vpn_io_packet_reader(&io); + } + + llarp_vpn_pkt_writer * + Writer() + { + return llarp_vpn_io_packet_writer(&io); + } + + ssize_t + ReadPacket(void *dst, size_t len) + { + if(io.impl == nullptr) + return -1; + unsigned char *buf = (unsigned char *)dst; + return llarp_vpn_io_readpkt(Reader(), buf, len); + } + + bool + WritePacket(void *pkt, size_t len) + { + if(io.impl == nullptr) + return false; + unsigned char *buf = (unsigned char *)pkt; + return llarp_vpn_io_writepkt(Writer(), buf, len); + } + + void + SetIfName(llarp::string_view val) + { + const auto sz = std::min(val.size(), sizeof(info.ifname)); + std::copy_n(val.data(), sz, info.ifname); + } + + void + SetIfAddr(llarp::string_view val) + { + const auto sz = std::min(val.size(), sizeof(info.ifaddr)); + std::copy_n(val.data(), sz, info.ifaddr); + } + }; +} // namespace lokinet + +struct lokinet_jni_vpnio : public lokinet::VPNIO +{ + void + InjectSuccess() override + { + } + + void + InjectFail() override + { + } + + void + Tick() override + { + } +}; + +#endif \ No newline at end of file diff --git a/jni/lokinet_vpn.cpp b/jni/lokinet_vpn.cpp new file mode 100644 index 000000000..8c8d39c1e --- /dev/null +++ b/jni/lokinet_vpn.cpp @@ -0,0 +1,90 @@ +#include "network_loki_lokinet_LokinetVPN.h" +#include "lokinet_jni_vpnio.hpp" +#include "lokinet_jni_common.hpp" +#include + +extern "C" +{ + JNIEXPORT jint JNICALL + Java_network_loki_lokinet_LokinetVPN_PacketSize(JNIEnv *, jclass) + { + return llarp::net::IPPacket::MaxSize; + } + + JNIEXPORT jobject JNICALL + Java_network_loki_lokinet_LokinetVPN_Alloc(JNIEnv *env, jclass) + { + lokinet_jni_vpnio *vpn = new lokinet_jni_vpnio(); + return env->NewDirectByteBuffer(vpn, sizeof(lokinet_jni_vpnio)); + } + + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetVPN_Free(JNIEnv *env, jclass, jobject buf) + { + lokinet_jni_vpnio *vpn = FromBuffer< lokinet_jni_vpnio >(env, buf); + if(vpn == nullptr) + return; + delete vpn; + } + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetVPN_Stop(JNIEnv *env, jobject self) + { + lokinet_jni_vpnio *vpn = + FromObjectMember< lokinet_jni_vpnio >(env, self, "impl"); + if(vpn) + { + vpn->Close(); + } + } + + JNIEXPORT jint JNICALL + Java_network_loki_lokinet_LokinetVPN_ReadPkt(JNIEnv *env, jobject self, + jobject pkt) + { + lokinet_jni_vpnio *vpn = + FromObjectMember< lokinet_jni_vpnio >(env, self, "impl"); + if(vpn == nullptr) + return -1; + void *pktbuf = env->GetDirectBufferAddress(pkt); + auto pktlen = env->GetDirectBufferCapacity(pkt); + if(pktbuf == nullptr) + return -1; + return vpn->ReadPacket(pktbuf, pktlen); + } + + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetVPN_WritePkt(JNIEnv *env, jobject self, + jobject pkt) + { + lokinet_jni_vpnio *vpn = + FromObjectMember< lokinet_jni_vpnio >(env, self, "impl"); + if(vpn == nullptr) + return false; + void *pktbuf = env->GetDirectBufferAddress(pkt); + auto pktlen = env->GetDirectBufferCapacity(pkt); + if(pktbuf == nullptr) + return false; + return vpn->WritePacket(pktbuf, pktlen); + } + + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetVPN_SetInfo(JNIEnv *env, jobject self, + jobject info) + { + lokinet_jni_vpnio *vpn = + FromObjectMember< lokinet_jni_vpnio >(env, self, "impl"); + if(vpn == nullptr) + return; + VisitObjectMemberStringAsStringView< bool >( + env, info, "ifaddr", [vpn](llarp::string_view val) -> bool { + vpn->SetIfAddr(val); + return true; + }); + VisitObjectMemberStringAsStringView< bool >( + env, info, "ifname", [vpn](llarp::string_view val) -> bool { + vpn->SetIfName(val); + return true; + }); + GetObjectMemberAsInt(env, info, "netmask", vpn->info.netmask); + } +} \ No newline at end of file diff --git a/jni/network_loki_lokinet_LokinetConfig.h b/jni/network_loki_lokinet_LokinetConfig.h new file mode 100644 index 000000000..f39b87542 --- /dev/null +++ b/jni/network_loki_lokinet_LokinetConfig.h @@ -0,0 +1,38 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class network_loki_lokinet_LokinetConfig */ + +#ifndef _Included_network_loki_lokinet_LokinetConfig +#define _Included_network_loki_lokinet_LokinetConfig +#ifdef __cplusplus +extern "C" +{ +#endif + /* + * Class: network_loki_lokinet_LokinetConfig + * Method: Obtain + * Signature: ()Ljava/nio/Buffer; + */ + JNIEXPORT jobject JNICALL + Java_network_loki_lokinet_LokinetConfig_Obtain(JNIEnv *, jclass); + + /* + * Class: network_loki_lokinet_LokinetConfig + * Method: Free + * Signature: (Ljava/nio/Buffer;)V + */ + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetConfig_Free(JNIEnv *, jclass, jobject); + + /* + * Class: network_loki_lokinet_LokinetConfig + * Method: Load + * Signature: (Ljava/lang/String;)Z + */ + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetConfig_Load(JNIEnv *, jobject, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/jni/network_loki_lokinet_LokinetDaemon.h b/jni/network_loki_lokinet_LokinetDaemon.h new file mode 100644 index 000000000..400807bb6 --- /dev/null +++ b/jni/network_loki_lokinet_LokinetDaemon.h @@ -0,0 +1,70 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class network_loki_lokinet_LokinetDaemon */ + +#ifndef _Included_network_loki_lokinet_LokinetDaemon +#define _Included_network_loki_lokinet_LokinetDaemon +#ifdef __cplusplus +extern "C" +{ +#endif + /* + * Class: network_loki_lokinet_LokinetDaemon + * Method: Obtain + * Signature: ()Ljava/nio/Buffer; + */ + JNIEXPORT jobject JNICALL + Java_network_loki_lokinet_LokinetDaemon_Obtain(JNIEnv *, jclass); + + /* + * Class: network_loki_lokinet_LokinetDaemon + * Method: Free + * Signature: (Ljava/nio/Buffer;)V + */ + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetDaemon_Free(JNIEnv *, jclass, jobject); + + /* + * Class: network_loki_lokinet_LokinetDaemon + * Method: Configure + * Signature: (Lnetwork/loki/lokinet/LokinetConfig;)Z + */ + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_Configure(JNIEnv *, jobject, jobject); + + /* + * Class: network_loki_lokinet_LokinetDaemon + * Method: Mainloop + * Signature: ()I + */ + JNIEXPORT jint JNICALL + Java_network_loki_lokinet_LokinetDaemon_Mainloop(JNIEnv *, jobject); + + /* + * Class: network_loki_lokinet_LokinetDaemon + * Method: IsRunning + * Signature: ()Z + */ + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_IsRunning(JNIEnv *, jobject); + + /* + * Class: network_loki_lokinet_LokinetDaemon + * Method: Stop + * Signature: ()Z + */ + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_Stop(JNIEnv *, jobject); + + /* + * Class: network_loki_lokinet_LokinetDaemon + * Method: InjectVPN + * Signature: (Lnetwork/loki/lokinet/LokinetVPN;)Z + */ + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetDaemon_InjectVPN(JNIEnv *, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/jni/network_loki_lokinet_LokinetVPN.h b/jni/network_loki_lokinet_LokinetVPN.h new file mode 100644 index 000000000..0aca1654f --- /dev/null +++ b/jni/network_loki_lokinet_LokinetVPN.h @@ -0,0 +1,69 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class network_loki_lokinet_LokinetVPN */ + +#ifndef _Included_network_loki_lokinet_LokinetVPN +#define _Included_network_loki_lokinet_LokinetVPN +#ifdef __cplusplus +extern "C" +{ +#endif + /* + * Class: network_loki_lokinet_LokinetVPN + * Method: PacketSize + * Signature: ()I + */ + JNIEXPORT jint JNICALL + Java_network_loki_lokinet_LokinetVPN_PacketSize(JNIEnv *, jclass); + + /* + * Class: network_loki_lokinet_LokinetVPN + * Method: Alloc + * Signature: ()Ljava/nio/Buffer; + */ + JNIEXPORT jobject JNICALL + Java_network_loki_lokinet_LokinetVPN_Alloc(JNIEnv *, jclass); + + /* + * Class: network_loki_lokinet_LokinetVPN + * Method: Free + * Signature: (Ljava/nio/Buffer;)V + */ + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetVPN_Free(JNIEnv *, jclass, jobject); + + /* + * Class: network_loki_lokinet_LokinetVPN + * Method: Stop + * Signature: ()V + */ + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetVPN_Stop(JNIEnv *, jobject); + + /* + * Class: network_loki_lokinet_LokinetVPN + * Method: ReadPkt + * Signature: (Ljava/nio/ByteBuffer;)I + */ + JNIEXPORT jint JNICALL + Java_network_loki_lokinet_LokinetVPN_ReadPkt(JNIEnv *, jobject, jobject); + + /* + * Class: network_loki_lokinet_LokinetVPN + * Method: WritePkt + * Signature: (Ljava/nio/ByteBuffer;)Z + */ + JNIEXPORT jboolean JNICALL + Java_network_loki_lokinet_LokinetVPN_WritePkt(JNIEnv *, jobject, jobject); + + /* + * Class: network_loki_lokinet_LokinetVPN + * Method: SetInfo + * Signature: (Lnetwork/loki/lokinet/LokinetVPN/VPNInfo;)V + */ + JNIEXPORT void JNICALL + Java_network_loki_lokinet_LokinetVPN_SetInfo(JNIEnv *, jobject, jobject); +#ifdef __cplusplus +} +#endif +#endif diff --git a/jni/network_loki_lokinet_LokinetVPN_VPNInfo.h b/jni/network_loki_lokinet_LokinetVPN_VPNInfo.h new file mode 100644 index 000000000..c7937a30f --- /dev/null +++ b/jni/network_loki_lokinet_LokinetVPN_VPNInfo.h @@ -0,0 +1,14 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class network_loki_lokinet_LokinetVPN_VPNInfo */ + +#ifndef _Included_network_loki_lokinet_LokinetVPN_VPNInfo +#define _Included_network_loki_lokinet_LokinetVPN_VPNInfo +#ifdef __cplusplus +extern "C" +{ +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/llarp/context.cpp b/llarp/context.cpp index 5c47bfe98..2c7197669 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -371,43 +370,62 @@ __ ___ ____ _ _ ___ _ _ ____ } } // namespace llarp -extern "C" +struct llarp_main +{ + llarp_main(llarp_config *conf); + ~llarp_main() = default; + std::unique_ptr< llarp::Context > ctx; +}; + +struct llarp_config { - struct llarp_main + llarp::Config impl; + llarp_config() = default; + + llarp_config(const llarp_config *other) : impl(other->impl) { - llarp_main(llarp_config *conf); - ~llarp_main() = default; - std::unique_ptr< llarp::Context > ctx; - }; + } +}; - struct llarp_config +extern "C" +{ + size_t + llarp_main_size() { - llarp::Config impl; - llarp_config() = default; + return sizeof(llarp_main); + } - llarp_config(const llarp_config *other) : impl(other->impl) - { - } - }; + size_t + llarp_config_size() + { + return sizeof(llarp_config); + } struct llarp_config * llarp_default_config() { - static llarp_config conf; + llarp_config *conf = new llarp_config(); #ifdef ANDROID // put andrid config overrides here #endif #ifdef IOS // put IOS config overrides here #endif - return &conf; + return conf; + } + + void + llarp_config_free(struct llarp_config *conf) + { + if(conf) + delete conf; } struct llarp_main * llarp_main_init_from_config(struct llarp_config *conf) { if(conf == nullptr) - conf = new llarp_config(llarp_default_config()); + return nullptr; llarp_main *m = new llarp_main(conf); if(m->ctx->Configure()) return m; diff --git a/llarp/service/context.cpp b/llarp/service/context.cpp index a02071e03..cea4d0b50 100644 --- a/llarp/service/context.cpp +++ b/llarp/service/context.cpp @@ -173,7 +173,7 @@ namespace llarp } Endpoint_ptr - Context::GetEndpointByName(const std::string & name) + Context::GetEndpointByName(const std::string &name) { auto itr = m_Endpoints.find(name); if(itr != m_Endpoints.end())