* 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
* llarp::service::NameIsValid was not checking that the tld was .loki, add this check.
* make link layer initial connection timeout 5s not the session activity timeout which happens to be 60 god damn seconds.
* add lokinet_add_bootstrap_rc function for adding an rc from memory
* prevent stack overflow on error closing connection in quic
* add in memory nodedb
* refactor how convotags are set as active
* add initial stubs for endpoint statistics
* refactor time stuff to be a bit cleaner
* update lnproxy script with more arguments
Replace stream_reset (which typically isn't called) with a stream_close
handler (which is already called whether or not it was a reset). Most
importantly, the server side needs to extend the max bidi streams
counter during stream_close (otherwise we run out when we hit the
limit and new connections just stall).
Stream forward on the client-side TCP connection gets set up within in
initial_client_data_handler (which also handles reading the initial
stream version byte).
Also fix a potential transmission delay because `again()` wasn't being
called when the expiry is already passed (i.e. meaning we should run
immediately).
Make stream closing with expiring connections work better. Fixes an
issue where the stream's uv_async could outlive the stream and/or
connection and segfault.
In the standalone plainquic code we triggered a retransmit when the
socket became writeable again, but that doesn't work here, so just
schedule it right away to let ngtcp2 worry about retrying.
For now we still steal buffers from uvw.
In the future I'd like to change that, but it's still uvw
work-in-progress to support custom data allocators, and so for now we
still steal data buffers from uvw.
ngtcp2 was rejecting them because we have the port when constructing,
but then it was 0 on the return packet (which ngtcp2 drops because it's
coming from an unknown/invalid path).
* wire up last of the quic stuff
* clean up udp packet generation code
* pass EndpointBase not quic tunnel for quic stuff
* add {n,h}uint16_t::FromString
* add nuint_t::FromString
* make AlignedBuffer::IsZero non constant time call for speed
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
They were failing to compile if output because implicit integer
promotion doesn't work for std::byte's (but rather needs an explicit
std::to_integer call).
- LogTrace() (and LogTraceTag, etc.) are now no-ops for release builds.
(hoping there are no side effects in trace logging!)
- renamed llarp::_Log to llarp::_log because _Log is a reserved keyword
- change logging code to implicitly convert 1-byte types (char, unsigned
char, uint8_t) to ints so that we print them as numeric values rather
than raw chars because, more often than not, printing a single char is
trying to log an 8-bit value.
- Move uvw target to external instead of llarp/CMakeLists.txt
- Add sqlite_orm headers via interface library rather than shoving it
into the global include search path.
- Find sqlite3 as part of the sqlite_orm target deps rather than linking
it separately. (Also don't link it into lokinet-util, which doesn't
appear to actually need it).
* add ip6-range option to network section to control which range we want to use for ipv6 traffic
* make ip6-range able to disable ipv6 exits ( i dont like this but eh )
- Make SockAddr endian arguments explicit
- Consolidate port-less contructors and port constructors into one with
a default port of 0.
- Add {h,n}uint128_t ctors for construction from IPv6 addrs
- De-lambda a lambda that is only called once, immediately after it is
defined.
- C++17 modernize key-value for loops
- Remove unused (and useless) method
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.
ip packet on read error was returning an uninitialized ip packet with non zero size so it was thinking it was a valid packet.
value initialize it to set the packet size to zero by default.
this fixed it in an emulator at least...
call(), when invoked from the logic thread, wasn't triggering a wakeup
which stalled some traffic (such as client-to-snode packets).
Fix it by triggering a wakeup on `call()`, and expose it because this is
a useful thing to be able to do.
The `const sockaddr*` conversion was returning a pointer to the
sockaddr_in6, but with its family set to AF_INET, so the receiving code
would have treated interpreting the result as a sockaddr_in pointer --
but it isn't, and trying to get the IPv4 from the mis-reinterpreted
sockaddr_in6 fails; this then prevented uvw UDP binding (which uses the
sockaddr* operator) from working.
This changes it to always leave the family value at the proper value and
using the ipv6_is_mapped_ipv4 check to determine when we have (and
should return) a pointer to the sockaddr_in rather than the
sockaddr_in6.
Also fixes toString() to compare the full prefix instead of just bytes
10 and 11.
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
when retransmissions happen, they will be executed in a deterministic order by their delivery id.
this reduces the jitter from delayed message delivery on link layer as with an unordered map the order of iteration is "random",
so when we iterate all messages for retransmission we do it lowest id first (the messages queued first).
- Previous android java and jni code updated to work, but with much love
still needed to make it work nicely, e.g. handling when the VPN is
turned off.
- DNS handling refactored to allow android to intercept and handle DNS
requests as we can't set the system DNS to use a high port
(and apparently Chrome ignores system DNS settings anyway)
- add packet router structure to allow separate handling of specific
intercepted traffic, e.g. UDP traffic to port 53 gets handled by our
DNS handler rather than being naively forwarded as exit traffic.
- For now, android lokinet is exit-only and hard-coded to use exit.loki
as its exit. The exit will be configurable before release, but
allowing to not use exit-only mode is more of a challenge.
- some old gitignore remnants which were matching to things we don't
want them to (and are no longer relevant) removed
- some minor changes to CI configuration
- Remove SIIT from method names & comments because we're doing IPv4
mapped addresses (::ffff:0:0/96) rather than actual SIIT
(::ffff:0:0:0/96).
- add constructor taking a string+numeric port (and then don't allow a
port in the string).
- simplify IP string parsing by using parse_int()
- replace addrIsV4 with call to ipv6_is_mapped_ipv4 (this also fixes a
bug where addrIsV4 was not checking for leading 0s and so could return
true for a public IPv6 that happened to have ffff in the wrong spot).
* bump zmq static dep
* lokimq -> oxenmq
* llarp_nodedb -> llarp::NodeDB
* remove all crufty api parts of NodeDB
* make NodeDB rc selection api not suck
* make path builder api not suck
* propagate all above changes so that unit tests work and it all compiles
when a path expires or fails or something causes its lifecycle to end we have cleanup
logic that handles clean up for it. this removes a code path that was crashing that
is duplicated elsewhere and is thus probably safe to bin. yolo.
* 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
this fixes the gui bug where it hangs on adding an exit becuase loopback gets routed over the exit.
before it was causing the lmq connection to hang becuase of that route change.
* fix deadlock in #1453
* remove use of shared_lock in profiling
* clean up Save and Load to acquire lock
* bencode and bdecode are now non locking
* remove all places using std::shared_lock
* bail if write fails
* deny message delivery from non registered nodes when whitelist is enabled and applicable
* use DoCallback and return true so that the event gets fired right
* add exit.localhost.loki cname record
* return cname in localhost.loki A/AAAA lookup reply
* correctly handle case where we have no exit
* typofix
* simplify logic
So apparently dnsConfig in Router was never set.
Router::networkConfig was set, but only used in the function
which set it and otherwise only passed to another function once.
dnsConfig was only used in one place.
both member variables have been removed in favor of just
referencing Router::m_Config.
Co-authored-by: Thomas Winget <tewinget@gmail.com>
* llarp::Config constructor can take an empty fs::path now and it will default to fs::current_path
* llarp::ensureConfig now throws on fs error
* updates to daemon/main.cpp to reflect changes to llarp::ensureConfig's new throwability
* dowse parts of the code with holy water for the 0.8.1 tag
* Update how we build libuv
- Update submoduled libuv to latest stable (1.40.0)
- Don't look for a system libuv if we're under BUILD_STATIC_DEPS
- Add a libuv interface library rather than using globals
- Make the windows build fall back to the submodule if not explicitly
given a LIBUV_ROOT
* Replace ${LIBS} global with `base_libs` interface
This simplifies linking and include handling a bit.
* Remove unneeded header
* Add missing csignal header
(This was previously being pulled in incredibly indirectly via some
stuff that eventually includes some other stuff that eventually included
uv.h)
* Use GNUInstallDirs to get lib dir instead of hard-coding lib
Fixes#1429
* enable client relay profiling by default
* macos dns fixes
* improve peer profiling algorithm to track timeouts vs failures
* remove debug ioctl call in tuntap code
* use ub_wait instead of ub_process as that was what was there before
* const correctness
* DRY out checking for SIIT
* typofix
* correct name
* more aggressive path building.
* do more than one in parallel path builds at a time
* correct last commit's logic
* rename numPaths -> numDesiredPaths to clarify intent
* revert string change as it will break a lot
* don't prematurly short circuit on snode builds
Co-authored-by: Thomas Winget <tewinget@gmail.com>
* Should fix some windows service issues
* fix return condition inversion
* Add some Trace level logging
also make the logger actually respect the log level you set.
* event loop should not queue things to itself...
at present, logic thread queue continues until it is empty, so
queueing things onto itself is just wasteful.
* call_later(foreach thing) is better than foreach thing (call later)
also if you already queued those things but they have not happened yet,
there is no sense to queue them to happen again.
* do not queue read on write finish, only on read finish
* failure to start DNS server should be proper startup failure.
without the DNS server working lokinet is...kinda pointless, right?
* format
* don't queue stuff to logic thread if in logic thread
the thing that clears the queue...clears it. So you're just delaying and adding overhead.
* windows unbound thread sleep instead of just busy-waiting
also clang-format decided I can't have a blank line for some reason...
* fix unbound async worker on windows