mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-03 23:15:52 +00:00
5b555ee5aa
- 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
276 lines
6.3 KiB
C++
276 lines
6.3 KiB
C++
#ifndef LLARP_BUFFER_HPP
|
|
#define LLARP_BUFFER_HPP
|
|
|
|
#include <type_traits>
|
|
#include <util/common.hpp>
|
|
#include <util/mem.h>
|
|
#include <util/types.hpp>
|
|
|
|
#include <cassert>
|
|
#include <iterator>
|
|
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <utility>
|
|
#include <algorithm>
|
|
#include <memory>
|
|
|
|
/**
|
|
* buffer.h
|
|
*
|
|
* generic memory buffer
|
|
*
|
|
* TODO: replace usage of these with std::span (via a backport until we move to C++20). That's a
|
|
* fairly big job, though, as llarp_buffer_t is currently used a bit differently (i.e. maintains
|
|
* both start and current position, plus has some value reading/writing methods).
|
|
*/
|
|
|
|
/**
|
|
llarp_buffer_t represents a region of memory that is ONLY
|
|
valid in the current scope.
|
|
|
|
make sure to follow the rules:
|
|
|
|
ALWAYS copy the contents of the buffer if that data is to be used outside the
|
|
current scope.
|
|
|
|
ALWAYS pass a llarp_buffer_t * if you plan on modifying the data associated
|
|
with the buffer
|
|
|
|
ALWAYS pass a llarp_buffer_t * if you plan on advancing the stream position
|
|
|
|
ALWAYS pass a const llarp_buffer_t & if you are doing a read only operation
|
|
that does not modify the buffer
|
|
|
|
ALWAYS pass a const llarp_buffer_t & if you don't want to advance the stream
|
|
position
|
|
|
|
ALWAYS bail out of the current operation if you run out of space in a buffer
|
|
|
|
ALWAYS assume the pointers in the buffer are stack allocated memory
|
|
(yes even if you know they are not)
|
|
|
|
NEVER malloc() the pointers in the buffer when using it
|
|
|
|
NEVER realloc() the pointers in the buffer when using it
|
|
|
|
NEVER free() the pointers in the buffer when using it
|
|
|
|
NEVER use llarp_buffer_t ** (double pointers)
|
|
|
|
NEVER use llarp_buffer_t ** (double pointers)
|
|
|
|
ABSOLUTELY NEVER USE DOUBLE POINTERS.
|
|
|
|
*/
|
|
|
|
struct ManagedBuffer;
|
|
|
|
struct llarp_buffer_t
|
|
{
|
|
/// starting memory address
|
|
byte_t* base{nullptr};
|
|
/// memory address of stream position
|
|
byte_t* cur{nullptr};
|
|
/// max size of buffer
|
|
size_t sz{0};
|
|
|
|
byte_t operator[](size_t x)
|
|
{
|
|
return *(this->base + x);
|
|
}
|
|
|
|
llarp_buffer_t() = default;
|
|
|
|
llarp_buffer_t(byte_t* b, byte_t* c, size_t s) : base(b), cur(c), sz(s)
|
|
{}
|
|
|
|
llarp_buffer_t(const ManagedBuffer&) = delete;
|
|
llarp_buffer_t(ManagedBuffer&&) = delete;
|
|
|
|
/// Construct referencing some 1-byte, trivially copyable (e.g. char, unsigned char, byte_t)
|
|
/// pointer type and a buffer size.
|
|
template <
|
|
typename T,
|
|
typename = std::enable_if_t<sizeof(T) == 1 and std::is_trivially_copyable_v<T>>>
|
|
llarp_buffer_t(T* buf, size_t _sz)
|
|
: base(reinterpret_cast<byte_t*>(const_cast<std::remove_const_t<T>*>(buf)))
|
|
, cur(base)
|
|
, sz(_sz)
|
|
{}
|
|
|
|
/// initialize llarp_buffer_t from containers supporting .data() and .size()
|
|
template <
|
|
typename T,
|
|
typename = std::void_t<decltype(std::declval<T>().data() + std::declval<T>().size())>>
|
|
llarp_buffer_t(T& t) : llarp_buffer_t{t.data(), t.size()}
|
|
{}
|
|
|
|
byte_t*
|
|
begin()
|
|
{
|
|
return base;
|
|
}
|
|
byte_t*
|
|
begin() const
|
|
{
|
|
return base;
|
|
}
|
|
byte_t*
|
|
end()
|
|
{
|
|
return base + sz;
|
|
}
|
|
byte_t*
|
|
end() const
|
|
{
|
|
return base + sz;
|
|
}
|
|
|
|
size_t
|
|
size_left() const;
|
|
|
|
template <typename OutputIt>
|
|
bool
|
|
read_into(OutputIt begin, OutputIt end);
|
|
|
|
template <typename InputIt>
|
|
bool
|
|
write(InputIt begin, InputIt end);
|
|
|
|
#ifndef _WIN32
|
|
bool
|
|
writef(const char* fmt, ...) __attribute__((format(printf, 2, 3)));
|
|
|
|
#elif defined(__MINGW64__) || defined(__MINGW32__)
|
|
bool
|
|
writef(const char* fmt, ...) __attribute__((__format__(__MINGW_PRINTF_FORMAT, 2, 3)));
|
|
#else
|
|
bool
|
|
writef(const char* fmt, ...);
|
|
#endif
|
|
|
|
bool
|
|
put_uint16(uint16_t i);
|
|
bool
|
|
put_uint32(uint32_t i);
|
|
|
|
bool
|
|
put_uint64(uint64_t i);
|
|
|
|
bool
|
|
read_uint16(uint16_t& i);
|
|
bool
|
|
read_uint32(uint32_t& i);
|
|
|
|
bool
|
|
read_uint64(uint64_t& i);
|
|
|
|
size_t
|
|
read_until(char delim, byte_t* result, size_t resultlen);
|
|
|
|
private:
|
|
friend struct ManagedBuffer;
|
|
llarp_buffer_t(const llarp_buffer_t&) = default;
|
|
llarp_buffer_t(llarp_buffer_t&&) = default;
|
|
};
|
|
|
|
bool
|
|
operator==(const llarp_buffer_t& buff, const char* data);
|
|
|
|
template <typename OutputIt>
|
|
bool
|
|
llarp_buffer_t::read_into(OutputIt begin, OutputIt end)
|
|
{
|
|
auto dist = std::distance(begin, end);
|
|
if (static_cast<decltype(dist)>(size_left()) >= dist)
|
|
{
|
|
std::copy_n(cur, dist, begin);
|
|
cur += dist;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template <typename InputIt>
|
|
bool
|
|
llarp_buffer_t::write(InputIt begin, InputIt end)
|
|
{
|
|
auto dist = std::distance(begin, end);
|
|
if (static_cast<decltype(dist)>(size_left()) >= dist)
|
|
{
|
|
cur = std::copy(begin, end, cur);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
Provide a copyable/moveable wrapper around `llarp_buffer_t`.
|
|
*/
|
|
struct ManagedBuffer
|
|
{
|
|
llarp_buffer_t underlying;
|
|
|
|
ManagedBuffer() = delete;
|
|
|
|
explicit ManagedBuffer(const llarp_buffer_t& b) : underlying(b)
|
|
{}
|
|
|
|
ManagedBuffer(ManagedBuffer&&) = default;
|
|
ManagedBuffer(const ManagedBuffer&) = default;
|
|
|
|
operator const llarp_buffer_t&() const
|
|
{
|
|
return underlying;
|
|
}
|
|
};
|
|
|
|
namespace llarp
|
|
{
|
|
// Wrapper around a std::unique_ptr<byte_t[]> that owns its own memory and is also implicitly
|
|
// convertible to a llarp_buffer_t.
|
|
struct OwnedBuffer
|
|
{
|
|
std::unique_ptr<byte_t[]> buf;
|
|
size_t sz;
|
|
|
|
template <typename T, typename = std::enable_if_t<sizeof(T) == 1>>
|
|
OwnedBuffer(std::unique_ptr<T[]> buf, size_t sz)
|
|
: buf{reinterpret_cast<byte_t*>(buf.release())}, sz{sz}
|
|
{}
|
|
|
|
// Create a new, uninitialized owned buffer of the given size.
|
|
explicit OwnedBuffer(size_t sz) : OwnedBuffer{std::make_unique<byte_t[]>(sz), sz}
|
|
{}
|
|
|
|
OwnedBuffer(const OwnedBuffer&) = delete;
|
|
OwnedBuffer&
|
|
operator=(const OwnedBuffer&) = delete;
|
|
OwnedBuffer(OwnedBuffer&&) = default;
|
|
OwnedBuffer&
|
|
operator=(OwnedBuffer&&) = delete;
|
|
|
|
// Implicit conversion so that this OwnedBuffer can be passed to anything taking a
|
|
// llarp_buffer_t
|
|
operator llarp_buffer_t()
|
|
{
|
|
return {buf.get(), sz};
|
|
}
|
|
|
|
// Creates an owned buffer by copying from a llarp_buffer_t. (Can also be used to copy from
|
|
// another OwnedBuffer via the implicit conversion operator above).
|
|
static OwnedBuffer
|
|
copy_from(const llarp_buffer_t& b);
|
|
|
|
// Creates an owned buffer by copying the used portion of a llarp_buffer_t (i.e. from base to
|
|
// cur), for when a llarp_buffer_t is used in write mode.
|
|
static OwnedBuffer
|
|
copy_used(const llarp_buffer_t& b);
|
|
};
|
|
|
|
} // namespace llarp
|
|
|
|
#endif
|