mirror of https://github.com/oxen-io/lokinet
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
3.9 KiB
C++
168 lines
3.9 KiB
C++
4 years ago
|
#pragma once
|
||
|
|
||
4 years ago
|
#include <llarp/net/ip_range.hpp>
|
||
|
#include <llarp/net/ip_packet.hpp>
|
||
3 years ago
|
#include <oxenc/variant.h>
|
||
3 years ago
|
|
||
2 years ago
|
#include "i_packet_io.hpp"
|
||
|
|
||
|
#include <set>
|
||
|
|
||
4 years ago
|
namespace llarp
|
||
|
{
|
||
|
struct Context;
|
||
3 years ago
|
struct AbstractRouter;
|
||
|
} // namespace llarp
|
||
4 years ago
|
|
||
|
namespace llarp::vpn
|
||
|
{
|
||
|
struct InterfaceAddress
|
||
|
{
|
||
|
constexpr InterfaceAddress(IPRange r, int f = AF_INET) : range{std::move(r)}, fam{f}
|
||
|
{}
|
||
|
IPRange range;
|
||
|
int fam;
|
||
|
bool
|
||
|
operator<(const InterfaceAddress& other) const
|
||
|
{
|
||
|
return range < other.range or fam < other.fam;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct InterfaceInfo
|
||
|
{
|
||
|
std::string ifname;
|
||
2 years ago
|
unsigned int index;
|
||
4 years ago
|
huint32_t dnsaddr;
|
||
2 years ago
|
std::vector<InterfaceAddress> addrs;
|
||
|
|
||
|
/// get address number N
|
||
|
inline net::ipaddr_t
|
||
|
operator[](size_t idx) const
|
||
|
{
|
||
|
const auto& range = addrs[idx].range;
|
||
|
if (range.IsV4())
|
||
|
return ToNet(net::TruncateV6(range.addr));
|
||
|
return ToNet(range.addr);
|
||
|
}
|
||
4 years ago
|
};
|
||
|
|
||
|
/// a vpn network interface
|
||
2 years ago
|
class NetworkInterface : public I_Packet_IO
|
||
4 years ago
|
{
|
||
2 years ago
|
protected:
|
||
|
InterfaceInfo m_Info;
|
||
|
|
||
4 years ago
|
public:
|
||
2 years ago
|
NetworkInterface(InterfaceInfo info) : m_Info{std::move(info)}
|
||
|
{}
|
||
4 years ago
|
NetworkInterface(const NetworkInterface&) = delete;
|
||
|
NetworkInterface(NetworkInterface&&) = delete;
|
||
|
|
||
|
virtual ~NetworkInterface() = default;
|
||
|
|
||
2 years ago
|
const InterfaceInfo&
|
||
|
Info() const
|
||
|
{
|
||
|
return m_Info;
|
||
|
}
|
||
3 years ago
|
|
||
|
/// idempotently wake up the upper layers as needed (platform dependant)
|
||
|
virtual void
|
||
|
MaybeWakeUpperLayers() const {};
|
||
4 years ago
|
};
|
||
|
|
||
3 years ago
|
class IRouteManager
|
||
|
{
|
||
|
public:
|
||
|
IRouteManager() = default;
|
||
|
IRouteManager(const IRouteManager&) = delete;
|
||
|
IRouteManager(IRouteManager&&) = delete;
|
||
|
virtual ~IRouteManager() = default;
|
||
|
|
||
2 years ago
|
virtual const llarp::net::Platform*
|
||
|
Net_ptr() const;
|
||
|
|
||
|
inline const llarp::net::Platform&
|
||
|
Net() const
|
||
|
{
|
||
|
return *Net_ptr();
|
||
|
}
|
||
|
|
||
3 years ago
|
virtual void
|
||
2 years ago
|
AddRoute(net::ipaddr_t ip, net::ipaddr_t gateway) = 0;
|
||
3 years ago
|
|
||
|
virtual void
|
||
2 years ago
|
DelRoute(net::ipaddr_t ip, net::ipaddr_t gateway) = 0;
|
||
3 years ago
|
|
||
|
virtual void
|
||
2 years ago
|
AddDefaultRouteViaInterface(NetworkInterface& vpn) = 0;
|
||
3 years ago
|
|
||
|
virtual void
|
||
2 years ago
|
DelDefaultRouteViaInterface(NetworkInterface& vpn) = 0;
|
||
3 years ago
|
|
||
3 years ago
|
virtual void
|
||
3 years ago
|
AddRouteViaInterface(NetworkInterface& vpn, IPRange range) = 0;
|
||
3 years ago
|
|
||
|
virtual void
|
||
3 years ago
|
DelRouteViaInterface(NetworkInterface& vpn, IPRange range) = 0;
|
||
3 years ago
|
|
||
2 years ago
|
virtual std::vector<net::ipaddr_t>
|
||
|
GetGatewaysNotOnInterface(NetworkInterface& vpn) = 0;
|
||
3 years ago
|
|
||
|
virtual void
|
||
3 years ago
|
AddBlackhole(){};
|
||
3 years ago
|
|
||
|
virtual void
|
||
3 years ago
|
DelBlackhole(){};
|
||
3 years ago
|
};
|
||
|
|
||
4 years ago
|
/// a vpn platform
|
||
|
/// responsible for obtaining vpn interfaces
|
||
|
class Platform
|
||
|
{
|
||
2 years ago
|
protected:
|
||
|
/// get a new network interface fully configured given the interface info
|
||
|
/// blocks until ready, throws on error
|
||
|
virtual std::shared_ptr<NetworkInterface>
|
||
|
ObtainInterface(InterfaceInfo info, AbstractRouter* router) = 0;
|
||
|
|
||
4 years ago
|
public:
|
||
|
Platform() = default;
|
||
|
Platform(const Platform&) = delete;
|
||
|
Platform(Platform&&) = delete;
|
||
|
virtual ~Platform() = default;
|
||
|
|
||
2 years ago
|
/// create and start a network interface
|
||
|
inline std::shared_ptr<NetworkInterface>
|
||
|
CreateInterface(InterfaceInfo info, AbstractRouter* router)
|
||
|
{
|
||
|
if (auto netif = ObtainInterface(std::move(info), router))
|
||
|
{
|
||
|
netif->Start();
|
||
|
return netif;
|
||
|
}
|
||
|
return nullptr;
|
||
|
}
|
||
3 years ago
|
|
||
|
/// get owned ip route manager for managing routing table
|
||
|
virtual IRouteManager&
|
||
|
RouteManager() = 0;
|
||
2 years ago
|
|
||
|
/// create a packet io that will read (and optionally write) packets on a network interface the
|
||
|
/// lokinet process does not own
|
||
|
/// @param index the interface index of the network interface to use or 0 for all
|
||
|
/// interfaces on the system
|
||
|
virtual std::shared_ptr<I_Packet_IO>
|
||
|
create_packet_io(unsigned int)
|
||
|
{
|
||
|
throw std::runtime_error{"raw packet io is unimplemented"};
|
||
|
}
|
||
4 years ago
|
};
|
||
|
|
||
|
/// create native vpn platform
|
||
4 years ago
|
std::shared_ptr<Platform>
|
||
4 years ago
|
MakeNativePlatform(llarp::Context* ctx);
|
||
|
|
||
|
} // namespace llarp::vpn
|