mirror of https://github.com/oxen-io/lokinet
wire up liblokient_udp_*
parent
1c70b0f42f
commit
ba57ab04aa
@ -0,0 +1,101 @@
|
||||
#include "egres_packet_router.hpp"
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
struct EgresUDPPacketHandler : public EgresLayer4Handler
|
||||
{
|
||||
EgresPacketHandlerFunc m_BaseHandler;
|
||||
std::unordered_map<nuint16_t, EgresPacketHandlerFunc> m_LocalPorts;
|
||||
|
||||
explicit EgresUDPPacketHandler(EgresPacketHandlerFunc baseHandler)
|
||||
: m_BaseHandler{std::move(baseHandler)}
|
||||
{}
|
||||
|
||||
void
|
||||
AddSubHandler(nuint16_t localport, EgresPacketHandlerFunc handler) override
|
||||
{
|
||||
m_LocalPorts.emplace(localport, std::move(handler));
|
||||
}
|
||||
|
||||
void
|
||||
RemoveSubHandler(nuint16_t localport) override
|
||||
{
|
||||
m_LocalPorts.erase(localport);
|
||||
}
|
||||
|
||||
void
|
||||
HandleIPPacketFrom(AddressVariant_t from, net::IPPacket pkt) override
|
||||
{
|
||||
const uint8_t* ptr = pkt.buf + (pkt.Header()->ihl * 4) + 2;
|
||||
const nuint16_t dstPort{*reinterpret_cast<const uint16_t*>(ptr)};
|
||||
if (auto itr = m_LocalPorts.find(dstPort); itr != m_LocalPorts.end())
|
||||
{
|
||||
itr->second(std::move(from), std::move(pkt));
|
||||
}
|
||||
else
|
||||
m_BaseHandler(std::move(from), std::move(pkt));
|
||||
}
|
||||
};
|
||||
|
||||
struct EgresGenericLayer4Handler : public EgresLayer4Handler
|
||||
{
|
||||
EgresPacketHandlerFunc m_BaseHandler;
|
||||
|
||||
explicit EgresGenericLayer4Handler(EgresPacketHandlerFunc baseHandler)
|
||||
: m_BaseHandler{std::move(baseHandler)}
|
||||
{}
|
||||
|
||||
void
|
||||
HandleIPPacketFrom(AddressVariant_t from, net::IPPacket pkt) override
|
||||
{
|
||||
m_BaseHandler(std::move(from), std::move(pkt));
|
||||
}
|
||||
};
|
||||
|
||||
EgresPacketRouter::EgresPacketRouter(EgresPacketHandlerFunc baseHandler)
|
||||
: m_BaseHandler{std::move(baseHandler)}
|
||||
{}
|
||||
|
||||
void
|
||||
EgresPacketRouter::HandleIPPacketFrom(AddressVariant_t from, net::IPPacket pkt)
|
||||
{
|
||||
const auto proto = pkt.Header()->protocol;
|
||||
if (const auto itr = m_IPProtoHandler.find(proto); itr != m_IPProtoHandler.end())
|
||||
{
|
||||
itr->second->HandleIPPacketFrom(std::move(from), std::move(pkt));
|
||||
}
|
||||
else
|
||||
m_BaseHandler(std::move(from), std::move(pkt));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr byte_t udp_proto = 0x11;
|
||||
}
|
||||
|
||||
void
|
||||
EgresPacketRouter::AddUDPHandler(huint16_t localport, EgresPacketHandlerFunc func)
|
||||
{
|
||||
if (m_IPProtoHandler.find(udp_proto) == m_IPProtoHandler.end())
|
||||
{
|
||||
m_IPProtoHandler.emplace(udp_proto, std::make_unique<EgresUDPPacketHandler>(m_BaseHandler));
|
||||
}
|
||||
m_IPProtoHandler[udp_proto]->AddSubHandler(ToNet(localport), func);
|
||||
}
|
||||
|
||||
void
|
||||
EgresPacketRouter::AddIProtoHandler(uint8_t proto, EgresPacketHandlerFunc func)
|
||||
{
|
||||
m_IPProtoHandler[proto] = std::make_unique<EgresGenericLayer4Handler>(std::move(func));
|
||||
}
|
||||
|
||||
void
|
||||
EgresPacketRouter::RemoveUDPHandler(huint16_t localport)
|
||||
{
|
||||
if (auto itr = m_IPProtoHandler.find(udp_proto); itr != m_IPProtoHandler.end())
|
||||
{
|
||||
itr->second->RemoveSubHandler(ToNet(localport));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace llarp::vpn
|
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include <llarp/net/net_int.hpp>
|
||||
#include <llarp/net/ip_packet.hpp>
|
||||
#include <llarp/endpoint_base.hpp>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
using AddressVariant_t = llarp::EndpointBase::AddressVariant_t;
|
||||
using EgresPacketHandlerFunc = std::function<void(AddressVariant_t, net::IPPacket)>;
|
||||
|
||||
struct EgresLayer4Handler
|
||||
{
|
||||
virtual ~EgresLayer4Handler() = default;
|
||||
|
||||
virtual void
|
||||
HandleIPPacketFrom(AddressVariant_t from, net::IPPacket pkt) = 0;
|
||||
|
||||
virtual void AddSubHandler(nuint16_t, EgresPacketHandlerFunc){};
|
||||
virtual void RemoveSubHandler(nuint16_t){};
|
||||
};
|
||||
|
||||
class EgresPacketRouter
|
||||
{
|
||||
EgresPacketHandlerFunc m_BaseHandler;
|
||||
std::unordered_map<uint8_t, std::unique_ptr<EgresLayer4Handler>> m_IPProtoHandler;
|
||||
|
||||
public:
|
||||
/// baseHandler will be called if no other handlers matches a packet
|
||||
explicit EgresPacketRouter(EgresPacketHandlerFunc baseHandler);
|
||||
|
||||
/// feed in an ip packet for handling
|
||||
void
|
||||
HandleIPPacketFrom(AddressVariant_t, net::IPPacket pkt);
|
||||
|
||||
/// add a non udp packet handler using ip protocol proto
|
||||
void
|
||||
AddIProtoHandler(uint8_t proto, EgresPacketHandlerFunc func);
|
||||
|
||||
/// helper that adds a udp packet handler for UDP destinted for localport
|
||||
void
|
||||
AddUDPHandler(huint16_t localport, EgresPacketHandlerFunc func);
|
||||
|
||||
/// remove a udp handler that is already set up by bound port
|
||||
void
|
||||
RemoveUDPHandler(huint16_t localport);
|
||||
};
|
||||
} // namespace llarp::vpn
|
Loading…
Reference in New Issue