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