lokinet/llarp/apple/vpn_interface.cpp
Jeff 388fc53380
match io loop event order on windows/apple to match linux.
on win32/apple reading packets from the interface does not count as an io operation.
manually trigger pump on win32/apple to pretend that it is an io event.
add platform quark function MaybeWakeUpperLayers on vpn::Interface to manaully wake up the other components on platforms that need that (ones on which packet io is not done via io events).
on non linux platforms, use uv_prepare_t instead of uv_check_t as the former triggers before blocking for io, instead of after. this better matches linux's order of operations in libuv.
2021-12-15 15:25:53 -05:00

65 lines
1.2 KiB
C++

#include "vpn_interface.hpp"
#include "context.hpp"
#include <llarp/router/abstractrouter.hpp>
namespace llarp::apple
{
VPNInterface::VPNInterface(
Context& ctx,
packet_write_callback packet_writer,
on_readable_callback on_readable,
AbstractRouter* router)
: m_PacketWriter{std::move(packet_writer)}
, m_OnReadable{std::move(on_readable)}
, _router{router}
{
ctx.loop->call_soon([this] { m_OnReadable(*this); });
}
bool
VPNInterface::OfferReadPacket(const llarp_buffer_t& buf)
{
llarp::net::IPPacket pkt;
if (!pkt.Load(buf))
return false;
m_ReadQueue.tryPushBack(std::move(pkt));
return true;
}
void
VPNInterface::MaybeWakeUpperLayers() const
{
_router->TriggerPump();
}
int
VPNInterface::PollFD() const
{
return -1;
}
std::string
VPNInterface::IfName() const
{
return "";
}
net::IPPacket
VPNInterface::ReadNextPacket()
{
net::IPPacket pkt{};
if (not m_ReadQueue.empty())
pkt = m_ReadQueue.popFront();
return pkt;
}
bool
VPNInterface::WritePacket(net::IPPacket pkt)
{
int af_family = pkt.IsV6() ? AF_INET6 : AF_INET;
return m_PacketWriter(af_family, pkt.buf, pkt.sz);
}
} // namespace llarp::apple