- windivert was being set up *before* DNS is set up, so the DNS port was
nullopt and thus we couldn't properly identify upstream DNS traffic.
- close() doesn't close a socket on Windows, so the socket-bind-close
approach to get a free UDP port wasn't actually closing, and thus
unbound upstream constrained to the given port were completely
failing.
- The unbound thread was accessing the same shared_ptr instance as the
outer code, which isn't thread-safe; changed it to copy a weak_ptr
into the lambda instead.
- Exclude upstream DNS traffic in the filter rather than capturing and
reinjecting it.
The inner lambda here wasn't keeping the `Query` (`this`) alive, so
`src` wasn't valid anymore. This changes it to copy the `src`
shared_ptr into the lambda instead of capturing `this`, and fixes it.
The current code isn't working and gives a 0 (which then fails unbound
initialization). This replaces it by doing a socket+bind to find a free
port then immediately closes (but passes the port we got into unbound).
* wintun vpn platform for windows
* bundle config snippets into nsis installer for exit node, keyfile persisting, reduced hops mode.
* use wintun for vpn platform
* isolate all windows platform specific code into their own compilation units and libraries
* split up internal libraries into more specific components
* rename liblokinet.a target to liblokinet-amalgum.a to elimiate ambiguity with liblokinet.so
* DNS platform for win32
* rename llarp/ev/ev_libuv.{c,h}pp to llarp/ev/libuv.{c,h}pp as the old name was idiotic
* split up net platform into win32 and posix specific compilation units
* rename lokinet_init.c to easter_eggs.cpp as that is what they are for and it does not need to be a c compilation target
* add cmake option STRIP_SYMBOLS for seperating out debug symbols for windows builds
* intercept dns traffic on all interfaces on windows using windivert and feed it into lokinet
we want to be able to have multiple locally bound dns sockets in lokinet so
i restructured most of the dns subsystem in order to make this easier.
specifically, we have a new structure to dns subsystem:
* dns::QueryJob_Base
base type for holding a dns query and response with virtual methods
in charge of sending a reply to whoever requested.
* dns::PacketSource_Base
base type for reading and writing dns messages to and from wherever they came from
* dns::Resolver_Base
base type for filtering and handling of dns messages asynchronously.
* dns::Server
contextualized per endpoint dns object, responsible for all dns related isms.
this change hides all impelementation details of all of the dns components.
adds some more helper functions for parsing dns and dealing with OwnedBuffer.
overall dns becomes less of a pain with this new structure. probably.
Adds support for building Lokinet as a system extension, and fixes
various problems in the macos implementation found during development of
the system extension support.
Fixes:
- tighten reserved name detection to not match fooloki.loki, but instead
only match "foo.loki.loki" and "loki.loki" (and similar for reserved
name "snode.loki").
- IPv6 PTR parsing was completely broken.
- Added tests for the above two issues.
Cleanups:
- Eliminate llarp::dns::Name_t typedef for std::string
- Use optional return instead of bool + output param
- Use string_views; we were doing a *lot* of string substr's during
parsing, each of which allocates a new string.
- Use fmt instead of stringstream
- Simplify IPv4 PTR parsing
Replaces custom logging system with spdlog-based oxen logging. This
commit mainly replaces the backend logging with the spdlog-based system,
but doesn't (yet) convert all the existing LogWarn, etc. to use the new
format-based logging.
New logging statements will look like:
llarp::log::warning(cat, "blah: {}", val);
where `cat` should be set up in each .cpp or cluster of .cpp files, as
described in the oxen-logging README.
As part of spdlog we get fmt, which gives us nice format strings, where
are applied generously in this commit.
Making types printable now requires two steps:
- add a ToString() method
- add this specialization:
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::Whatever> = true;
This will then allow the type to be printed as a "{}" value in a
fmt::format string. This is applied to all our printable types here,
and all of the `operator<<` are removed.
This commit also:
- replaces various uses of `operator<<` to ToString()
- replaces various uses of std::stringstream with either fmt::format or
plain std::string
- Rename some to_string and toString() methods to ToString() for
consistency (and to work with fmt)
- Replace `stringify(...)` and `make_exception` usage with fmt::format
(and remove stringify/make_exception from util/str.hpp).
* use std::source_location instead of godawful macros in logging
* remove unused/absolutely haram af json logstream
* fix bug in android logger where it doesn't respect eLogNone
When we enable/disable exit mode on this restarts the unbound DNS
responder with the DNS trampoline (or restores upstream, when disabling)
to properly route DNS requests through the tunnel (because libunbound's
direct requests don't get tunneled because unbound is inside the network
extension).
PR #1725 reversed argument orders but UnboundResolver was still using
(from,to) ordering in its callbacks, which leaked through to make a
wrong order in our reply function (which simply forwards arguments).
This fixes that bug by making UnboundResolver callback argument order
consistent (i.e. using to, from) with the PacketHandler argument order.
The reason the dns fix on android didn't work is that the DnsInterceptor
had a reversed to/from argument order for its
`SendServerMessageBufferTo` overload, and so android/mac needed the
to/from to be reversed so that the second reverse cancelled out the
first one.
Upon review, the DnsInterceptor order (to, from) is more intuitive than
the base order (from, to), so this reapplies the dns fix and swaps
everything *except* DnsInterceptor to match the (to, from) argument
order.
* make it so that we don't set up unbound resolver when we have no resolvers provided by config
* clean up dns codepath and make it use llarp::SockAddr instead of llarp::IpAddress
* add srv records in RCs if we have any
* add mechanism to add SRV records for plainquic exposed ports
* resign and republish rc or introset on srv record changes
All #ifndef guards on headers have been removed, I think,
in favor of #pragma once
Headers are now included as `#include "filename"` if the included file
resides in the same directory as the file including it, or any
subdirectory therein. Otherwise they are included as
`#include <project/top/dir/relative/path/filename>`
The above does not include system/os headers.
loop->call(...) is similar to the old logic->Call(...), but is smart
about the current thread: if called from within the event loop it simply
runs the argument directly, otherwise it queues it.
Similarly most of the other event loop calls are also now thread-aware:
for example, `call_later(...)` can queue the job directly when called if
in the event loop rather than having to double-queue through the even
loop (once to call, then inside the call to initiate the time).
- removes all the llarp_ev_* functions, replacing with methods/classes/functions in the llarp
namespace.
- banish ev/ev.h to the void
- Passes various things by const lvalue ref, especially shared_ptr's that don't need to be copied
(to avoid an atomic refcount increment/decrement).
- Add a llarp::UDPHandle abstract class for UDP handling
- Removes the UDP tick handler; code that needs tick can just do a separate handler on the event
loop outside the UDP socket.
- Adds an "OwnedBuffer" which owns its own memory but is implicitly convertible to a llarp_buffer_t.
This is mostly needed to take over ownership of buffers from uvw without copying them as,
currently, uvw does its own allocation (pending some open upstream issues/PRs).
- Logic:
- add `make_caller`/`call_forever`/`call_every` utility functions to abstract Call wrapping and
dependent timed tasks.
- Add inLogicThread() so that code can tell its inside the logic thread (typically for
debugging assertions).
- get rid of janky integer returns and dealing with cancellations on call_later: the other methods
added here and the event loop code remove the need for them.
- Event loop:
- redo everything with uvw instead of libuv
- rename EventLoopWakeup::Wakeup to EventLoopWakeup::Trigger to better reflect what it does.
- add EventLoopRepeater for repeated events, and replace the code that reschedules itself every
time it is called with a repeater.
- Split up `EventLoop::run()` into a non-virtual base method and abstract `run_loop()` methods;
the base method does a couple extra setup/teardown things that don't need to be in the derived class.
- udp_listen is replaced with ev->udp(...) which returns a new UDPHandle object rather that
needing gross C-style-but-not-actually-C-compatible structs.
- Remove unused register_poll_fd_(un)readable
- Use shared_ptr for EventLoopWakeup rather than returning a raw pointer; uvw lets us not have to
worry about having the event loop class maintain ownership of it.
- Add factory EventLoop::create() function to create a default (uvw-based) event loop (previously
this was one of the llarp_ev_blahblah unnamespaced functions).
- ev_libuv: this is mostly rewritten; all of the glue code/structs, in particular, are gone as
they are no longer needed with uvw.
- DNS:
- Rename DnsHandler to DnsInterceptor to better describe what it does (this is the code that
intercepts all DNS to the tun IP range for Android).
- endpoint:
- remove unused "isolated network" code
- remove distinct (but actually always the same) variables for router/endpoint logic objects
- llarp_buffer_t
- make constructors type-safe against being called with points to non-size-1 values
- tun packet reading:
- read all available packets off the device/file descriptor; previously we were reading one packet
at a time then returning to the event loop to poll again.
- ReadNextPacket() now returns a 0-size packet if the read would block (so that we can implement
the previous point).
- ReadNextPacket() now throws on I/O error
- Miscellaneous code cleanups/simplifications