lokinet/jni/lokinet_jni_vpnio.hpp

150 lines
2.7 KiB
C++
Raw Normal View History

2019-10-08 14:52:01 +00:00
#ifndef LOKINET_JNI_VPNIO_HPP
#define LOKINET_JNI_VPNIO_HPP
#include <llarp.h>
#include <memory>
#include <future>
#include <string_view>
2019-10-08 14:52:01 +00:00
#include <algorithm>
2019-10-09 12:40:40 +00:00
#include <jni.h>
2019-10-08 14:52:01 +00:00
namespace lokinet
{
struct VPNIO
{
static VPNIO*
Get(llarp_vpn_io* vpn)
2019-10-08 14:52:01 +00:00
{
return static_cast<VPNIO*>(vpn->user);
2019-10-08 14:52:01 +00:00
}
virtual ~VPNIO() = default;
llarp_vpn_io io;
llarp_vpn_ifaddr_info info{{0}, {0}, 0};
std::unique_ptr<std::promise<void>> closeWaiter;
2019-10-08 14:52:01 +00:00
void
Closed()
{
if (closeWaiter)
2019-10-09 12:40:40 +00:00
closeWaiter->set_value();
2019-10-08 14:52:01 +00:00
}
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)
2019-10-08 14:52:01 +00:00
ptr->InjectSuccess();
else
ptr->InjectFail();
};
io.tick = [](llarp_vpn_io* vpn) { VPNIO::Get(vpn)->Tick(); };
2019-10-08 14:52:01 +00:00
}
bool
Init(llarp::Context* ptr)
2019-10-08 14:52:01 +00:00
{
if (Ready())
2019-10-09 12:40:40 +00:00
return false;
2019-10-08 14:52:01 +00:00
return llarp_vpn_io_init(ptr, &io);
}
2019-10-09 12:40:40 +00:00
bool
Ready() const
{
return io.impl != nullptr;
}
2019-10-08 14:52:01 +00:00
void
Close()
{
if (not Ready())
2019-10-08 14:52:01 +00:00
return;
if (closeWaiter)
2019-10-08 14:52:01 +00:00
return;
closeWaiter = std::make_unique<std::promise<void>>();
2019-10-08 14:52:01 +00:00
llarp_vpn_io_close_async(&io);
2019-10-09 12:40:40 +00:00
closeWaiter->get_future().wait();
2019-10-08 14:52:01 +00:00
closeWaiter.reset();
io.impl = nullptr;
}
llarp_vpn_pkt_reader*
2019-10-08 14:52:01 +00:00
Reader()
{
return llarp_vpn_io_packet_reader(&io);
}
llarp_vpn_pkt_writer*
2019-10-08 14:52:01 +00:00
Writer()
{
return llarp_vpn_io_packet_writer(&io);
}
ssize_t
ReadPacket(void* dst, size_t len)
2019-10-08 14:52:01 +00:00
{
if (not Ready())
2019-10-08 14:52:01 +00:00
return -1;
unsigned char* buf = (unsigned char*)dst;
2019-10-08 14:52:01 +00:00
return llarp_vpn_io_readpkt(Reader(), buf, len);
}
bool
WritePacket(void* pkt, size_t len)
2019-10-08 14:52:01 +00:00
{
if (not Ready())
2019-10-08 14:52:01 +00:00
return false;
unsigned char* buf = (unsigned char*)pkt;
2019-10-08 14:52:01 +00:00
return llarp_vpn_io_writepkt(Writer(), buf, len);
}
void
SetIfName(std::string_view val)
2019-10-08 14:52:01 +00:00
{
const auto sz = std::min(val.size(), sizeof(info.ifname));
std::copy_n(val.data(), sz, info.ifname);
}
void
SetIfAddr(std::string_view val)
2019-10-08 14:52:01 +00:00
{
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