2018-08-08 19:37:33 +00:00
|
|
|
#ifndef LLARP_HANDLERS_TUN_HPP
|
|
|
|
#define LLARP_HANDLERS_TUN_HPP
|
2018-12-12 02:15:08 +00:00
|
|
|
|
|
|
|
#include <dns/server.hpp>
|
2019-01-11 01:19:36 +00:00
|
|
|
#include <ev/ev.h>
|
2019-10-04 18:10:58 +00:00
|
|
|
#include <ev/vpnio.hpp>
|
2019-01-14 21:46:07 +00:00
|
|
|
#include <net/ip.hpp>
|
2019-01-11 01:42:02 +00:00
|
|
|
#include <net/net.hpp>
|
2018-12-12 02:15:08 +00:00
|
|
|
#include <service/endpoint.hpp>
|
2019-01-13 22:39:10 +00:00
|
|
|
#include <util/codel.hpp>
|
2019-09-01 13:26:16 +00:00
|
|
|
#include <util/thread/threading.hpp>
|
2018-08-08 19:37:33 +00:00
|
|
|
|
2019-03-03 20:51:47 +00:00
|
|
|
#include <future>
|
|
|
|
|
2018-08-08 19:37:33 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace handlers
|
|
|
|
{
|
2019-04-23 16:13:22 +00:00
|
|
|
struct TunEndpoint : public service::Endpoint,
|
|
|
|
public dns::IQueryHandler,
|
|
|
|
public std::enable_shared_from_this< TunEndpoint >
|
2018-08-08 19:37:33 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
TunEndpoint(const std::string& nickname, AbstractRouter* r,
|
2019-10-04 18:10:58 +00:00
|
|
|
llarp::service::Context* parent, bool lazyVPN = false);
|
2019-07-30 23:42:13 +00:00
|
|
|
~TunEndpoint() override;
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2019-04-23 16:13:22 +00:00
|
|
|
path::PathSet_ptr
|
|
|
|
GetSelf() override
|
|
|
|
{
|
|
|
|
return shared_from_this();
|
|
|
|
}
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
bool
|
2018-12-04 23:45:08 +00:00
|
|
|
SetOption(const std::string& k, const std::string& v) override;
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
void
|
2018-12-04 23:45:08 +00:00
|
|
|
Tick(llarp_time_t now) override;
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject
|
2019-04-19 15:10:26 +00:00
|
|
|
ExtractStatus() const;
|
2019-02-08 19:43:25 +00:00
|
|
|
|
2019-04-22 14:00:59 +00:00
|
|
|
std::unordered_map< std::string, std::string >
|
|
|
|
NotifyParams() const override;
|
|
|
|
|
2019-06-11 16:44:05 +00:00
|
|
|
bool
|
|
|
|
SupportsV6() const override;
|
|
|
|
|
2018-12-03 22:22:59 +00:00
|
|
|
bool
|
|
|
|
ShouldHookDNSMessage(const dns::Message& msg) const override;
|
|
|
|
|
|
|
|
bool
|
|
|
|
HandleHookedDNSMessage(
|
2019-01-07 22:15:31 +00:00
|
|
|
dns::Message&& query,
|
2018-12-03 22:22:59 +00:00
|
|
|
std::function< void(dns::Message) > sendreply) override;
|
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
void
|
|
|
|
TickTun(llarp_time_t now);
|
|
|
|
|
2019-11-20 19:45:23 +00:00
|
|
|
static void
|
|
|
|
tunifTick(llarp_tun_io*);
|
|
|
|
|
2018-08-22 15:52:10 +00:00
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
MapAddress(const service::Address& remote, huint128_t ip, bool SNode);
|
2018-08-22 15:52:10 +00:00
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
bool
|
2018-12-04 23:45:08 +00:00
|
|
|
Start() override;
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2018-12-24 16:09:05 +00:00
|
|
|
bool
|
|
|
|
Stop() override;
|
|
|
|
|
2018-12-02 18:07:07 +00:00
|
|
|
bool
|
2018-11-30 14:14:30 +00:00
|
|
|
IsSNode() const;
|
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
/// set up tun interface, blocking
|
|
|
|
bool
|
|
|
|
SetupTun();
|
|
|
|
|
|
|
|
/// overrides Endpoint
|
|
|
|
bool
|
2018-12-04 23:45:08 +00:00
|
|
|
SetupNetworking() override;
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2018-09-18 17:48:26 +00:00
|
|
|
/// overrides Endpoint
|
2019-07-01 13:44:25 +00:00
|
|
|
bool
|
2019-07-01 14:56:56 +00:00
|
|
|
HandleInboundPacket(const service::ConvoTag tag,
|
|
|
|
const llarp_buffer_t& pkt,
|
|
|
|
service::ProtocolType t) override
|
2019-07-01 13:44:25 +00:00
|
|
|
{
|
2019-07-01 14:56:56 +00:00
|
|
|
if(t != service::eProtocolTrafficV4 && t != service::eProtocolTrafficV6)
|
|
|
|
return false;
|
|
|
|
AlignedBuffer< 32 > addr;
|
|
|
|
bool snode = false;
|
|
|
|
if(!GetEndpointWithConvoTag(tag, addr, snode))
|
|
|
|
return false;
|
|
|
|
return HandleWriteIPPacket(
|
|
|
|
pkt, [=]() -> huint128_t { return ObtainIPForAddr(addr, snode); });
|
2019-07-01 13:44:25 +00:00
|
|
|
}
|
|
|
|
|
2018-08-21 18:17:16 +00:00
|
|
|
/// handle inbound traffic
|
2018-09-18 11:08:47 +00:00
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
HandleWriteIPPacket(const llarp_buffer_t& buf,
|
2019-07-01 13:44:25 +00:00
|
|
|
std::function< huint128_t(void) > getFromIP);
|
2018-08-18 14:01:21 +00:00
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
/// queue outbound packet to the world
|
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
QueueOutboundTraffic(llarp::net::IPPacket&& pkt);
|
2018-11-14 12:23:08 +00:00
|
|
|
|
|
|
|
/// get the local interface's address
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t
|
2019-07-05 14:41:26 +00:00
|
|
|
GetIfAddr() const override;
|
2018-11-14 12:23:08 +00:00
|
|
|
|
2019-07-05 14:48:10 +00:00
|
|
|
/// we have an interface addr
|
|
|
|
bool
|
|
|
|
HasIfAddr() const override
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
HasLocalIP(const huint128_t& ip) const;
|
2018-11-14 12:23:08 +00:00
|
|
|
|
2019-10-04 18:10:58 +00:00
|
|
|
std::unique_ptr< llarp_tun_io > tunif;
|
|
|
|
llarp_vpn_io* vpnif = nullptr;
|
|
|
|
|
|
|
|
bool
|
2019-12-10 14:14:16 +00:00
|
|
|
InjectVPN(llarp_vpn_io* io, llarp_vpn_ifaddr_info info) override
|
2019-10-04 18:10:58 +00:00
|
|
|
{
|
|
|
|
if(tunif)
|
|
|
|
return false;
|
|
|
|
m_LazyVPNPromise.set_value(lazy_vpn{info, io});
|
|
|
|
return true;
|
|
|
|
}
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2018-08-21 18:17:16 +00:00
|
|
|
/// called before writing to tun interface
|
2018-08-16 14:34:15 +00:00
|
|
|
static void
|
2018-08-17 19:49:58 +00:00
|
|
|
tunifBeforeWrite(llarp_tun_io* t);
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2018-08-22 15:52:10 +00:00
|
|
|
/// handle user to network send buffer flush
|
|
|
|
/// called in router logic thread
|
|
|
|
static void
|
|
|
|
handleNetSend(void*);
|
|
|
|
|
2018-08-21 18:17:16 +00:00
|
|
|
/// called every time we wish to read a packet from the tun interface
|
2018-08-16 14:34:15 +00:00
|
|
|
static void
|
2019-02-01 01:58:06 +00:00
|
|
|
tunifRecvPkt(llarp_tun_io* t, const llarp_buffer_t& buf);
|
2018-08-16 14:34:15 +00:00
|
|
|
|
2018-08-21 18:17:16 +00:00
|
|
|
/// called in the endpoint logic thread
|
2018-08-16 14:34:15 +00:00
|
|
|
static void
|
|
|
|
handleTickTun(void* u);
|
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
/// get a key for ip address
|
2019-11-29 00:37:58 +00:00
|
|
|
template < typename Addr_t >
|
|
|
|
Addr_t
|
2019-06-11 16:44:05 +00:00
|
|
|
ObtainAddrForIP(huint128_t ip, bool isSNode)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
2019-11-29 00:37:58 +00:00
|
|
|
Addr_t addr;
|
2018-11-14 12:23:08 +00:00
|
|
|
auto itr = m_IPToAddr.find(ip);
|
2019-11-29 00:37:58 +00:00
|
|
|
if(itr != m_IPToAddr.end() and m_SNodes[itr->second] == isSNode)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
2019-11-29 00:37:58 +00:00
|
|
|
addr = Addr_t(itr->second);
|
2018-11-14 12:23:08 +00:00
|
|
|
}
|
|
|
|
// found
|
2019-11-29 00:37:58 +00:00
|
|
|
return addr;
|
2018-11-14 12:23:08 +00:00
|
|
|
}
|
2018-10-19 14:53:06 +00:00
|
|
|
|
2019-11-29 00:37:58 +00:00
|
|
|
template < typename Addr_t >
|
|
|
|
bool
|
|
|
|
FindAddrForIP(Addr_t& addr, huint128_t ip);
|
|
|
|
|
2018-10-23 18:18:00 +00:00
|
|
|
bool
|
2019-07-01 13:44:25 +00:00
|
|
|
HasAddress(const AlignedBuffer< 32 >& addr) const
|
2018-10-23 18:18:00 +00:00
|
|
|
{
|
2018-11-14 12:23:08 +00:00
|
|
|
return m_AddrToIP.find(addr) != m_AddrToIP.end();
|
2018-10-23 18:18:00 +00:00
|
|
|
}
|
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
/// get ip address for key unconditionally
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t
|
2019-07-01 13:44:25 +00:00
|
|
|
ObtainIPForAddr(const AlignedBuffer< 32 >& addr, bool serviceNode);
|
2018-10-23 21:33:49 +00:00
|
|
|
|
2018-12-15 16:56:35 +00:00
|
|
|
/// flush network traffic
|
|
|
|
void
|
|
|
|
Flush();
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
void
|
2019-05-07 17:46:38 +00:00
|
|
|
ResetInternalState() override;
|
|
|
|
|
2018-08-17 19:49:58 +00:00
|
|
|
protected:
|
2019-11-29 18:11:57 +00:00
|
|
|
bool
|
2019-11-29 18:37:19 +00:00
|
|
|
ShouldFlushNow(llarp_time_t now) const;
|
2019-11-29 18:11:57 +00:00
|
|
|
|
|
|
|
llarp_time_t m_LastFlushAt = 0;
|
|
|
|
using PacketQueue_t = llarp::util::CoDelQueue<
|
2019-06-11 16:44:05 +00:00
|
|
|
net::IPPacket, net::IPPacket::GetTime, net::IPPacket::PutTime,
|
|
|
|
net::IPPacket::CompareOrder, net::IPPacket::GetNow >;
|
2019-11-25 13:18:24 +00:00
|
|
|
|
|
|
|
/// queue packet for send on net thread from user
|
|
|
|
std::vector< net::IPPacket > m_TunPkts;
|
2018-08-17 19:49:58 +00:00
|
|
|
/// queue for sending packets over the network from us
|
|
|
|
PacketQueue_t m_UserToNetworkPktQueue;
|
|
|
|
/// queue for sending packets to user from network
|
|
|
|
PacketQueue_t m_NetworkToUserPktQueue;
|
|
|
|
/// return true if we have a remote loki address for this ip address
|
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
HasRemoteForIP(huint128_t ipv4) const;
|
2018-10-19 14:53:06 +00:00
|
|
|
|
2018-08-21 18:17:16 +00:00
|
|
|
/// mark this address as active
|
|
|
|
void
|
2019-06-11 16:44:05 +00:00
|
|
|
MarkIPActive(huint128_t ip);
|
2018-08-21 18:17:16 +00:00
|
|
|
|
2018-09-10 11:08:09 +00:00
|
|
|
/// mark this address as active forever
|
|
|
|
void
|
2019-06-11 16:44:05 +00:00
|
|
|
MarkIPActiveForever(huint128_t ip);
|
2018-09-10 11:08:09 +00:00
|
|
|
|
2018-11-12 16:43:40 +00:00
|
|
|
/// flush ip packets
|
|
|
|
virtual void
|
2018-08-22 15:52:10 +00:00
|
|
|
FlushSend();
|
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
/// maps ip to key (host byte order)
|
2019-06-11 16:44:05 +00:00
|
|
|
std::unordered_map< huint128_t, AlignedBuffer< 32 >, huint128_t::Hash >
|
2018-11-14 12:23:08 +00:00
|
|
|
m_IPToAddr;
|
|
|
|
/// maps key to ip (host byte order)
|
2019-06-11 16:44:05 +00:00
|
|
|
std::unordered_map< AlignedBuffer< 32 >, huint128_t,
|
2018-11-14 12:23:08 +00:00
|
|
|
AlignedBuffer< 32 >::Hash >
|
|
|
|
m_AddrToIP;
|
|
|
|
|
2018-12-02 18:07:07 +00:00
|
|
|
/// 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;
|
2018-11-29 13:12:35 +00:00
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
private:
|
2019-10-04 18:10:58 +00:00
|
|
|
llarp_vpn_io_impl*
|
|
|
|
GetVPNImpl()
|
|
|
|
{
|
|
|
|
if(vpnif && vpnif->impl)
|
|
|
|
return static_cast< llarp_vpn_io_impl* >(vpnif->impl);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-11-14 19:34:17 +00:00
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
QueueInboundPacketForExit(const llarp_buffer_t& buf)
|
2018-11-14 19:34:17 +00:00
|
|
|
{
|
2019-02-03 00:48:10 +00:00
|
|
|
ManagedBuffer copy{buf};
|
2018-11-14 19:34:17 +00:00
|
|
|
return m_NetworkToUserPktQueue.EmplaceIf(
|
2019-06-11 16:44:05 +00:00
|
|
|
[&](llarp::net::IPPacket& pkt) -> bool {
|
2019-02-02 23:12:42 +00:00
|
|
|
if(!pkt.Load(copy.underlying))
|
2018-11-14 19:34:17 +00:00
|
|
|
return false;
|
2019-06-11 16:44:05 +00:00
|
|
|
if(SupportsV6())
|
|
|
|
{
|
|
|
|
if(pkt.IsV4())
|
|
|
|
{
|
2019-06-11 21:27:06 +00:00
|
|
|
pkt.UpdateIPv6Address(net::IPPacket::ExpandV4(pkt.srcv4()),
|
2019-06-11 21:28:55 +00:00
|
|
|
m_OurIP);
|
2019-06-11 16:44:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-06-11 21:27:06 +00:00
|
|
|
pkt.UpdateIPv6Address(pkt.srcv6(), m_OurIP);
|
2019-06-11 16:44:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(pkt.IsV4())
|
2019-06-11 21:28:55 +00:00
|
|
|
pkt.UpdateIPv4Address(
|
|
|
|
xhtonl(pkt.srcv4()),
|
|
|
|
xhtonl(net::IPPacket::TruncateV6(m_OurIP)));
|
2019-06-11 16:44:05 +00:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
2018-11-14 19:34:17 +00:00
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-01 19:10:42 +00:00
|
|
|
template < typename Addr_t, typename Endpoint_t >
|
2018-12-03 22:22:59 +00:00
|
|
|
void
|
2020-02-01 15:28:10 +00:00
|
|
|
SendDNSReply(Addr_t addr, Endpoint_t ctx,
|
|
|
|
std::shared_ptr< dns::Message > query,
|
2019-03-27 13:36:11 +00:00
|
|
|
std::function< void(dns::Message) > reply, bool snode,
|
|
|
|
bool sendIPv6)
|
2019-03-01 19:10:42 +00:00
|
|
|
{
|
|
|
|
if(ctx)
|
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t ip = ObtainIPForAddr(addr, snode);
|
2019-03-27 13:36:11 +00:00
|
|
|
query->AddINReply(ip, sendIPv6);
|
2019-03-01 19:10:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
query->AddNXReply();
|
|
|
|
reply(*query);
|
|
|
|
}
|
2018-12-03 22:22:59 +00:00
|
|
|
/// our dns resolver
|
2019-05-22 16:20:50 +00:00
|
|
|
std::shared_ptr< dns::Proxy > m_Resolver;
|
2018-09-22 10:25:16 +00:00
|
|
|
|
2018-08-21 18:17:16 +00:00
|
|
|
/// maps ip address to timestamp last active
|
2019-06-11 16:44:05 +00:00
|
|
|
std::unordered_map< huint128_t, llarp_time_t, huint128_t::Hash >
|
2018-10-10 15:50:52 +00:00
|
|
|
m_IPActivity;
|
2018-09-23 16:47:18 +00:00
|
|
|
/// our ip address (host byte order)
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t m_OurIP;
|
2018-09-23 16:47:18 +00:00
|
|
|
/// next ip address to allocate (host byte order)
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t m_NextIP;
|
2018-10-10 15:14:45 +00:00
|
|
|
/// highest ip address to allocate (host byte order)
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t m_MaxIP;
|
2018-12-03 22:22:59 +00:00
|
|
|
/// our ip range we are using
|
|
|
|
llarp::IPRange m_OurRange;
|
|
|
|
/// upstream dns resolver list
|
|
|
|
std::vector< llarp::Addr > m_UpstreamResolvers;
|
2018-11-11 13:14:19 +00:00
|
|
|
/// local dns
|
|
|
|
llarp::Addr m_LocalResolverAddr;
|
2019-05-06 12:42:21 +00:00
|
|
|
/// list of strict connect addresses for hooks
|
|
|
|
std::vector< llarp::Addr > m_StrictConnectAddrs;
|
2019-06-11 16:44:05 +00:00
|
|
|
/// use v6?
|
|
|
|
bool m_UseV6;
|
2019-10-04 18:10:58 +00:00
|
|
|
struct lazy_vpn
|
|
|
|
{
|
|
|
|
llarp_vpn_ifaddr_info info;
|
|
|
|
llarp_vpn_io* io;
|
|
|
|
};
|
|
|
|
std::promise< lazy_vpn > m_LazyVPNPromise;
|
|
|
|
|
|
|
|
/// send packets on endpoint to user using send function
|
|
|
|
/// send function returns true to indicate stop iteration and do codel
|
|
|
|
/// drop
|
|
|
|
void
|
|
|
|
FlushToUser(std::function< bool(net::IPPacket&) > sendfunc);
|
2018-08-08 19:37:33 +00:00
|
|
|
};
|
2019-11-29 00:37:58 +00:00
|
|
|
|
2018-08-08 19:37:33 +00:00
|
|
|
} // namespace handlers
|
|
|
|
} // namespace llarp
|
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
#endif
|