llarp/handlers/tun.hpp
Namespaces
| Name |
|---|
| llarp [crypto.hpp] |
| llarp::handlers |
Classes
| Name | |
|---|---|
| struct | llarp::handlers::TunEndpoint |
Source code
#pragma once
#include <llarp/dns/server.hpp>
#include <llarp/ev/ev.hpp>
#include <llarp/net/ip.hpp>
#include <llarp/net/ip_packet.hpp>
#include <llarp/net/net.hpp>
#include <llarp/service/endpoint.hpp>
#include <llarp/service/protocol_type.hpp>
#include <llarp/util/priority_queue.hpp>
#include <llarp/util/thread/threading.hpp>
#include <llarp/vpn/packet_router.hpp>
#include <llarp/vpn/platform.hpp>
#include <future>
#include <type_traits>
#include <variant>
namespace llarp
{
namespace handlers
{
struct TunEndpoint : public service::Endpoint,
public dns::Resolver_Base,
public std::enable_shared_from_this<TunEndpoint>
{
TunEndpoint(AbstractRouter* r, llarp::service::Context* parent);
~TunEndpoint() override;
vpn::NetworkInterface*
GetVPNInterface() override
{
return m_NetIf.get();
}
int
Rank() const override
{
return 0;
}
std::string_view
ResolverName() const override
{
return "lokinet";
}
bool
MaybeHookDNS(
std::shared_ptr<dns::PacketSource_Base> source,
const dns::Message& query,
const SockAddr& to,
const SockAddr& from) override;
path::PathSet_ptr
GetSelf() override
{
return shared_from_this();
}
std::weak_ptr<path::PathSet>
GetWeak() override
{
return weak_from_this();
}
void
Thaw() override;
// Reconfigures DNS servers and restarts libunbound with the new servers.
void
ReconfigureDNS(std::vector<SockAddr> servers);
bool
Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) override;
void
SendPacketToRemote(const llarp_buffer_t&, service::ProtocolType) override{};
std::string
GetIfName() const override;
void
Tick(llarp_time_t now) override;
std::unordered_map<std::string, std::string>
NotifyParams() const override;
bool
SupportsV6() const override;
bool
ShouldHookDNSMessage(const dns::Message& msg) const;
bool
HandleHookedDNSMessage(dns::Message query, std::function<void(dns::Message)> sendreply);
void
TickTun(llarp_time_t now);
bool
MapAddress(const service::Address& remote, net::ipv6addr_t ip, bool SNode);
bool
Start() override;
bool
Stop() override;
bool
IsSNode() const;
bool
SetupTun();
void
SetupDNS();
std::shared_ptr<dns::Server>
DNS() const override
{
return m_DNS;
};
bool
SetupNetworking() override;
bool
HandleInboundPacket(
const service::ConvoTag tag,
const llarp_buffer_t& pkt,
service::ProtocolType t,
uint64_t seqno) override;
bool
HandleWriteIPPacket(
const llarp_buffer_t& buf, net::ipv6addr_t src, net::ipv6addr_t dst, uint64_t seqno);
void
HandleGotUserPacket(llarp::net::IPPacket pkt);
net::ipv6addr_t
GetIfAddr() const override;
bool
HasIfAddr() const override
{
return true;
}
bool
HasLocalIP(const net::ipv6addr_t& ip) const;
std::optional<net::TrafficPolicy>
GetExitPolicy() const override
{
return m_TrafficPolicy;
}
std::set<IPRange>
GetOwnedRanges() const override
{
return m_OwnedRanges;
}
llarp_time_t
PathAlignmentTimeout() const override
{
return m_PathAlignmentTimeout;
}
bool
ShouldAllowTraffic(const net::IPPacket& pkt) const;
std::optional<std::variant<service::Address, RouterID>>
ObtainAddrForIP(net::ipv6addr_t ip) const override;
bool
HasAddress(const AlignedBuffer<32>& addr) const
{
return m_AddrToIP.find(addr) != m_AddrToIP.end();
}
net::ipv6addr_t
ObtainIPForAddr(std::variant<service::Address, RouterID> addr) override;
void
ResetInternalState() override;
protected:
struct WritePacket
{
uint64_t seqno;
net::IPPacket pkt;
bool
operator<(const WritePacket& other) const
{
return seqno < other.seqno;
}
};
std::priority_queue<WritePacket> m_NetworkToUserPktQueue;
void
Pump(llarp_time_t now) override;
bool
HasRemoteForIP(net::ipv6addr_t ipv4) const;
void
MarkIPActive(net::ipv6addr_t ip);
void
MarkIPActiveForever(net::ipv6addr_t ip);
void
FlushWrite();
std::unordered_map<net::ipv6addr_t, AlignedBuffer<32>> m_IPToAddr;
std::unordered_map<AlignedBuffer<32>, net::ipv6addr_t> m_AddrToIP;
std::unordered_map<AlignedBuffer<32>, bool> m_SNodes;
std::unordered_map<net::ipv6addr_t, service::Address> m_ExitIPToExitAddress;
private:
std::optional<service::Address>
ObtainExitAddressFor(
net::ipv6addr_t ip,
std::function<service::Address(std::unordered_set<service::Address>)> exitSelectionStrat =
nullptr);
template <typename Addr_t, typename Endpoint_t>
void
SendDNSReply(
Addr_t addr,
Endpoint_t ctx,
std::shared_ptr<dns::Message> query,
std::function<void(dns::Message)> reply,
bool sendIPv6)
{
if (ctx)
{
auto ip = ObtainIPForAddr(addr);
query->answers.clear();
query->AddINReply(ToHost(ip), sendIPv6);
}
else
query->AddNXReply();
reply(*query);
}
std::shared_ptr<dns::Server> m_DNS;
DnsConfig m_DnsConfig;
std::unordered_map<net::ipv6addr_t, llarp_time_t> m_IPActivity;
net::ipv6addr_t m_OurIP;
net::ipv6addr_t m_OurIPv6;
huint128_t m_NextIP;
net::ipv6addr_t m_MaxIP;
llarp::IPRange m_OurRange;
std::vector<SockAddr> m_StrictConnectAddrs;
bool m_UseV6;
std::string m_IfName;
std::optional<net::ipv6addr_t> m_BaseV6Address;
std::shared_ptr<vpn::NetworkInterface> m_NetIf;
std::shared_ptr<vpn::PacketRouter> m_PacketRouter;
std::optional<net::TrafficPolicy> m_TrafficPolicy;
std::set<IPRange> m_OwnedRanges;
llarp_time_t m_PathAlignmentTimeout;
std::optional<fs::path> m_PersistAddrMapFile;
std::shared_ptr<vpn::I_Packet_IO> m_RawDNS;
};
} // namespace handlers
} // namespace llarp
Updated on 2026-01-10 at 22:49:45 +0000