mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-17 15:25:35 +00:00
49b9ad7197
* partial tun code refactor * take out the trash * move vpn platform code into llarp/vpn/platform.cpp * fix hive build * fix win32 * fix memory leak on win32 * reduce cpu use * make macos compile * win32 patches: * use wepoll for zmq * use all cores on windows iocp read loop * fix zmq patch for windows * clean up cmake for win32 * add uninstall before reinstall option to win32 installer * more ipv6 stuff * make it compile * fix up route poker * remove an unneeded code block in macos wtf * always use call to system * fix route poker behavior on macos * disable ipv6 on windows for now * cpu perf improvement: * colease calls to Router::PumpLL to 1 per event loop wakeup * set up THEN add addresses * emulate proactor event loop on win32 * remove excessively verbose error message * fix issue #1499 * exclude uv_poll from win32 so that it can start up * update logtag to include directory * create minidump on windows if there was a crash * make windows happy * use dmp suffix on minidump files * typo fix * address feedback from jason * use PROJECT_SOURCE_DIR instead of CMAKE_SOURCE_DIR * quote $@ in apply-patches in case path has spaces in it * address feedback from tom * remove llarp/ev/pipe * add comments for clairification * make event loop queue size constant named
261 lines
6.5 KiB
C++
261 lines
6.5 KiB
C++
#ifndef LLARP_HANDLERS_TUN_HPP
|
|
#define LLARP_HANDLERS_TUN_HPP
|
|
|
|
#include <dns/server.hpp>
|
|
#include <ev/ev.hpp>
|
|
#include <ev/vpn.hpp>
|
|
#include <net/ip.hpp>
|
|
#include <net/ip_packet.hpp>
|
|
#include <net/net.hpp>
|
|
#include <service/endpoint.hpp>
|
|
#include <util/codel.hpp>
|
|
#include <util/thread/threading.hpp>
|
|
|
|
#include <future>
|
|
#include <queue>
|
|
|
|
namespace llarp
|
|
{
|
|
namespace handlers
|
|
{
|
|
struct TunEndpoint : public service::Endpoint,
|
|
public dns::IQueryHandler,
|
|
public std::enable_shared_from_this<TunEndpoint>
|
|
{
|
|
TunEndpoint(AbstractRouter* r, llarp::service::Context* parent);
|
|
~TunEndpoint() override;
|
|
|
|
path::PathSet_ptr
|
|
GetSelf() override
|
|
{
|
|
return shared_from_this();
|
|
}
|
|
|
|
bool
|
|
Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) override;
|
|
|
|
void
|
|
SendPacketToRemote(const llarp_buffer_t&) override{};
|
|
|
|
std::string
|
|
GetIfName() const override;
|
|
|
|
void
|
|
Tick(llarp_time_t now) override;
|
|
|
|
util::StatusObject
|
|
ExtractStatus() const override;
|
|
|
|
std::unordered_map<std::string, std::string>
|
|
NotifyParams() const override;
|
|
|
|
bool
|
|
SupportsV6() const override;
|
|
|
|
bool
|
|
ShouldHookDNSMessage(const dns::Message& msg) const override;
|
|
|
|
bool
|
|
HandleHookedDNSMessage(
|
|
dns::Message query, std::function<void(dns::Message)> sendreply) override;
|
|
|
|
void
|
|
TickTun(llarp_time_t now);
|
|
|
|
bool
|
|
MapAddress(const service::Address& remote, huint128_t ip, bool SNode);
|
|
|
|
bool
|
|
Start() override;
|
|
|
|
bool
|
|
Stop() override;
|
|
|
|
bool
|
|
IsSNode() const;
|
|
|
|
/// set up tun interface, blocking
|
|
bool
|
|
SetupTun();
|
|
|
|
/// overrides Endpoint
|
|
bool
|
|
SetupNetworking() override;
|
|
|
|
/// overrides Endpoint
|
|
bool
|
|
HandleInboundPacket(
|
|
const service::ConvoTag tag,
|
|
const llarp_buffer_t& pkt,
|
|
service::ProtocolType t,
|
|
uint64_t seqno) override;
|
|
|
|
/// handle inbound traffic
|
|
bool
|
|
HandleWriteIPPacket(
|
|
const llarp_buffer_t& buf, huint128_t src, huint128_t dst, uint64_t seqno);
|
|
|
|
/// queue outbound packet to the world
|
|
bool
|
|
QueueOutboundTraffic(llarp::net::IPPacket&& pkt);
|
|
|
|
/// we got a packet from the user
|
|
void
|
|
HandleGotUserPacket(llarp::net::IPPacket pkt);
|
|
|
|
/// get the local interface's address
|
|
huint128_t
|
|
GetIfAddr() const override;
|
|
|
|
/// we have an interface addr
|
|
bool
|
|
HasIfAddr() const override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
HasLocalIP(const huint128_t& ip) const;
|
|
|
|
/// get a key for ip address
|
|
template <typename Addr_t>
|
|
Addr_t
|
|
ObtainAddrForIP(huint128_t ip, bool isSNode)
|
|
{
|
|
Addr_t addr;
|
|
auto itr = m_IPToAddr.find(ip);
|
|
if (itr != m_IPToAddr.end() and m_SNodes[itr->second] == isSNode)
|
|
{
|
|
addr = Addr_t(itr->second);
|
|
}
|
|
// found
|
|
return addr;
|
|
}
|
|
|
|
template <typename Addr_t>
|
|
bool
|
|
FindAddrForIP(Addr_t& addr, huint128_t ip);
|
|
|
|
bool
|
|
HasAddress(const AlignedBuffer<32>& addr) const
|
|
{
|
|
return m_AddrToIP.find(addr) != m_AddrToIP.end();
|
|
}
|
|
|
|
/// get ip address for key unconditionally
|
|
huint128_t
|
|
ObtainIPForAddr(const AlignedBuffer<32>& addr, bool serviceNode) override;
|
|
|
|
/// flush network traffic
|
|
void
|
|
Flush();
|
|
|
|
void
|
|
ResetInternalState() override;
|
|
|
|
protected:
|
|
bool
|
|
ShouldFlushNow(llarp_time_t now) const;
|
|
|
|
llarp_time_t m_LastFlushAt = 0s;
|
|
using PacketQueue_t = llarp::util::CoDelQueue<
|
|
net::IPPacket,
|
|
net::IPPacket::GetTime,
|
|
net::IPPacket::PutTime,
|
|
net::IPPacket::CompareOrder,
|
|
net::IPPacket::GetNow>;
|
|
|
|
/// queue for sending packets over the network from us
|
|
PacketQueue_t m_UserToNetworkPktQueue;
|
|
|
|
struct WritePacket
|
|
{
|
|
uint64_t seqno;
|
|
net::IPPacket pkt;
|
|
|
|
bool
|
|
operator<(const WritePacket& other) const
|
|
{
|
|
return other.seqno < seqno;
|
|
}
|
|
};
|
|
|
|
/// queue for sending packets to user from network
|
|
std::priority_queue<WritePacket> m_NetworkToUserPktQueue;
|
|
/// return true if we have a remote loki address for this ip address
|
|
bool
|
|
HasRemoteForIP(huint128_t ipv4) const;
|
|
|
|
/// mark this address as active
|
|
void
|
|
MarkIPActive(huint128_t ip);
|
|
|
|
/// mark this address as active forever
|
|
void
|
|
MarkIPActiveForever(huint128_t ip);
|
|
|
|
/// flush ip packets
|
|
virtual void
|
|
FlushSend();
|
|
|
|
/// maps ip to key (host byte order)
|
|
std::unordered_map<huint128_t, AlignedBuffer<32>> m_IPToAddr;
|
|
/// maps key to ip (host byte order)
|
|
std::unordered_map<AlignedBuffer<32>, huint128_t, AlignedBuffer<32>::Hash> m_AddrToIP;
|
|
|
|
/// maps key to true if key is a service node, maps key to false if key is
|
|
/// a hidden service
|
|
std::unordered_map<AlignedBuffer<32>, bool, AlignedBuffer<32>::Hash> m_SNodes;
|
|
|
|
private:
|
|
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 snode,
|
|
bool sendIPv6)
|
|
{
|
|
if (ctx)
|
|
{
|
|
huint128_t ip = ObtainIPForAddr(addr, snode);
|
|
query->answers.clear();
|
|
query->AddINReply(ip, sendIPv6);
|
|
}
|
|
else
|
|
query->AddNXReply();
|
|
reply(*query);
|
|
}
|
|
/// our dns resolver
|
|
std::shared_ptr<dns::Proxy> m_Resolver;
|
|
|
|
/// maps ip address to timestamp last active
|
|
std::unordered_map<huint128_t, llarp_time_t> m_IPActivity;
|
|
/// our ip address (host byte order)
|
|
huint128_t m_OurIP;
|
|
/// next ip address to allocate (host byte order)
|
|
huint128_t m_NextIP;
|
|
/// highest ip address to allocate (host byte order)
|
|
huint128_t m_MaxIP;
|
|
/// our ip range we are using
|
|
llarp::IPRange m_OurRange;
|
|
/// upstream dns resolver list
|
|
std::vector<IpAddress> m_UpstreamResolvers;
|
|
/// local dns
|
|
IpAddress m_LocalResolverAddr;
|
|
/// list of strict connect addresses for hooks
|
|
std::vector<IpAddress> m_StrictConnectAddrs;
|
|
/// use v6?
|
|
bool m_UseV6;
|
|
std::string m_IfName;
|
|
|
|
std::shared_ptr<vpn::NetworkInterface> m_NetIf;
|
|
};
|
|
|
|
} // namespace handlers
|
|
} // namespace llarp
|
|
|
|
#endif
|