mirror of https://github.com/oxen-io/oxen-mq.git
Rename LokiMQ to OxenMQ
This commit is contained in:
parent
bd9313bf19
commit
2ae6b96016
142
CMakeLists.txt
142
CMakeLists.txt
|
@ -3,63 +3,63 @@ cmake_minimum_required(VERSION 3.7)
|
|||
# Has to be set before `project()`, and ignored on non-macos:
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12 CACHE STRING "macOS deployment target (Apple clang only)")
|
||||
|
||||
project(liblokimq CXX C)
|
||||
project(liboxenmq CXX C)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(LOKIMQ_VERSION_MAJOR 1)
|
||||
set(LOKIMQ_VERSION_MINOR 2)
|
||||
set(LOKIMQ_VERSION_PATCH 3)
|
||||
set(LOKIMQ_VERSION "${LOKIMQ_VERSION_MAJOR}.${LOKIMQ_VERSION_MINOR}.${LOKIMQ_VERSION_PATCH}")
|
||||
message(STATUS "lokimq v${LOKIMQ_VERSION}")
|
||||
set(OXENMQ_VERSION_MAJOR 1)
|
||||
set(OXENMQ_VERSION_MINOR 2)
|
||||
set(OXENMQ_VERSION_PATCH 3)
|
||||
set(OXENMQ_VERSION "${OXENMQ_VERSION_MAJOR}.${OXENMQ_VERSION_MINOR}.${OXENMQ_VERSION_PATCH}")
|
||||
message(STATUS "oxenmq v${OXENMQ_VERSION}")
|
||||
|
||||
set(LOKIMQ_LIBVERSION 0)
|
||||
set(OXENMQ_LIBVERSION 0)
|
||||
|
||||
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
set(lokimq_IS_TOPLEVEL_PROJECT TRUE)
|
||||
set(oxenmq_IS_TOPLEVEL_PROJECT TRUE)
|
||||
else()
|
||||
set(lokimq_IS_TOPLEVEL_PROJECT FALSE)
|
||||
set(oxenmq_IS_TOPLEVEL_PROJECT FALSE)
|
||||
endif()
|
||||
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries instead of static ones" ON)
|
||||
set(lokimq_INSTALL_DEFAULT OFF)
|
||||
if(BUILD_SHARED_LIBS OR lokimq_IS_TOPLEVEL_PROJECT)
|
||||
set(lokimq_INSTALL_DEFAULT ON)
|
||||
set(oxenmq_INSTALL_DEFAULT OFF)
|
||||
if(BUILD_SHARED_LIBS OR oxenmq_IS_TOPLEVEL_PROJECT)
|
||||
set(oxenmq_INSTALL_DEFAULT ON)
|
||||
endif()
|
||||
option(LOKIMQ_BUILD_TESTS "Building and perform lokimq tests" ${lokimq_IS_TOPLEVEL_PROJECT})
|
||||
option(LOKIMQ_INSTALL "Add lokimq libraries and headers to cmake install target; defaults to ON if BUILD_SHARED_LIBS is enabled or we are the top-level project; OFF for a static subdirectory build" ${lokimq_INSTALL_DEFAULT})
|
||||
option(LOKIMQ_INSTALL_CPPZMQ "Install cppzmq header with lokimq/ headers (requires LOKIMQ_INSTALL)" ON)
|
||||
option(OXENMQ_BUILD_TESTS "Building and perform oxenmq tests" ${oxenmq_IS_TOPLEVEL_PROJECT})
|
||||
option(OXENMQ_INSTALL "Add oxenmq libraries and headers to cmake install target; defaults to ON if BUILD_SHARED_LIBS is enabled or we are the top-level project; OFF for a static subdirectory build" ${oxenmq_INSTALL_DEFAULT})
|
||||
option(OXENMQ_INSTALL_CPPZMQ "Install cppzmq header with oxenmq/ headers (requires OXENMQ_INSTALL)" ON)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
configure_file(lokimq/version.h.in lokimq/version.h @ONLY)
|
||||
configure_file(liblokimq.pc.in liblokimq.pc @ONLY)
|
||||
configure_file(oxenmq/version.h.in oxenmq/version.h @ONLY)
|
||||
configure_file(liboxenmq.pc.in liboxenmq.pc @ONLY)
|
||||
|
||||
add_library(lokimq
|
||||
lokimq/address.cpp
|
||||
lokimq/auth.cpp
|
||||
lokimq/bt_serialize.cpp
|
||||
lokimq/connections.cpp
|
||||
lokimq/jobs.cpp
|
||||
lokimq/lokimq.cpp
|
||||
lokimq/proxy.cpp
|
||||
lokimq/worker.cpp
|
||||
add_library(oxenmq
|
||||
oxenmq/address.cpp
|
||||
oxenmq/auth.cpp
|
||||
oxenmq/bt_serialize.cpp
|
||||
oxenmq/connections.cpp
|
||||
oxenmq/jobs.cpp
|
||||
oxenmq/oxenmq.cpp
|
||||
oxenmq/proxy.cpp
|
||||
oxenmq/worker.cpp
|
||||
)
|
||||
set_target_properties(lokimq PROPERTIES SOVERSION ${LOKIMQ_LIBVERSION})
|
||||
set_target_properties(oxenmq PROPERTIES SOVERSION ${OXENMQ_LIBVERSION})
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(lokimq PRIVATE Threads::Threads)
|
||||
target_link_libraries(oxenmq PRIVATE Threads::Threads)
|
||||
|
||||
# libzmq is nearly impossible to link statically from a system-installed static library: it depends
|
||||
# on a ton of other libraries, some of which are not all statically available. If the caller wants
|
||||
# to mess with this, so be it: they can set up a libzmq target and we'll use it. Otherwise if they
|
||||
# asked us to do things statically, don't even try to find a system lib and just build it.
|
||||
set(lokimq_build_static_libzmq OFF)
|
||||
set(oxenmq_build_static_libzmq OFF)
|
||||
if(TARGET libzmq)
|
||||
target_link_libraries(lokimq PUBLIC libzmq)
|
||||
target_link_libraries(oxenmq PUBLIC libzmq)
|
||||
elseif(BUILD_SHARED_LIBS)
|
||||
include(FindPkgConfig)
|
||||
pkg_check_modules(libzmq libzmq>=4.3 IMPORTED_TARGET)
|
||||
|
@ -75,30 +75,30 @@ elseif(BUILD_SHARED_LIBS)
|
|||
set_property(TARGET PkgConfig::libzmq PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${zmq_inc})
|
||||
endif()
|
||||
|
||||
target_link_libraries(lokimq PUBLIC PkgConfig::libzmq)
|
||||
target_link_libraries(oxenmq PUBLIC PkgConfig::libzmq)
|
||||
else()
|
||||
set(lokimq_build_static_libzmq ON)
|
||||
set(oxenmq_build_static_libzmq ON)
|
||||
endif()
|
||||
else()
|
||||
set(lokimq_build_static_libzmq ON)
|
||||
set(oxenmq_build_static_libzmq ON)
|
||||
endif()
|
||||
|
||||
if(lokimq_build_static_libzmq)
|
||||
if(oxenmq_build_static_libzmq)
|
||||
message(STATUS "libzmq >= 4.3 not found or static build requested, building bundled version")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/local-libzmq")
|
||||
include(LocalLibzmq)
|
||||
target_link_libraries(lokimq PUBLIC libzmq_vendor)
|
||||
target_link_libraries(oxenmq PUBLIC libzmq_vendor)
|
||||
endif()
|
||||
|
||||
target_include_directories(lokimq
|
||||
target_include_directories(oxenmq
|
||||
PUBLIC
|
||||
$<INSTALL_INTERFACE:>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cppzmq>
|
||||
)
|
||||
|
||||
target_compile_options(lokimq PRIVATE -Wall -Wextra -Werror)
|
||||
set_target_properties(lokimq PROPERTIES
|
||||
target_compile_options(oxenmq PRIVATE -Wall -Wextra -Werror)
|
||||
set_target_properties(oxenmq PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS OFF
|
||||
|
@ -117,8 +117,8 @@ endfunction()
|
|||
# If the caller has already set up a sodium target then we will just link to it, otherwise we go
|
||||
# looking for it.
|
||||
if(TARGET sodium)
|
||||
target_link_libraries(lokimq PUBLIC sodium)
|
||||
if(lokimq_build_static_libzmq)
|
||||
target_link_libraries(oxenmq PUBLIC sodium)
|
||||
if(oxenmq_build_static_libzmq)
|
||||
target_link_libraries(libzmq_vendor INTERFACE sodium)
|
||||
endif()
|
||||
else()
|
||||
|
@ -126,67 +126,67 @@ else()
|
|||
pkg_check_modules(sodium REQUIRED libsodium IMPORTED_TARGET)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_link_libraries(lokimq PUBLIC PkgConfig::sodium)
|
||||
if(lokimq_build_static_libzmq)
|
||||
target_link_libraries(oxenmq PUBLIC PkgConfig::sodium)
|
||||
if(oxenmq_build_static_libzmq)
|
||||
target_link_libraries(libzmq_vendor INTERFACE PkgConfig::sodium)
|
||||
endif()
|
||||
else()
|
||||
link_dep_libs(lokimq PUBLIC "${sodium_STATIC_LIBRARY_DIRS}" ${sodium_STATIC_LIBRARIES})
|
||||
target_include_directories(lokimq PUBLIC ${sodium_STATIC_INCLUDE_DIRS})
|
||||
if(lokimq_build_static_libzmq)
|
||||
link_dep_libs(oxenmq PUBLIC "${sodium_STATIC_LIBRARY_DIRS}" ${sodium_STATIC_LIBRARIES})
|
||||
target_include_directories(oxenmq PUBLIC ${sodium_STATIC_INCLUDE_DIRS})
|
||||
if(oxenmq_build_static_libzmq)
|
||||
link_dep_libs(libzmq_vendor INTERFACE "${sodium_STATIC_LIBRARY_DIRS}" ${sodium_STATIC_LIBRARIES})
|
||||
target_link_libraries(libzmq_vendor INTERFACE ${sodium_STATIC_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(lokimq::lokimq ALIAS lokimq)
|
||||
add_library(oxenmq::oxenmq ALIAS oxenmq)
|
||||
|
||||
export(
|
||||
TARGETS lokimq
|
||||
NAMESPACE lokimq::
|
||||
FILE lokimqTargets.cmake
|
||||
TARGETS oxenmq
|
||||
NAMESPACE oxenmq::
|
||||
FILE oxenmqTargets.cmake
|
||||
)
|
||||
|
||||
if(LOKIMQ_INSTALL)
|
||||
if(OXENMQ_INSTALL)
|
||||
install(
|
||||
TARGETS lokimq
|
||||
EXPORT lokimqConfig
|
||||
TARGETS oxenmq
|
||||
EXPORT oxenmqConfig
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES lokimq/address.h
|
||||
lokimq/auth.h
|
||||
lokimq/base32z.h
|
||||
lokimq/base64.h
|
||||
lokimq/batch.h
|
||||
lokimq/bt_serialize.h
|
||||
lokimq/bt_value.h
|
||||
lokimq/connections.h
|
||||
lokimq/hex.h
|
||||
lokimq/lokimq.h
|
||||
lokimq/message.h
|
||||
lokimq/string_view.h
|
||||
lokimq/variant.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lokimq/version.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lokimq
|
||||
FILES oxenmq/address.h
|
||||
oxenmq/auth.h
|
||||
oxenmq/base32z.h
|
||||
oxenmq/base64.h
|
||||
oxenmq/batch.h
|
||||
oxenmq/bt_serialize.h
|
||||
oxenmq/bt_value.h
|
||||
oxenmq/connections.h
|
||||
oxenmq/hex.h
|
||||
oxenmq/oxenmq.h
|
||||
oxenmq/message.h
|
||||
oxenmq/string_view.h
|
||||
oxenmq/variant.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/oxenmq/version.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/oxenmq
|
||||
)
|
||||
|
||||
if(LOKIMQ_INSTALL_CPPZMQ)
|
||||
if(OXENMQ_INSTALL_CPPZMQ)
|
||||
install(
|
||||
FILES cppzmq/zmq.hpp
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lokimq
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/oxenmq
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/liblokimq.pc
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/liboxenmq.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LOKIMQ_BUILD_TESTS)
|
||||
if(OXENMQ_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
|
|
@ -3,11 +3,11 @@ exec_prefix=${prefix}
|
|||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
|
||||
Name: liblokimq
|
||||
Description: ZeroMQ-based communication library for Loki
|
||||
Version: @LOKIMQ_VERSION@
|
||||
Name: liboxenmq
|
||||
Description: ZeroMQ-based communication library
|
||||
Version: @OXENMQ_VERSION@
|
||||
|
||||
Libs: -L${libdir} -llokimq
|
||||
Libs: -L${libdir} -loxenmq
|
||||
Libs.private: @PRIVATE_LIBS@
|
||||
Requires.private: libzmq libsodium
|
||||
Cflags: -I${includedir}
|
|
@ -1,5 +0,0 @@
|
|||
namespace lokimq {
|
||||
constexpr int VERSION_MAJOR = @LOKIMQ_VERSION_MAJOR@;
|
||||
constexpr int VERSION_MINOR = @LOKIMQ_VERSION_MINOR@;
|
||||
constexpr int VERSION_PATCH = @LOKIMQ_VERSION_PATCH@;
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
#include "base32z.h"
|
||||
#include "base64.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
constexpr size_t enc_length(address::encoding enc) {
|
||||
return enc == address::encoding::hex ? 64 :
|
||||
|
@ -23,13 +23,13 @@ constexpr size_t enc_length(address::encoding enc) {
|
|||
// given: for QR-friendly we only accept hex or base32z (since QR cannot handle base64's alphabet).
|
||||
std::string decode_pubkey(std::string_view& in, bool qr) {
|
||||
std::string pubkey;
|
||||
if (in.size() >= 64 && lokimq::is_hex(in.substr(0, 64))) {
|
||||
if (in.size() >= 64 && is_hex(in.substr(0, 64))) {
|
||||
pubkey = from_hex(in.substr(0, 64));
|
||||
in.remove_prefix(64);
|
||||
} else if (in.size() >= 52 && lokimq::is_base32z(in.substr(0, 52))) {
|
||||
} else if (in.size() >= 52 && is_base32z(in.substr(0, 52))) {
|
||||
pubkey = from_base32z(in.substr(0, 52));
|
||||
in.remove_prefix(52);
|
||||
} else if (!qr && in.size() >= 43 && lokimq::is_base64(in.substr(0, 43))) {
|
||||
} else if (!qr && in.size() >= 43 && is_base64(in.substr(0, 43))) {
|
||||
pubkey = from_base64(in.substr(0, 43));
|
||||
in.remove_prefix(43);
|
||||
if (!in.empty() && in.front() == '=')
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2020, The Loki Project
|
||||
// Copyright (c) 2020-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -32,11 +32,11 @@
|
|||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
/** LokiMQ address abstraction class. This class uses and extends standard ZMQ addresses allowing
|
||||
/** OxenMQ address abstraction class. This class uses and extends standard ZMQ addresses allowing
|
||||
* extra parameters to be passed in in a relative standard way.
|
||||
*
|
||||
* External ZMQ addresses generally have two forms that we are concerned with: one for TCP and one
|
|
@ -1,10 +1,10 @@
|
|||
#include "lokimq.h"
|
||||
#include "oxenmq.h"
|
||||
#include "hex.h"
|
||||
#include "lokimq-internal.h"
|
||||
#include "oxenmq-internal.h"
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, AuthLevel a) {
|
||||
return o << to_string(a);
|
||||
|
@ -31,7 +31,7 @@ std::string zmtp_metadata(std::string_view key, std::string_view value) {
|
|||
}
|
||||
|
||||
|
||||
bool LokiMQ::proxy_check_auth(size_t conn_index, bool outgoing, const peer_info& peer,
|
||||
bool OxenMQ::proxy_check_auth(size_t conn_index, bool outgoing, const peer_info& peer,
|
||||
zmq::message_t& cmd, const cat_call_t& cat_call, std::vector<zmq::message_t>& data) {
|
||||
auto command = view(cmd);
|
||||
std::string reply;
|
||||
|
@ -45,7 +45,7 @@ bool LokiMQ::proxy_check_auth(size_t conn_index, bool outgoing, const peer_info&
|
|||
reply = "FORBIDDEN";
|
||||
} else if (cat_call.first->access.local_sn && !local_service_node) {
|
||||
LMQ_LOG(warn, "Access denied to ", command, " for peer [", to_hex(peer.pubkey), "]/", peer_address(cmd),
|
||||
": that command is only available when this LokiMQ is running in service node mode");
|
||||
": that command is only available when this OxenMQ is running in service node mode");
|
||||
reply = "NOT_A_SERVICE_NODE";
|
||||
} else if (cat_call.first->access.remote_sn && !peer.service_node) {
|
||||
LMQ_LOG(warn, "Access denied to ", command, " for peer [", to_hex(peer.pubkey), "]/", peer_address(cmd),
|
||||
|
@ -81,7 +81,7 @@ bool LokiMQ::proxy_check_auth(size_t conn_index, bool outgoing, const peer_info&
|
|||
return false;
|
||||
}
|
||||
|
||||
void LokiMQ::set_active_sns(pubkey_set pubkeys) {
|
||||
void OxenMQ::set_active_sns(pubkey_set pubkeys) {
|
||||
if (proxy_thread.joinable()) {
|
||||
auto data = bt_serialize(detail::serialize_object(std::move(pubkeys)));
|
||||
detail::send_control(get_control_socket(), "SET_SNS", data);
|
||||
|
@ -89,10 +89,10 @@ void LokiMQ::set_active_sns(pubkey_set pubkeys) {
|
|||
proxy_set_active_sns(std::move(pubkeys));
|
||||
}
|
||||
}
|
||||
void LokiMQ::proxy_set_active_sns(std::string_view data) {
|
||||
void OxenMQ::proxy_set_active_sns(std::string_view data) {
|
||||
proxy_set_active_sns(detail::deserialize_object<pubkey_set>(bt_deserialize<uintptr_t>(data)));
|
||||
}
|
||||
void LokiMQ::proxy_set_active_sns(pubkey_set pubkeys) {
|
||||
void OxenMQ::proxy_set_active_sns(pubkey_set pubkeys) {
|
||||
pubkey_set added, removed;
|
||||
for (auto it = pubkeys.begin(); it != pubkeys.end(); ) {
|
||||
auto& pk = *it;
|
||||
|
@ -118,7 +118,7 @@ void LokiMQ::proxy_set_active_sns(pubkey_set pubkeys) {
|
|||
proxy_update_active_sns_clean(std::move(added), std::move(removed));
|
||||
}
|
||||
|
||||
void LokiMQ::update_active_sns(pubkey_set added, pubkey_set removed) {
|
||||
void OxenMQ::update_active_sns(pubkey_set added, pubkey_set removed) {
|
||||
LMQ_LOG(info, "uh, ", added.size());
|
||||
if (proxy_thread.joinable()) {
|
||||
std::array<uintptr_t, 2> data;
|
||||
|
@ -129,12 +129,12 @@ void LokiMQ::update_active_sns(pubkey_set added, pubkey_set removed) {
|
|||
proxy_update_active_sns(std::move(added), std::move(removed));
|
||||
}
|
||||
}
|
||||
void LokiMQ::proxy_update_active_sns(bt_list_consumer data) {
|
||||
void OxenMQ::proxy_update_active_sns(bt_list_consumer data) {
|
||||
auto added = detail::deserialize_object<pubkey_set>(data.consume_integer<uintptr_t>());
|
||||
auto remed = detail::deserialize_object<pubkey_set>(data.consume_integer<uintptr_t>());
|
||||
proxy_update_active_sns(std::move(added), std::move(remed));
|
||||
}
|
||||
void LokiMQ::proxy_update_active_sns(pubkey_set added, pubkey_set removed) {
|
||||
void OxenMQ::proxy_update_active_sns(pubkey_set added, pubkey_set removed) {
|
||||
// We take a caller-provided set of added/removed then filter out any junk (bad pks, conflicting
|
||||
// values, pubkeys that already(added) or do not(removed) exist), then pass the purified lists
|
||||
// to the _clean version.
|
||||
|
@ -167,7 +167,7 @@ void LokiMQ::proxy_update_active_sns(pubkey_set added, pubkey_set removed) {
|
|||
proxy_update_active_sns_clean(std::move(added), std::move(removed));
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_update_active_sns_clean(pubkey_set added, pubkey_set removed) {
|
||||
void OxenMQ::proxy_update_active_sns_clean(pubkey_set added, pubkey_set removed) {
|
||||
LMQ_LOG(debug, "Updating SN auth status with +", added.size(), "/-", removed.size(), " pubkeys");
|
||||
|
||||
// For anything we remove we want close the connection to the SN (if outgoing), and remove the
|
||||
|
@ -192,7 +192,7 @@ void LokiMQ::proxy_update_active_sns_clean(pubkey_set added, pubkey_set removed)
|
|||
active_service_nodes.insert(std::move(pk));
|
||||
}
|
||||
|
||||
void LokiMQ::process_zap_requests() {
|
||||
void OxenMQ::process_zap_requests() {
|
||||
for (std::vector<zmq::message_t> frames; recv_message_parts(zap_auth, frames, zmq::recv_flags::dontwait); frames.clear()) {
|
||||
#ifndef NDEBUG
|
||||
if (log_level() >= LogLevel::trace) {
|
|
@ -4,7 +4,7 @@
|
|||
#include <cstring>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
/// Authentication levels for command categories and connections
|
||||
enum class AuthLevel {
|
||||
|
@ -45,7 +45,7 @@ struct already_hashed {
|
|||
};
|
||||
|
||||
/// std::unordered_set specialization for specifying pubkeys (used, in particular, by
|
||||
/// LokiMQ::set_active_sns and LokiMQ::update_active_sns); this is a std::string unordered_set that
|
||||
/// OxenMQ::set_active_sns and OxenMQ::update_active_sns); this is a std::string unordered_set that
|
||||
/// also uses a specialized trivial hash function that uses part of the value itself (i.e. the
|
||||
/// pubkey) directly as a hash value. (This is nice and fast for uniformly distributed values like
|
||||
/// pubkeys and a terrible hash choice for anything else).
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019-2020, The Loki Project
|
||||
// Copyright (c) 2019-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include <cassert>
|
||||
#include "byte_type.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
namespace detail {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019-2020, The Loki Project
|
||||
// Copyright (c) 2019-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include <cassert>
|
||||
#include "byte_type.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
namespace detail {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2020, The Loki Project
|
||||
// Copyright (c) 2020-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -30,9 +30,9 @@
|
|||
#include <exception>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include "lokimq.h"
|
||||
#include "oxenmq.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
* This is designed to be like a very stripped down version of a std::promise/std::future pair. We
|
||||
* reimplemented it, however, because by ditching all the thread synchronization that promise/future
|
||||
* guarantees we can substantially reduce call overhead (by a factor of ~8 according to benchmarking
|
||||
* code). Since LokiMQ's proxy<->worker communication channel already gives us thread that overhead
|
||||
* code). Since OxenMQ's proxy<->worker communication channel already gives us thread that overhead
|
||||
* would just be wasted.
|
||||
*
|
||||
* @tparam R the value type held by the result; must be default constructible. Note, however, that
|
||||
|
@ -135,13 +135,13 @@ public:
|
|||
void get() { if (exc) std::rethrow_exception(exc); }
|
||||
};
|
||||
|
||||
/// Helper class used to set up batches of jobs to be scheduled via the lokimq job handler.
|
||||
/// Helper class used to set up batches of jobs to be scheduled via the oxenmq job handler.
|
||||
///
|
||||
/// @tparam R - the return type of the individual jobs
|
||||
///
|
||||
template <typename R>
|
||||
class Batch final : private detail::Batch {
|
||||
friend class LokiMQ;
|
||||
friend class OxenMQ;
|
||||
public:
|
||||
/// The completion function type, called after all jobs have finished.
|
||||
using CompletionFunc = std::function<void(std::vector<job_result<R>> results)>;
|
||||
|
@ -168,7 +168,7 @@ private:
|
|||
|
||||
void check_not_started() {
|
||||
if (started)
|
||||
throw std::logic_error("Cannot add jobs or completion function after starting a lokimq::Batch!");
|
||||
throw std::logic_error("Cannot add jobs or completion function after starting a oxenmq::Batch!");
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -202,7 +202,7 @@ public:
|
|||
/// \param thread - optional tagged thread in which to schedule the completion job. If not
|
||||
/// provided then the completion job is scheduled in the pool of batch job threads.
|
||||
///
|
||||
/// `thread` can be provided the value &LokiMQ::run_in_proxy to invoke the completion function
|
||||
/// `thread` can be provided the value &OxenMQ::run_in_proxy to invoke the completion function
|
||||
/// *IN THE PROXY THREAD* itself after all jobs have finished. Be very, very careful: this
|
||||
/// should be a nearly trivial job that does not require any substantial CPU time and does not
|
||||
/// block for any reason. This is only intended for the case where the completion job is so
|
||||
|
@ -268,7 +268,7 @@ private:
|
|||
|
||||
|
||||
template <typename R>
|
||||
void LokiMQ::batch(Batch<R>&& batch) {
|
||||
void OxenMQ::batch(Batch<R>&& batch) {
|
||||
if (batch.size().first == 0)
|
||||
throw std::logic_error("Cannot batch a a job batch with 0 jobs");
|
||||
// Need to send this over to the proxy thread via the base class pointer. It assumes ownership.
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019-2020, The Loki Project
|
||||
// Copyright (c) 2019-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include "bt_serialize.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
namespace detail {
|
||||
|
||||
/// Reads digits into an unsigned 64-bit int.
|
||||
|
@ -228,4 +228,4 @@ std::pair<std::string_view, std::string_view> bt_dict_consumer::next_string() {
|
|||
}
|
||||
|
||||
|
||||
} // namespace lokimq
|
||||
} // namespace oxenmq
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019-2020, The Loki Project
|
||||
// Copyright (c) 2019-2020, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -46,12 +46,12 @@
|
|||
|
||||
#include "bt_value.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
/** \file
|
||||
* LokiMQ serialization for internal commands is very simple: we support two primitive types,
|
||||
* OxenMQ serialization for internal commands is very simple: we support two primitive types,
|
||||
* strings and integers, and two container types, lists and dicts with string keys. On the wire
|
||||
* these go in BitTorrent byte encoding as described in BEP-0003
|
||||
* (https://www.bittorrent.org/beps/bep_0003.html#bencoding).
|
||||
|
@ -596,7 +596,7 @@ template <typename T, typename It>
|
|||
void get_tuple_impl_one(T& t, It& it) {
|
||||
const bt_variant& v = *it++;
|
||||
if constexpr (std::is_integral_v<T>) {
|
||||
t = lokimq::get_int<T>(v);
|
||||
t = oxenmq::get_int<T>(v);
|
||||
} else if constexpr (is_bt_tuple<T>) {
|
||||
if (std::holds_alternative<bt_list>(v))
|
||||
throw std::invalid_argument{"Unable to convert tuple: cannot create sub-tuple from non-bt_list"};
|
||||
|
@ -912,4 +912,4 @@ public:
|
|||
};
|
||||
|
||||
|
||||
} // namespace lokimq
|
||||
} // namespace oxenmq
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019-2020, The Loki Project
|
||||
// Copyright (c) 2019-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -38,7 +38,7 @@
|
|||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
struct bt_value;
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace lokimq::detail {
|
||||
namespace oxenmq::detail {
|
||||
|
||||
// Fallback - we just try a char
|
||||
template <typename OutputIt, typename = void>
|
|
@ -1,8 +1,8 @@
|
|||
#include "lokimq.h"
|
||||
#include "lokimq-internal.h"
|
||||
#include "oxenmq.h"
|
||||
#include "oxenmq-internal.h"
|
||||
#include "hex.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const ConnectionID& conn) {
|
||||
if (!conn.pk.empty())
|
||||
|
@ -24,7 +24,7 @@ void add_pollitem(std::vector<zmq::pollitem_t>& pollitems, zmq::socket_t& sock)
|
|||
} // anonymous namespace
|
||||
|
||||
|
||||
void LokiMQ::rebuild_pollitems() {
|
||||
void OxenMQ::rebuild_pollitems() {
|
||||
pollitems.clear();
|
||||
add_pollitem(pollitems, command);
|
||||
add_pollitem(pollitems, workers_socket);
|
||||
|
@ -35,7 +35,7 @@ void LokiMQ::rebuild_pollitems() {
|
|||
pollitems_stale = false;
|
||||
}
|
||||
|
||||
void LokiMQ::setup_external_socket(zmq::socket_t& socket) {
|
||||
void OxenMQ::setup_external_socket(zmq::socket_t& socket) {
|
||||
socket.set(zmq::sockopt::reconnect_ivl, (int) RECONNECT_INTERVAL.count());
|
||||
socket.set(zmq::sockopt::reconnect_ivl_max, (int) RECONNECT_INTERVAL_MAX.count());
|
||||
socket.set(zmq::sockopt::handshake_ivl, (int) HANDSHAKE_TIME.count());
|
||||
|
@ -47,7 +47,7 @@ void LokiMQ::setup_external_socket(zmq::socket_t& socket) {
|
|||
}
|
||||
}
|
||||
|
||||
void LokiMQ::setup_outgoing_socket(zmq::socket_t& socket, std::string_view remote_pubkey) {
|
||||
void OxenMQ::setup_outgoing_socket(zmq::socket_t& socket, std::string_view remote_pubkey) {
|
||||
|
||||
setup_external_socket(socket);
|
||||
|
||||
|
@ -67,7 +67,7 @@ void LokiMQ::setup_outgoing_socket(zmq::socket_t& socket, std::string_view remot
|
|||
// else let ZMQ pick a random one
|
||||
}
|
||||
|
||||
ConnectionID LokiMQ::connect_sn(std::string_view pubkey, std::chrono::milliseconds keep_alive, std::string_view hint) {
|
||||
ConnectionID OxenMQ::connect_sn(std::string_view pubkey, std::chrono::milliseconds keep_alive, std::string_view hint) {
|
||||
if (!proxy_thread.joinable())
|
||||
throw std::logic_error("Cannot call connect_sn() before calling `start()`");
|
||||
|
||||
|
@ -76,7 +76,7 @@ ConnectionID LokiMQ::connect_sn(std::string_view pubkey, std::chrono::millisecon
|
|||
return pubkey;
|
||||
}
|
||||
|
||||
ConnectionID LokiMQ::connect_remote(const address& remote, ConnectSuccess on_connect, ConnectFailure on_failure,
|
||||
ConnectionID OxenMQ::connect_remote(const address& remote, ConnectSuccess on_connect, ConnectFailure on_failure,
|
||||
AuthLevel auth_level, std::chrono::milliseconds timeout) {
|
||||
if (!proxy_thread.joinable())
|
||||
throw std::logic_error("Cannot call connect_remote() before calling `start()`");
|
||||
|
@ -96,13 +96,13 @@ ConnectionID LokiMQ::connect_remote(const address& remote, ConnectSuccess on_con
|
|||
return id;
|
||||
}
|
||||
|
||||
ConnectionID LokiMQ::connect_remote(std::string_view remote, ConnectSuccess on_connect, ConnectFailure on_failure,
|
||||
ConnectionID OxenMQ::connect_remote(std::string_view remote, ConnectSuccess on_connect, ConnectFailure on_failure,
|
||||
std::string_view pubkey, AuthLevel auth_level, std::chrono::milliseconds timeout) {
|
||||
return connect_remote(address{remote}.set_pubkey(pubkey),
|
||||
std::move(on_connect), std::move(on_failure), auth_level, timeout);
|
||||
}
|
||||
|
||||
void LokiMQ::disconnect(ConnectionID id, std::chrono::milliseconds linger) {
|
||||
void OxenMQ::disconnect(ConnectionID id, std::chrono::milliseconds linger) {
|
||||
detail::send_control(get_control_socket(), "DISCONNECT", bt_serialize<bt_dict>({
|
||||
{"conn_id", id.id},
|
||||
{"linger_ms", linger.count()},
|
||||
|
@ -111,7 +111,7 @@ void LokiMQ::disconnect(ConnectionID id, std::chrono::milliseconds linger) {
|
|||
}
|
||||
|
||||
std::pair<zmq::socket_t *, std::string>
|
||||
LokiMQ::proxy_connect_sn(std::string_view remote, std::string_view connect_hint, bool optional, bool incoming_only, bool outgoing_only, std::chrono::milliseconds keep_alive) {
|
||||
OxenMQ::proxy_connect_sn(std::string_view remote, std::string_view connect_hint, bool optional, bool incoming_only, bool outgoing_only, std::chrono::milliseconds keep_alive) {
|
||||
ConnectionID remote_cid{remote};
|
||||
auto its = peers.equal_range(remote_cid);
|
||||
peer_info* peer = nullptr;
|
||||
|
@ -186,7 +186,7 @@ LokiMQ::proxy_connect_sn(std::string_view remote, std::string_view connect_hint,
|
|||
return {&connections.back(), ""s};
|
||||
}
|
||||
|
||||
std::pair<zmq::socket_t *, std::string> LokiMQ::proxy_connect_sn(bt_dict_consumer data) {
|
||||
std::pair<zmq::socket_t *, std::string> OxenMQ::proxy_connect_sn(bt_dict_consumer data) {
|
||||
std::string_view hint, remote_pk;
|
||||
std::chrono::milliseconds keep_alive;
|
||||
bool optional = false, incoming_only = false, outgoing_only = false;
|
||||
|
@ -226,7 +226,7 @@ void update_connection_indices(Container& c, size_t index, AccessIndex get_index
|
|||
/// Closes outgoing connections and removes all references. Note that this will call `erase()`
|
||||
/// which can invalidate iterators on the various connection containers - if you don't want that,
|
||||
/// delete it first so that the container won't contain the element being deleted.
|
||||
void LokiMQ::proxy_close_connection(size_t index, std::chrono::milliseconds linger) {
|
||||
void OxenMQ::proxy_close_connection(size_t index, std::chrono::milliseconds linger) {
|
||||
connections[index].set(zmq::sockopt::linger, linger > 0ms ? (int) linger.count() : 0);
|
||||
pollitems_stale = true;
|
||||
connections.erase(connections.begin() + index);
|
||||
|
@ -244,7 +244,7 @@ void LokiMQ::proxy_close_connection(size_t index, std::chrono::milliseconds ling
|
|||
conn_index_to_id.erase(conn_index_to_id.begin() + index);
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_expire_idle_peers() {
|
||||
void OxenMQ::proxy_expire_idle_peers() {
|
||||
for (auto it = peers.begin(); it != peers.end(); ) {
|
||||
auto &info = it->second;
|
||||
if (info.outgoing()) {
|
||||
|
@ -267,7 +267,7 @@ void LokiMQ::proxy_expire_idle_peers() {
|
|||
}
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_conn_cleanup() {
|
||||
void OxenMQ::proxy_conn_cleanup() {
|
||||
LMQ_TRACE("starting proxy connections cleanup");
|
||||
|
||||
// Drop idle connections (if we haven't done it in a while)
|
||||
|
@ -307,7 +307,7 @@ void LokiMQ::proxy_conn_cleanup() {
|
|||
LMQ_TRACE("done proxy connections cleanup");
|
||||
};
|
||||
|
||||
void LokiMQ::proxy_connect_remote(bt_dict_consumer data) {
|
||||
void OxenMQ::proxy_connect_remote(bt_dict_consumer data) {
|
||||
AuthLevel auth_level = AuthLevel::none;
|
||||
long long conn_id = -1;
|
||||
ConnectSuccess on_connect;
|
||||
|
@ -372,7 +372,7 @@ void LokiMQ::proxy_connect_remote(bt_dict_consumer data) {
|
|||
peers.emplace(std::move(conn), std::move(peer));
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_disconnect(bt_dict_consumer data) {
|
||||
void OxenMQ::proxy_disconnect(bt_dict_consumer data) {
|
||||
ConnectionID connid{-1};
|
||||
std::chrono::milliseconds linger = 1s;
|
||||
|
||||
|
@ -388,7 +388,7 @@ void LokiMQ::proxy_disconnect(bt_dict_consumer data) {
|
|||
|
||||
proxy_disconnect(std::move(connid), linger);
|
||||
}
|
||||
void LokiMQ::proxy_disconnect(ConnectionID conn, std::chrono::milliseconds linger) {
|
||||
void OxenMQ::proxy_disconnect(ConnectionID conn, std::chrono::milliseconds linger) {
|
||||
LMQ_TRACE("Disconnecting outgoing connection to ", conn);
|
||||
auto pr = peers.equal_range(conn);
|
||||
for (auto it = pr.first; it != pr.second; ++it) {
|
|
@ -8,7 +8,7 @@
|
|||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
struct ConnectionID;
|
||||
|
||||
|
@ -77,18 +77,18 @@ private:
|
|||
long long id = 0;
|
||||
std::string pk;
|
||||
std::string route;
|
||||
friend class LokiMQ;
|
||||
friend class OxenMQ;
|
||||
friend struct std::hash<ConnectionID>;
|
||||
template <typename... T>
|
||||
friend bt_dict detail::build_send(ConnectionID to, std::string_view cmd, T&&... opts);
|
||||
friend std::ostream& operator<<(std::ostream& o, const ConnectionID& conn);
|
||||
};
|
||||
|
||||
} // namespace lokimq
|
||||
} // namespace oxenmq
|
||||
namespace std {
|
||||
template <> struct hash<lokimq::ConnectionID> {
|
||||
size_t operator()(const lokimq::ConnectionID &c) const {
|
||||
return c.sn() ? lokimq::already_hashed{}(c.pk) :
|
||||
template <> struct hash<oxenmq::ConnectionID> {
|
||||
size_t operator()(const oxenmq::ConnectionID &c) const {
|
||||
return c.sn() ? oxenmq::already_hashed{}(c.pk) :
|
||||
std::hash<long long>{}(c.id) + std::hash<std::string>{}(c.route);
|
||||
}
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019-2020, The Loki Project
|
||||
// Copyright (c) 2019-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include <cassert>
|
||||
#include "byte_type.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
namespace detail {
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#include "lokimq.h"
|
||||
#include "oxenmq.h"
|
||||
#include "batch.h"
|
||||
#include "lokimq-internal.h"
|
||||
#include "oxenmq-internal.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
void LokiMQ::proxy_batch(detail::Batch* batch) {
|
||||
void OxenMQ::proxy_batch(detail::Batch* batch) {
|
||||
batches.insert(batch);
|
||||
const auto [jobs, tagged_threads] = batch->size();
|
||||
LMQ_TRACE("proxy queuing batch job with ", jobs, " jobs", tagged_threads ? " (job uses tagged thread(s))" : "");
|
||||
|
@ -26,7 +26,7 @@ void LokiMQ::proxy_batch(detail::Batch* batch) {
|
|||
proxy_skip_one_poll = true;
|
||||
}
|
||||
|
||||
void LokiMQ::job(std::function<void()> f, std::optional<TaggedThreadID> thread) {
|
||||
void OxenMQ::job(std::function<void()> f, std::optional<TaggedThreadID> thread) {
|
||||
if (thread && thread->_id == -1)
|
||||
throw std::logic_error{"job() cannot be used to queue an in-proxy job"};
|
||||
auto* b = new Batch<void>;
|
||||
|
@ -35,7 +35,7 @@ void LokiMQ::job(std::function<void()> f, std::optional<TaggedThreadID> thread)
|
|||
detail::send_control(get_control_socket(), "BATCH", bt_serialize(reinterpret_cast<uintptr_t>(baseptr)));
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_schedule_reply_job(std::function<void()> f) {
|
||||
void OxenMQ::proxy_schedule_reply_job(std::function<void()> f) {
|
||||
auto* b = new Batch<void>;
|
||||
b->add_job(std::move(f));
|
||||
batches.insert(b);
|
||||
|
@ -43,7 +43,7 @@ void LokiMQ::proxy_schedule_reply_job(std::function<void()> f) {
|
|||
proxy_skip_one_poll = true;
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_run_batch_jobs(std::queue<batch_job>& jobs, const int reserved, int& active, bool reply) {
|
||||
void OxenMQ::proxy_run_batch_jobs(std::queue<batch_job>& jobs, const int reserved, int& active, bool reply) {
|
||||
while (!jobs.empty() && active_workers() < max_workers &&
|
||||
(active < reserved || active_workers() < general_workers)) {
|
||||
proxy_run_worker(get_idle_worker().load(std::move(jobs.front()), reply));
|
||||
|
@ -54,20 +54,20 @@ void LokiMQ::proxy_run_batch_jobs(std::queue<batch_job>& jobs, const int reserve
|
|||
|
||||
// Called either within the proxy thread, or before the proxy thread has been created; actually adds
|
||||
// the timer. If the timer object hasn't been set up yet it gets set up here.
|
||||
void LokiMQ::proxy_timer(std::function<void()> job, std::chrono::milliseconds interval, bool squelch, int thread) {
|
||||
void OxenMQ::proxy_timer(std::function<void()> job, std::chrono::milliseconds interval, bool squelch, int thread) {
|
||||
if (!timers)
|
||||
timers.reset(zmq_timers_new());
|
||||
|
||||
int timer_id = zmq_timers_add(timers.get(),
|
||||
interval.count(),
|
||||
[](int timer_id, void* self) { static_cast<LokiMQ*>(self)->_queue_timer_job(timer_id); },
|
||||
[](int timer_id, void* self) { static_cast<OxenMQ*>(self)->_queue_timer_job(timer_id); },
|
||||
this);
|
||||
if (timer_id == -1)
|
||||
throw zmq::error_t{};
|
||||
timer_jobs[timer_id] = { std::move(job), squelch, false, thread };
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_timer(bt_list_consumer timer_data) {
|
||||
void OxenMQ::proxy_timer(bt_list_consumer timer_data) {
|
||||
std::unique_ptr<std::function<void()>> func{reinterpret_cast<std::function<void()>*>(timer_data.consume_integer<uintptr_t>())};
|
||||
auto interval = std::chrono::milliseconds{timer_data.consume_integer<uint64_t>()};
|
||||
auto squelch = timer_data.consume_integer<bool>();
|
||||
|
@ -77,7 +77,7 @@ void LokiMQ::proxy_timer(bt_list_consumer timer_data) {
|
|||
proxy_timer(std::move(*func), interval, squelch, thread);
|
||||
}
|
||||
|
||||
void LokiMQ::_queue_timer_job(int timer_id) {
|
||||
void OxenMQ::_queue_timer_job(int timer_id) {
|
||||
auto it = timer_jobs.find(timer_id);
|
||||
if (it == timer_jobs.end()) {
|
||||
LMQ_LOG(warn, "Could not find timer job ", timer_id);
|
||||
|
@ -107,7 +107,7 @@ void LokiMQ::_queue_timer_job(int timer_id) {
|
|||
auto it = timer_jobs.find(timer_id);
|
||||
if (it != timer_jobs.end())
|
||||
it->second.running = false;
|
||||
}, LokiMQ::run_in_proxy);
|
||||
}, OxenMQ::run_in_proxy);
|
||||
}
|
||||
batches.insert(b);
|
||||
LMQ_TRACE("b: ", b->size().first, ", ", b->size().second, "; thread = ", thread);
|
||||
|
@ -118,7 +118,7 @@ void LokiMQ::_queue_timer_job(int timer_id) {
|
|||
queue.emplace(static_cast<detail::Batch*>(b), 0);
|
||||
}
|
||||
|
||||
void LokiMQ::add_timer(std::function<void()> job, std::chrono::milliseconds interval, bool squelch, std::optional<TaggedThreadID> thread) {
|
||||
void OxenMQ::add_timer(std::function<void()> job, std::chrono::milliseconds interval, bool squelch, std::optional<TaggedThreadID> thread) {
|
||||
int th_id = thread ? thread->_id : 0;
|
||||
if (proxy_thread.joinable()) {
|
||||
detail::send_control(get_control_socket(), "TIMER", bt_serialize(bt_list{{
|
||||
|
@ -131,9 +131,9 @@ void LokiMQ::add_timer(std::function<void()> job, std::chrono::milliseconds inte
|
|||
}
|
||||
}
|
||||
|
||||
void LokiMQ::TimersDeleter::operator()(void* timers) { zmq_timers_destroy(&timers); }
|
||||
void OxenMQ::TimersDeleter::operator()(void* timers) { zmq_timers_destroy(&timers); }
|
||||
|
||||
TaggedThreadID LokiMQ::add_tagged_thread(std::string name, std::function<void()> start) {
|
||||
TaggedThreadID OxenMQ::add_tagged_thread(std::string name, std::function<void()> start) {
|
||||
if (proxy_thread.joinable())
|
||||
throw std::logic_error{"Cannot add tagged threads after calling `start()`"};
|
||||
|
||||
|
@ -146,7 +146,7 @@ TaggedThreadID LokiMQ::add_tagged_thread(std::string name, std::function<void()>
|
|||
run.worker_routing_id = "t" + std::to_string(run.worker_id);
|
||||
LMQ_TRACE("Created new tagged thread ", name, " with routing id ", run.worker_routing_id);
|
||||
|
||||
run.worker_thread = std::thread{&LokiMQ::worker_thread, this, run.worker_id, name, std::move(start)};
|
||||
run.worker_thread = std::thread{&OxenMQ::worker_thread, this, run.worker_id, name, std::move(start)};
|
||||
|
||||
return TaggedThreadID{static_cast<int>(run.worker_id)};
|
||||
}
|
|
@ -2,16 +2,16 @@
|
|||
#include <vector>
|
||||
#include "connections.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
class LokiMQ;
|
||||
class OxenMQ;
|
||||
|
||||
/// Encapsulates an incoming message from a remote connection with message details plus extra
|
||||
/// info need to send a reply back through the proxy thread via the `reply()` method. Note that
|
||||
/// this object gets reused: callbacks should use but not store any reference beyond the callback.
|
||||
class Message {
|
||||
public:
|
||||
LokiMQ& lokimq; ///< The owning LokiMQ object
|
||||
OxenMQ& oxenmq; ///< The owning OxenMQ object
|
||||
std::vector<std::string_view> data; ///< The provided command data parts, if any.
|
||||
ConnectionID conn; ///< The connection info for routing a reply; also contains the pubkey/sn status.
|
||||
std::string reply_tag; ///< If the invoked command is a request command this is the required reply tag that will be prepended by `send_reply()`.
|
||||
|
@ -19,8 +19,8 @@ public:
|
|||
std::string remote; ///< Some sort of remote address from which the request came. Often "IP" for TCP connections and "localhost:UID:GID:PID" for UDP connections.
|
||||
|
||||
/// Constructor
|
||||
Message(LokiMQ& lmq, ConnectionID cid, Access access, std::string remote)
|
||||
: lokimq{lmq}, conn{std::move(cid)}, access{std::move(access)}, remote{std::move(remote)} {}
|
||||
Message(OxenMQ& lmq, ConnectionID cid, Access access, std::string remote)
|
||||
: oxenmq{lmq}, conn{std::move(cid)}, access{std::move(access)}, remote{std::move(remote)} {}
|
||||
|
||||
// Non-copyable
|
||||
Message(const Message&) = delete;
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
#include "lokimq.h"
|
||||
#include "oxenmq.h"
|
||||
|
||||
// Inside some method:
|
||||
// LMQ_LOG(warn, "bad ", 42, " stuff");
|
||||
|
@ -13,7 +13,7 @@
|
|||
# define LMQ_TRACE(...)
|
||||
#endif
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
constexpr char SN_ADDR_COMMAND[] = "inproc://sn-command";
|
||||
constexpr char SN_ADDR_WORKERS[] = "inproc://sn-workers";
|
|
@ -1,5 +1,5 @@
|
|||
#include "lokimq.h"
|
||||
#include "lokimq-internal.h"
|
||||
#include "oxenmq.h"
|
||||
#include "oxenmq-internal.h"
|
||||
#include "zmq.hpp"
|
||||
#include <map>
|
||||
#include <random>
|
||||
|
@ -13,7 +13,7 @@ extern "C" {
|
|||
}
|
||||
#include "hex.h"
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -76,20 +76,20 @@ std::pair<std::string, AuthLevel> extract_metadata(zmq::message_t& msg) {
|
|||
|
||||
} // namespace detail
|
||||
|
||||
void LokiMQ::set_zmq_context_option(zmq::ctxopt option, int value) {
|
||||
void OxenMQ::set_zmq_context_option(zmq::ctxopt option, int value) {
|
||||
context.set(option, value);
|
||||
}
|
||||
|
||||
void LokiMQ::log_level(LogLevel level) {
|
||||
void OxenMQ::log_level(LogLevel level) {
|
||||
log_lvl.store(level, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
LogLevel LokiMQ::log_level() const {
|
||||
LogLevel OxenMQ::log_level() const {
|
||||
return log_lvl.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
|
||||
CatHelper LokiMQ::add_category(std::string name, Access access_level, unsigned int reserved_threads, int max_queue) {
|
||||
CatHelper OxenMQ::add_category(std::string name, Access access_level, unsigned int reserved_threads, int max_queue) {
|
||||
check_not_started(proxy_thread, "add a category");
|
||||
|
||||
if (name.size() > MAX_CATEGORY_LENGTH)
|
||||
|
@ -107,7 +107,7 @@ CatHelper LokiMQ::add_category(std::string name, Access access_level, unsigned i
|
|||
return ret;
|
||||
}
|
||||
|
||||
void LokiMQ::add_command(const std::string& category, std::string name, CommandCallback callback) {
|
||||
void OxenMQ::add_command(const std::string& category, std::string name, CommandCallback callback) {
|
||||
check_not_started(proxy_thread, "add a command");
|
||||
|
||||
if (name.size() > MAX_COMMAND_LENGTH)
|
||||
|
@ -126,12 +126,12 @@ void LokiMQ::add_command(const std::string& category, std::string name, CommandC
|
|||
throw std::runtime_error("Cannot add command `" + fullname + "': that command already exists");
|
||||
}
|
||||
|
||||
void LokiMQ::add_request_command(const std::string& category, std::string name, CommandCallback callback) {
|
||||
void OxenMQ::add_request_command(const std::string& category, std::string name, CommandCallback callback) {
|
||||
add_command(category, name, std::move(callback));
|
||||
categories.at(category).commands.at(name).second = true;
|
||||
}
|
||||
|
||||
void LokiMQ::add_command_alias(std::string from, std::string to) {
|
||||
void OxenMQ::add_command_alias(std::string from, std::string to) {
|
||||
check_not_started(proxy_thread, "add a command alias");
|
||||
|
||||
if (from.empty())
|
||||
|
@ -160,10 +160,10 @@ std::atomic<int> next_id{1};
|
|||
/// Accesses a thread-local command socket connected to the proxy's command socket used to issue
|
||||
/// commands in a thread-safe manner. A mutex is only required here the first time a thread
|
||||
/// accesses the control socket.
|
||||
zmq::socket_t& LokiMQ::get_control_socket() {
|
||||
zmq::socket_t& OxenMQ::get_control_socket() {
|
||||
assert(proxy_thread.joinable());
|
||||
|
||||
// Optimize by caching the last value; LokiMQ is often a singleton and in that case we're
|
||||
// Optimize by caching the last value; OxenMQ is often a singleton and in that case we're
|
||||
// going to *always* hit this optimization. Even if it isn't, we're probably likely to need the
|
||||
// same control socket from the same thread multiple times sequentially so this may still help.
|
||||
static thread_local int last_id = -1;
|
||||
|
@ -174,7 +174,7 @@ zmq::socket_t& LokiMQ::get_control_socket() {
|
|||
std::lock_guard lock{control_sockets_mutex};
|
||||
|
||||
if (proxy_shutting_down)
|
||||
throw std::runtime_error("Unable to obtain LokiMQ control socket: proxy thread is shutting down");
|
||||
throw std::runtime_error("Unable to obtain OxenMQ control socket: proxy thread is shutting down");
|
||||
|
||||
auto& socket = control_sockets[std::this_thread::get_id()];
|
||||
if (!socket) {
|
||||
|
@ -188,7 +188,7 @@ zmq::socket_t& LokiMQ::get_control_socket() {
|
|||
}
|
||||
|
||||
|
||||
LokiMQ::LokiMQ(
|
||||
OxenMQ::OxenMQ(
|
||||
std::string pubkey_,
|
||||
std::string privkey_,
|
||||
bool service_node,
|
||||
|
@ -199,17 +199,17 @@ LokiMQ::LokiMQ(
|
|||
sn_lookup{std::move(lookup)}, log_lvl{level}, logger{std::move(logger)}
|
||||
{
|
||||
|
||||
LMQ_TRACE("Constructing LokiMQ, id=", object_id, ", this=", this);
|
||||
LMQ_TRACE("Constructing OxenMQ, id=", object_id, ", this=", this);
|
||||
|
||||
if (sodium_init() == -1)
|
||||
throw std::runtime_error{"libsodium initialization failed"};
|
||||
|
||||
if (pubkey.empty() != privkey.empty()) {
|
||||
throw std::invalid_argument("LokiMQ construction failed: one (and only one) of pubkey/privkey is empty. Both must be specified, or both empty to generate a key.");
|
||||
throw std::invalid_argument("OxenMQ construction failed: one (and only one) of pubkey/privkey is empty. Both must be specified, or both empty to generate a key.");
|
||||
} else if (pubkey.empty()) {
|
||||
if (service_node)
|
||||
throw std::invalid_argument("Cannot construct a service node mode LokiMQ without a keypair");
|
||||
LMQ_LOG(debug, "generating x25519 keypair for remote-only LokiMQ instance");
|
||||
throw std::invalid_argument("Cannot construct a service node mode OxenMQ without a keypair");
|
||||
LMQ_LOG(debug, "generating x25519 keypair for remote-only OxenMQ instance");
|
||||
pubkey.resize(crypto_box_PUBLICKEYBYTES);
|
||||
privkey.resize(crypto_box_SECRETKEYBYTES);
|
||||
crypto_box_keypair(reinterpret_cast<unsigned char*>(&pubkey[0]), reinterpret_cast<unsigned char*>(&privkey[0]));
|
||||
|
@ -224,11 +224,11 @@ LokiMQ::LokiMQ(
|
|||
std::string verify_pubkey(crypto_box_PUBLICKEYBYTES, 0);
|
||||
crypto_scalarmult_base(reinterpret_cast<unsigned char*>(&verify_pubkey[0]), reinterpret_cast<unsigned char*>(&privkey[0]));
|
||||
if (verify_pubkey != pubkey)
|
||||
throw std::invalid_argument("Invalid pubkey/privkey values given to LokiMQ construction: pubkey verification failed");
|
||||
throw std::invalid_argument("Invalid pubkey/privkey values given to OxenMQ construction: pubkey verification failed");
|
||||
}
|
||||
}
|
||||
|
||||
void LokiMQ::start() {
|
||||
void OxenMQ::start() {
|
||||
if (proxy_thread.joinable())
|
||||
throw std::logic_error("Cannot call start() multiple times!");
|
||||
|
||||
|
@ -238,19 +238,19 @@ void LokiMQ::start() {
|
|||
if (bind.empty() && local_service_node)
|
||||
throw std::invalid_argument{"Cannot create a service node listener with no address(es) to bind"};
|
||||
|
||||
LMQ_LOG(info, "Initializing LokiMQ ", bind.empty() ? "remote-only" : "listener", " with pubkey ", to_hex(pubkey));
|
||||
LMQ_LOG(info, "Initializing OxenMQ ", bind.empty() ? "remote-only" : "listener", " with pubkey ", to_hex(pubkey));
|
||||
|
||||
int zmq_socket_limit = context.get(zmq::ctxopt::socket_limit);
|
||||
if (MAX_SOCKETS > 1 && MAX_SOCKETS <= zmq_socket_limit)
|
||||
context.set(zmq::ctxopt::max_sockets, MAX_SOCKETS);
|
||||
else
|
||||
LMQ_LOG(error, "Not applying LokiMQ::MAX_SOCKETS setting: ", MAX_SOCKETS, " must be in [1, ", zmq_socket_limit, "]");
|
||||
LMQ_LOG(error, "Not applying OxenMQ::MAX_SOCKETS setting: ", MAX_SOCKETS, " must be in [1, ", zmq_socket_limit, "]");
|
||||
|
||||
// We bind `command` here so that the `get_control_socket()` below is always connecting to a
|
||||
// bound socket, but we do nothing else here: the proxy thread is responsible for everything
|
||||
// except binding it.
|
||||
command.bind(SN_ADDR_COMMAND);
|
||||
proxy_thread = std::thread{&LokiMQ::proxy_loop, this};
|
||||
proxy_thread = std::thread{&OxenMQ::proxy_loop, this};
|
||||
|
||||
LMQ_LOG(debug, "Waiting for proxy thread to get ready...");
|
||||
auto &control = get_control_socket();
|
||||
|
@ -260,14 +260,14 @@ void LokiMQ::start() {
|
|||
zmq::message_t ready_msg;
|
||||
std::vector<zmq::message_t> parts;
|
||||
try { recv_message_parts(control, parts); }
|
||||
catch (const zmq::error_t &e) { throw std::runtime_error("Failure reading from LokiMQ::Proxy thread: "s + e.what()); }
|
||||
catch (const zmq::error_t &e) { throw std::runtime_error("Failure reading from OxenMQ::Proxy thread: "s + e.what()); }
|
||||
|
||||
if (!(parts.size() == 1 && view(parts.front()) == "READY"))
|
||||
throw std::runtime_error("Invalid startup message from proxy thread (didn't get expected READY message)");
|
||||
LMQ_LOG(debug, "Proxy thread is ready");
|
||||
}
|
||||
|
||||
void LokiMQ::listen_curve(std::string bind_addr, AllowFunc allow_connection) {
|
||||
void OxenMQ::listen_curve(std::string bind_addr, AllowFunc allow_connection) {
|
||||
// TODO: there's no particular reason we can't start listening after starting up; just needs to
|
||||
// be implemented. (But if we can start we'll probably also want to be able to stop, so it's
|
||||
// more than just binding that needs implementing).
|
||||
|
@ -276,7 +276,7 @@ void LokiMQ::listen_curve(std::string bind_addr, AllowFunc allow_connection) {
|
|||
bind.emplace_back(std::move(bind_addr), bind_data{true, std::move(allow_connection)});
|
||||
}
|
||||
|
||||
void LokiMQ::listen_plain(std::string bind_addr, AllowFunc allow_connection) {
|
||||
void OxenMQ::listen_plain(std::string bind_addr, AllowFunc allow_connection) {
|
||||
// TODO: As above.
|
||||
check_not_started(proxy_thread, "start listening");
|
||||
|
||||
|
@ -284,7 +284,7 @@ void LokiMQ::listen_plain(std::string bind_addr, AllowFunc allow_connection) {
|
|||
}
|
||||
|
||||
|
||||
std::pair<LokiMQ::category*, const std::pair<LokiMQ::CommandCallback, bool>*> LokiMQ::get_command(std::string& command) {
|
||||
std::pair<OxenMQ::category*, const std::pair<OxenMQ::CommandCallback, bool>*> OxenMQ::get_command(std::string& command) {
|
||||
if (command.size() > MAX_CATEGORY_LENGTH + 1 + MAX_COMMAND_LENGTH) {
|
||||
LMQ_LOG(warn, "Invalid command '", command, "': command too long");
|
||||
return {};
|
||||
|
@ -320,7 +320,7 @@ std::pair<LokiMQ::category*, const std::pair<LokiMQ::CommandCallback, bool>*> Lo
|
|||
return {&catit->second, &callback_it->second};
|
||||
}
|
||||
|
||||
void LokiMQ::set_batch_threads(int threads) {
|
||||
void OxenMQ::set_batch_threads(int threads) {
|
||||
if (proxy_thread.joinable())
|
||||
throw std::logic_error("Cannot change reserved batch threads after calling `start()`");
|
||||
if (threads < -1) // -1 is the default which is based on general threads
|
||||
|
@ -328,7 +328,7 @@ void LokiMQ::set_batch_threads(int threads) {
|
|||
batch_jobs_reserved = threads;
|
||||
}
|
||||
|
||||
void LokiMQ::set_reply_threads(int threads) {
|
||||
void OxenMQ::set_reply_threads(int threads) {
|
||||
if (proxy_thread.joinable())
|
||||
throw std::logic_error("Cannot change reserved reply threads after calling `start()`");
|
||||
if (threads < -1) // -1 is the default which is based on general threads
|
||||
|
@ -336,7 +336,7 @@ void LokiMQ::set_reply_threads(int threads) {
|
|||
reply_jobs_reserved = threads;
|
||||
}
|
||||
|
||||
void LokiMQ::set_general_threads(int threads) {
|
||||
void OxenMQ::set_general_threads(int threads) {
|
||||
if (proxy_thread.joinable())
|
||||
throw std::logic_error("Cannot change general thread count after calling `start()`");
|
||||
if (threads < 1)
|
||||
|
@ -344,7 +344,7 @@ void LokiMQ::set_general_threads(int threads) {
|
|||
general_workers = threads;
|
||||
}
|
||||
|
||||
LokiMQ::run_info& LokiMQ::run_info::load(category* cat_, std::string command_, ConnectionID conn_, Access access_, std::string remote_,
|
||||
OxenMQ::run_info& OxenMQ::run_info::load(category* cat_, std::string command_, ConnectionID conn_, Access access_, std::string remote_,
|
||||
std::vector<zmq::message_t> data_parts_, const std::pair<CommandCallback, bool>* callback_) {
|
||||
reset();
|
||||
cat = cat_;
|
||||
|
@ -357,7 +357,7 @@ LokiMQ::run_info& LokiMQ::run_info::load(category* cat_, std::string command_, C
|
|||
return *this;
|
||||
}
|
||||
|
||||
LokiMQ::run_info& LokiMQ::run_info::load(category* cat_, std::string command_, std::string remote_, std::function<void()> callback) {
|
||||
OxenMQ::run_info& OxenMQ::run_info::load(category* cat_, std::string command_, std::string remote_, std::function<void()> callback) {
|
||||
reset();
|
||||
is_injected = true;
|
||||
cat = cat_;
|
||||
|
@ -369,7 +369,7 @@ LokiMQ::run_info& LokiMQ::run_info::load(category* cat_, std::string command_, s
|
|||
return *this;
|
||||
}
|
||||
|
||||
LokiMQ::run_info& LokiMQ::run_info::load(pending_command&& pending) {
|
||||
OxenMQ::run_info& OxenMQ::run_info::load(pending_command&& pending) {
|
||||
if (auto *f = std::get_if<std::function<void()>>(&pending.callback))
|
||||
return load(&pending.cat, std::move(pending.command), std::move(pending.remote), std::move(*f));
|
||||
|
||||
|
@ -378,7 +378,7 @@ LokiMQ::run_info& LokiMQ::run_info::load(pending_command&& pending) {
|
|||
std::move(pending.remote), std::move(pending.data_parts), var::get<0>(pending.callback));
|
||||
}
|
||||
|
||||
LokiMQ::run_info& LokiMQ::run_info::load(batch_job&& bj, bool reply_job, int tagged_thread) {
|
||||
OxenMQ::run_info& OxenMQ::run_info::load(batch_job&& bj, bool reply_job, int tagged_thread) {
|
||||
reset();
|
||||
is_batch_job = true;
|
||||
is_reply_job = reply_job;
|
||||
|
@ -389,7 +389,7 @@ LokiMQ::run_info& LokiMQ::run_info::load(batch_job&& bj, bool reply_job, int tag
|
|||
}
|
||||
|
||||
|
||||
LokiMQ::~LokiMQ() {
|
||||
OxenMQ::~OxenMQ() {
|
||||
if (!proxy_thread.joinable()) {
|
||||
if (!tagged_workers.empty()) {
|
||||
// This is a bit icky: we have tagged workers that are waiting for a signal on
|
||||
|
@ -416,10 +416,10 @@ LokiMQ::~LokiMQ() {
|
|||
return;
|
||||
}
|
||||
|
||||
LMQ_LOG(info, "LokiMQ shutting down proxy thread");
|
||||
LMQ_LOG(info, "OxenMQ shutting down proxy thread");
|
||||
detail::send_control(get_control_socket(), "QUIT");
|
||||
proxy_thread.join();
|
||||
LMQ_LOG(info, "LokiMQ proxy thread has stopped");
|
||||
LMQ_LOG(info, "OxenMQ proxy thread has stopped");
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, LogLevel lvl) {
|
||||
|
@ -443,5 +443,5 @@ std::string make_random_string(size_t size) {
|
|||
return rando;
|
||||
}
|
||||
|
||||
} // namespace lokimq
|
||||
} // namespace oxenmq
|
||||
// vim:sw=4:et
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019-2020, The Loki Project
|
||||
// Copyright (c) 2019-2021, The Oxen Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -56,7 +56,7 @@
|
|||
#error "ZMQ >= 4.3.0 required"
|
||||
#endif
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
|
@ -95,22 +95,22 @@ struct TaggedThreadID {
|
|||
private:
|
||||
int _id;
|
||||
explicit constexpr TaggedThreadID(int id) : _id{id} {}
|
||||
friend class LokiMQ;
|
||||
friend class OxenMQ;
|
||||
template <typename R> friend class Batch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that handles LokiMQ listeners, connections, proxying, and workers. An application
|
||||
* Class that handles OxenMQ listeners, connections, proxying, and workers. An application
|
||||
* typically has just one instance of this class.
|
||||
*/
|
||||
class LokiMQ {
|
||||
class OxenMQ {
|
||||
|
||||
private:
|
||||
|
||||
/// The global context
|
||||
zmq::context_t context;
|
||||
|
||||
/// A unique id for this LokiMQ instance, assigned in a thread-safe manner during construction.
|
||||
/// A unique id for this OxenMQ instance, assigned in a thread-safe manner during construction.
|
||||
const int object_id;
|
||||
|
||||
/// The x25519 keypair of this connection. For service nodes these are the long-run x25519 keys
|
||||
|
@ -135,10 +135,10 @@ private:
|
|||
std::mutex control_sockets_mutex;
|
||||
|
||||
/// Called to obtain a "command" socket that attaches to `control` to send commands to the
|
||||
/// proxy thread from other threads. This socket is unique per thread and LokiMQ instance.
|
||||
/// proxy thread from other threads. This socket is unique per thread and OxenMQ instance.
|
||||
zmq::socket_t& get_control_socket();
|
||||
|
||||
/// Per-thread control sockets used by lokimq threads to talk to this object's proxy thread.
|
||||
/// Per-thread control sockets used by oxenmq threads to talk to this object's proxy thread.
|
||||
std::unordered_map<std::thread::id, std::unique_ptr<zmq::socket_t>> control_sockets;
|
||||
|
||||
public:
|
||||
|
@ -171,7 +171,7 @@ public:
|
|||
using ReplyCallback = std::function<void(bool success, std::vector<std::string> data)>;
|
||||
|
||||
/// Called to write a log message. This will only be called if the `level` is >= the current
|
||||
/// LokiMQ object log level. It must be a raw function pointer (or a capture-less lambda) for
|
||||
/// OxenMQ object log level. It must be a raw function pointer (or a capture-less lambda) for
|
||||
/// performance reasons. Takes four arguments: the log level of the message, the filename and
|
||||
/// line number where the log message was invoked, and the log message itself.
|
||||
using Logger = std::function<void(LogLevel level, const char* file, int line, std::string msg)>;
|
||||
|
@ -182,12 +182,12 @@ public:
|
|||
using ConnectFailure = std::function<void(ConnectionID, std::string_view)>;
|
||||
|
||||
/// Explicitly non-copyable, non-movable because most things here aren't copyable, and a few
|
||||
/// things aren't movable, either. If you need to pass the LokiMQ instance around, wrap it
|
||||
/// things aren't movable, either. If you need to pass the OxenMQ instance around, wrap it
|
||||
/// in a unique_ptr or shared_ptr.
|
||||
LokiMQ(const LokiMQ&) = delete;
|
||||
LokiMQ& operator=(const LokiMQ&) = delete;
|
||||
LokiMQ(LokiMQ&&) = delete;
|
||||
LokiMQ& operator=(LokiMQ&&) = delete;
|
||||
OxenMQ(const OxenMQ&) = delete;
|
||||
OxenMQ& operator=(const OxenMQ&) = delete;
|
||||
OxenMQ(OxenMQ&&) = delete;
|
||||
OxenMQ& operator=(OxenMQ&&) = delete;
|
||||
|
||||
/** How long to wait for handshaking to complete on external connections before timing out and
|
||||
* closing the connection. Setting this only affects new outgoing connections. */
|
||||
|
@ -196,8 +196,8 @@ public:
|
|||
/** Whether to use a zmq routing ID based on the pubkey for new outgoing connections. This is
|
||||
* normally desirable as it allows the listener to recognize that the incoming connection is a
|
||||
* reconnection from the same remote and handover routing to the new socket while closing off
|
||||
* the (likely dead) old socket. This, however, prevents a single LokiMQ instance from
|
||||
* establishing multiple connections to the same listening LokiMQ, which is sometimes useful
|
||||
* the (likely dead) old socket. This, however, prevents a single OxenMQ instance from
|
||||
* establishing multiple connections to the same listening OxenMQ, which is sometimes useful
|
||||
* (for example when testing), and so this option can be overridden to `false` to use completely
|
||||
* random zmq routing ids on outgoing connections (which will thus allow multiple connections).
|
||||
*/
|
||||
|
@ -214,13 +214,13 @@ public:
|
|||
|
||||
/** Minimum reconnect interval: when a connection fails or dies, wait this long before
|
||||
* attempting to reconnect. (ZMQ may randomize the value somewhat to avoid reconnection
|
||||
* storms). See RECONNECT_INTERVAL_MAX as well. The LokiMQ default is 250ms.
|
||||
* storms). See RECONNECT_INTERVAL_MAX as well. The OxenMQ default is 250ms.
|
||||
*/
|
||||
std::chrono::milliseconds RECONNECT_INTERVAL = 250ms;
|
||||
|
||||
/** Maximum reconnect interval. When this is set to a value larger than RECONNECT_INTERVAL then
|
||||
* ZMQ's reconnection logic uses an exponential backoff: each reconnection attempts waits twice
|
||||
* as long as the previous attempt, up to this maximum. The LokiMQ default is 5 seconds.
|
||||
* as long as the previous attempt, up to this maximum. The OxenMQ default is 5 seconds.
|
||||
*/
|
||||
std::chrono::milliseconds RECONNECT_INTERVAL_MAX = 5s;
|
||||
|
||||
|
@ -539,7 +539,7 @@ private:
|
|||
/// Runs any queued batch jobs
|
||||
void proxy_run_batch_jobs(std::queue<batch_job>& jobs, int reserved, int& active, bool reply);
|
||||
|
||||
/// BATCH command. Called with a Batch<R> (see lokimq/batch.h) object pointer for the proxy to
|
||||
/// BATCH command. Called with a Batch<R> (see oxenmq/batch.h) object pointer for the proxy to
|
||||
/// take over and queue batch jobs.
|
||||
void proxy_batch(detail::Batch* batch);
|
||||
|
||||
|
@ -626,7 +626,7 @@ private:
|
|||
/// Details for a pending command; such a command already has authenticated access and is just
|
||||
/// waiting for a thread to become available to handle it. This also gets used (via the
|
||||
/// `callback` variant) for injected external jobs to be able to integrate some external
|
||||
/// interface with the lokimq job queue.
|
||||
/// interface with the oxenmq job queue.
|
||||
struct pending_command {
|
||||
category& cat;
|
||||
std::string command;
|
||||
|
@ -721,7 +721,7 @@ private:
|
|||
|
||||
public:
|
||||
/**
|
||||
* LokiMQ constructor. This constructs the object but does not start it; you will typically
|
||||
* OxenMQ constructor. This constructs the object but does not start it; you will typically
|
||||
* want to first add categories and commands, then finish startup by invoking `start()`.
|
||||
* (Categories and commands cannot be added after startup).
|
||||
*
|
||||
|
@ -745,7 +745,7 @@ public:
|
|||
* listening in curve25519 mode (otherwise we couldn't verify its authenticity). Should return
|
||||
* empty for not found or if SN lookups are not supported.
|
||||
*
|
||||
* @param allow_incoming is a callback that LokiMQ can use to determine whether an incoming
|
||||
* @param allow_incoming is a callback that OxenMQ can use to determine whether an incoming
|
||||
* connection should be allowed at all and, if so, whether the connection is from a known
|
||||
* service node. Called with the connecting IP, the remote's verified x25519 pubkey, and the
|
||||
* called on incoming connections with the (verified) incoming connection
|
||||
|
@ -758,7 +758,7 @@ public:
|
|||
* @param level the initial log level; defaults to warn. The log level can be changed later by
|
||||
* calling log_level(...).
|
||||
*/
|
||||
LokiMQ( std::string pubkey,
|
||||
OxenMQ( std::string pubkey,
|
||||
std::string privkey,
|
||||
bool service_node,
|
||||
SNRemoteAddress sn_lookup,
|
||||
|
@ -766,26 +766,26 @@ public:
|
|||
LogLevel level = LogLevel::warn);
|
||||
|
||||
/**
|
||||
* Simplified LokiMQ constructor for a non-listening client or simple listener without any
|
||||
* outgoing SN connection lookup capabilities. The LokiMQ object will not be able to establish
|
||||
* Simplified OxenMQ constructor for a non-listening client or simple listener without any
|
||||
* outgoing SN connection lookup capabilities. The OxenMQ object will not be able to establish
|
||||
* new connections (including reconnections) to service nodes by pubkey.
|
||||
*/
|
||||
explicit LokiMQ(
|
||||
explicit OxenMQ(
|
||||
Logger logger = [](LogLevel, const char*, int, std::string) { },
|
||||
LogLevel level = LogLevel::warn)
|
||||
: LokiMQ("", "", false, [](auto) { return ""s; /*no peer lookups*/ }, std::move(logger), level) {}
|
||||
: OxenMQ("", "", false, [](auto) { return ""s; /*no peer lookups*/ }, std::move(logger), level) {}
|
||||
|
||||
/**
|
||||
* Destructor; instructs the proxy to quit. The proxy tells all workers to quit, waits for them
|
||||
* to quit and rejoins the threads then quits itself. The outer thread (where the destructor is
|
||||
* running) rejoins the proxy thread.
|
||||
*/
|
||||
~LokiMQ();
|
||||
~OxenMQ();
|
||||
|
||||
/// Sets the log level of the LokiMQ object.
|
||||
/// Sets the log level of the OxenMQ object.
|
||||
void log_level(LogLevel level);
|
||||
|
||||
/// Gets the log level of the LokiMQ object.
|
||||
/// Gets the log level of the OxenMQ object.
|
||||
LogLevel log_level() const;
|
||||
|
||||
/**
|
||||
|
@ -848,7 +848,7 @@ public:
|
|||
*
|
||||
* Aliases should follow the `category.command` format for both the from and to names, and
|
||||
* should only be called for `to` categories that are already defined. The category name is not
|
||||
* currently enforced on the `from` name (for backwards compatility with Loki's quorumnet code)
|
||||
* currently enforced on the `from` name (for backwards compatility with Oxen's quorumnet code)
|
||||
* but will be at some point.
|
||||
*
|
||||
* Access permissions for an aliased command depend only on the mapped-to value; for example, if
|
||||
|
@ -871,7 +871,7 @@ public:
|
|||
* \param name - the name of the thread; will be used in log messages and (if supported by the
|
||||
* OS) as the system thread name.
|
||||
*
|
||||
* \param start - an optional callback to invoke from the thread as soon as LokiMQ itself starts
|
||||
* \param start - an optional callback to invoke from the thread as soon as OxenMQ itself starts
|
||||
* up (i.e. after a call to `start()`).
|
||||
*
|
||||
* \returns a TaggedThreadID object that can be passed to job(), batch(), or add_timer() to
|
||||
|
@ -887,7 +887,7 @@ public:
|
|||
* Note that some internal jobs are counted as batch jobs: in particular timers added via
|
||||
* add_timer() are scheduled as batch jobs.
|
||||
*
|
||||
* Cannot be called after start()ing the LokiMQ instance.
|
||||
* Cannot be called after start()ing the OxenMQ instance.
|
||||
*/
|
||||
void set_batch_threads(int threads);
|
||||
|
||||
|
@ -899,7 +899,7 @@ public:
|
|||
*
|
||||
* Defaults to one-eighth of the number of configured general threads, rounded up.
|
||||
*
|
||||
* Cannot be changed after start()ing the LokiMQ instance.
|
||||
* Cannot be changed after start()ing the OxenMQ instance.
|
||||
*/
|
||||
void set_reply_threads(int threads);
|
||||
|
||||
|
@ -914,7 +914,7 @@ public:
|
|||
*
|
||||
* Defaults to `std::thread::hardware_concurrency()`.
|
||||
*
|
||||
* Cannot be called after start()ing the LokiMQ instance.
|
||||
* Cannot be called after start()ing the OxenMQ instance.
|
||||
*/
|
||||
void set_general_threads(int threads);
|
||||
|
||||
|
@ -1006,7 +1006,7 @@ public:
|
|||
* established or failed to establish.
|
||||
*
|
||||
* @param remote the remote connection address either as implicitly from a string or as a full
|
||||
* lokimq::address object; see address.h for details. This specifies both the connection
|
||||
* oxenmq::address object; see address.h for details. This specifies both the connection
|
||||
* address and whether curve encryption should be used.
|
||||
* @param on_connect called with the identifier after the connection has been established.
|
||||
* @param on_failure called with the identifier and failure message if we fail to connect.
|
||||
|
@ -1033,7 +1033,7 @@ public:
|
|||
/// encryption as separate arguments. New code should either use a pubkey-embedded address
|
||||
/// string, or specify remote address and pubkey with an `address` object such as:
|
||||
/// connect_remote(address{remote, pubkey}, ...)
|
||||
[[deprecated("use connect_remote() with a lokimq::address instead")]]
|
||||
[[deprecated("use connect_remote() with a oxenmq::address instead")]]
|
||||
ConnectionID connect_remote(std::string_view remote, ConnectSuccess on_connect, ConnectFailure on_failure,
|
||||
std::string_view pubkey,
|
||||
AuthLevel auth_level = AuthLevel::none,
|
||||
|
@ -1058,7 +1058,7 @@ public:
|
|||
|
||||
/**
|
||||
* Queue a message to be relayed to the given service node or remote without requiring a reply.
|
||||
* LokiMQ will attempt to relay the message (first connecting and handshaking to the remote SN
|
||||
* OxenMQ will attempt to relay the message (first connecting and handshaking to the remote SN
|
||||
* if not already connected).
|
||||
*
|
||||
* If a new connection is established it will have a relatively short (30s) idle timeout. If
|
||||
|
@ -1128,10 +1128,10 @@ public:
|
|||
template <typename... T>
|
||||
void request(ConnectionID to, std::string_view cmd, ReplyCallback callback, const T&... opts);
|
||||
|
||||
/** Injects an external task into the lokimq command queue. This is used to allow connecting
|
||||
* non-LokiMQ requests into the LokiMQ thread pool as if they were ordinary requests, to be
|
||||
/** Injects an external task into the oxenmq command queue. This is used to allow connecting
|
||||
* non-OxenMQ requests into the OxenMQ thread pool as if they were ordinary requests, to be
|
||||
* scheduled as commands of an individual category. For example, you might support rpc requests
|
||||
* via LokiMQ as `rpc.some_command` and *also* accept them over HTTP. Using `inject_task()`
|
||||
* via OxenMQ as `rpc.some_command` and *also* accept them over HTTP. Using `inject_task()`
|
||||
* allows you to handle processing the request in the same thread pool with the same priority as
|
||||
* `rpc.*` commands.
|
||||
*
|
||||
|
@ -1154,12 +1154,12 @@ public:
|
|||
*/
|
||||
void inject_task(const std::string& category, std::string command, std::string remote, std::function<void()> callback);
|
||||
|
||||
/// The key pair this LokiMQ was created with; if empty keys were given during construction then
|
||||
/// The key pair this OxenMQ was created with; if empty keys were given during construction then
|
||||
/// this returns the generated keys.
|
||||
const std::string& get_pubkey() const { return pubkey; }
|
||||
const std::string& get_privkey() const { return privkey; }
|
||||
|
||||
/** Updates (or initially sets) LokiMQ's list of service node pubkeys with the given list.
|
||||
/** Updates (or initially sets) OxenMQ's list of service node pubkeys with the given list.
|
||||
*
|
||||
* This has two main effects:
|
||||
*
|
||||
|
@ -1182,7 +1182,7 @@ public:
|
|||
|
||||
/** Updates the list of active pubkeys by adding or removing the given pubkeys from the existing
|
||||
* list. This is more efficient when the incremental information is already available; if it
|
||||
* isn't, simply call set_active_sns with a new list to have LokiMQ figure out what was added or
|
||||
* isn't, simply call set_active_sns with a new list to have OxenMQ figure out what was added or
|
||||
* removed.
|
||||
*
|
||||
* \param added new pubkeys that were added since the last set_active_sns or update_active_sns
|
||||
|
@ -1197,7 +1197,7 @@ public:
|
|||
/**
|
||||
* Batches a set of jobs to be executed by workers, optionally followed by a completion function.
|
||||
*
|
||||
* Must include lokimq/batch.h to use.
|
||||
* Must include oxenmq/batch.h to use.
|
||||
*/
|
||||
template <typename R>
|
||||
void batch(Batch<R>&& batch);
|
||||
|
@ -1241,18 +1241,18 @@ public:
|
|||
/// .add_request_command("b", ...)
|
||||
/// ;
|
||||
class CatHelper {
|
||||
LokiMQ& lmq;
|
||||
OxenMQ& lmq;
|
||||
std::string cat;
|
||||
|
||||
public:
|
||||
CatHelper(LokiMQ& lmq, std::string cat) : lmq{lmq}, cat{std::move(cat)} {}
|
||||
CatHelper(OxenMQ& lmq, std::string cat) : lmq{lmq}, cat{std::move(cat)} {}
|
||||
|
||||
CatHelper& add_command(std::string name, LokiMQ::CommandCallback callback) {
|
||||
CatHelper& add_command(std::string name, OxenMQ::CommandCallback callback) {
|
||||
lmq.add_command(cat, std::move(name), std::move(callback));
|
||||
return *this;
|
||||
}
|
||||
|
||||
CatHelper& add_request_command(std::string name, LokiMQ::CommandCallback callback) {
|
||||
CatHelper& add_request_command(std::string name, OxenMQ::CommandCallback callback) {
|
||||
lmq.add_request_command(cat, std::move(name), std::move(callback));
|
||||
return *this;
|
||||
}
|
||||
|
@ -1368,7 +1368,7 @@ struct queue_full {
|
|||
namespace detail {
|
||||
|
||||
/// Takes an rvalue reference, moves it into a new instance then returns a uintptr_t value
|
||||
/// containing the pointer to be serialized to pass (via lokimq queues) from one thread to another.
|
||||
/// containing the pointer to be serialized to pass (via oxenmq queues) from one thread to another.
|
||||
/// Must be matched with a deserializer_pointer on the other side to reconstitute the object and
|
||||
/// destroy the intermediate pointer.
|
||||
template <typename T>
|
||||
|
@ -1468,7 +1468,7 @@ bt_dict build_send(ConnectionID to, std::string_view cmd, T&&... opts) {
|
|||
|
||||
|
||||
template <typename... T>
|
||||
void LokiMQ::send(ConnectionID to, std::string_view cmd, const T&... opts) {
|
||||
void OxenMQ::send(ConnectionID to, std::string_view cmd, const T&... opts) {
|
||||
detail::send_control(get_control_socket(), "SEND",
|
||||
bt_serialize(detail::build_send(std::move(to), cmd, opts...)));
|
||||
}
|
||||
|
@ -1476,7 +1476,7 @@ void LokiMQ::send(ConnectionID to, std::string_view cmd, const T&... opts) {
|
|||
std::string make_random_string(size_t size);
|
||||
|
||||
template <typename... T>
|
||||
void LokiMQ::request(ConnectionID to, std::string_view cmd, ReplyCallback callback, const T &...opts) {
|
||||
void OxenMQ::request(ConnectionID to, std::string_view cmd, ReplyCallback callback, const T &...opts) {
|
||||
const auto reply_tag = make_random_string(15); // 15 random bytes is lots and should keep us in most stl implementations' small string optimization
|
||||
bt_dict control_data = detail::build_send(std::move(to), cmd, reply_tag, opts...);
|
||||
control_data["request"] = true;
|
||||
|
@ -1487,23 +1487,23 @@ void LokiMQ::request(ConnectionID to, std::string_view cmd, ReplyCallback callba
|
|||
|
||||
template <typename... Args>
|
||||
void Message::send_back(std::string_view command, Args&&... args) {
|
||||
lokimq.send(conn, command, send_option::optional{!conn.sn()}, std::forward<Args>(args)...);
|
||||
oxenmq.send(conn, command, send_option::optional{!conn.sn()}, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void Message::send_reply(Args&&... args) {
|
||||
assert(!reply_tag.empty());
|
||||
lokimq.send(conn, "REPLY", reply_tag, send_option::optional{!conn.sn()}, std::forward<Args>(args)...);
|
||||
oxenmq.send(conn, "REPLY", reply_tag, send_option::optional{!conn.sn()}, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Callback, typename... Args>
|
||||
void Message::send_request(std::string_view cmd, Callback&& callback, Args&&... args) {
|
||||
lokimq.request(conn, cmd, std::forward<Callback>(callback),
|
||||
oxenmq.request(conn, cmd, std::forward<Callback>(callback),
|
||||
send_option::optional{!conn.sn()}, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// When log messages are invoked we strip out anything before this in the filename:
|
||||
constexpr std::string_view LOG_PREFIX{"lokimq/", 7};
|
||||
constexpr std::string_view LOG_PREFIX{"oxenmq/", 7};
|
||||
inline std::string_view trim_log_filename(std::string_view local_file) {
|
||||
auto chop = local_file.rfind(LOG_PREFIX);
|
||||
if (chop != local_file.npos)
|
||||
|
@ -1512,7 +1512,7 @@ inline std::string_view trim_log_filename(std::string_view local_file) {
|
|||
}
|
||||
|
||||
template <typename... T>
|
||||
void LokiMQ::log(LogLevel lvl, const char* file, int line, const T&... stuff) {
|
||||
void OxenMQ::log(LogLevel lvl, const char* file, int line, const T&... stuff) {
|
||||
if (log_level() < lvl)
|
||||
return;
|
||||
|
||||
|
@ -1523,6 +1523,6 @@ void LokiMQ::log(LogLevel lvl, const char* file, int line, const T&... stuff) {
|
|||
|
||||
std::ostream &operator<<(std::ostream &os, LogLevel lvl);
|
||||
|
||||
} // namespace lokimq
|
||||
} // namespace oxenmq
|
||||
|
||||
// vim:sw=4:et
|
|
@ -1,5 +1,5 @@
|
|||
#include "lokimq.h"
|
||||
#include "lokimq-internal.h"
|
||||
#include "oxenmq.h"
|
||||
#include "oxenmq-internal.h"
|
||||
#include "hex.h"
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
|
@ -17,9 +17,9 @@ extern "C" {
|
|||
}
|
||||
#endif
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
void LokiMQ::proxy_quit() {
|
||||
void OxenMQ::proxy_quit() {
|
||||
LMQ_LOG(debug, "Received quit command, shutting down proxy thread");
|
||||
|
||||
assert(std::none_of(workers.begin(), workers.end(), [](auto& worker) { return worker.worker_thread.joinable(); }));
|
||||
|
@ -41,7 +41,7 @@ void LokiMQ::proxy_quit() {
|
|||
LMQ_LOG(debug, "Proxy thread teardown complete");
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_send(bt_dict_consumer data) {
|
||||
void OxenMQ::proxy_send(bt_dict_consumer data) {
|
||||
// NB: bt_dict_consumer goes in alphabetical order
|
||||
std::string_view hint;
|
||||
std::chrono::milliseconds keep_alive{DEFAULT_SEND_KEEP_ALIVE};
|
||||
|
@ -205,7 +205,7 @@ void LokiMQ::proxy_send(bt_dict_consumer data) {
|
|||
}
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_reply(bt_dict_consumer data) {
|
||||
void OxenMQ::proxy_reply(bt_dict_consumer data) {
|
||||
bool have_conn_id = false;
|
||||
ConnectionID conn_id{0};
|
||||
if (data.skip_until("conn_id")) {
|
||||
|
@ -250,11 +250,11 @@ void LokiMQ::proxy_reply(bt_dict_consumer data) {
|
|||
}
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_control_message(std::vector<zmq::message_t>& parts) {
|
||||
void OxenMQ::proxy_control_message(std::vector<zmq::message_t>& parts) {
|
||||
// We throw an uncaught exception here because we only generate control messages internally in
|
||||
// lokimq code: if one of these condition fail it's a lokimq bug.
|
||||
// oxenmq code: if one of these condition fail it's a oxenmq bug.
|
||||
if (parts.size() < 2)
|
||||
throw std::logic_error("LokiMQ bug: Expected 2-3 message parts for a proxy control message");
|
||||
throw std::logic_error("OxenMQ bug: Expected 2-3 message parts for a proxy control message");
|
||||
auto route = view(parts[0]), cmd = view(parts[1]);
|
||||
LMQ_TRACE("control message: ", cmd);
|
||||
if (parts.size() == 3) {
|
||||
|
@ -306,11 +306,11 @@ void LokiMQ::proxy_control_message(std::vector<zmq::message_t>& parts) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("LokiMQ bug: Proxy received invalid control command: " +
|
||||
throw std::runtime_error("OxenMQ bug: Proxy received invalid control command: " +
|
||||
std::string{cmd} + " (" + std::to_string(parts.size()) + ")");
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_loop() {
|
||||
void OxenMQ::proxy_loop() {
|
||||
|
||||
#if defined(__linux__) || defined(__sun) || defined(__MINGW32__)
|
||||
pthread_setname_np(pthread_self(), "lmq-proxy");
|
||||
|
@ -371,7 +371,7 @@ void LokiMQ::proxy_loop() {
|
|||
listener.set(zmq::sockopt::router_mandatory, true);
|
||||
|
||||
listener.bind(bind[i].first);
|
||||
LMQ_LOG(info, "LokiMQ listening on ", bind[i].first);
|
||||
LMQ_LOG(info, "OxenMQ listening on ", bind[i].first);
|
||||
|
||||
connections.push_back(std::move(listener));
|
||||
auto conn_id = next_conn_id++;
|
||||
|
@ -547,7 +547,7 @@ static bool is_error_response(std::string_view cmd) {
|
|||
|
||||
// Return true if we recognized/handled the builtin command (even if we reject it for whatever
|
||||
// reason)
|
||||
bool LokiMQ::proxy_handle_builtin(size_t conn_index, std::vector<zmq::message_t>& parts) {
|
||||
bool OxenMQ::proxy_handle_builtin(size_t conn_index, std::vector<zmq::message_t>& parts) {
|
||||
// Doubling as a bool and an offset:
|
||||
size_t incoming = connections[conn_index].get(zmq::sockopt::type) == ZMQ_ROUTER;
|
||||
|
||||
|
@ -644,7 +644,7 @@ bool LokiMQ::proxy_handle_builtin(size_t conn_index, std::vector<zmq::message_t>
|
|||
// pre-1.1.0 sent just a plain UNKNOWNCOMMAND (without the actual command); this was not
|
||||
// useful, but also this response is *expected* for things 1.0.5 didn't understand, like
|
||||
// FORBIDDEN_SN: so log it only at debug level and move on.
|
||||
LMQ_LOG(debug, "Received plain UNKNOWNCOMMAND; remote is probably an older lokimq. Ignoring.");
|
||||
LMQ_LOG(debug, "Received plain UNKNOWNCOMMAND; remote is probably an older oxenmq. Ignoring.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -669,7 +669,7 @@ bool LokiMQ::proxy_handle_builtin(size_t conn_index, std::vector<zmq::message_t>
|
|||
return false;
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_process_queue() {
|
||||
void OxenMQ::proxy_process_queue() {
|
||||
if (max_workers == 0) // shutting down
|
||||
return;
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <string_view>
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
// Deprecated type alias for std::string_view
|
||||
using string_view = std::string_view;
|
|
@ -0,0 +1,5 @@
|
|||
namespace oxenmq {
|
||||
constexpr int VERSION_MAJOR = @OXENMQ_VERSION_MAJOR@;
|
||||
constexpr int VERSION_MINOR = @OXENMQ_VERSION_MINOR@;
|
||||
constexpr int VERSION_PATCH = @OXENMQ_VERSION_PATCH@;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#include "lokimq.h"
|
||||
#include "oxenmq.h"
|
||||
#include "batch.h"
|
||||
#include "lokimq-internal.h"
|
||||
#include "oxenmq-internal.h"
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
extern "C" {
|
||||
|
@ -9,7 +9,7 @@ extern "C" {
|
|||
}
|
||||
#endif
|
||||
|
||||
namespace lokimq {
|
||||
namespace oxenmq {
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace {
|
|||
// received. If "QUIT" was received, replies with "QUITTING" on the socket and closes it, then
|
||||
// returns false.
|
||||
[[gnu::always_inline]] inline
|
||||
bool worker_wait_for(LokiMQ& lmq, zmq::socket_t& sock, std::vector<zmq::message_t>& parts, const std::string_view worker_id, const std::string_view expect) {
|
||||
bool worker_wait_for(OxenMQ& lmq, zmq::socket_t& sock, std::vector<zmq::message_t>& parts, const std::string_view worker_id, const std::string_view expect) {
|
||||
while (true) {
|
||||
lmq.log(LogLevel::debug, __FILE__, __LINE__, "worker ", worker_id, " waiting for ", expect);
|
||||
parts.clear();
|
||||
|
@ -46,7 +46,7 @@ bool worker_wait_for(LokiMQ& lmq, zmq::socket_t& sock, std::vector<zmq::message_
|
|||
|
||||
}
|
||||
|
||||
void LokiMQ::worker_thread(unsigned int index, std::optional<std::string> tagged, std::function<void()> start) {
|
||||
void OxenMQ::worker_thread(unsigned int index, std::optional<std::string> tagged, std::function<void()> start) {
|
||||
std::string routing_id = (tagged ? "t" : "w") + std::to_string(index); // for routing
|
||||
std::string_view worker_id{tagged ? *tagged : routing_id}; // for debug
|
||||
|
||||
|
@ -72,8 +72,8 @@ void LokiMQ::worker_thread(unsigned int index, std::optional<std::string> tagged
|
|||
|
||||
bool waiting_for_command;
|
||||
if (tagged) {
|
||||
// If we're a tagged worker then we got started up before LokiMQ started, so we need to wait
|
||||
// for an all-clear signal from LokiMQ first, then we fire our `start` callback, then we can
|
||||
// If we're a tagged worker then we got started up before OxenMQ started, so we need to wait
|
||||
// for an all-clear signal from OxenMQ first, then we fire our `start` callback, then we can
|
||||
// start waiting for commands in the main loop further down. (We also can't get the
|
||||
// reference to our `tagged_workers` element until the main proxy threads is running).
|
||||
|
||||
|
@ -159,7 +159,7 @@ void LokiMQ::worker_thread(unsigned int index, std::optional<std::string> tagged
|
|||
}
|
||||
|
||||
|
||||
LokiMQ::run_info& LokiMQ::get_idle_worker() {
|
||||
OxenMQ::run_info& OxenMQ::get_idle_worker() {
|
||||
if (idle_workers.empty()) {
|
||||
size_t id = workers.size();
|
||||
assert(workers.capacity() > id);
|
||||
|
@ -174,7 +174,7 @@ LokiMQ::run_info& LokiMQ::get_idle_worker() {
|
|||
return workers[id];
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_worker_message(std::vector<zmq::message_t>& parts) {
|
||||
void OxenMQ::proxy_worker_message(std::vector<zmq::message_t>& parts) {
|
||||
// Process messages sent by workers
|
||||
if (parts.size() != 2) {
|
||||
LMQ_LOG(error, "Received send invalid ", parts.size(), "-part message");
|
||||
|
@ -268,14 +268,14 @@ void LokiMQ::proxy_worker_message(std::vector<zmq::message_t>& parts) {
|
|||
}
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_run_worker(run_info& run) {
|
||||
void OxenMQ::proxy_run_worker(run_info& run) {
|
||||
if (!run.worker_thread.joinable())
|
||||
run.worker_thread = std::thread{[this, id=run.worker_id] { worker_thread(id); }};
|
||||
else
|
||||
send_routed_message(workers_socket, run.worker_routing_id, "RUN");
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_to_worker(size_t conn_index, std::vector<zmq::message_t>& parts) {
|
||||
void OxenMQ::proxy_to_worker(size_t conn_index, std::vector<zmq::message_t>& parts) {
|
||||
bool outgoing = connections[conn_index].get(zmq::sockopt::type) == ZMQ_DEALER;
|
||||
|
||||
peer_info tmp_peer;
|
||||
|
@ -377,7 +377,7 @@ void LokiMQ::proxy_to_worker(size_t conn_index, std::vector<zmq::message_t>& par
|
|||
category.active_threads++;
|
||||
}
|
||||
|
||||
void LokiMQ::inject_task(const std::string& category, std::string command, std::string remote, std::function<void()> callback) {
|
||||
void OxenMQ::inject_task(const std::string& category, std::string command, std::string remote, std::function<void()> callback) {
|
||||
if (!callback) return;
|
||||
auto it = categories.find(category);
|
||||
if (it == categories.end())
|
||||
|
@ -386,7 +386,7 @@ void LokiMQ::inject_task(const std::string& category, std::string command, std::
|
|||
injected_task{it->second, std::move(command), std::move(remote), std::move(callback)})));
|
||||
}
|
||||
|
||||
void LokiMQ::proxy_inject_task(injected_task task) {
|
||||
void OxenMQ::proxy_inject_task(injected_task task) {
|
||||
auto& category = task.cat;
|
||||
if (category.active_threads >= category.reserved_threads && active_workers() >= general_workers) {
|
||||
// No free worker slot, queue for later
|
|
@ -19,7 +19,7 @@ add_executable(tests ${LMQ_TEST_SRC})
|
|||
|
||||
find_package(Threads)
|
||||
|
||||
target_link_libraries(tests Catch2::Catch2 lokimq Threads::Threads)
|
||||
target_link_libraries(tests Catch2::Catch2 oxenmq Threads::Threads)
|
||||
|
||||
set_target_properties(tests PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
#include "lokimq/lokimq.h"
|
||||
#include "oxenmq/oxenmq.h"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
using namespace lokimq;
|
||||
using namespace oxenmq;
|
||||
|
||||
static auto startup = std::chrono::steady_clock::now();
|
||||
|
||||
|
@ -41,7 +41,7 @@ inline std::unique_lock<std::mutex> catch_lock() {
|
|||
return std::unique_lock<std::mutex>{mutex};
|
||||
}
|
||||
|
||||
inline LokiMQ::Logger get_logger(std::string prefix = "") {
|
||||
inline OxenMQ::Logger get_logger(std::string prefix = "") {
|
||||
std::string me = "tests/common.h";
|
||||
std::string strip = __FILE__;
|
||||
if (strip.substr(strip.size() - me.size()) == me)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "lokimq/address.h"
|
||||
#include "oxenmq/address.h"
|
||||
#include "common.h"
|
||||
|
||||
const std::string pk = "\xf1\x6b\xa5\x59\x10\x39\xf0\x89\xb4\x2a\x83\x41\x75\x09\x30\x94\x07\x4d\x0d\x93\x7a\x79\xe5\x3e\x5c\xe7\x30\xf9\x46\xe1\x4b\x88";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "lokimq/batch.h"
|
||||
#include "oxenmq/batch.h"
|
||||
#include "common.h"
|
||||
#include <future>
|
||||
|
||||
|
@ -12,7 +12,7 @@ double do_my_task(int input) {
|
|||
|
||||
std::promise<std::pair<double, int>> done;
|
||||
|
||||
void continue_big_task(std::vector<lokimq::job_result<double>> results) {
|
||||
void continue_big_task(std::vector<oxenmq::job_result<double>> results) {
|
||||
double sum = 0;
|
||||
int exc_count = 0;
|
||||
for (auto& r : results) {
|
||||
|
@ -25,10 +25,10 @@ void continue_big_task(std::vector<lokimq::job_result<double>> results) {
|
|||
done.set_value({sum, exc_count});
|
||||
}
|
||||
|
||||
void start_big_task(lokimq::LokiMQ& lmq) {
|
||||
void start_big_task(oxenmq::OxenMQ& lmq) {
|
||||
size_t num_jobs = 32;
|
||||
|
||||
lokimq::Batch<double /*return type*/> batch;
|
||||
oxenmq::Batch<double /*return type*/> batch;
|
||||
batch.reserve(num_jobs);
|
||||
|
||||
for (size_t i = 0; i < num_jobs; i++)
|
||||
|
@ -41,7 +41,7 @@ void start_big_task(lokimq::LokiMQ& lmq) {
|
|||
|
||||
|
||||
TEST_CASE("batching many small jobs", "[batch-many]") {
|
||||
lokimq::LokiMQ lmq{
|
||||
oxenmq::OxenMQ lmq{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -58,7 +58,7 @@ TEST_CASE("batching many small jobs", "[batch-many]") {
|
|||
}
|
||||
|
||||
TEST_CASE("batch exception propagation", "[batch-exceptions]") {
|
||||
lokimq::LokiMQ lmq{
|
||||
oxenmq::OxenMQ lmq{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -73,7 +73,7 @@ TEST_CASE("batch exception propagation", "[batch-exceptions]") {
|
|||
using Catch::Matchers::Message;
|
||||
|
||||
SECTION( "value return" ) {
|
||||
lokimq::Batch<int> batch;
|
||||
oxenmq::Batch<int> batch;
|
||||
for (int i : {1, 2})
|
||||
batch.add_job([i]() { if (i == 1) return 42; throw std::domain_error("bad value " + std::to_string(i)); });
|
||||
batch.completion([&done_promise](auto results) {
|
||||
|
@ -88,7 +88,7 @@ TEST_CASE("batch exception propagation", "[batch-exceptions]") {
|
|||
}
|
||||
|
||||
SECTION( "lvalue return" ) {
|
||||
lokimq::Batch<int&> batch;
|
||||
oxenmq::Batch<int&> batch;
|
||||
int forty_two = 42;
|
||||
for (int i : {1, 2})
|
||||
batch.add_job([i,&forty_two]() -> int& {
|
||||
|
@ -110,7 +110,7 @@ TEST_CASE("batch exception propagation", "[batch-exceptions]") {
|
|||
}
|
||||
|
||||
SECTION( "void return" ) {
|
||||
lokimq::Batch<void> batch;
|
||||
oxenmq::Batch<void> batch;
|
||||
for (int i : {1, 2})
|
||||
batch.add_job([i]() { if (i != 1) throw std::domain_error("bad value " + std::to_string(i)); });
|
||||
batch.completion([&done_promise](auto results) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "lokimq/bt_serialize.h"
|
||||
#include "oxenmq/bt_serialize.h"
|
||||
#include "common.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
@ -129,10 +129,10 @@ TEST_CASE("bt_value deserialization", "[bt][deserialization][bt_value]") {
|
|||
REQUIRE( var::get<int64_t>(dna2) == -42 );
|
||||
REQUIRE_THROWS( var::get<int64_t>(dna1) );
|
||||
REQUIRE_THROWS( var::get<uint64_t>(dna2) );
|
||||
REQUIRE( lokimq::get_int<int>(dna1) == 42 );
|
||||
REQUIRE( lokimq::get_int<int>(dna2) == -42 );
|
||||
REQUIRE( lokimq::get_int<unsigned>(dna1) == 42 );
|
||||
REQUIRE_THROWS( lokimq::get_int<unsigned>(dna2) );
|
||||
REQUIRE( oxenmq::get_int<int>(dna1) == 42 );
|
||||
REQUIRE( oxenmq::get_int<int>(dna2) == -42 );
|
||||
REQUIRE( oxenmq::get_int<unsigned>(dna1) == 42 );
|
||||
REQUIRE_THROWS( oxenmq::get_int<unsigned>(dna2) );
|
||||
|
||||
bt_value x = bt_deserialize<bt_value>("d3:barle3:foold1:ali1ei2ei3ee1:bleed1:cli-5ei4eeeee");
|
||||
REQUIRE( std::holds_alternative<bt_dict>(x) );
|
||||
|
@ -150,9 +150,9 @@ TEST_CASE("bt_value deserialization", "[bt][deserialization][bt_value]") {
|
|||
bt_list& foo1b = var::get<bt_list>(foo1.at("b"));
|
||||
bt_list& foo2c = var::get<bt_list>(foo2.at("c"));
|
||||
std::list<int> foo1a_vals, foo1b_vals, foo2c_vals;
|
||||
for (auto& v : foo1a) foo1a_vals.push_back(lokimq::get_int<int>(v));
|
||||
for (auto& v : foo1b) foo1b_vals.push_back(lokimq::get_int<int>(v));
|
||||
for (auto& v : foo2c) foo2c_vals.push_back(lokimq::get_int<int>(v));
|
||||
for (auto& v : foo1a) foo1a_vals.push_back(oxenmq::get_int<int>(v));
|
||||
for (auto& v : foo1b) foo1b_vals.push_back(oxenmq::get_int<int>(v));
|
||||
for (auto& v : foo2c) foo2c_vals.push_back(oxenmq::get_int<int>(v));
|
||||
REQUIRE( foo1a_vals == std::list{{1,2,3}} );
|
||||
REQUIRE( foo1b_vals == std::list<int>{} );
|
||||
REQUIRE( foo2c_vals == std::list{{-5, 4}} );
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#include "common.h"
|
||||
#include <lokimq/hex.h>
|
||||
#include <oxenmq/hex.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
using namespace lokimq;
|
||||
using namespace oxenmq;
|
||||
|
||||
TEST_CASE("basic commands", "[commands]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -31,7 +31,7 @@ TEST_CASE("basic commands", "[commands]") {
|
|||
|
||||
server.start();
|
||||
|
||||
LokiMQ client{get_logger("C» "), LogLevel::trace};
|
||||
OxenMQ client{get_logger("C» "), LogLevel::trace};
|
||||
|
||||
client.add_category("public", Access{AuthLevel::none});
|
||||
client.add_command("public", "hi", [&](auto&) { his++; });
|
||||
|
@ -77,7 +77,7 @@ TEST_CASE("basic commands", "[commands]") {
|
|||
|
||||
TEST_CASE("outgoing auth level", "[commands][auth]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -93,7 +93,7 @@ TEST_CASE("outgoing auth level", "[commands][auth]") {
|
|||
|
||||
server.start();
|
||||
|
||||
LokiMQ client{get_logger("C» "), LogLevel::trace};
|
||||
OxenMQ client{get_logger("C» "), LogLevel::trace};
|
||||
|
||||
std::atomic<int> public_hi{0}, basic_hi{0}, admin_hi{0};
|
||||
client.add_category("public", Access{AuthLevel::none});
|
||||
|
@ -159,7 +159,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
// original node.
|
||||
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -178,7 +178,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
m.send_reply("Okay, I'll remember that.");
|
||||
|
||||
if (backdoor)
|
||||
m.lokimq.send(backdoor, "backdoor.data", m.data[0]);
|
||||
m.oxenmq.send(backdoor, "backdoor.data", m.data[0]);
|
||||
});
|
||||
server.add_command("hey google", "recall", [&](Message& m) {
|
||||
auto l = catch_lock();
|
||||
|
@ -199,7 +199,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
|
||||
std::set<std::string> backdoor_details;
|
||||
|
||||
LokiMQ nsa{get_logger("NSA» ")};
|
||||
OxenMQ nsa{get_logger("NSA» ")};
|
||||
nsa.add_category("backdoor", Access{AuthLevel::admin});
|
||||
nsa.add_command("backdoor", "data", [&](Message& m) {
|
||||
auto l = catch_lock();
|
||||
|
@ -215,7 +215,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
REQUIRE( backdoor );
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<LokiMQ>> clients;
|
||||
std::vector<std::unique_ptr<OxenMQ>> clients;
|
||||
std::vector<ConnectionID> conns;
|
||||
std::map<int, std::set<std::string>> personal_details{
|
||||
{0, {"Loretta"s, "photos"s}},
|
||||
|
@ -231,7 +231,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
std::map<int, std::set<std::string>> google_knows;
|
||||
int things_remembered{0};
|
||||
for (int i = 0; i < 5; i++) {
|
||||
clients.push_back(std::make_unique<LokiMQ>(
|
||||
clients.push_back(std::make_unique<OxenMQ>(
|
||||
get_logger("C" + std::to_string(i) + "» "), LogLevel::trace
|
||||
));
|
||||
auto& c = clients.back();
|
||||
|
@ -271,7 +271,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
|
||||
TEST_CASE("send failure callbacks", "[commands][queue_full]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -298,7 +298,7 @@ TEST_CASE("send failure callbacks", "[commands][queue_full]") {
|
|||
server.start();
|
||||
|
||||
// Use a raw socket here because I want to stall it by not reading from it at all, and that is
|
||||
// hard with LokiMQ.
|
||||
// hard with OxenMQ.
|
||||
zmq::context_t client_ctx;
|
||||
zmq::socket_t client{client_ctx, zmq::socket_type::dealer};
|
||||
client.connect(listen);
|
||||
|
@ -365,7 +365,7 @@ TEST_CASE("send failure callbacks", "[commands][queue_full]") {
|
|||
|
||||
TEST_CASE("data parts", "[send][data_parts]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -385,7 +385,7 @@ TEST_CASE("data parts", "[send][data_parts]") {
|
|||
});
|
||||
server.start();
|
||||
|
||||
LokiMQ client{get_logger("C» "), LogLevel::trace};
|
||||
OxenMQ client{get_logger("C» "), LogLevel::trace};
|
||||
client.start();
|
||||
|
||||
std::atomic<bool> got{false};
|
||||
|
@ -406,7 +406,7 @@ TEST_CASE("data parts", "[send][data_parts]") {
|
|||
}
|
||||
|
||||
std::vector some_data{{"abc"s, "def"s, "omg123\0zzz"s}};
|
||||
client.send(c, "public.hello", lokimq::send_option::data_parts(some_data.begin(), some_data.end()));
|
||||
client.send(c, "public.hello", oxenmq::send_option::data_parts(some_data.begin(), some_data.end()));
|
||||
reply_sleep();
|
||||
{
|
||||
auto lock = catch_lock();
|
||||
|
@ -418,10 +418,10 @@ TEST_CASE("data parts", "[send][data_parts]") {
|
|||
std::vector some_data2{{"a"sv, "b"sv, "\0"sv}};
|
||||
client.send(c, "public.hello",
|
||||
"hi",
|
||||
lokimq::send_option::data_parts(some_data2.begin(), some_data2.end()),
|
||||
oxenmq::send_option::data_parts(some_data2.begin(), some_data2.end()),
|
||||
"another",
|
||||
"string"sv,
|
||||
lokimq::send_option::data_parts(some_data.begin(), some_data.end()));
|
||||
oxenmq::send_option::data_parts(some_data.begin(), some_data.end()));
|
||||
|
||||
std::vector<std::string> expected;
|
||||
expected.push_back("hi");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "common.h"
|
||||
#include <lokimq/hex.h>
|
||||
#include <oxenmq/hex.h>
|
||||
extern "C" {
|
||||
#include <sodium.h>
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ extern "C" {
|
|||
|
||||
TEST_CASE("connections with curve authentication", "[curve][connect]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -20,7 +20,7 @@ TEST_CASE("connections with curve authentication", "[curve][connect]") {
|
|||
server.add_request_command("public", "hello", [&](Message& m) { m.send_reply("hi"); });
|
||||
server.start();
|
||||
|
||||
LokiMQ client{get_logger("C» "), LogLevel::trace};
|
||||
OxenMQ client{get_logger("C» "), LogLevel::trace};
|
||||
|
||||
client.start();
|
||||
|
||||
|
@ -55,7 +55,7 @@ TEST_CASE("self-connection SN optimization", "[connect][self]") {
|
|||
REQUIRE(sodium_init() != -1);
|
||||
auto listen_addr = random_localhost();
|
||||
crypto_box_keypair(reinterpret_cast<unsigned char*>(&pubkey[0]), reinterpret_cast<unsigned char*>(&privkey[0]));
|
||||
LokiMQ sn{
|
||||
OxenMQ sn{
|
||||
pubkey, privkey,
|
||||
true,
|
||||
[&](auto pk) { if (pk == pubkey) return listen_addr; else return ""s; },
|
||||
|
@ -92,7 +92,7 @@ TEST_CASE("self-connection SN optimization", "[connect][self]") {
|
|||
|
||||
TEST_CASE("plain-text connections", "[plaintext][connect]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{get_logger("S» "), LogLevel::trace};
|
||||
OxenMQ server{get_logger("S» "), LogLevel::trace};
|
||||
|
||||
server.add_category("public", Access{AuthLevel::none});
|
||||
server.add_request_command("public", "hello", [&](Message& m) { m.send_reply("hi"); });
|
||||
|
@ -101,7 +101,7 @@ TEST_CASE("plain-text connections", "[plaintext][connect]") {
|
|||
|
||||
server.start();
|
||||
|
||||
LokiMQ client{get_logger("C» "), LogLevel::trace};
|
||||
OxenMQ client{get_logger("C» "), LogLevel::trace};
|
||||
|
||||
client.start();
|
||||
|
||||
|
@ -131,7 +131,7 @@ TEST_CASE("plain-text connections", "[plaintext][connect]") {
|
|||
|
||||
TEST_CASE("unique connection IDs", "[connect][id]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{get_logger("S» "), LogLevel::trace};
|
||||
OxenMQ server{get_logger("S» "), LogLevel::trace};
|
||||
|
||||
ConnectionID first, second;
|
||||
server.add_category("x", Access{AuthLevel::none})
|
||||
|
@ -143,8 +143,8 @@ TEST_CASE("unique connection IDs", "[connect][id]") {
|
|||
|
||||
server.start();
|
||||
|
||||
LokiMQ client1{get_logger("C1» "), LogLevel::trace};
|
||||
LokiMQ client2{get_logger("C2» "), LogLevel::trace};
|
||||
OxenMQ client1{get_logger("C1» "), LogLevel::trace};
|
||||
OxenMQ client2{get_logger("C2» "), LogLevel::trace};
|
||||
client1.start();
|
||||
client2.start();
|
||||
|
||||
|
@ -186,7 +186,7 @@ TEST_CASE("unique connection IDs", "[connect][id]") {
|
|||
|
||||
|
||||
TEST_CASE("SN disconnections", "[connect][disconnect]") {
|
||||
std::vector<std::unique_ptr<LokiMQ>> lmq;
|
||||
std::vector<std::unique_ptr<OxenMQ>> lmq;
|
||||
std::vector<std::string> pubkey, privkey;
|
||||
std::unordered_map<std::string, std::string> conn;
|
||||
REQUIRE(sodium_init() != -1);
|
||||
|
@ -200,7 +200,7 @@ TEST_CASE("SN disconnections", "[connect][disconnect]") {
|
|||
}
|
||||
std::atomic<int> his{0};
|
||||
for (int i = 0; i < pubkey.size(); i++) {
|
||||
lmq.push_back(std::make_unique<LokiMQ>(
|
||||
lmq.push_back(std::make_unique<OxenMQ>(
|
||||
pubkey[i], privkey[i], true,
|
||||
[conn](auto pk) { auto it = conn.find((std::string) pk); if (it != conn.end()) return it->second; return ""s; },
|
||||
get_logger("S" + std::to_string(i) + "» "),
|
||||
|
@ -238,7 +238,7 @@ TEST_CASE("SN auth checks", "[sandwich][auth]") {
|
|||
privkey.resize(crypto_box_SECRETKEYBYTES);
|
||||
REQUIRE(sodium_init() != -1);
|
||||
crypto_box_keypair(reinterpret_cast<unsigned char*>(&pubkey[0]), reinterpret_cast<unsigned char*>(&privkey[0]));
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
pubkey, privkey,
|
||||
true, // service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -265,7 +265,7 @@ TEST_CASE("SN auth checks", "[sandwich][auth]") {
|
|||
.add_request_command("make", [&](Message& m) { m.send_reply("okay"); });
|
||||
server.start();
|
||||
|
||||
LokiMQ client{
|
||||
OxenMQ client{
|
||||
"", "", false,
|
||||
[&](auto remote_pk) { if (remote_pk == pubkey) return listen; return ""s; },
|
||||
get_logger("B» "), LogLevel::trace};
|
||||
|
@ -352,7 +352,7 @@ TEST_CASE("SN single worker test", "[connect][worker]") {
|
|||
// Tests a failure case that could trigger when all workers are allocated (here we make that
|
||||
// simpler by just having one worker).
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "",
|
||||
false, // service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -368,7 +368,7 @@ TEST_CASE("SN single worker test", "[connect][worker]") {
|
|||
;
|
||||
server.start();
|
||||
|
||||
LokiMQ client{get_logger("B» "), LogLevel::trace};
|
||||
OxenMQ client{get_logger("B» "), LogLevel::trace};
|
||||
client.start();
|
||||
auto conn = client.connect_remote(listen, [](auto) {}, [](auto, auto) {});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "lokimq/hex.h"
|
||||
#include "lokimq/base32z.h"
|
||||
#include "lokimq/base64.h"
|
||||
#include "oxenmq/hex.h"
|
||||
#include "oxenmq/base32z.h"
|
||||
#include "oxenmq/base64.h"
|
||||
#include "common.h"
|
||||
#include <iterator>
|
||||
|
||||
|
@ -12,123 +12,123 @@ const std::string pk_b32z = "6fi4kseo88aeupbkopyzknjo1odw4dcuxjh6kx1hhhax1tzbjqr
|
|||
const std::string pk_b64 = "8WulWRA58Im0KoNBdQkwlAdNDZN6eeU+XOcw+UbhS4g=";
|
||||
|
||||
TEST_CASE("hex encoding/decoding", "[encoding][decoding][hex]") {
|
||||
REQUIRE( lokimq::to_hex("\xff\x42\x12\x34") == "ff421234"s );
|
||||
REQUIRE( oxenmq::to_hex("\xff\x42\x12\x34") == "ff421234"s );
|
||||
std::vector<uint8_t> chars{{1, 10, 100, 254}};
|
||||
std::array<uint8_t, 8> out;
|
||||
std::array<uint8_t, 8> expected{{'0', '1', '0', 'a', '6', '4', 'f', 'e'}};
|
||||
lokimq::to_hex(chars.begin(), chars.end(), out.begin());
|
||||
oxenmq::to_hex(chars.begin(), chars.end(), out.begin());
|
||||
REQUIRE( out == expected );
|
||||
|
||||
REQUIRE( lokimq::to_hex(chars.begin(), chars.end()) == "010a64fe" );
|
||||
REQUIRE( oxenmq::to_hex(chars.begin(), chars.end()) == "010a64fe" );
|
||||
|
||||
REQUIRE( lokimq::from_hex("12345678ffEDbca9") == "\x12\x34\x56\x78\xff\xed\xbc\xa9"s );
|
||||
REQUIRE( oxenmq::from_hex("12345678ffEDbca9") == "\x12\x34\x56\x78\xff\xed\xbc\xa9"s );
|
||||
|
||||
REQUIRE( lokimq::is_hex("1234567890abcdefABCDEF1234567890abcdefABCDEF") );
|
||||
REQUIRE_FALSE( lokimq::is_hex("1234567890abcdefABCDEF1234567890aGcdefABCDEF") );
|
||||
REQUIRE( oxenmq::is_hex("1234567890abcdefABCDEF1234567890abcdefABCDEF") );
|
||||
REQUIRE_FALSE( oxenmq::is_hex("1234567890abcdefABCDEF1234567890aGcdefABCDEF") );
|
||||
// ^
|
||||
REQUIRE_FALSE( lokimq::is_hex("1234567890abcdefABCDEF1234567890agcdefABCDEF") );
|
||||
REQUIRE_FALSE( oxenmq::is_hex("1234567890abcdefABCDEF1234567890agcdefABCDEF") );
|
||||
// ^
|
||||
REQUIRE_FALSE( lokimq::is_hex("\x11\xff") );
|
||||
REQUIRE_FALSE( oxenmq::is_hex("\x11\xff") );
|
||||
constexpr auto odd_hex = "1234567890abcdefABCDEF1234567890abcdefABCDE"sv;
|
||||
REQUIRE_FALSE( lokimq::is_hex(odd_hex) );
|
||||
REQUIRE_FALSE( lokimq::is_hex("0") );
|
||||
REQUIRE_FALSE( oxenmq::is_hex(odd_hex) );
|
||||
REQUIRE_FALSE( oxenmq::is_hex("0") );
|
||||
|
||||
REQUIRE( std::all_of(odd_hex.begin(), odd_hex.end(), lokimq::is_hex_digit<char>) );
|
||||
REQUIRE( std::all_of(odd_hex.begin(), odd_hex.end(), oxenmq::is_hex_digit<char>) );
|
||||
|
||||
REQUIRE( lokimq::from_hex(pk_hex) == pk );
|
||||
REQUIRE( lokimq::to_hex(pk) == pk_hex );
|
||||
REQUIRE( oxenmq::from_hex(pk_hex) == pk );
|
||||
REQUIRE( oxenmq::to_hex(pk) == pk_hex );
|
||||
|
||||
REQUIRE( lokimq::from_hex(pk_hex.begin(), pk_hex.end()) == pk );
|
||||
REQUIRE( oxenmq::from_hex(pk_hex.begin(), pk_hex.end()) == pk );
|
||||
|
||||
std::vector<std::byte> bytes{{std::byte{0xff}, std::byte{0x42}, std::byte{0x12}, std::byte{0x34}}};
|
||||
std::basic_string_view<std::byte> b{bytes.data(), bytes.size()};
|
||||
REQUIRE( lokimq::to_hex(b) == "ff421234"s );
|
||||
REQUIRE( oxenmq::to_hex(b) == "ff421234"s );
|
||||
|
||||
bytes.resize(8);
|
||||
bytes[0] = std::byte{'f'}; bytes[1] = std::byte{'f'}; bytes[2] = std::byte{'4'}; bytes[3] = std::byte{'2'};
|
||||
bytes[4] = std::byte{'1'}; bytes[5] = std::byte{'2'}; bytes[6] = std::byte{'3'}; bytes[7] = std::byte{'4'};
|
||||
std::basic_string_view<std::byte> hex_bytes{bytes.data(), bytes.size()};
|
||||
REQUIRE( lokimq::is_hex(hex_bytes) );
|
||||
REQUIRE( lokimq::from_hex(hex_bytes) == "\xff\x42\x12\x34" );
|
||||
REQUIRE( oxenmq::is_hex(hex_bytes) );
|
||||
REQUIRE( oxenmq::from_hex(hex_bytes) == "\xff\x42\x12\x34" );
|
||||
}
|
||||
|
||||
TEST_CASE("base32z encoding/decoding", "[encoding][decoding][base32z]") {
|
||||
REQUIRE( lokimq::to_base32z("\0\0\0\0\0"s) == "yyyyyyyy" );
|
||||
REQUIRE( lokimq::to_base32z("\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"sv)
|
||||
REQUIRE( oxenmq::to_base32z("\0\0\0\0\0"s) == "yyyyyyyy" );
|
||||
REQUIRE( oxenmq::to_base32z("\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"sv)
|
||||
== "yrtwk3hjixg66yjdeiuauk6p7hy1gtm8tgih55abrpnsxnpm3zzo");
|
||||
|
||||
REQUIRE( lokimq::from_base32z("yrtwk3hjixg66yjdeiuauk6p7hy1gtm8tgih55abrpnsxnpm3zzo")
|
||||
REQUIRE( oxenmq::from_base32z("yrtwk3hjixg66yjdeiuauk6p7hy1gtm8tgih55abrpnsxnpm3zzo")
|
||||
== "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"sv);
|
||||
|
||||
REQUIRE( lokimq::from_base32z("YRTWK3HJIXG66YJDEIUAUK6P7HY1GTM8TGIH55ABRPNSXNPM3ZZO")
|
||||
REQUIRE( oxenmq::from_base32z("YRTWK3HJIXG66YJDEIUAUK6P7HY1GTM8TGIH55ABRPNSXNPM3ZZO")
|
||||
== "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"sv);
|
||||
|
||||
auto five_nulls = lokimq::from_base32z("yyyyyyyy");
|
||||
auto five_nulls = oxenmq::from_base32z("yyyyyyyy");
|
||||
REQUIRE( five_nulls.size() == 5 );
|
||||
REQUIRE( five_nulls == "\0\0\0\0\0"s );
|
||||
|
||||
// 00000 00001 00010 00011 00100 00101 00110 00111
|
||||
// ==
|
||||
// 00000000 01000100 00110010 00010100 11000111
|
||||
REQUIRE( lokimq::from_base32z("ybndrfg8") == "\x00\x44\x32\x14\xc7"s );
|
||||
REQUIRE( oxenmq::from_base32z("ybndrfg8") == "\x00\x44\x32\x14\xc7"s );
|
||||
|
||||
// Special case 1: 7 base32z digits with 3 trailing 0 bits -> 4 bytes (the trailing 0s are dropped)
|
||||
// 00000 00001 00010 00011 00100 00101 11000
|
||||
// ==
|
||||
// 00000000 01000100 00110010 00010111
|
||||
REQUIRE( lokimq::from_base32z("ybndrfa") == "\x00\x44\x32\x17"s );
|
||||
REQUIRE( oxenmq::from_base32z("ybndrfa") == "\x00\x44\x32\x17"s );
|
||||
|
||||
// Round-trip it:
|
||||
REQUIRE( lokimq::from_base32z(lokimq::to_base32z("\x00\x44\x32\x17"sv)) == "\x00\x44\x32\x17"sv );
|
||||
REQUIRE( lokimq::to_base32z(lokimq::from_base32z("ybndrfa")) == "ybndrfa" );
|
||||
REQUIRE( oxenmq::from_base32z(oxenmq::to_base32z("\x00\x44\x32\x17"sv)) == "\x00\x44\x32\x17"sv );
|
||||
REQUIRE( oxenmq::to_base32z(oxenmq::from_base32z("ybndrfa")) == "ybndrfa" );
|
||||
|
||||
// Special case 2: 7 base32z digits with 3 trailing bits 010; we just ignore the trailing stuff,
|
||||
// as if it was specified as 0. (The last digit here is 11010 instead of 11000).
|
||||
REQUIRE( lokimq::from_base32z("ybndrf4") == "\x00\x44\x32\x17"s );
|
||||
REQUIRE( oxenmq::from_base32z("ybndrf4") == "\x00\x44\x32\x17"s );
|
||||
// This one won't round-trip to the same value since it has ignored garbage bytes at the end
|
||||
REQUIRE( lokimq::to_base32z(lokimq::from_base32z("ybndrf4"s)) == "ybndrfa" );
|
||||
REQUIRE( oxenmq::to_base32z(oxenmq::from_base32z("ybndrf4"s)) == "ybndrfa" );
|
||||
|
||||
REQUIRE( lokimq::to_base32z(pk) == pk_b32z );
|
||||
REQUIRE( lokimq::to_base32z(pk.begin(), pk.end()) == pk_b32z );
|
||||
REQUIRE( lokimq::from_base32z(pk_b32z) == pk );
|
||||
REQUIRE( lokimq::from_base32z(pk_b32z.begin(), pk_b32z.end()) == pk );
|
||||
REQUIRE( oxenmq::to_base32z(pk) == pk_b32z );
|
||||
REQUIRE( oxenmq::to_base32z(pk.begin(), pk.end()) == pk_b32z );
|
||||
REQUIRE( oxenmq::from_base32z(pk_b32z) == pk );
|
||||
REQUIRE( oxenmq::from_base32z(pk_b32z.begin(), pk_b32z.end()) == pk );
|
||||
|
||||
std::string pk_b32z_again, pk_again;
|
||||
lokimq::to_base32z(pk.begin(), pk.end(), std::back_inserter(pk_b32z_again));
|
||||
lokimq::from_base32z(pk_b32z.begin(), pk_b32z.end(), std::back_inserter(pk_again));
|
||||
oxenmq::to_base32z(pk.begin(), pk.end(), std::back_inserter(pk_b32z_again));
|
||||
oxenmq::from_base32z(pk_b32z.begin(), pk_b32z.end(), std::back_inserter(pk_again));
|
||||
REQUIRE( pk_b32z_again == pk_b32z );
|
||||
REQUIRE( pk_again == pk );
|
||||
|
||||
std::vector<std::byte> bytes{{std::byte{0}, std::byte{255}}};
|
||||
std::basic_string_view<std::byte> b{bytes.data(), bytes.size()};
|
||||
REQUIRE( lokimq::to_base32z(b) == "yd9o" );
|
||||
REQUIRE( oxenmq::to_base32z(b) == "yd9o" );
|
||||
|
||||
bytes.resize(4);
|
||||
bytes[0] = std::byte{'y'}; bytes[1] = std::byte{'d'}; bytes[2] = std::byte{'9'}; bytes[3] = std::byte{'o'};
|
||||
std::basic_string_view<std::byte> b32_bytes{bytes.data(), bytes.size()};
|
||||
REQUIRE( lokimq::is_base32z(b32_bytes) );
|
||||
REQUIRE( lokimq::from_base32z(b32_bytes) == "\x00\xff"sv );
|
||||
REQUIRE( oxenmq::is_base32z(b32_bytes) );
|
||||
REQUIRE( oxenmq::from_base32z(b32_bytes) == "\x00\xff"sv );
|
||||
}
|
||||
|
||||
TEST_CASE("base64 encoding/decoding", "[encoding][decoding][base64]") {
|
||||
// 00000000 00000000 00000000 -> 000000 000000 000000 000000
|
||||
REQUIRE( lokimq::to_base64("\0\0\0"s) == "AAAA" );
|
||||
REQUIRE( oxenmq::to_base64("\0\0\0"s) == "AAAA" );
|
||||
// 00000001 00000002 00000003 -> 000000 010000 000200 000003
|
||||
REQUIRE( lokimq::to_base64("\x01\x02\x03"s) == "AQID" );
|
||||
REQUIRE( lokimq::to_base64("\0\0\0\0"s) == "AAAAAA==" );
|
||||
REQUIRE( oxenmq::to_base64("\x01\x02\x03"s) == "AQID" );
|
||||
REQUIRE( oxenmq::to_base64("\0\0\0\0"s) == "AAAAAA==" );
|
||||
// 00000000 00000000 00000000 11111111 ->
|
||||
// 000000 000000 000000 000000 111111 110000 (pad) (pad)
|
||||
REQUIRE( lokimq::to_base64("a") == "YQ==" );
|
||||
REQUIRE( lokimq::to_base64("ab") == "YWI=" );
|
||||
REQUIRE( lokimq::to_base64("abc") == "YWJj" );
|
||||
REQUIRE( lokimq::to_base64("abcd") == "YWJjZA==" );
|
||||
REQUIRE( lokimq::to_base64("abcde") == "YWJjZGU=" );
|
||||
REQUIRE( lokimq::to_base64("abcdef") == "YWJjZGVm" );
|
||||
REQUIRE( oxenmq::to_base64("a") == "YQ==" );
|
||||
REQUIRE( oxenmq::to_base64("ab") == "YWI=" );
|
||||
REQUIRE( oxenmq::to_base64("abc") == "YWJj" );
|
||||
REQUIRE( oxenmq::to_base64("abcd") == "YWJjZA==" );
|
||||
REQUIRE( oxenmq::to_base64("abcde") == "YWJjZGU=" );
|
||||
REQUIRE( oxenmq::to_base64("abcdef") == "YWJjZGVm" );
|
||||
|
||||
REQUIRE( lokimq::to_base64("\0\0\0\xff"s) == "AAAA/w==" );
|
||||
REQUIRE( lokimq::to_base64("\0\0\0\xff\xff"s) == "AAAA//8=" );
|
||||
REQUIRE( lokimq::to_base64("\0\0\0\xff\xff\xff"s) == "AAAA////" );
|
||||
REQUIRE( lokimq::to_base64(
|
||||
REQUIRE( oxenmq::to_base64("\0\0\0\xff"s) == "AAAA/w==" );
|
||||
REQUIRE( oxenmq::to_base64("\0\0\0\xff\xff"s) == "AAAA//8=" );
|
||||
REQUIRE( oxenmq::to_base64("\0\0\0\xff\xff\xff"s) == "AAAA////" );
|
||||
REQUIRE( oxenmq::to_base64(
|
||||
"Man is distinguished, not only by his reason, but by this singular passion from other "
|
||||
"animals, which is a lust of the mind, that by a perseverance of delight in the "
|
||||
"continued and indefatigable generation of knowledge, exceeds the short vehemence of "
|
||||
|
@ -140,33 +140,33 @@ TEST_CASE("base64 encoding/decoding", "[encoding][decoding][base64]") {
|
|||
"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
|
||||
"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=" );
|
||||
|
||||
REQUIRE( lokimq::from_base64("A+/A") == "\x03\xef\xc0" );
|
||||
REQUIRE( lokimq::from_base64("YWJj") == "abc" );
|
||||
REQUIRE( lokimq::from_base64("YWJjZA==") == "abcd" );
|
||||
REQUIRE( lokimq::from_base64("YWJjZA") == "abcd" );
|
||||
REQUIRE( lokimq::from_base64("YWJjZB") == "abcd" ); // ignore superfluous bits
|
||||
REQUIRE( lokimq::from_base64("YWJjZB") == "abcd" ); // ignore superfluous bits
|
||||
REQUIRE( lokimq::from_base64("YWJj+") == "abc" ); // ignore superfluous bits
|
||||
REQUIRE( lokimq::from_base64("YWJjZGU=") == "abcde" );
|
||||
REQUIRE( lokimq::from_base64("YWJjZGU") == "abcde" );
|
||||
REQUIRE( lokimq::from_base64("YWJjZGVm") == "abcdef" );
|
||||
REQUIRE( oxenmq::from_base64("A+/A") == "\x03\xef\xc0" );
|
||||
REQUIRE( oxenmq::from_base64("YWJj") == "abc" );
|
||||
REQUIRE( oxenmq::from_base64("YWJjZA==") == "abcd" );
|
||||
REQUIRE( oxenmq::from_base64("YWJjZA") == "abcd" );
|
||||
REQUIRE( oxenmq::from_base64("YWJjZB") == "abcd" ); // ignore superfluous bits
|
||||
REQUIRE( oxenmq::from_base64("YWJjZB") == "abcd" ); // ignore superfluous bits
|
||||
REQUIRE( oxenmq::from_base64("YWJj+") == "abc" ); // ignore superfluous bits
|
||||
REQUIRE( oxenmq::from_base64("YWJjZGU=") == "abcde" );
|
||||
REQUIRE( oxenmq::from_base64("YWJjZGU") == "abcde" );
|
||||
REQUIRE( oxenmq::from_base64("YWJjZGVm") == "abcdef" );
|
||||
|
||||
REQUIRE( lokimq::is_base64("YWJjZGVm") );
|
||||
REQUIRE( lokimq::is_base64("YWJjZGU") );
|
||||
REQUIRE( lokimq::is_base64("YWJjZGU=") );
|
||||
REQUIRE( lokimq::is_base64("YWJjZA==") );
|
||||
REQUIRE( lokimq::is_base64("YWJjZA") );
|
||||
REQUIRE( lokimq::is_base64("YWJjZB") ); // not really valid, but we explicitly accept it
|
||||
REQUIRE( oxenmq::is_base64("YWJjZGVm") );
|
||||
REQUIRE( oxenmq::is_base64("YWJjZGU") );
|
||||
REQUIRE( oxenmq::is_base64("YWJjZGU=") );
|
||||
REQUIRE( oxenmq::is_base64("YWJjZA==") );
|
||||
REQUIRE( oxenmq::is_base64("YWJjZA") );
|
||||
REQUIRE( oxenmq::is_base64("YWJjZB") ); // not really valid, but we explicitly accept it
|
||||
|
||||
REQUIRE_FALSE( lokimq::is_base64("YWJjZ=") ); // invalid padding (padding can only be 4th or 3rd+4th of a 4-char block)
|
||||
REQUIRE_FALSE( lokimq::is_base64("YWJj=") );
|
||||
REQUIRE_FALSE( lokimq::is_base64("YWJj=A") );
|
||||
REQUIRE_FALSE( lokimq::is_base64("YWJjA===") );
|
||||
REQUIRE_FALSE( lokimq::is_base64("YWJ[") );
|
||||
REQUIRE_FALSE( lokimq::is_base64("YWJ.") );
|
||||
REQUIRE_FALSE( lokimq::is_base64("_YWJ") );
|
||||
REQUIRE_FALSE( oxenmq::is_base64("YWJjZ=") ); // invalid padding (padding can only be 4th or 3rd+4th of a 4-char block)
|
||||
REQUIRE_FALSE( oxenmq::is_base64("YWJj=") );
|
||||
REQUIRE_FALSE( oxenmq::is_base64("YWJj=A") );
|
||||
REQUIRE_FALSE( oxenmq::is_base64("YWJjA===") );
|
||||
REQUIRE_FALSE( oxenmq::is_base64("YWJ[") );
|
||||
REQUIRE_FALSE( oxenmq::is_base64("YWJ.") );
|
||||
REQUIRE_FALSE( oxenmq::is_base64("_YWJ") );
|
||||
|
||||
REQUIRE( lokimq::from_base64(
|
||||
REQUIRE( oxenmq::from_base64(
|
||||
"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
|
||||
"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
|
||||
"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
|
||||
|
@ -178,26 +178,26 @@ TEST_CASE("base64 encoding/decoding", "[encoding][decoding][base64]") {
|
|||
"continued and indefatigable generation of knowledge, exceeds the short vehemence of "
|
||||
"any carnal pleasure.");
|
||||
|
||||
REQUIRE( lokimq::to_base64(pk) == pk_b64 );
|
||||
REQUIRE( lokimq::to_base64(pk.begin(), pk.end()) == pk_b64 );
|
||||
REQUIRE( lokimq::from_base64(pk_b64) == pk );
|
||||
REQUIRE( lokimq::from_base64(pk_b64.begin(), pk_b64.end()) == pk );
|
||||
REQUIRE( oxenmq::to_base64(pk) == pk_b64 );
|
||||
REQUIRE( oxenmq::to_base64(pk.begin(), pk.end()) == pk_b64 );
|
||||
REQUIRE( oxenmq::from_base64(pk_b64) == pk );
|
||||
REQUIRE( oxenmq::from_base64(pk_b64.begin(), pk_b64.end()) == pk );
|
||||
|
||||
std::string pk_b64_again, pk_again;
|
||||
lokimq::to_base64(pk.begin(), pk.end(), std::back_inserter(pk_b64_again));
|
||||
lokimq::from_base64(pk_b64.begin(), pk_b64.end(), std::back_inserter(pk_again));
|
||||
oxenmq::to_base64(pk.begin(), pk.end(), std::back_inserter(pk_b64_again));
|
||||
oxenmq::from_base64(pk_b64.begin(), pk_b64.end(), std::back_inserter(pk_again));
|
||||
REQUIRE( pk_b64_again == pk_b64 );
|
||||
REQUIRE( pk_again == pk );
|
||||
|
||||
std::vector<std::byte> bytes{{std::byte{0}, std::byte{255}}};
|
||||
std::basic_string_view<std::byte> b{bytes.data(), bytes.size()};
|
||||
REQUIRE( lokimq::to_base64(b) == "AP8=" );
|
||||
REQUIRE( oxenmq::to_base64(b) == "AP8=" );
|
||||
|
||||
bytes.resize(4);
|
||||
bytes[0] = std::byte{'/'}; bytes[1] = std::byte{'w'}; bytes[2] = std::byte{'A'}; bytes[3] = std::byte{'='};
|
||||
std::basic_string_view<std::byte> b64_bytes{bytes.data(), bytes.size()};
|
||||
REQUIRE( lokimq::is_base64(b64_bytes) );
|
||||
REQUIRE( lokimq::from_base64(b64_bytes) == "\xff\x00"sv );
|
||||
REQUIRE( oxenmq::is_base64(b64_bytes) );
|
||||
REQUIRE( oxenmq::from_base64(b64_bytes) == "\xff\x00"sv );
|
||||
}
|
||||
|
||||
TEST_CASE("std::byte decoding", "[decoding][hex][base32z][base64]") {
|
||||
|
@ -208,33 +208,33 @@ TEST_CASE("std::byte decoding", "[decoding][hex][base32z][base64]") {
|
|||
// hex
|
||||
auto b_in = "ff42"s;
|
||||
std::vector<std::byte> b_out;
|
||||
lokimq::from_hex(b_in.begin(), b_in.end(), std::back_inserter(b_out));
|
||||
oxenmq::from_hex(b_in.begin(), b_in.end(), std::back_inserter(b_out));
|
||||
REQUIRE( b_out == std::vector{std::byte{0xff}, std::byte{0x42}} );
|
||||
b_out.emplace_back();
|
||||
lokimq::from_hex(b_in.begin(), b_in.end(), b_out.begin() + 1);
|
||||
oxenmq::from_hex(b_in.begin(), b_in.end(), b_out.begin() + 1);
|
||||
REQUIRE( b_out == std::vector{std::byte{0xff}, std::byte{0xff}, std::byte{0x42}} );
|
||||
lokimq::from_hex(b_in.begin(), b_in.end(), b_out.data());
|
||||
oxenmq::from_hex(b_in.begin(), b_in.end(), b_out.data());
|
||||
REQUIRE( b_out == std::vector{std::byte{0xff}, std::byte{0x42}, std::byte{0x42}} );
|
||||
|
||||
// base32z
|
||||
b_in = "yojky"s;
|
||||
b_out.clear();
|
||||
lokimq::from_base32z(b_in.begin(), b_in.end(), std::back_inserter(b_out));
|
||||
oxenmq::from_base32z(b_in.begin(), b_in.end(), std::back_inserter(b_out));
|
||||
REQUIRE( b_out == std::vector{std::byte{0x04}, std::byte{0x12}, std::byte{0xa0}} );
|
||||
b_out.emplace_back();
|
||||
lokimq::from_base32z(b_in.begin(), b_in.end(), b_out.begin() + 1);
|
||||
oxenmq::from_base32z(b_in.begin(), b_in.end(), b_out.begin() + 1);
|
||||
REQUIRE( b_out == std::vector{std::byte{0x04}, std::byte{0x04}, std::byte{0x12}, std::byte{0xa0}} );
|
||||
lokimq::from_base32z(b_in.begin(), b_in.end(), b_out.data());
|
||||
oxenmq::from_base32z(b_in.begin(), b_in.end(), b_out.data());
|
||||
REQUIRE( b_out == std::vector{std::byte{0x04}, std::byte{0x12}, std::byte{0xa0}, std::byte{0xa0}} );
|
||||
|
||||
// base64
|
||||
b_in = "yojk"s;
|
||||
b_out.clear();
|
||||
lokimq::from_base64(b_in.begin(), b_in.end(), std::back_inserter(b_out));
|
||||
oxenmq::from_base64(b_in.begin(), b_in.end(), std::back_inserter(b_out));
|
||||
REQUIRE( b_out == std::vector{std::byte{0xca}, std::byte{0x88}, std::byte{0xe4}} );
|
||||
b_out.emplace_back();
|
||||
lokimq::from_base64(b_in.begin(), b_in.end(), b_out.begin() + 1);
|
||||
oxenmq::from_base64(b_in.begin(), b_in.end(), b_out.begin() + 1);
|
||||
REQUIRE( b_out == std::vector{std::byte{0xca}, std::byte{0xca}, std::byte{0x88}, std::byte{0xe4}} );
|
||||
lokimq::from_base64(b_in.begin(), b_in.end(), b_out.data());
|
||||
oxenmq::from_base64(b_in.begin(), b_in.end(), b_out.data());
|
||||
REQUIRE( b_out == std::vector{std::byte{0xca}, std::byte{0x88}, std::byte{0xe4}, std::byte{0xe4}} );
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#include "common.h"
|
||||
#include <lokimq/hex.h>
|
||||
#include <oxenmq/hex.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
using namespace lokimq;
|
||||
using namespace oxenmq;
|
||||
|
||||
TEST_CASE("failure responses - UNKNOWNCOMMAND", "[failure][UNKNOWNCOMMAND]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -48,7 +48,7 @@ TEST_CASE("failure responses - UNKNOWNCOMMAND", "[failure][UNKNOWNCOMMAND]") {
|
|||
|
||||
TEST_CASE("failure responses - NO_REPLY_TAG", "[failure][NO_REPLY_TAG]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -109,7 +109,7 @@ TEST_CASE("failure responses - NO_REPLY_TAG", "[failure][NO_REPLY_TAG]") {
|
|||
|
||||
TEST_CASE("failure responses - FORBIDDEN", "[failure][FORBIDDEN]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -192,7 +192,7 @@ TEST_CASE("failure responses - FORBIDDEN", "[failure][FORBIDDEN]") {
|
|||
|
||||
TEST_CASE("failure responses - NOT_A_SERVICE_NODE", "[failure][NOT_A_SERVICE_NODE]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -259,7 +259,7 @@ TEST_CASE("failure responses - NOT_A_SERVICE_NODE", "[failure][NOT_A_SERVICE_NOD
|
|||
|
||||
TEST_CASE("failure responses - FORBIDDEN_SN", "[failure][FORBIDDEN_SN]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "common.h"
|
||||
|
||||
using namespace lokimq;
|
||||
using namespace oxenmq;
|
||||
|
||||
TEST_CASE("injected external commands", "[injected]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -24,17 +24,26 @@ TEST_CASE("injected external commands", "[injected]") {
|
|||
|
||||
server.start();
|
||||
|
||||
LokiMQ client{get_logger("C» "), LogLevel::trace};
|
||||
OxenMQ client{get_logger("C» "), LogLevel::trace};
|
||||
client.start();
|
||||
|
||||
std::atomic<bool> got{false};
|
||||
bool success = false;
|
||||
|
||||
// Deliberately using a deprecated command here, disable -Wdeprecated-declarations
|
||||
#ifdef __GNUG__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
auto c = client.connect_remote(listen,
|
||||
[&](auto conn) { success = true; got = true; },
|
||||
[&](auto conn, std::string_view) { got = true; },
|
||||
server.get_pubkey());
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
wait_for_conn(got);
|
||||
{
|
||||
auto lock = catch_lock();
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include "common.h"
|
||||
#include <lokimq/hex.h>
|
||||
#include <oxenmq/hex.h>
|
||||
|
||||
using namespace lokimq;
|
||||
using namespace oxenmq;
|
||||
|
||||
TEST_CASE("basic requests", "[requests]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -20,7 +20,7 @@ TEST_CASE("basic requests", "[requests]") {
|
|||
});
|
||||
server.start();
|
||||
|
||||
LokiMQ client(
|
||||
OxenMQ client(
|
||||
[](LogLevel, const char* file, int line, std::string msg) { std::cerr << file << ":" << line << " --C-- " << msg << "\n"; }
|
||||
);
|
||||
//client.log_level(LogLevel::trace);
|
||||
|
@ -62,7 +62,7 @@ TEST_CASE("basic requests", "[requests]") {
|
|||
|
||||
TEST_CASE("request from server to client", "[requests]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -77,7 +77,7 @@ TEST_CASE("request from server to client", "[requests]") {
|
|||
});
|
||||
server.start();
|
||||
|
||||
LokiMQ client(
|
||||
OxenMQ client(
|
||||
[](LogLevel, const char* file, int line, std::string msg) { std::cerr << file << ":" << line << " --C-- " << msg << "\n"; }
|
||||
);
|
||||
//client.log_level(LogLevel::trace);
|
||||
|
@ -125,7 +125,7 @@ TEST_CASE("request from server to client", "[requests]") {
|
|||
|
||||
TEST_CASE("request timeouts", "[requests][timeout]") {
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
OxenMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
[](auto) { return ""; },
|
||||
|
@ -138,7 +138,7 @@ TEST_CASE("request timeouts", "[requests][timeout]") {
|
|||
server.add_request_command("public", "blackhole", [&](Message& m) { /* doesn't reply */ });
|
||||
server.start();
|
||||
|
||||
LokiMQ client(
|
||||
OxenMQ client(
|
||||
[](LogLevel, const char* file, int line, std::string msg) { std::cerr << file << ":" << line << " --C-- " << msg << "\n"; }
|
||||
);
|
||||
//client.log_level(LogLevel::trace);
|
||||
|
@ -167,7 +167,7 @@ TEST_CASE("request timeouts", "[requests][timeout]") {
|
|||
success = ok;
|
||||
data = std::move(data_);
|
||||
},
|
||||
lokimq::send_option::request_timeout{10ms}
|
||||
oxenmq::send_option::request_timeout{10ms}
|
||||
);
|
||||
|
||||
std::atomic<bool> got_triggered2{false};
|
||||
|
@ -176,7 +176,7 @@ TEST_CASE("request timeouts", "[requests][timeout]") {
|
|||
success = ok;
|
||||
data = std::move(data_);
|
||||
},
|
||||
lokimq::send_option::request_timeout{200ms}
|
||||
oxenmq::send_option::request_timeout{200ms}
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(100ms);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "lokimq/batch.h"
|
||||
#include "oxenmq/batch.h"
|
||||
#include "common.h"
|
||||
#include <future>
|
||||
|
||||
TEST_CASE("tagged thread start functions", "[tagged][start]") {
|
||||
lokimq::LokiMQ lmq{get_logger(""), LogLevel::trace};
|
||||
oxenmq::OxenMQ lmq{get_logger(""), LogLevel::trace};
|
||||
|
||||
lmq.set_general_threads(2);
|
||||
lmq.set_batch_threads(2);
|
||||
|
@ -26,13 +26,13 @@ TEST_CASE("tagged thread start functions", "[tagged][start]") {
|
|||
}
|
||||
|
||||
TEST_CASE("tagged threads quit-before-start", "[tagged][quit]") {
|
||||
auto lmq = std::make_unique<lokimq::LokiMQ>(get_logger(""), LogLevel::trace);
|
||||
auto lmq = std::make_unique<oxenmq::OxenMQ>(get_logger(""), LogLevel::trace);
|
||||
auto t_abc = lmq->add_tagged_thread("abc");
|
||||
REQUIRE_NOTHROW(lmq.reset());
|
||||
}
|
||||
|
||||
TEST_CASE("batch jobs to tagged threads", "[tagged][batch]") {
|
||||
lokimq::LokiMQ lmq{get_logger(""), LogLevel::trace};
|
||||
oxenmq::OxenMQ lmq{get_logger(""), LogLevel::trace};
|
||||
|
||||
lmq.set_general_threads(2);
|
||||
lmq.set_batch_threads(2);
|
||||
|
@ -111,7 +111,7 @@ TEST_CASE("batch jobs to tagged threads", "[tagged][batch]") {
|
|||
}
|
||||
|
||||
TEST_CASE("batch job completion on tagged threads", "[tagged][batch-completion]") {
|
||||
lokimq::LokiMQ lmq{get_logger(""), LogLevel::trace};
|
||||
oxenmq::OxenMQ lmq{get_logger(""), LogLevel::trace};
|
||||
|
||||
lmq.set_general_threads(4);
|
||||
lmq.set_batch_threads(4);
|
||||
|
@ -119,7 +119,7 @@ TEST_CASE("batch job completion on tagged threads", "[tagged][batch-completion]"
|
|||
auto t_abc = lmq.add_tagged_thread("abc", [&] { id_abc = std::this_thread::get_id(); });
|
||||
lmq.start();
|
||||
|
||||
lokimq::Batch<int> batch;
|
||||
oxenmq::Batch<int> batch;
|
||||
for (int i = 1; i < 10; i++)
|
||||
batch.add_job([i, &id_abc]() { if (std::this_thread::get_id() == id_abc) return 0; return i; });
|
||||
|
||||
|
@ -140,7 +140,7 @@ TEST_CASE("batch job completion on tagged threads", "[tagged][batch-completion]"
|
|||
|
||||
|
||||
TEST_CASE("timer job completion on tagged threads", "[tagged][timer]") {
|
||||
lokimq::LokiMQ lmq{get_logger(""), LogLevel::trace};
|
||||
oxenmq::OxenMQ lmq{get_logger(""), LogLevel::trace};
|
||||
|
||||
lmq.set_general_threads(4);
|
||||
lmq.set_batch_threads(4);
|
||||
|
|
Loading…
Reference in New Issue