mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-15 12:13:24 +00:00
TUN ip packet re-writing; deps bump
- Packets coming in and out of full clients need their IP src/dest addresses re-written - Lokinet's TUN device sucks up all packets aimed at the if range, correctly addressing them to the proper outbound - On reception, lokinet's TUN device addresses correctly for the mapped application receiving the packet - Brought a lil somethin' somethin' from libquic for CI - Bump oxenmq to cpp20 branch - Revert cpr to 1.9 stable for subproject curl dep bug
This commit is contained in:
parent
4979f9aab8
commit
f755d2601f
@ -384,7 +384,7 @@ local docs_pipeline(name, image, extra_cmds=[], allow_fail=false) = {
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
apt_get_quiet + ' update',
|
||||
apt_get_quiet + ' install -y eatmydata',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git clang-format-17 jsonnet',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git clang-format-15 jsonnet',
|
||||
'./contrib/ci/drone-format-verify.sh',
|
||||
],
|
||||
}],
|
||||
|
@ -188,14 +188,22 @@ if(NOT TARGET sodium)
|
||||
endif()
|
||||
|
||||
set(warning_flags -Wall -Wextra -Wno-unknown-pragmas -Wno-unused-function -Werror=vla)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND warning_flags -Wno-unknown-warning-option)
|
||||
endif()
|
||||
|
||||
if(WARNINGS_AS_ERRORS)
|
||||
list(APPEND warning_flags -Werror -Wno-error=array-bounds)
|
||||
endif()
|
||||
|
||||
list(APPEND warning_flags -Wno-deprecated-declarations)
|
||||
|
||||
add_library(lokinet-base-internal_warnings INTERFACE)
|
||||
|
||||
# If we blindly add these directly as compile_options then they get passed to swiftc on Apple and
|
||||
# break, so we use a generate expression to set them only for C++/C/ObjC
|
||||
add_compile_options("$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:OBJC>>:${warning_flags}>")
|
||||
target_compile_options(lokinet-base-internal_warnings INTERFACE "$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:OBJC>>:${warning_flags}>")
|
||||
|
||||
if(XSAN)
|
||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fsanitize=${XSAN} -fno-omit-frame-pointer -fno-sanitize-recover")
|
||||
@ -268,6 +276,11 @@ add_library(lokinet-base INTERFACE)
|
||||
target_include_directories(lokinet-base INTERFACE . include)
|
||||
target_link_libraries(lokinet-base INTERFACE quic nlohmann_json::nlohmann_json)
|
||||
|
||||
add_library(lokinet-base-internal INTERFACE)
|
||||
target_include_directories(lokinet-base-internal INTERFACE include/lokinet)
|
||||
|
||||
target_link_libraries(lokinet-base-internal INTERFACE lokinet-base-internal_warnings)
|
||||
|
||||
if(WITH_SYSTEMD AND (NOT ANDROID))
|
||||
if(NOT SD_FOUND)
|
||||
message(FATAL_ERROR "libsystemd not found")
|
||||
@ -276,7 +289,6 @@ if(WITH_SYSTEMD AND (NOT ANDROID))
|
||||
target_compile_definitions(lokinet-base INTERFACE WITH_SYSTEMD)
|
||||
endif()
|
||||
|
||||
|
||||
if(USE_JEMALLOC AND NOT STATIC_LINK)
|
||||
pkg_check_modules(JEMALLOC jemalloc IMPORTED_TARGET)
|
||||
if(JEMALLOC_FOUND)
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
CLANG_FORMAT_DESIRED_VERSION=17
|
||||
CLANG_FORMAT_DESIRED_VERSION=16
|
||||
|
||||
CLANG_FORMAT=$(command -v clang-format-$CLANG_FORMAT_DESIRED_VERSION 2>/dev/null)
|
||||
if [ $? -ne 0 ]; then
|
||||
|
4
external/CMakeLists.txt
vendored
4
external/CMakeLists.txt
vendored
@ -81,10 +81,6 @@ if(WITH_PEERSTATS)
|
||||
target_link_libraries(sqlite_orm INTERFACE sqlite3)
|
||||
endif()
|
||||
|
||||
add_library(uvw INTERFACE)
|
||||
target_include_directories(uvw INTERFACE uvw/src)
|
||||
target_link_libraries(uvw INTERFACE libuv)
|
||||
|
||||
add_subdirectory(oxen-libquic)
|
||||
|
||||
# cpr configuration. Ideally we'd just do this via add_subdirectory, but cpr's cmake requires
|
||||
|
2
external/cpr
vendored
2
external/cpr
vendored
@ -1 +1 @@
|
||||
Subproject commit 3b15fa82ea74739b574d705fea44959b58142eb8
|
||||
Subproject commit 23598e8a867934280db1f3bd3fe8cfa268a8d378
|
2
external/oxen-mq
vendored
2
external/oxen-mq
vendored
@ -1 +1 @@
|
||||
Subproject commit a27961d787c9065f2bf6da9d60d01dca2e125739
|
||||
Subproject commit 9d5776bc5f85e68b03f927374710d359929e72ba
|
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "lokinet/lokinet_addr.h"
|
||||
#include "lokinet/lokinet_context.h"
|
||||
#include "lokinet/lokinet_misc.h"
|
||||
#include "lokinet/lokinet_srv.h"
|
||||
#include "lokinet/lokinet_stream.h"
|
||||
#include "lokinet/lokinet_udp.h"
|
||||
#include "lokinet/addr.h"
|
||||
#include "lokinet/context.h"
|
||||
#include "lokinet/misc.h"
|
||||
#include "lokinet/srv.h"
|
||||
#include "lokinet/stream.h"
|
||||
#include "lokinet/udp.h"
|
||||
|
@ -6,7 +6,7 @@ include(Version)
|
||||
# lokinet_add_library(lokinet-foo foo/source1.cpp foo/source2.cpp)
|
||||
function(lokinet_add_library libname)
|
||||
add_library(${libname} STATIC ${ARGN})
|
||||
target_link_libraries(${libname} PUBLIC lokinet-base)
|
||||
target_link_libraries(${libname} PUBLIC lokinet-base PRIVATE lokinet-base-internal)
|
||||
enable_lto(${libname})
|
||||
endfunction()
|
||||
|
||||
@ -266,19 +266,20 @@ target_link_libraries(lokinet-core
|
||||
lokinet-wire
|
||||
)
|
||||
|
||||
target_link_libraries(lokinet-base INTERFACE oxenc::oxenc oxen::logging)
|
||||
# target_link_libraries(lokinet-base INTERFACE oxenc::oxenc oxen::logging)
|
||||
target_link_libraries(lokinet-base INTERFACE oxenc::oxenc oxen::logging oxenmq::oxenmq Threads::Threads libunbound)
|
||||
|
||||
target_link_libraries(lokinet-rpc PUBLIC oxenmq::oxenmq)
|
||||
target_link_libraries(lokinet-core PUBLIC oxenmq::oxenmq)
|
||||
target_link_libraries(lokinet-config PUBLIC oxenmq::oxenmq)
|
||||
target_link_libraries(lokinet-nodedb PUBLIC oxenmq::oxenmq)
|
||||
target_link_libraries(lokinet-path PUBLIC oxenmq::oxenmq)
|
||||
target_link_libraries(lokinet-time-place PUBLIC uvw)
|
||||
target_link_libraries(lokinet-platform PUBLIC oxenmq::oxenmq Threads::Threads uvw)
|
||||
target_link_libraries(lokinet-cryptography PUBLIC sodium)
|
||||
target_link_libraries(lokinet-dns PUBLIC libunbound)
|
||||
target_link_libraries(lokinet-utils PUBLIC nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(lokinet-wire PUBLIC oxenmq::oxenmq quic)
|
||||
|
||||
# target_link_libraries(lokinet-rpc PUBLIC oxenmq::oxenmq)
|
||||
# target_link_libraries(lokinet-core PUBLIC oxenmq::oxenmq)
|
||||
# target_link_libraries(lokinet-config PUBLIC oxenmq::oxenmq)
|
||||
# target_link_libraries(lokinet-nodedb PUBLIC oxenmq::oxenmq)
|
||||
# target_link_libraries(lokinet-path PUBLIC oxenmq::oxenmq)
|
||||
# target_link_libraries(lokinet-platform PUBLIC oxenmq::oxenmq Threads::Threads)
|
||||
# target_link_libraries(lokinet-cryptography PUBLIC sodium)
|
||||
# target_link_libraries(lokinet-dns PUBLIC libunbound)
|
||||
# target_link_libraries(lokinet-utils PUBLIC nlohmann_json::nlohmann_json)
|
||||
# target_link_libraries(lokinet-wire PUBLIC oxenmq::oxenmq quic)
|
||||
|
||||
if(WITH_EMBEDDED_LOKINET)
|
||||
include(GNUInstallDirs)
|
||||
|
@ -44,7 +44,7 @@ namespace llarp
|
||||
_init_internals();
|
||||
}
|
||||
|
||||
IPPacket IPPacket::from_udp(UDPPacket pkt)
|
||||
IPPacket IPPacket::from_netpkt(NetworkPacket pkt)
|
||||
{
|
||||
auto data = pkt.data();
|
||||
return IPPacket{reinterpret_cast<const unsigned char*>(data.data()), data.size()};
|
||||
@ -217,6 +217,7 @@ namespace llarp
|
||||
{
|
||||
case 6: // TCP
|
||||
chksumoff = 16;
|
||||
[[fallthrough]];
|
||||
case 33: // DCCP
|
||||
chksum = tcp_checksum_ipv6(&hdr->srcaddr, &hdr->dstaddr, hdr->payload_len, 0);
|
||||
|
||||
@ -296,9 +297,9 @@ namespace llarp
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
UDPPacket IPPacket::make_udp()
|
||||
NetworkPacket IPPacket::make_netpkt()
|
||||
{
|
||||
return UDPPacket{oxen::quic::Path{_src_addr, _dst_addr}, bview()};
|
||||
return NetworkPacket{oxen::quic::Path{_src_addr, _dst_addr}, bview()};
|
||||
}
|
||||
|
||||
bool IPPacket::load(ustring_view data)
|
||||
@ -345,7 +346,7 @@ namespace llarp
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> IPPacket::steal() &&
|
||||
std::vector<uint8_t> IPPacket::steal_buffer() &&
|
||||
{
|
||||
std::vector<uint8_t> b;
|
||||
b.resize(size());
|
||||
@ -353,7 +354,14 @@ namespace llarp
|
||||
return b;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> IPPacket::give()
|
||||
std::string IPPacket::steal_payload() &&
|
||||
{
|
||||
auto ret = to_string();
|
||||
_buf.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> IPPacket::give_buffer()
|
||||
{
|
||||
std::vector<uint8_t> b;
|
||||
b.resize(size());
|
||||
|
@ -12,6 +12,24 @@ namespace llarp
|
||||
inline constexpr size_t MAX_PACKET_SIZE{1500};
|
||||
inline constexpr size_t MIN_PACKET_SIZE{20};
|
||||
|
||||
struct IPPacket;
|
||||
|
||||
// Typedef for packets being transmitted between lokinet instances
|
||||
using NetworkPacket = oxen::quic::Packet;
|
||||
|
||||
using net_pkt_hook = std::function<void(NetworkPacket&& pkt)>;
|
||||
using ip_pkt_hook = std::function<void(IPPacket)>;
|
||||
|
||||
/** IPPacket
|
||||
This class encapsulates the functionalities and attributes required for data transmission between the local
|
||||
lokinet instance and the surrounding IP landscape. As data enters lokinet from the device/internet/etc, it is
|
||||
transmitted across the network as a NetworkPacket via QUIC. As it exits lokinet to the device/internet/etc, it
|
||||
is constructed into an IPPacket.
|
||||
|
||||
This allows for necessary functionalities at the junction that data is entering and exiting the local lokinet
|
||||
instance. For example
|
||||
|
||||
*/
|
||||
struct IPPacket
|
||||
{
|
||||
private:
|
||||
@ -36,10 +54,10 @@ namespace llarp
|
||||
explicit IPPacket(std::vector<uint8_t> data);
|
||||
explicit IPPacket(const uint8_t* buf, size_t len);
|
||||
|
||||
static IPPacket from_udp(UDPPacket pkt);
|
||||
static IPPacket from_netpkt(NetworkPacket pkt);
|
||||
static std::optional<IPPacket> from_buffer(const uint8_t* buf, size_t len);
|
||||
|
||||
UDPPacket make_udp();
|
||||
NetworkPacket make_netpkt();
|
||||
|
||||
bool is_ipv4() const { return _is_v4; }
|
||||
|
||||
@ -55,9 +73,9 @@ namespace llarp
|
||||
|
||||
ipv6 source_ipv6() { return _src_addr.to_ipv6(); }
|
||||
|
||||
ipv4 dest_ipv4() { return _dst_addr.to_ipv4(); }
|
||||
ipv4 dest_ipv4() const { return _dst_addr.to_ipv4(); }
|
||||
|
||||
ipv6 dest_ipv6() { return _dst_addr.to_ipv6(); }
|
||||
ipv6 dest_ipv6() const { return _dst_addr.to_ipv6(); }
|
||||
|
||||
ip_header* header() { return _header; }
|
||||
|
||||
@ -69,6 +87,13 @@ namespace llarp
|
||||
|
||||
std::optional<std::pair<const char*, size_t>> l4_data() const;
|
||||
|
||||
void clear_addresses()
|
||||
{
|
||||
if (_is_v4)
|
||||
return update_ipv4_address(ipv4{}, ipv4{});
|
||||
return update_ipv6_address(ipv6{}, ipv6{});
|
||||
}
|
||||
|
||||
void update_ipv4_address(ipv4 src, ipv4 dst);
|
||||
|
||||
void update_ipv6_address(ipv6 src, ipv6 dst, std::optional<uint32_t> flowlabel = std::nullopt);
|
||||
@ -79,6 +104,8 @@ namespace llarp
|
||||
|
||||
const uint8_t* data() const { return _buf.data(); }
|
||||
|
||||
const uint8_t* protocol() const { return _is_v4 ? &header()->protocol : &v6_header()->protocol; }
|
||||
|
||||
size_t size() const { return _buf.size(); }
|
||||
|
||||
bool empty() const { return _buf.empty(); }
|
||||
@ -95,10 +122,12 @@ namespace llarp
|
||||
bool take(std::vector<uint8_t> data);
|
||||
|
||||
// steals posession of the underlying data, and can only be used in an r-value context
|
||||
std::vector<uint8_t> steal() &&;
|
||||
std::vector<uint8_t> steal_buffer() &&;
|
||||
|
||||
std::string steal_payload() &&;
|
||||
|
||||
// gives a copy of the underlying data
|
||||
std::vector<uint8_t> give();
|
||||
std::vector<uint8_t> give_buffer();
|
||||
|
||||
std::string_view view() const { return {reinterpret_cast<const char*>(data()), size()}; }
|
||||
|
||||
|
@ -171,7 +171,7 @@ namespace llarp
|
||||
if (range_exhausted())
|
||||
return ret;
|
||||
|
||||
if (auto b = is_ipv4() ? _increment_ipv4() : _increment_ipv6())
|
||||
if (is_ipv4() ? _increment_ipv4() : _increment_ipv6())
|
||||
ret = _current_ip;
|
||||
|
||||
return ret;
|
||||
|
@ -30,6 +30,24 @@ namespace llarp
|
||||
|
||||
inline constexpr size_t ICMP_HEADER_SIZE{8};
|
||||
|
||||
// Compares the given ip variant against a quic address
|
||||
// Returns:
|
||||
// - true : ip == address
|
||||
// - false : ip != address
|
||||
// Error:
|
||||
// - throws : ip and address are mismatched ipv4 vs ipv6
|
||||
inline bool ip_equals_address(const ip_v& ip, const oxen::quic::Address& addr, bool compare_v4)
|
||||
{
|
||||
if (compare_v4 and std::holds_alternative<ipv4>(ip))
|
||||
return std::get<ipv4>(ip) == addr.to_ipv4();
|
||||
|
||||
if (not compare_v4 and std::holds_alternative<ipv6>(ip))
|
||||
return std::get<ipv6>(ip) == addr.to_ipv6();
|
||||
|
||||
throw std::invalid_argument{
|
||||
"Failed to compare ip variant in desired {} scheme!"_format(compare_v4 ? "ipv4" : "ipv6")};
|
||||
}
|
||||
|
||||
struct ip_header_le
|
||||
{
|
||||
uint8_t header_len : 4;
|
||||
|
@ -119,10 +119,10 @@ namespace llarp
|
||||
|
||||
bool KeyManager::copy_backup_keyfile(const fs::path& filepath)
|
||||
{
|
||||
auto findFreeBackupFilename = [](const fs::path& filepath) {
|
||||
auto findFreeBackupFilename = [](const fs::path& filepath) mutable {
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
std::string ext("." + std::to_string(i) + ".bak");
|
||||
auto ext = ".{}.bak"_format(i);
|
||||
fs::path newPath = filepath;
|
||||
newPath += ext;
|
||||
|
||||
|
@ -36,14 +36,13 @@ namespace llarp::dns
|
||||
public:
|
||||
explicit UDPReader(Server& dns, const std::shared_ptr<EventLoop>& loop, oxen::quic::Address bind) : _dns{dns}
|
||||
{
|
||||
_udp = std::make_unique<UDPHandle>(loop, bind, [&](UDPPacket pkt) {
|
||||
_udp = std::make_unique<UDPHandle>(loop, bind, [&](NetworkPacket pkt) {
|
||||
auto& src = pkt.path.local;
|
||||
|
||||
if (src == _local_addr)
|
||||
return;
|
||||
(void)_dns;
|
||||
|
||||
if (not _dns.maybe_handle_packet(shared_from_this(), _local_addr, src, IPPacket::from_udp(pkt)))
|
||||
if (not _dns.maybe_handle_packet(shared_from_this(), _local_addr, src, IPPacket::from_netpkt(pkt)))
|
||||
{
|
||||
log::warning(logcat, "did not handle dns packet from {} to {}", src, _local_addr);
|
||||
}
|
||||
@ -66,7 +65,7 @@ namespace llarp::dns
|
||||
|
||||
void send_to(const oxen::quic::Address& to, const oxen::quic::Address&, IPPacket data) const override
|
||||
{
|
||||
_udp->send(to, data.give());
|
||||
_udp->send(to, data.give_buffer());
|
||||
}
|
||||
|
||||
void send_to(
|
||||
@ -157,7 +156,7 @@ namespace llarp::dns
|
||||
hdr.Encode(&buf);
|
||||
|
||||
// send reply
|
||||
query->send_reply(std::move(pkt).give());
|
||||
query->send_reply(std::move(pkt).give_buffer());
|
||||
}
|
||||
|
||||
void add_upstream_resolver(const oxen::quic::Address& dns)
|
||||
|
@ -72,10 +72,10 @@ namespace llarp::dns
|
||||
class PacketSource_Wrapper : public PacketSource_Base
|
||||
{
|
||||
std::weak_ptr<PacketSource_Base> _wrapped;
|
||||
udp_pkt_hook _write_pkt;
|
||||
ip_pkt_hook _write_pkt;
|
||||
|
||||
public:
|
||||
explicit PacketSource_Wrapper(std::weak_ptr<PacketSource_Base> wrapped, udp_pkt_hook write_packet)
|
||||
explicit PacketSource_Wrapper(std::weak_ptr<PacketSource_Base> wrapped, ip_pkt_hook write_packet)
|
||||
: _wrapped{std::move(wrapped)}, _write_pkt{std::move(write_packet)}
|
||||
{}
|
||||
|
||||
@ -93,7 +93,7 @@ namespace llarp::dns
|
||||
(void)to;
|
||||
(void)from;
|
||||
(void)data;
|
||||
_write_pkt(data.make_udp());
|
||||
_write_pkt(data);
|
||||
}
|
||||
|
||||
void send_to(
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
#include <llarp/address/ip_packet.hpp>
|
||||
#include <llarp/net/interface_info.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
@ -17,6 +16,11 @@ namespace llarp
|
||||
class NetworkInterface;
|
||||
} // namespace vpn
|
||||
|
||||
using event_ptr = oxen::quic::event_ptr;
|
||||
|
||||
// shared_ptr containing the actual libev loop
|
||||
using loop_ptr = std::shared_ptr<::event_base>;
|
||||
|
||||
struct EventHandler
|
||||
{
|
||||
event_ptr ev;
|
||||
|
@ -61,6 +61,7 @@ namespace llarp
|
||||
|
||||
auto *conn = reinterpret_cast<TCPConnection *>(user_arg);
|
||||
assert(conn);
|
||||
(void)conn;
|
||||
|
||||
// conn->stream->close();
|
||||
}
|
||||
@ -92,6 +93,7 @@ namespace llarp
|
||||
|
||||
auto *handle = reinterpret_cast<TCPHandle *>(user_arg);
|
||||
assert(handle);
|
||||
(void)handle;
|
||||
|
||||
// DISCUSS: close everything here?
|
||||
};
|
||||
|
@ -6,23 +6,5 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct IPPacket;
|
||||
|
||||
using UDPPacket = oxen::quic::Packet;
|
||||
|
||||
using udp_pkt_hook = std::function<void(UDPPacket&& pkt)>;
|
||||
using ip_pkt_hook = std::function<void(IPPacket)>;
|
||||
|
||||
using UDPSocket = oxen::quic::UDPSocket;
|
||||
|
||||
using io_result = oxen::quic::io_result;
|
||||
|
||||
using event_ptr = oxen::quic::event_ptr;
|
||||
|
||||
// shared_ptr containing the actual libev loop
|
||||
using loop_ptr = std::shared_ptr<::event_base>;
|
||||
|
||||
// Libevent callbacks
|
||||
using event_hook = std::function<void()>;
|
||||
|
||||
//
|
||||
} // namespace llarp
|
||||
|
@ -11,7 +11,7 @@ namespace llarp
|
||||
1;
|
||||
#endif
|
||||
|
||||
UDPHandle::UDPHandle(const std::shared_ptr<EventLoop>& ev, const oxen::quic::Address& bind, udp_pkt_hook cb)
|
||||
UDPHandle::UDPHandle(const std::shared_ptr<EventLoop>& ev, const oxen::quic::Address& bind, net_pkt_hook cb)
|
||||
: _loop{ev}
|
||||
{
|
||||
socket = std::make_unique<UDPSocket>(ev->loop().get(), bind, std::move(cb));
|
||||
|
@ -5,15 +5,21 @@
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
#include <oxen/quic.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
class EventLoop;
|
||||
|
||||
using UDPSocket = oxen::quic::UDPSocket;
|
||||
|
||||
using io_result = oxen::quic::io_result;
|
||||
|
||||
class UDPHandle
|
||||
{
|
||||
public:
|
||||
UDPHandle() = delete;
|
||||
explicit UDPHandle(const std::shared_ptr<EventLoop>& ev, const oxen::quic::Address& bind, udp_pkt_hook cb);
|
||||
explicit UDPHandle(const std::shared_ptr<EventLoop>& ev, const oxen::quic::Address& bind, net_pkt_hook cb);
|
||||
~UDPHandle();
|
||||
|
||||
private:
|
||||
@ -37,8 +43,6 @@ namespace llarp
|
||||
io_result send(const oxen::quic::Address& dest, std::vector<uint8_t> data);
|
||||
|
||||
oxen::quic::Address bind() { return _local; }
|
||||
|
||||
// void close();
|
||||
};
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -43,13 +43,12 @@ namespace llarp::handlers
|
||||
/// (windows/macos/ios/android ... aka everything that is not linux... funny that)
|
||||
class DnsInterceptor : public dns::PacketSource_Base
|
||||
{
|
||||
// TODO: refactor this with deprecating IP_packet_deprecated
|
||||
udp_pkt_hook _hook;
|
||||
ip_pkt_hook _hook;
|
||||
oxen::quic::Address _our_ip; // maybe should be an IP type...?
|
||||
llarp::DnsConfig _config;
|
||||
|
||||
public:
|
||||
explicit DnsInterceptor(udp_pkt_hook reply, oxen::quic::Address our_ip, llarp::DnsConfig conf)
|
||||
explicit DnsInterceptor(ip_pkt_hook reply, oxen::quic::Address our_ip, llarp::DnsConfig conf)
|
||||
: _hook{std::move(reply)}, _our_ip{std::move(our_ip)}, _config{std::move(conf)}
|
||||
{}
|
||||
|
||||
@ -104,17 +103,21 @@ namespace llarp::handlers
|
||||
~TunDNS() override = default;
|
||||
|
||||
explicit TunDNS(TunEndpoint* ep, const llarp::DnsConfig& conf)
|
||||
: dns::Server{ep->router().loop(), conf, 0}, _tun{ep}, _query_bind{conf._query_bind}
|
||||
// TOFIX:
|
||||
// _our_ip{ep->get_if_addr(), _query_bind ? _query_bind->port() : 0}
|
||||
{}
|
||||
: dns::Server{ep->router().loop(), conf, 0},
|
||||
_tun{ep},
|
||||
_query_bind{conf._query_bind},
|
||||
_our_ip{ep->get_if_addr()}
|
||||
{
|
||||
if (_query_bind)
|
||||
_our_ip.set_port(_query_bind->port());
|
||||
}
|
||||
|
||||
std::shared_ptr<dns::PacketSource_Base> make_packet_source_on(
|
||||
const oxen::quic::Address&, const llarp::DnsConfig& conf) override
|
||||
{
|
||||
(void)_tun;
|
||||
auto ptr = std::make_shared<DnsInterceptor>(
|
||||
[](UDPPacket pkt) {
|
||||
[](IPPacket pkt) {
|
||||
(void)pkt;
|
||||
// ep->handle_write_ip_packet(pkt.ConstBuffer(), pkt.srcv6(), pkt.dstv6(), 0);
|
||||
},
|
||||
@ -144,7 +147,7 @@ namespace llarp::handlers
|
||||
}
|
||||
|
||||
_packet_router =
|
||||
std::make_shared<vpn::PacketRouter>([this](IPPacket pkt) { handle_user_packet(std::move(pkt)); });
|
||||
std::make_shared<vpn::PacketRouter>([this](IPPacket pkt) { handle_outbound_packet(std::move(pkt)); });
|
||||
}
|
||||
|
||||
void TunEndpoint::setup_dns()
|
||||
@ -159,16 +162,16 @@ namespace llarp::handlers
|
||||
auto dns = std::make_shared<TunDNS>(this, dns_config);
|
||||
_dns = dns;
|
||||
|
||||
_packet_router->add_udp_handler(uint16_t{53}, [this, dns](UDPPacket pkt) {
|
||||
_packet_router->add_udp_handler(uint16_t{53}, [this, dns](NetworkPacket pkt) {
|
||||
auto dns_pkt_src = dns->pkt_source;
|
||||
|
||||
auto& pkt_path = pkt.path;
|
||||
|
||||
if (dns->maybe_handle_packet(
|
||||
std::move(dns_pkt_src), pkt_path.remote, pkt_path.local, IPPacket::from_udp(pkt)))
|
||||
std::move(dns_pkt_src), pkt_path.remote, pkt_path.local, IPPacket::from_netpkt(pkt)))
|
||||
return;
|
||||
|
||||
handle_user_packet(IPPacket::from_udp(pkt));
|
||||
handle_outbound_packet(IPPacket::from_netpkt(pkt));
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -207,6 +210,8 @@ namespace llarp::handlers
|
||||
// });
|
||||
// m_RawDNS = dns_io;
|
||||
}
|
||||
|
||||
(void)vpn;
|
||||
}
|
||||
|
||||
if (_raw_DNS)
|
||||
@ -830,11 +835,7 @@ namespace llarp::handlers
|
||||
|
||||
std::string TunEndpoint::get_if_name() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return net::TruncateV6(GetIfAddr()).to_string();
|
||||
#else
|
||||
return _if_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool TunEndpoint::is_service_node() const
|
||||
@ -883,17 +884,6 @@ namespace llarp::handlers
|
||||
return true;
|
||||
}
|
||||
|
||||
void TunEndpoint::handle_outbound_packet(bstring data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
bool TunEndpoint::handle_inbound_packet(IPPacket pkt)
|
||||
{
|
||||
(void)pkt;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<ip_v> TunEndpoint::get_next_local_ip()
|
||||
{
|
||||
// if our IP range is exhausted, we loop back around to see if any have been unmapped from terminated sessions;
|
||||
@ -975,326 +965,177 @@ namespace llarp::handlers
|
||||
}
|
||||
}
|
||||
|
||||
// std::optional<service::Address> TunEndpoint::get_exit_address_for_ip(
|
||||
// huint128_t ip, std::function<service::Address(std::unordered_set<service::Address>)> exitSelectionStrat)
|
||||
// {
|
||||
// // is it already mapped? return the mapping
|
||||
// if (auto itr = _exit_to_ip.find(ip); itr != _exit_to_ip.end())
|
||||
// return itr->second;
|
||||
|
||||
// const auto& net = router().net();
|
||||
// const bool is_bogon = net.IsBogonIP(ip);
|
||||
// build up our candidates to choose
|
||||
|
||||
// std::unordered_set<service::Address> candidates;
|
||||
// for (const auto& entry : _exit_map.FindAllEntries(ip))
|
||||
// {
|
||||
// // in the event the exit's range is a bogon range, make sure the ip is located in that
|
||||
// range
|
||||
// // to allow it
|
||||
// if ((is_bogon and net.IsBogonRange(entry.first) and entry.first.Contains(ip))
|
||||
// or entry.first.Contains(ip))
|
||||
// candidates.emplace(entry.second);
|
||||
// }
|
||||
// // no candidates? bail.
|
||||
// if (candidates.empty())
|
||||
// return std::nullopt;
|
||||
// if (not exitSelectionStrat)
|
||||
// {
|
||||
// // default strat to random choice
|
||||
// exitSelectionStrat = [](auto candidates) {
|
||||
// auto itr = candidates.begin();
|
||||
// std::advance(itr, llarp::randint() % candidates.size());
|
||||
// return *itr;
|
||||
// };
|
||||
// }
|
||||
// // map the exit and return the endpoint we mapped it to
|
||||
// return _exit_to_ip.emplace(ip, exitSelectionStrat(candidates)).first->second;
|
||||
// }
|
||||
|
||||
void TunEndpoint::handle_user_packet(IPPacket pkt)
|
||||
void TunEndpoint::handle_outbound_packet(IPPacket pkt)
|
||||
{
|
||||
(void)pkt;
|
||||
// huint128_t dst, src;
|
||||
// if (pkt.IsV4())
|
||||
// {
|
||||
// dst = pkt.dst4to6();
|
||||
// src = pkt.src4to6();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dst = pkt.dstv6();
|
||||
// src = pkt.srcv6();
|
||||
// }
|
||||
ip_v src, dest;
|
||||
|
||||
// if constexpr (llarp::platform::is_apple)
|
||||
// {
|
||||
// if (dst == _local_ip)
|
||||
// {
|
||||
// handle_write_ip_packet(pkt.ConstBuffer(), src, dst, 0);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
auto pkt_is_ipv4 = pkt.is_ipv4();
|
||||
|
||||
// // if (_state->is_exit_enabled)
|
||||
// // {
|
||||
// // dst = net::ExpandV4(net::TruncateV6(dst));
|
||||
// // }
|
||||
if (pkt_is_ipv4)
|
||||
{
|
||||
src = pkt.source_ipv4();
|
||||
dest = pkt.dest_ipv4();
|
||||
}
|
||||
else
|
||||
{
|
||||
src = pkt.source_ipv6();
|
||||
dest = pkt.dest_ipv6();
|
||||
}
|
||||
|
||||
// auto itr = _ip_to_addr.find(dst);
|
||||
if constexpr (llarp::platform::is_apple)
|
||||
{
|
||||
if (ip_equals_address(dest, _local_addr, pkt_is_ipv4))
|
||||
{
|
||||
rewrite_and_send_packet(std::move(pkt), src, dest);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if (itr == _ip_to_addr.end())
|
||||
// {
|
||||
// service::Address addr{};
|
||||
// we pass `dest` because that is our local private IP on the outgoing IPPacket
|
||||
if (auto maybe_remote = _local_ip_mapping.get_remote_from_local(dest))
|
||||
{
|
||||
auto& remote = *maybe_remote;
|
||||
pkt.clear_addresses();
|
||||
|
||||
// if (auto maybe = get_exit_address_for_ip(dst))
|
||||
// addr = *maybe;
|
||||
// else
|
||||
// {
|
||||
// // send icmp unreachable as we dont have any exits for this ip
|
||||
// if (const auto icmp = pkt.MakeICMPUnreachable())
|
||||
// handle_write_ip_packet(icmp->ConstBuffer(), dst, src, 0);
|
||||
|
||||
// return;
|
||||
// }
|
||||
|
||||
// std::function<void(void)> extra_cb;
|
||||
|
||||
// // if (not HasFlowToService(addr))
|
||||
// // {
|
||||
// // extra_cb = [poker = router().route_poker()]() { poker->put_up(); };
|
||||
// // }
|
||||
|
||||
// // pkt.ZeroSourceAddress();
|
||||
// // MarkAddressOutbound(addr);
|
||||
|
||||
// // EnsurePathToService(
|
||||
// // addr,
|
||||
// // [pkt, extra_cb, this](service::Address addr, service::OutboundContext* ctx)
|
||||
// // mutable {
|
||||
// // if (ctx)
|
||||
// // {
|
||||
// // if (extra_cb)
|
||||
// // extra_cb();
|
||||
// // ctx->send_packet_to_remote(pkt.to_string());
|
||||
// // router().TriggerPump();
|
||||
// // return;
|
||||
// // }
|
||||
// // log::warning(logcat, "cannot ensure path to exit {}; so we drop some packets", addr);
|
||||
// // },
|
||||
// // PathAlignmentTimeout());
|
||||
// return;
|
||||
// }
|
||||
// std::variant<service::Address, RouterID> to;
|
||||
// service::ProtocolType type{};
|
||||
// // if (m_SNodes.at(itr->second))
|
||||
// // {
|
||||
// // to = RouterID{itr->second.as_array()};
|
||||
// // type = service::ProtocolType::TrafficV4;
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // to = service::Address{itr->second.as_array()};
|
||||
// // type = _state->is_exit_enabled and src != m_OurIP ? service::ProtocolType::Exit
|
||||
// // : pkt.ServiceProtocol();
|
||||
// // }
|
||||
|
||||
// // prepare packet for insertion into network
|
||||
// // this includes clearing IP addresses, recalculating checksums, etc
|
||||
// // this does not happen for exits because the point is they don't rewrite addresses
|
||||
// // TODO: can we fix this shit
|
||||
// // - clear addresses if it is our local TUN address, invariant of protocoltype
|
||||
// if (type != service::ProtocolType::Exit)
|
||||
// {
|
||||
// if (pkt.IsV4())
|
||||
// pkt.UpdateIPv4Address({0}, {0});
|
||||
// else
|
||||
// pkt.UpdateIPv6Address({0}, {0});
|
||||
// }
|
||||
// // try sending it on an existing convotag
|
||||
// // this succeds for inbound convos, probably.
|
||||
// // if (auto maybe = GetBestConvoTagFor(to))
|
||||
// // {
|
||||
// // if (send_to(*maybe, pkt.to_string()))
|
||||
// // {
|
||||
// // MarkIPActive(dst);
|
||||
// // router().TriggerPump();
|
||||
// // return;
|
||||
// // }
|
||||
// // }
|
||||
// // // try establishing a path to this guy
|
||||
// // // will fail if it's an inbound convo
|
||||
// // EnsurePathTo(
|
||||
// // to,
|
||||
// // [pkt, dst, to, this](auto maybe) mutable {
|
||||
// // if (not maybe)
|
||||
// // {
|
||||
// // var::visit(
|
||||
// // [this](auto&& addr) {
|
||||
// // Log Warn(name(), " failed to ensure path to ", addr, " no convo tag found");
|
||||
// // },
|
||||
// // to);
|
||||
// // }
|
||||
// // if (send_to(*maybe, pkt.to_string()))
|
||||
// // {
|
||||
// // MarkIPActive(dst);
|
||||
// // router().TriggerPump();
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // var::visit(
|
||||
// // [this](auto&& addr) {
|
||||
// // Log Warn(name(), " failed to send to ", addr, ", SendToOrQueue failed");
|
||||
// // },
|
||||
// // to);
|
||||
// // }
|
||||
// // },
|
||||
// // PathAlignmentTimeout());
|
||||
if (auto session = _router.session_endpoint()->get_session(remote))
|
||||
{
|
||||
log::info(logcat, "Dispatching outbound packet for session (remote: {})", remote);
|
||||
session->send_path_data_message(std::move(pkt).steal_payload());
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error{"Could not find session (remote: {}) for outbound packet!"_format(remote)};
|
||||
}
|
||||
throw std::runtime_error{"Could not find remote mapped to local ip: {}"_format(dest)};
|
||||
}
|
||||
|
||||
bool TunEndpoint::is_allowing_traffic(const IPPacket& pkt) const
|
||||
bool TunEndpoint::obtain_src_for_remote(const NetworkAddress& remote, ip_v& src, bool use_ipv4)
|
||||
{
|
||||
// if (auto exitPolicy = get_traffic_policy())
|
||||
// return exitPolicy->allow_ip_traffic(pkt);
|
||||
|
||||
(void)pkt;
|
||||
// we are receiving traffic from a session to a local exit node
|
||||
if (auto maybe_src = _local_ip_mapping.get_local_from_remote(remote))
|
||||
{
|
||||
if (std::holds_alternative<ipv4>(*maybe_src))
|
||||
{
|
||||
if (use_ipv4)
|
||||
src = *maybe_src;
|
||||
else
|
||||
{
|
||||
auto quicaddr = oxen::quic::Address{std::get<ipv4>(*maybe_src)};
|
||||
src = quicaddr.to_ipv6();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (use_ipv4)
|
||||
{
|
||||
auto quicaddr = oxen::quic::Address{std::get<ipv6>(*maybe_src)};
|
||||
src = quicaddr.to_ipv4();
|
||||
}
|
||||
else
|
||||
src = *maybe_src;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log::critical(logcat, "Unable to find local IP for inbound packet from remote: {}", remote);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// bool TunEndpoint::handle_inbound_packet(
|
||||
// const service::SessionTag tag, const llarp_buffer_t& buf, service::ProtocolType t, uint64_t seqno)
|
||||
// {
|
||||
// log::trace(logcat, "Inbound packet on session:{}", tag);
|
||||
|
||||
// // if (t == service::ProtocolType::QUIC)
|
||||
// // {
|
||||
// // auto* quic = GetQUICTunnel();
|
||||
// // if (!quic)
|
||||
// // {
|
||||
// // Log Warn("incoming quic packet but this endpoint is not quic capable; dropping");
|
||||
// // return false;
|
||||
// // }
|
||||
// // if (buf.sz < 4)
|
||||
// // {
|
||||
// // Log Warn("invalid incoming quic packet, dropping");
|
||||
// // return false;
|
||||
// // }
|
||||
// // log::info(logcat, "tag active T={}", tag);
|
||||
|
||||
// // // TODO:
|
||||
// // // quic->receive_packet(tag, buf);
|
||||
// // return true;
|
||||
// // }
|
||||
|
||||
// if (t != service::ProtocolType::TrafficV4 && t != service::ProtocolType::TrafficV6
|
||||
// && t != service::ProtocolType::Exit)
|
||||
// return false;
|
||||
// // std::variant<service::Address, RouterID> addr;
|
||||
// // if (auto maybe = GetEndpointWithConvoTag(tag))
|
||||
// // {
|
||||
// // addr = *maybe;
|
||||
// // }
|
||||
// // else
|
||||
// // return false;
|
||||
// huint128_t src, dst;
|
||||
|
||||
// IPPacket pkt;
|
||||
// if (not pkt.load(buf.base))
|
||||
// return false;
|
||||
|
||||
// // if (_state->is_exit_enabled)
|
||||
// // {
|
||||
// // // exit side from exit
|
||||
|
||||
// // // check packet against exit policy and if as needed
|
||||
// // if (not ShouldAllowTraffic(pkt))
|
||||
// // return false;
|
||||
|
||||
// // src = ObtainIPForAddr(addr);
|
||||
// // if (t == service::ProtocolType::Exit)
|
||||
// // {
|
||||
// // if (pkt.IsV4())
|
||||
// // dst = pkt.dst4to6();
|
||||
// // else if (pkt.IsV6())
|
||||
// // {
|
||||
// // dst = pkt.dstv6();
|
||||
// // src = net::ExpandV4Lan(net::TruncateV6(src));
|
||||
// // }
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // // non exit traffic on exit
|
||||
// // dst = m_OurIP;
|
||||
// // }
|
||||
// // }
|
||||
// // else if (t == service::ProtocolType::Exit)
|
||||
// // {
|
||||
// // // client side exit traffic from exit
|
||||
// // if (pkt.IsV4())
|
||||
// // {
|
||||
// // dst = m_OurIP;
|
||||
// // src = pkt.src4to6();
|
||||
// // }
|
||||
// // else if (pkt.IsV6())
|
||||
// // {
|
||||
// // dst = m_OurIPv6;
|
||||
// // src = pkt.srcv6();
|
||||
// // }
|
||||
// // // find what exit we think this should be for
|
||||
// // service::Address fromAddr{};
|
||||
// // if (const auto* ptr = std::get_if<service::Address>(&addr))
|
||||
// // {
|
||||
// // fromAddr = *ptr;
|
||||
// // }
|
||||
// // else // don't allow snode
|
||||
// // return false;
|
||||
// // // make sure the mapping matches
|
||||
// // if (auto itr = m_ExitIPToExitAddress.find(src); itr != m_ExitIPToExitAddress.end())
|
||||
// // {
|
||||
// // if (itr->second != fromAddr)
|
||||
// // return false;
|
||||
// // }
|
||||
// // else
|
||||
// // return false;
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // // snapp traffic
|
||||
// // src = ObtainIPForAddr(addr);
|
||||
// // dst = m_OurIP;
|
||||
// // }
|
||||
// handle_write_ip_packet(buf, src, dst, seqno);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
bool TunEndpoint::handle_write_ip_packet(const llarp_buffer_t& b, huint128_t src, huint128_t dst, uint64_t seqno)
|
||||
void TunEndpoint::send_packet_to_net_if(IPPacket&& pkt)
|
||||
{
|
||||
ManagedBuffer buf(b);
|
||||
IPPacket pkt;
|
||||
_router.loop()->call([this, pkt = std::move(pkt)]() { _net_if->WritePacket(std::move(pkt)); });
|
||||
}
|
||||
|
||||
// load
|
||||
if (!pkt.load(buf.underlying.base))
|
||||
void TunEndpoint::rewrite_and_send_packet(IPPacket&& pkt, ip_v src, ip_v dest)
|
||||
{
|
||||
if (pkt.is_ipv4())
|
||||
pkt.update_ipv4_address(std::get<ipv4>(src), std::get<ipv4>(dest));
|
||||
else
|
||||
pkt.update_ipv6_address(std::get<ipv6>(src), std::get<ipv6>(dest));
|
||||
|
||||
send_packet_to_net_if(std::move(pkt));
|
||||
}
|
||||
|
||||
bool TunEndpoint::handle_inbound_packet(
|
||||
IPPacket pkt, NetworkAddress remote, bool is_exit_session, bool is_outbound_session)
|
||||
{
|
||||
ip_v src, dest;
|
||||
|
||||
auto pkt_is_ipv4 = pkt.is_ipv4();
|
||||
|
||||
if (is_exit_session and is_outbound_session)
|
||||
{
|
||||
return false;
|
||||
// we are receiving traffic from a session to a remote exit node
|
||||
if (pkt_is_ipv4)
|
||||
{
|
||||
src = pkt.source_ipv4();
|
||||
dest = _local_addr.to_ipv4();
|
||||
}
|
||||
else
|
||||
{
|
||||
src = pkt.source_ipv6();
|
||||
dest = _local_ipv6.to_ipv6();
|
||||
}
|
||||
|
||||
assert(remote.is_client());
|
||||
|
||||
auto maybe_remote = _local_ip_mapping.get_remote_from_local(src);
|
||||
|
||||
if (not maybe_remote)
|
||||
{
|
||||
log::critical(
|
||||
logcat, "Could not find mapping of local IP (ip:{}) for session to remote: {}", src, remote);
|
||||
return false;
|
||||
}
|
||||
if (*maybe_remote != remote)
|
||||
{
|
||||
log::critical(
|
||||
logcat,
|
||||
"Internal mapping of local IP (ip:{}, remote:{}) did not match inbound packet from remote: {}",
|
||||
src,
|
||||
*maybe_remote,
|
||||
remote);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if (pkt.IsV4())
|
||||
// {
|
||||
// pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(src)), xhtonl(net::TruncateV6(dst)));
|
||||
// }
|
||||
// else if (pkt.IsV6())
|
||||
// {
|
||||
// pkt.UpdateIPv6Address(src, dst);
|
||||
// }
|
||||
(void)src;
|
||||
(void)dst;
|
||||
(void)seqno;
|
||||
else
|
||||
{
|
||||
if (is_exit_session and not is_outbound_session)
|
||||
{
|
||||
// we are receiving traffic from a session to a local exit node
|
||||
if (not is_allowing_traffic(pkt))
|
||||
return false;
|
||||
|
||||
// TODO: send this along but without a fucking huint182_t
|
||||
// m_NetworkToUserPktQueue.push(std::move(write));
|
||||
if (pkt_is_ipv4)
|
||||
dest = pkt.dest_ipv4();
|
||||
else
|
||||
dest = pkt.dest_ipv6();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are receiving hidden service traffic
|
||||
if (pkt_is_ipv4)
|
||||
dest = _local_addr.to_ipv4();
|
||||
else
|
||||
dest = _local_ipv6.to_ipv6();
|
||||
}
|
||||
|
||||
if (not obtain_src_for_remote(remote, src, pkt_is_ipv4))
|
||||
return false;
|
||||
}
|
||||
|
||||
rewrite_and_send_packet(std::move(pkt), src, dest);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TunEndpoint::is_allowing_traffic(const IPPacket& pkt) const
|
||||
{
|
||||
if (auto exitPolicy = get_traffic_policy())
|
||||
return exitPolicy->allow_ip_traffic(pkt);
|
||||
|
||||
// wake up so we ensure that all packets are written to user
|
||||
// router().TriggerPump();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -70,30 +70,22 @@ namespace llarp::handlers
|
||||
// };
|
||||
|
||||
// INPROGRESS: new API
|
||||
// Handles a packet going out of the network through the TUN device
|
||||
void handle_outbound_packet(bstring data);
|
||||
// Handle a packet coming into the network through the TUN device
|
||||
bool handle_inbound_packet(IPPacket pkt);
|
||||
// Handles an outbound packet going out INTO the network
|
||||
void handle_outbound_packet(IPPacket pkt);
|
||||
|
||||
void rewrite_and_send_packet(IPPacket&& pkt, ip_v src, ip_v dest);
|
||||
|
||||
// Handle an inbound packet coming in FROM the network
|
||||
bool handle_inbound_packet(IPPacket pkt, NetworkAddress remote, bool is_exit_session, bool is_outbound_session);
|
||||
|
||||
// TODO: think of a better name
|
||||
// Upon session creation, SessionHandler will instruct TunEndpoint to requisition a private IP through which to
|
||||
// route session traffic
|
||||
std::optional<ip_v> map_session_to_local_ip(const NetworkAddress& remote);
|
||||
|
||||
void unmap_session_to_local_ip(const NetworkAddress& remote);
|
||||
|
||||
// TONUKE: this old bullshit
|
||||
// bool handle_inbound_packet(
|
||||
// const service::SessionTag tag, const llarp_buffer_t& pkt, service::ProtocolType t, uint64_t seqno);
|
||||
/// handle inbound traffic
|
||||
bool handle_write_ip_packet(const llarp_buffer_t& buf, huint128_t src, huint128_t dst, uint64_t seqno);
|
||||
/// we got a packet from the user
|
||||
void handle_user_packet(llarp::IPPacket pkt);
|
||||
|
||||
/// get the local interface's address
|
||||
oxen::quic::Address get_if_addr() const;
|
||||
|
||||
/// we have an interface addr
|
||||
bool has_if_addr() const { return true; }
|
||||
|
||||
std::optional<net::TrafficPolicy> get_traffic_policy() const { return _traffic_policy; }
|
||||
@ -130,6 +122,10 @@ namespace llarp::handlers
|
||||
private:
|
||||
std::optional<ip_v> get_next_local_ip();
|
||||
|
||||
bool obtain_src_for_remote(const NetworkAddress& remote, ip_v& src, bool use_ipv4);
|
||||
|
||||
void send_packet_to_net_if(IPPacket&& pkt);
|
||||
|
||||
template <typename Addr_t, typename Endpoint_t>
|
||||
void send_dns_reply(
|
||||
Addr_t addr,
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <llarp/util/priority_queue.hpp>
|
||||
|
||||
#include <oxen/quic.hpp>
|
||||
#include <oxen/quic/format.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <set>
|
||||
|
@ -62,24 +62,12 @@ namespace llarp::net
|
||||
port = std::nullopt;
|
||||
}
|
||||
|
||||
// DISCUSS: wtf is this
|
||||
bool ProtocolInfo::matches_packet_proto(const IPPacket&) const
|
||||
bool ProtocolInfo::matches_packet_proto(const IPPacket& pkt) const
|
||||
{
|
||||
// if (pkt.Header()->protocol != static_cast<std::underlying_type_t<IPProtocol>>(protocol))
|
||||
// return false;
|
||||
|
||||
if (not port)
|
||||
return true;
|
||||
|
||||
// if (const auto maybe = pkt.DstPort())
|
||||
// {
|
||||
// return *port == *maybe;
|
||||
// }
|
||||
// we can't tell what the port is but the protocol matches and that's good enough
|
||||
return true;
|
||||
return pkt.header()->protocol == static_cast<std::underlying_type_t<IPProtocol>>(protocol);
|
||||
}
|
||||
|
||||
bool TrafficPolicy::allow_ip_traffic(IPPacket& pkt) const
|
||||
bool TrafficPolicy::allow_ip_traffic(const IPPacket& pkt)
|
||||
{
|
||||
if (protocols.empty() and ranges.empty())
|
||||
return true;
|
||||
|
@ -75,6 +75,6 @@ namespace llarp::net
|
||||
|
||||
/// returns true if we allow the traffic in this ip packet
|
||||
/// returns false otherwise
|
||||
bool allow_ip_traffic(IPPacket& pkt) const;
|
||||
bool allow_ip_traffic(const IPPacket& pkt);
|
||||
};
|
||||
} // namespace llarp::net
|
||||
|
@ -20,13 +20,15 @@ namespace llarp::session
|
||||
NetworkAddress remote,
|
||||
service::SessionTag _t,
|
||||
bool use_tun,
|
||||
bool is_exit,
|
||||
bool is_outbound)
|
||||
: _r{r},
|
||||
_parent{parent},
|
||||
_tag{std::move(_t)},
|
||||
_remote{std::move(remote)},
|
||||
_use_tun{use_tun},
|
||||
_is_outbound{is_outbound}
|
||||
_is_outbound{is_outbound},
|
||||
_is_exit_session{is_exit}
|
||||
{
|
||||
set_new_current_path(std::move(_p));
|
||||
}
|
||||
@ -57,11 +59,13 @@ namespace llarp::session
|
||||
_current_hop_id = _current_path->intro.pivot_hop_id;
|
||||
|
||||
if (_use_tun)
|
||||
_current_path->link_session(
|
||||
[this](bstring data) { _r.tun_endpoint()->handle_outbound_packet(std::move(data)); });
|
||||
_current_path->link_session([this](bstring data) {
|
||||
_r.tun_endpoint()->handle_inbound_packet(
|
||||
IPPacket{std::move(data)}, _remote, _is_exit_session, _is_outbound);
|
||||
});
|
||||
else
|
||||
_current_path->link_session([this](bstring data) {
|
||||
_ep->manually_receive_packet(UDPPacket{oxen::quic::Path{}, std::move(data)});
|
||||
_ep->manually_receive_packet(NetworkPacket{oxen::quic::Path{}, std::move(data)});
|
||||
});
|
||||
|
||||
assert(_current_path->is_linked());
|
||||
@ -153,18 +157,25 @@ namespace llarp::session
|
||||
service::SessionTag _t,
|
||||
bool is_exit)
|
||||
: PathHandler{parent._router, path::DEFAULT_PATHS_HELD},
|
||||
BaseSession{_router, std::move(path), parent, std::move(remote), std::move(_t), _router.using_tun_if(), true},
|
||||
BaseSession{
|
||||
_router,
|
||||
std::move(path),
|
||||
parent,
|
||||
std::move(remote),
|
||||
std::move(_t),
|
||||
_router.using_tun_if(),
|
||||
is_exit,
|
||||
true},
|
||||
_last_use{_router.now()},
|
||||
_is_exit_service{is_exit},
|
||||
_is_snode_service{not _remote.is_client()}
|
||||
_is_snode_session{not _remote.is_client()}
|
||||
{
|
||||
// These can both be false but CANNOT both be true
|
||||
if (_is_exit_service and _is_snode_service)
|
||||
if (_is_exit_session and _is_snode_session)
|
||||
throw std::runtime_error{"Cannot create OutboundSession for a remote exit and remote service!"};
|
||||
|
||||
add_path(_current_path);
|
||||
|
||||
if (_is_snode_service)
|
||||
if (_is_snode_session)
|
||||
_session_key = _router.identity();
|
||||
else
|
||||
crypto::identity_keygen(_session_key);
|
||||
@ -312,8 +323,15 @@ namespace llarp::session
|
||||
handlers::SessionEndpoint& parent,
|
||||
service::SessionTag _t,
|
||||
bool use_tun)
|
||||
: BaseSession{parent._router, std::move(_path), parent, std::move(remote), std::move(_t), use_tun, false},
|
||||
_is_exit_node{_parent.is_exit_node()}
|
||||
: BaseSession{
|
||||
parent._router,
|
||||
std::move(_path),
|
||||
parent,
|
||||
std::move(remote),
|
||||
std::move(_t),
|
||||
use_tun,
|
||||
parent.is_exit_node(),
|
||||
false}
|
||||
{
|
||||
if (not _current_path->is_client_path() and _remote.is_client())
|
||||
throw std::runtime_error{
|
||||
|
@ -51,6 +51,8 @@ namespace llarp
|
||||
bool _use_tun;
|
||||
bool _is_outbound;
|
||||
|
||||
const bool _is_exit_session{false};
|
||||
|
||||
std::shared_ptr<path::Path> _current_path;
|
||||
HopID _current_hop_id;
|
||||
|
||||
@ -76,6 +78,7 @@ namespace llarp
|
||||
NetworkAddress remote,
|
||||
service::SessionTag _t,
|
||||
bool use_tun,
|
||||
bool is_exit,
|
||||
bool is_outbound);
|
||||
|
||||
bool is_outbound() const { return _is_outbound; }
|
||||
@ -102,6 +105,8 @@ namespace llarp
|
||||
service::SessionTag tag() { return _tag; }
|
||||
|
||||
const service::SessionTag& tag() const { return _tag; }
|
||||
|
||||
bool is_exit_session() const { return _is_exit_session; }
|
||||
};
|
||||
|
||||
struct OutboundSession final : public llarp::path::PathHandler,
|
||||
@ -123,8 +128,7 @@ namespace llarp
|
||||
|
||||
std::chrono::milliseconds _last_use;
|
||||
|
||||
const bool _is_exit_service{false};
|
||||
const bool _is_snode_service{false};
|
||||
const bool _is_snode_session{false};
|
||||
|
||||
public:
|
||||
std::shared_ptr<path::PathHandler> get_self() override { return shared_from_this(); }
|
||||
@ -186,9 +190,6 @@ namespace llarp
|
||||
~InboundSession() = default;
|
||||
|
||||
void set_new_tag(const service::SessionTag& tag);
|
||||
|
||||
private:
|
||||
const bool _is_exit_node{false}; // TODO: remember why I added this here...
|
||||
};
|
||||
|
||||
template <typename session_t>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@ -22,19 +23,47 @@ namespace llarp
|
||||
using bstring = std::basic_string<std::byte>;
|
||||
using bstring_view = std::basic_string_view<std::byte>;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <size_t N>
|
||||
struct bsv_literal
|
||||
{
|
||||
consteval bsv_literal(const char (&s)[N])
|
||||
{
|
||||
for (size_t i = 0; i < N; i++)
|
||||
str[i] = static_cast<std::byte>(s[i]);
|
||||
}
|
||||
std::byte str[N]; // we keep the null on the end, in case you pass .data() to a C func
|
||||
using size = std::integral_constant<size_t, N - 1>;
|
||||
};
|
||||
template <size_t N>
|
||||
struct usv_literal
|
||||
{
|
||||
consteval usv_literal(const char (&s)[N])
|
||||
{
|
||||
for (size_t i = 0; i < N; i++)
|
||||
str[i] = static_cast<unsigned char>(s[i]);
|
||||
}
|
||||
unsigned char str[N]; // we keep the null on the end, in case you pass .data() to a C func
|
||||
using size = std::integral_constant<size_t, N - 1>;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
inline ustring operator""_us(const char* str, size_t len) noexcept
|
||||
{
|
||||
return {reinterpret_cast<const unsigned char*>(str), len};
|
||||
}
|
||||
|
||||
inline ustring_view operator""_usv(const char* str, size_t len) noexcept
|
||||
template <detail::usv_literal UStr>
|
||||
constexpr ustring_view operator""_usv() noexcept
|
||||
{
|
||||
return {reinterpret_cast<const unsigned char*>(str), len};
|
||||
return {UStr.str, decltype(UStr)::size::value};
|
||||
}
|
||||
|
||||
inline bstring_view operator""_bsv(const char* str, size_t len) noexcept
|
||||
template <detail::bsv_literal BStr>
|
||||
constexpr bstring_view operator""_bsv()
|
||||
{
|
||||
return {reinterpret_cast<const std::byte*>(str), len};
|
||||
return {BStr.str, decltype(BStr)::size::value};
|
||||
}
|
||||
|
||||
inline bstring operator""_bs(const char* str, size_t len) noexcept
|
||||
|
@ -39,7 +39,8 @@ namespace llarp
|
||||
|
||||
inline timeval loop_time_to_timeval(loop_time t)
|
||||
{
|
||||
return timeval{.tv_sec = t / 1s, .tv_usec = (t % 1s) / 1us};
|
||||
return timeval{
|
||||
.tv_sec = static_cast<long>(t.count() / 1000), .tv_usec = static_cast<long>((t.count() % 1000) * 1000)};
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds get_timestamp();
|
||||
|
@ -69,7 +69,9 @@ namespace llarp::vpn
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
auto in4 = range.address().in4();
|
||||
std::memcpy(
|
||||
&((sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr, &in4.sin_addr.s_addr, sizeof(sockaddr));
|
||||
&((sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr,
|
||||
&in4.sin_addr.s_addr,
|
||||
range.address().socklen());
|
||||
|
||||
control.ioctl(SIOCSIFADDR, &ifr);
|
||||
|
||||
|
@ -5,16 +5,16 @@ namespace llarp::vpn
|
||||
struct UDPPacketHandler : public Layer4Handler
|
||||
{
|
||||
ip_pkt_hook _base_handler;
|
||||
std::unordered_map<uint16_t, udp_pkt_hook> _port_mapped_handlers;
|
||||
std::unordered_map<uint16_t, net_pkt_hook> _port_mapped_handlers;
|
||||
|
||||
explicit UDPPacketHandler(ip_pkt_hook baseHandler) : _base_handler{std::move(baseHandler)} {}
|
||||
|
||||
void add_sub_handler(uint16_t localport, udp_pkt_hook handler) override
|
||||
void add_sub_handler(uint16_t localport, net_pkt_hook handler) override
|
||||
{
|
||||
_port_mapped_handlers.emplace(localport, std::move(handler));
|
||||
}
|
||||
|
||||
void handle_ip_packet(UDPPacket pkt) override
|
||||
void handle_ip_packet(NetworkPacket pkt) override
|
||||
{
|
||||
auto dstport = pkt.path.remote.port();
|
||||
|
||||
@ -38,7 +38,7 @@ namespace llarp::vpn
|
||||
|
||||
explicit GenericLayer4Handler(ip_pkt_hook baseHandler) : _base_handler{std::move(baseHandler)} {}
|
||||
|
||||
void handle_ip_packet(UDPPacket) override
|
||||
void handle_ip_packet(NetworkPacket) override
|
||||
{
|
||||
// TOFIX:
|
||||
// _base_handler(IPPacket::from_udp(std::move(pkt)));
|
||||
@ -57,7 +57,7 @@ namespace llarp::vpn
|
||||
// _handler(std::move(pkt));
|
||||
}
|
||||
|
||||
void PacketRouter::add_udp_handler(uint16_t localport, udp_pkt_hook func)
|
||||
void PacketRouter::add_udp_handler(uint16_t localport, net_pkt_hook func)
|
||||
{
|
||||
constexpr uint8_t udp_proto = 0x11;
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace llarp::vpn
|
||||
void add_ip_proto_handler(uint8_t proto, ip_pkt_hook func);
|
||||
|
||||
/// helper that adds a udp packet handler for UDP destined for localport
|
||||
void add_udp_handler(uint16_t port, udp_pkt_hook func);
|
||||
void add_udp_handler(uint16_t port, net_pkt_hook func);
|
||||
|
||||
/// remove a udp handler that is already set up by bound port
|
||||
void remove_udp_handler(uint16_t port);
|
||||
@ -35,9 +35,9 @@ namespace llarp::vpn
|
||||
{
|
||||
virtual ~Layer4Handler() = default;
|
||||
|
||||
virtual void handle_ip_packet(UDPPacket pkt) = 0;
|
||||
virtual void handle_ip_packet(NetworkPacket pkt) = 0;
|
||||
|
||||
virtual void add_sub_handler(uint16_t, udp_pkt_hook){};
|
||||
virtual void add_sub_handler(uint16_t, net_pkt_hook){};
|
||||
};
|
||||
|
||||
} // namespace llarp::vpn
|
||||
|
Loading…
Reference in New Issue
Block a user