2019-02-11 14:43:48 +00:00
|
|
|
#include <llarp.h>
|
|
|
|
#include <config.hpp>
|
|
|
|
#include <util/fs.hpp>
|
2018-08-05 23:49:23 +00:00
|
|
|
|
|
|
|
#include <jni.h>
|
|
|
|
#include <signal.h>
|
2018-08-06 00:06:00 +00:00
|
|
|
#include <memory>
|
2018-08-05 23:49:23 +00:00
|
|
|
#include <thread>
|
|
|
|
|
2018-08-06 00:06:00 +00:00
|
|
|
struct AndroidMain
|
2018-08-05 23:49:23 +00:00
|
|
|
{
|
2018-08-06 00:06:00 +00:00
|
|
|
llarp_main* m_impl = nullptr;
|
|
|
|
std::thread* m_thread = nullptr;
|
2018-11-26 14:31:52 +00:00
|
|
|
std::string configFile;
|
2018-08-05 23:49:23 +00:00
|
|
|
|
2018-11-26 14:31:52 +00:00
|
|
|
/// set configuration and ensure files
|
2018-12-12 02:52:51 +00:00
|
|
|
bool
|
2019-02-11 14:43:48 +00:00
|
|
|
Configure(const char* conf, const char* basedir)
|
2018-11-26 14:31:52 +00:00
|
|
|
{
|
|
|
|
configFile = conf;
|
|
|
|
return llarp_ensure_config(conf, basedir, false, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// reload config on runtime
|
|
|
|
bool
|
|
|
|
ReloadConfig()
|
|
|
|
{
|
2018-11-26 22:46:22 +00:00
|
|
|
if(!m_impl)
|
2018-11-26 14:31:52 +00:00
|
|
|
return false;
|
|
|
|
llarp_main_signal(m_impl, SIGHUP);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// start daemon thread
|
2018-08-06 01:48:15 +00:00
|
|
|
bool
|
2018-11-26 14:31:52 +00:00
|
|
|
Start()
|
2018-08-05 23:49:23 +00:00
|
|
|
{
|
|
|
|
if(m_impl || m_thread)
|
2018-08-06 01:52:46 +00:00
|
|
|
return true;
|
2018-11-26 14:31:52 +00:00
|
|
|
m_impl = llarp_main_init(configFile.c_str(), true);
|
2018-08-06 01:48:15 +00:00
|
|
|
if(m_impl == nullptr)
|
|
|
|
return false;
|
2018-11-26 22:46:22 +00:00
|
|
|
if(llarp_main_setup(m_impl))
|
|
|
|
{
|
|
|
|
llarp_main_free(m_impl);
|
|
|
|
m_impl = nullptr;
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-05 23:49:23 +00:00
|
|
|
m_thread = new std::thread(std::bind(&AndroidMain::Run, this));
|
2018-08-06 01:48:15 +00:00
|
|
|
return true;
|
2018-08-05 23:49:23 +00:00
|
|
|
}
|
|
|
|
|
2018-11-26 14:31:52 +00:00
|
|
|
/// return true if we are running
|
2018-08-06 00:12:19 +00:00
|
|
|
bool
|
|
|
|
Running() const
|
|
|
|
{
|
2018-11-26 14:31:52 +00:00
|
|
|
return m_impl != nullptr && m_thread != nullptr;
|
2018-08-06 00:12:19 +00:00
|
|
|
}
|
|
|
|
|
2018-11-26 14:31:52 +00:00
|
|
|
/// blocking run
|
2018-08-06 00:06:00 +00:00
|
|
|
void
|
|
|
|
Run()
|
2018-08-05 23:49:23 +00:00
|
|
|
{
|
2018-11-26 22:46:22 +00:00
|
|
|
if(llarp_main_run(m_impl))
|
|
|
|
{
|
|
|
|
// on error
|
|
|
|
llarp::LogError("daemon run fail");
|
2019-02-11 14:43:48 +00:00
|
|
|
llarp_main* ptr = m_impl;
|
|
|
|
m_impl = nullptr;
|
2018-11-26 22:46:22 +00:00
|
|
|
llarp_main_signal(ptr, SIGINT);
|
|
|
|
llarp_main_free(ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-11 14:43:48 +00:00
|
|
|
const char*
|
|
|
|
GetIfAddr()
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
|
|
|
if(m_impl)
|
|
|
|
{
|
|
|
|
auto tun = main_router_getFirstTunEndpoint(m_impl);
|
|
|
|
if(tun)
|
|
|
|
return tun->tunif.ifaddr;
|
|
|
|
}
|
2019-02-11 14:43:48 +00:00
|
|
|
return "";
|
2018-11-26 22:46:22 +00:00
|
|
|
}
|
|
|
|
|
2019-02-11 14:43:48 +00:00
|
|
|
int
|
|
|
|
GetIfRange() const
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
|
|
|
if(m_impl)
|
|
|
|
{
|
|
|
|
auto tun = main_router_getFirstTunEndpoint(m_impl);
|
|
|
|
if(tun)
|
|
|
|
return tun->tunif.netmask;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-12-12 02:52:51 +00:00
|
|
|
void
|
2018-11-26 22:46:22 +00:00
|
|
|
SetVPN_FD(int fd)
|
|
|
|
{
|
|
|
|
if(m_impl)
|
|
|
|
llarp_main_inject_vpn_fd(m_impl, fd);
|
2018-08-05 23:49:23 +00:00
|
|
|
}
|
|
|
|
|
2018-11-26 14:31:52 +00:00
|
|
|
/// stop daemon thread
|
2018-08-06 00:06:00 +00:00
|
|
|
void
|
|
|
|
Stop()
|
2018-08-05 23:49:23 +00:00
|
|
|
{
|
2018-11-26 22:46:22 +00:00
|
|
|
if(m_impl)
|
|
|
|
llarp_main_signal(m_impl, SIGINT);
|
2018-08-06 00:12:19 +00:00
|
|
|
m_thread->join();
|
|
|
|
delete m_thread;
|
|
|
|
m_thread = nullptr;
|
2018-11-26 22:46:22 +00:00
|
|
|
if(m_impl)
|
|
|
|
llarp_main_free(m_impl);
|
2018-08-06 00:12:19 +00:00
|
|
|
m_impl = nullptr;
|
2018-08-05 23:49:23 +00:00
|
|
|
}
|
|
|
|
|
2018-08-06 00:06:00 +00:00
|
|
|
typedef std::unique_ptr< AndroidMain > Ptr;
|
2018-08-06 00:13:08 +00:00
|
|
|
};
|
2018-08-05 23:49:23 +00:00
|
|
|
|
2018-08-06 00:12:19 +00:00
|
|
|
static AndroidMain::Ptr daemon(new AndroidMain());
|
|
|
|
|
2018-08-05 23:49:23 +00:00
|
|
|
extern "C"
|
|
|
|
{
|
2018-08-06 00:06:00 +00:00
|
|
|
JNIEXPORT jstring JNICALL
|
2018-08-06 00:12:19 +00:00
|
|
|
Java_network_loki_lokinet_Lokinet_1JNI_getABICompiledWith(JNIEnv* env, jclass)
|
2018-08-06 00:06:00 +00:00
|
|
|
{
|
|
|
|
// TODO: fixme
|
2018-08-06 00:14:39 +00:00
|
|
|
return env->NewStringUTF("android");
|
2018-08-06 00:06:00 +00:00
|
|
|
}
|
2018-08-05 23:49:23 +00:00
|
|
|
|
2018-08-06 00:12:19 +00:00
|
|
|
JNIEXPORT jstring JNICALL
|
2018-11-26 22:46:22 +00:00
|
|
|
Java_network_loki_lokinet_Lokinet_1JNI_startLokinet(JNIEnv* env, jclass,
|
2018-08-06 01:48:15 +00:00
|
|
|
jstring configfile)
|
2018-08-05 23:49:23 +00:00
|
|
|
{
|
2018-08-06 00:12:19 +00:00
|
|
|
if(daemon->Running())
|
2018-08-06 00:14:39 +00:00
|
|
|
return env->NewStringUTF("already running");
|
2018-08-06 01:48:15 +00:00
|
|
|
std::string conf;
|
2018-11-06 14:06:09 +00:00
|
|
|
fs::path basepath;
|
2018-08-06 00:06:00 +00:00
|
|
|
{
|
2018-08-06 04:24:25 +00:00
|
|
|
const char* nativeString = env->GetStringUTFChars(configfile, JNI_FALSE);
|
2018-08-06 04:23:08 +00:00
|
|
|
conf += std::string(nativeString);
|
2018-08-06 04:24:25 +00:00
|
|
|
env->ReleaseStringUTFChars(configfile, nativeString);
|
2018-11-06 14:06:09 +00:00
|
|
|
basepath = fs::path(conf).parent_path();
|
2018-08-06 00:06:00 +00:00
|
|
|
}
|
2018-11-26 14:31:52 +00:00
|
|
|
if(daemon->Configure(conf.c_str(), basepath.string().c_str()))
|
|
|
|
{
|
|
|
|
if(daemon->Start())
|
|
|
|
return env->NewStringUTF("ok");
|
2018-12-12 02:52:51 +00:00
|
|
|
else
|
2018-11-26 14:31:52 +00:00
|
|
|
return env->NewStringUTF("failed to start daemon");
|
|
|
|
}
|
|
|
|
else
|
2018-11-26 22:46:22 +00:00
|
|
|
return env->NewStringUTF("failed to configure daemon");
|
2018-08-06 00:06:00 +00:00
|
|
|
}
|
|
|
|
|
2018-08-06 01:54:24 +00:00
|
|
|
JNIEXPORT void JNICALL
|
2018-11-26 22:46:22 +00:00
|
|
|
Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet(JNIEnv*, jclass)
|
2018-08-06 00:06:00 +00:00
|
|
|
{
|
2018-08-06 01:54:24 +00:00
|
|
|
if(daemon->Running())
|
|
|
|
{
|
|
|
|
daemon->Stop();
|
|
|
|
}
|
2018-08-06 00:06:00 +00:00
|
|
|
}
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2018-11-26 22:46:22 +00:00
|
|
|
JNIEXPORT void JNICALL
|
2019-02-11 14:43:48 +00:00
|
|
|
Java_network_loki_lokinet_Lokinet_1JNI_setVPNFileDescriptor(JNIEnv*, jclass,
|
|
|
|
jint fd)
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
|
|
|
daemon->SetVPN_FD(fd);
|
|
|
|
}
|
|
|
|
|
2019-02-11 14:43:48 +00:00
|
|
|
JNIEXPORT jstring JNICALL
|
|
|
|
Java_network_loki_lokinet_Lokinet_1JNI_getIfAddr(JNIEnv* env, jclass)
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
|
|
|
if(daemon)
|
|
|
|
return env->NewStringUTF(daemon->GetIfAddr());
|
|
|
|
else
|
|
|
|
return env->NewStringUTF("");
|
|
|
|
}
|
|
|
|
|
2019-02-11 14:43:48 +00:00
|
|
|
JNIEXPORT jint JNICALL
|
|
|
|
Java_network_loki_lokinet_Lokinet_1JNI_getIfRange(JNIEnv*, jclass)
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
2019-02-11 14:43:48 +00:00
|
|
|
if(daemon)
|
2018-11-26 22:46:22 +00:00
|
|
|
return daemon->GetIfRange();
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
2018-08-06 01:48:15 +00:00
|
|
|
|
2018-08-06 01:54:24 +00:00
|
|
|
JNIEXPORT void JNICALL
|
2019-02-11 14:43:48 +00:00
|
|
|
Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged(
|
|
|
|
JNIEnv*, jclass, jboolean isConnected)
|
2018-08-06 01:54:24 +00:00
|
|
|
{
|
2018-11-26 14:31:52 +00:00
|
|
|
if(isConnected)
|
|
|
|
{
|
|
|
|
if(!daemon->Running())
|
|
|
|
{
|
|
|
|
if(!daemon->Start())
|
|
|
|
{
|
|
|
|
// TODO: do some kind of callback here
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(daemon->Running())
|
|
|
|
{
|
|
|
|
daemon->Stop();
|
|
|
|
}
|
2018-08-06 01:54:24 +00:00
|
|
|
}
|
2018-12-12 02:52:51 +00:00
|
|
|
}
|