diff options
Diffstat (limited to 'contrib')
34 files changed, 368 insertions, 432 deletions
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 990a05c08..3bebbe0d2 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -26,10 +26,5 @@ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# warnings are cleared only for GCC on Linux -if (NOT (MINGW OR APPLE OR FREEBSD OR OPENBSD OR DRAGONFLY)) - add_compile_options("${WARNINGS_AS_ERRORS_FLAG}") # applies only to targets that follow -endif() - add_subdirectory(epee) diff --git a/contrib/depends/Makefile b/contrib/depends/Makefile index b0c032c09..bf33d706d 100644 --- a/contrib/depends/Makefile +++ b/contrib/depends/Makefile @@ -3,9 +3,6 @@ SOURCES_PATH ?= $(BASEDIR)/sources BASE_CACHE ?= $(BASEDIR)/built SDK_PATH ?= $(BASEDIR)/SDKs -NO_QT ?= -NO_WALLET ?= -NO_UPNP ?= FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources BUILD = $(shell ./config.guess) @@ -97,17 +94,10 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null) $(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) $(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) -qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) -wallet_packages_$(NO_WALLET) = $(wallet_packages) -upnp_packages_$(NO_UPNP) = $(upnp_packages) -packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) +packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) -ifneq ($(qt_packages_),) -native_packages += $(qt_native_packages) -endif - all_packages = $(packages) $(native_packages) meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk @@ -153,9 +143,6 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \ -e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \ - -e 's|@no_qt@|$(NO_QT)|' \ - -e 's|@no_wallet@|$(NO_WALLET)|' \ - -e 's|@no_upnp@|$(NO_UPNP)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ $(AT)touch $@ @@ -176,9 +163,6 @@ $(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \ -e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \ - -e 's|@no_qt@|$(NO_QT)|' \ - -e 's|@no_wallet@|$(NO_WALLET)|' \ - -e 's|@no_upnp@|$(NO_UPNP)|' \ -e 's|@debug@|$(DEBUG)|' \ -e 's|@depends@|$(host_cmake)|' \ -e 's|@prefix@|$($(host_arch)_$(host_os)_prefix)|'\ diff --git a/contrib/depends/README.md b/contrib/depends/README.md index dd2824569..c9f8b0783 100644 --- a/contrib/depends/README.md +++ b/contrib/depends/README.md @@ -12,11 +12,11 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -A prefix will be generated that's suitable for plugging into Bitcoin's -configure. In the above example, a dir named x86_64-w64-mingw32 will be -created. To use it for Bitcoin: +A toolchain will be generated that's suitable for plugging into Monero's +cmake. In the above example, a dir named x86_64-w64-mingw32 will be +created. To use it for Monero: - ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 + cmake -DCMAKE_TOOLCHAIN=`pwd`/contrib/depends/x86_64-w64-mingw32 Common `host-platform-triplets` for cross compilation are: @@ -35,16 +35,10 @@ The following can be set when running make: make FOO=bar BASE_CACHE: built packages will be placed here SDK_PATH: Path where sdk's can be found (used by OSX) FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up - NO_QT: Don't download/build/cache qt and its dependencies - NO_WALLET: Don't download/build/cache libs needed to enable the wallet - NO_UPNP: Don't download/build/cache packages needed for enabling upnp DEBUG: disable some optimizations and enable more runtime checking HOST_ID_SALT: Optional salt to use when generating host package ids BUILD_ID_SALT: Optional salt to use when generating build package ids -If some packages are not built, for example `make NO_WALLET=1`, the appropriate -options will be passed to bitcoin's configure. In this case, `--disable-wallet`. - Additional targets: download: run 'make download' to fetch all sources without building them @@ -59,6 +53,16 @@ Download it from apple, or search for it on github. Create a new directoty calle directory and place the entire MacOSX10.11.sdk folder in it. The depends build will then pick it up automatically (without requiring SDK_PATH). + +#Mingw builds + +Building for 32/64bit mingw requires switching alternatives to a posix mode + +```bash +update-alternatives --set x86_64-w64-mingw32-g++ x86_64-w64-mingw32-g++-posix +update-alternatives --set x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gcc-posix +``` + ### Other documentation - [description.md](description.md): General description of the depends system diff --git a/contrib/depends/config.site.in b/contrib/depends/config.site.in index 0a4a9c327..dd91bcb2a 100644 --- a/contrib/depends/config.site.in +++ b/contrib/depends/config.site.in @@ -13,25 +13,6 @@ fi if test -z $with_qt_translationdir; then with_qt_translationdir=$depends_prefix/translations fi -if test -z $with_qt_bindir && test -z "@no_qt@"; then - with_qt_bindir=$depends_prefix/native/bin -fi -if test -z $with_protoc_bindir && test -z "@no_qt@"; then - with_protoc_bindir=$depends_prefix/native/bin -fi - - -if test -z $enable_wallet && test -n "@no_wallet@"; then - enable_wallet=no -fi - -if test -z $with_miniupnpc && test -n "@no_upnp@"; then - with_miniupnpc=no -fi - -if test -z $with_gui && test -n "@no_qt@"; then - with_gui=no -fi if test x@host_os@ = xdarwin; then BREW=no diff --git a/contrib/depends/packages/bdb.mk b/contrib/depends/packages/bdb.mk deleted file mode 100644 index 050a60add..000000000 --- a/contrib/depends/packages/bdb.mk +++ /dev/null @@ -1,31 +0,0 @@ -package=bdb -$(package)_version=4.8.30 -$(package)_download_path=https://download.oracle.com/berkeley-db -$(package)_file_name=db-$($(package)_version).NC.tar.gz -$(package)_sha256_hash=12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef -$(package)_build_subdir=build_unix - -define $(package)_set_vars -$(package)_config_opts=--disable-shared --enable-cxx --disable-replication -$(package)_config_opts_mingw32=--enable-mingw -$(package)_config_opts_linux=--with-pic -$(package)_cxxflags=-std=c++11 -endef - -define $(package)_preprocess_cmds - sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h && \ - sed -i.old 's/atomic_init/atomic_init_db/' dbinc/atomic.h mp/mp_region.c mp/mp_mvcc.c mp/mp_fget.c mutex/mut_method.c mutex/mut_tas.c && \ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub dist -endef - -define $(package)_config_cmds - ../dist/$($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) libdb_cxx-4.8.a libdb-4.8.a -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install_lib install_include -endef diff --git a/contrib/depends/packages/libusb.mk b/contrib/depends/packages/libusb.mk index 6d60cce26..d865d2a17 100644 --- a/contrib/depends/packages/libusb.mk +++ b/contrib/depends/packages/libusb.mk @@ -11,13 +11,21 @@ endef define $(package)_set_vars $(package)_config_opts=--disable-shared $(package)_config_opts_linux=--with-pic --disable-udev + $(package)_config_opts_mingw32=--disable-udev + $(package)_config_opts_darwin=--disable-udev endef -define $(package)_config_cmds - cp -f $(BASEDIR)/config.guess config.guess &&\ - cp -f $(BASEDIR)/config.sub config.sub &&\ - $($(package)_autoconf) -endef +ifneq ($(host_os),darwin) + define $(package)_config_cmds + cp -f $(BASEDIR)/config.guess config.guess &&\ + cp -f $(BASEDIR)/config.sub config.sub &&\ + $($(package)_autoconf) + endef +else + define $(package)_config_cmds + $($(package)_autoconf) + endef +endif define $(package)_build_cmd $(MAKE) @@ -27,5 +35,5 @@ define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef -define $(package)_postprocess_cmds cp -f lib/libusb-1.0.a lib/libusb.a +define $(package)_postprocess_cmds cp -f lib/libusb-1.0.a lib/libusb.a endef diff --git a/contrib/depends/packages/miniupnpc.mk b/contrib/depends/packages/miniupnpc.mk deleted file mode 100644 index 1bb8cb5d2..000000000 --- a/contrib/depends/packages/miniupnpc.mk +++ /dev/null @@ -1,28 +0,0 @@ -package=miniupnpc -$(package)_version=2.0.20170509 -$(package)_download_path=http://miniupnp.free.fr/files -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=d3c368627f5cdfb66d3ebd64ca39ba54d6ff14a61966dbecb8dd296b7039f16a - -define $(package)_set_vars -$(package)_build_opts=CC="$($(package)_cc)" -$(package)_build_opts_darwin=OS=Darwin LIBTOOL="$($(package)_libtool)" -$(package)_build_opts_mingw32=-f Makefile.mingw -$(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)" -endef - -define $(package)_preprocess_cmds - mkdir dll && \ - sed -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"$($(package)_version)\"|' -e 's|OS/version|$(host)|' miniupnpcstrings.h.in > miniupnpcstrings.h && \ - sed -i.old "s|miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings|miniupnpcstrings.h: miniupnpcstrings.h.in|" Makefile.mingw -endef - -define $(package)_build_cmds - $(MAKE) libminiupnpc.a $($(package)_build_opts) -endef - -define $(package)_stage_cmds - mkdir -p $($(package)_staging_prefix_dir)/include/miniupnpc $($(package)_staging_prefix_dir)/lib &&\ - install *.h $($(package)_staging_prefix_dir)/include/miniupnpc &&\ - install libminiupnpc.a $($(package)_staging_prefix_dir)/lib -endef diff --git a/contrib/depends/packages/native_protobuf.mk b/contrib/depends/packages/native_protobuf.mk new file mode 100644 index 000000000..83e602341 --- /dev/null +++ b/contrib/depends/packages/native_protobuf.mk @@ -0,0 +1,28 @@ +package=protobuf3 +$(package)_version=3.6.1 +$(package)_download_path=https://github.com/protocolbuffers/protobuf/releases/download/v$($(package)_version)/ +$(package)_file_name=protobuf-cpp-$($(package)_version).tar.gz +$(package)_sha256_hash=b3732e471a9bb7950f090fd0457ebd2536a9ba0891b7f3785919c654fe2a2529 +$(package)_cxxflags=-std=c++11 + +define $(package)_set_vars + $(package)_config_opts=--disable-shared --prefix=$(build_prefix) + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) -C src libprotobuf.la all +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install install-libLTLIBRARIES install-nobase_includeHEADERS &&\ + $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA +endef + +define $(package)_postprocess_cmds + rm lib/libprotoc.a +endef diff --git a/contrib/depends/packages/packages.mk b/contrib/depends/packages/packages.mk index f814c14d6..b3a5992d0 100644 --- a/contrib/depends/packages/packages.mk +++ b/contrib/depends/packages/packages.mk @@ -1,12 +1,10 @@ -packages:=boost openssl libevent zeromq cppzmq zlib expat ldns cppzmq readline libiconv qt hidapi -native_packages := native_ccache - -wallet_packages=bdb +packages:=boost openssl libevent zeromq cppzmq zlib expat ldns cppzmq readline libiconv qt hidapi protobuf libusb +native_packages := native_ccache native_protobuf darwin_native_packages = native_biplist native_ds_store native_mac_alias darwin_packages = sodium-darwin -linux_packages = eudev libusb +linux_packages = eudev ifeq ($(host_os),linux) packages += unwind diff --git a/contrib/depends/toolchain.cmake.in b/contrib/depends/toolchain.cmake.in index f59b7b5ee..547b59108 100644 --- a/contrib/depends/toolchain.cmake.in +++ b/contrib/depends/toolchain.cmake.in @@ -21,6 +21,12 @@ SET(LIBUNWIND_LIBRARY_DIRS @prefix@/lib) SET(LIBUSB-1.0_LIBRARY @prefix@/lib/libusb-1.0.a) SET(LIBUDEV_LIBRARY @prefix@/lib/libudev.a) +SET(Protobuf_FOUND 1) +SET(Protobuf_PROTOC_EXECUTABLE @prefix@/native/bin/protoc CACHE FILEPATH "Path to the native protoc") +SET(Protobuf_INCLUDE_DIR @prefix@/include CACHE PATH "Protobuf include dir") +SET(Protobuf_INCLUDE_DIRS @prefix@/include CACHE PATH "Protobuf include dir") +SET(Protobuf_LIBRARY @prefix@/lib/libprotobuf.a CACHE FILEPATH "Protobuf library") + SET(ZMQ_INCLUDE_PATH @prefix@/include) SET(ZMQ_LIB @prefix@/lib/libzmq.a) diff --git a/contrib/epee/include/math_helper.h b/contrib/epee/include/math_helper.h index ef839f609..e22e8ee6e 100644 --- a/contrib/epee/include/math_helper.h +++ b/contrib/epee/include/math_helper.h @@ -230,35 +230,56 @@ namespace math_helper } } - template<int default_interval, bool start_immediate = true> - class once_a_time_seconds + template<uint64_t scale, int default_interval, bool start_immediate = true> + class once_a_time { + uint64_t get_time() const + { +#ifdef _WIN32 + FILETIME fileTime; + GetSystemTimeAsFileTime(&fileTime); + unsigned __int64 present = 0; + present |= fileTime.dwHighDateTime; + present = present << 32; + present |= fileTime.dwLowDateTime; + present /= 10; // mic-sec +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000000 + tv.tv_usec; +#endif + } + public: - once_a_time_seconds():m_interval(default_interval) + once_a_time():m_interval(default_interval * scale) { m_last_worked_time = 0; if(!start_immediate) - time(&m_last_worked_time); + m_last_worked_time = get_time(); } template<class functor_t> bool do_call(functor_t functr) { - time_t current_time = 0; - time(¤t_time); + uint64_t current_time = get_time(); if(current_time - m_last_worked_time > m_interval) { bool res = functr(); - time(&m_last_worked_time); + m_last_worked_time = get_time(); return res; } return true; } private: - time_t m_last_worked_time; - time_t m_interval; + uint64_t m_last_worked_time; + uint64_t m_interval; }; + + template<int default_interval, bool start_immediate = true> + class once_a_time_seconds: public once_a_time<1000000, default_interval, start_immediate> {}; + template<int default_interval, bool start_immediate = true> + class once_a_time_milliseconds: public once_a_time<1000, default_interval, start_immediate> {}; } } diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 9100a8db3..1ff9da3a7 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -38,14 +38,21 @@ #define MAX_LOG_FILE_SIZE 104850000 // 100 MB - 7600 bytes #define MAX_LOG_FILES 50 -#define MCFATAL(cat,x) CLOG(FATAL,cat) << x -#define MCERROR(cat,x) CLOG(ERROR,cat) << x -#define MCWARNING(cat,x) CLOG(WARNING,cat) << x -#define MCINFO(cat,x) CLOG(INFO,cat) << x -#define MCDEBUG(cat,x) CLOG(DEBUG,cat) << x -#define MCTRACE(cat,x) CLOG(TRACE,cat) << x -#define MCLOG(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::NormalLog, cat) << x -#define MCLOG_FILE(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::FileOnlyLog, cat) << x +#define MCLOG_TYPE(level, cat, type, x) do { \ + if (ELPP->vRegistry()->allowed(level, cat)) { \ + el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \ + } \ + } while (0) + +#define MCLOG(level, cat, x) MCLOG_TYPE(level, cat, el::base::DispatchAction::NormalLog, x) +#define MCLOG_FILE(level, cat, x) MCLOG_TYPE(level, cat, el::base::DispatchAction::FileOnlyLog, x) + +#define MCFATAL(cat,x) MCLOG(el::Level::Fatal,cat, x) +#define MCERROR(cat,x) MCLOG(el::Level::Error,cat, x) +#define MCWARNING(cat,x) MCLOG(el::Level::Warning,cat, x) +#define MCINFO(cat,x) MCLOG(el::Level::Info,cat, x) +#define MCDEBUG(cat,x) MCLOG(el::Level::Debug,cat, x) +#define MCTRACE(cat,x) MCLOG(el::Level::Trace,cat, x) #define MCLOG_COLOR(level,cat,color,x) MCLOG(level,cat,"\033[1;" color "m" << x << "\033[0m") #define MCLOG_RED(level,cat,x) MCLOG_COLOR(level,cat,"31",x) diff --git a/contrib/epee/include/net/buffer.h b/contrib/epee/include/net/buffer.h new file mode 100644 index 000000000..56c67f6bf --- /dev/null +++ b/contrib/epee/include/net/buffer.h @@ -0,0 +1,62 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <vector> +#include "misc_log_ex.h" +#include "span.h" + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "net.buffer" + +//#define NET_BUFFER_LOG(x) MDEBUG(x) +#define NET_BUFFER_LOG(x) ((void)0) + +namespace epee +{ +namespace net_utils +{ +class buffer +{ +public: + buffer(size_t reserve = 0): offset(0) { storage.reserve(reserve); } + + void append(const void *data, size_t sz); + void erase(size_t sz) { NET_BUFFER_LOG("erasing " << sz << "/" << size()); CHECK_AND_ASSERT_THROW_MES(offset + sz <= storage.size(), "erase: sz too large"); offset += sz; if (offset == storage.size()) { storage.resize(0); offset = 0; } } + epee::span<const uint8_t> span(size_t sz) const { CHECK_AND_ASSERT_THROW_MES(sz <= size(), "span is too large"); return epee::span<const uint8_t>(storage.data() + offset, sz); } + // carve must keep the data in scope till next call, other API calls (such as append, erase) can invalidate the carved buffer + epee::span<const uint8_t> carve(size_t sz) { CHECK_AND_ASSERT_THROW_MES(sz <= size(), "span is too large"); offset += sz; return epee::span<const uint8_t>(storage.data() + offset - sz, sz); } + size_t size() const { return storage.size() - offset; } + +private: + std::vector<uint8_t> storage; + size_t offset; +}; +} +} diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 997c801d1..64d035df9 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -92,7 +92,7 @@ handled = true; \ uint64_t ticks = misc_utils::get_tick_count(); \ boost::value_initialized<command_type::request> req; \ - bool parse_res = epee::serialization::load_t_from_binary(static_cast<command_type::request&>(req), query_info.m_body); \ + bool parse_res = epee::serialization::load_t_from_binary(static_cast<command_type::request&>(req), epee::strspan<uint8_t>(query_info.m_body)); \ CHECK_AND_ASSERT_MES(parse_res, false, "Failed to parse bin body data, body size=" << query_info.m_body.size()); \ uint64_t ticks1 = misc_utils::get_tick_count(); \ boost::value_initialized<command_type::response> resp;\ diff --git a/contrib/epee/include/net/levin_base.h b/contrib/epee/include/net/levin_base.h index 7d060f5ef..a88a1eb49 100644 --- a/contrib/epee/include/net/levin_base.h +++ b/contrib/epee/include/net/levin_base.h @@ -80,8 +80,8 @@ namespace levin template<class t_connection_context = net_utils::connection_context_base> struct levin_commands_handler { - virtual int invoke(int command, const std::string& in_buff, std::string& buff_out, t_connection_context& context)=0; - virtual int notify(int command, const std::string& in_buff, t_connection_context& context)=0; + virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_connection_context& context)=0; + virtual int notify(int command, const epee::span<const uint8_t> in_buff, t_connection_context& context)=0; virtual void callback(t_connection_context& context){}; virtual void on_connection_new(t_connection_context& context){}; diff --git a/contrib/epee/include/net/levin_client.h b/contrib/epee/include/net/levin_client.h index 335f6ba02..76d528234 100644 --- a/contrib/epee/include/net/levin_client.h +++ b/contrib/epee/include/net/levin_client.h @@ -57,7 +57,7 @@ namespace levin bool is_connected(); bool disconnect(); - virtual int invoke(int command, const std::string& in_buff, std::string& buff_out); + virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out); virtual int notify(int command, const std::string& in_buff); protected: @@ -72,7 +72,7 @@ namespace levin { public: - int invoke(int command, const std::string& in_buff, std::string& buff_out); + int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out); int notify(int command, const std::string& in_buff); }; diff --git a/contrib/epee/include/net/levin_client.inl b/contrib/epee/include/net/levin_client.inl index a580e81fd..2f048b027 100644 --- a/contrib/epee/include/net/levin_client.inl +++ b/contrib/epee/include/net/levin_client.inl @@ -74,7 +74,7 @@ levin_client_impl::~levin_client_impl() } //------------------------------------------------------------------------------ inline -int levin_client_impl::invoke(int command, const std::string& in_buff, std::string& buff_out) +int levin_client_impl::invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out) { if(!is_connected()) return -1; @@ -133,7 +133,7 @@ int levin_client_impl::notify(int command, const std::string& in_buff) //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ inline - int levin_client_impl2::invoke(int command, const std::string& in_buff, std::string& buff_out) + int levin_client_impl2::invoke(int command, epee::span<const uint8_t>string& in_buff, std::string& buff_out) { if(!is_connected()) return -1; diff --git a/contrib/epee/include/net/levin_client_async.h b/contrib/epee/include/net/levin_client_async.h index b3a46465b..ed92f4b95 100644 --- a/contrib/epee/include/net/levin_client_async.h +++ b/contrib/epee/include/net/levin_client_async.h @@ -431,7 +431,7 @@ namespace levin } CRITICAL_REGION_END(); - LOG_PRINT_L4("LEVIN_PACKET_RECIEVED. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]"); + LOG_PRINT_L4("LEVIN_PACKET_RECEIVED. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]"); if(is_request) { diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 6b1528caf..a1ea3e680 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -34,6 +34,7 @@ #include <atomic> #include "levin_base.h" +#include "buffer.h" #include "misc_language.h" #include "syncobj.h" #include "misc_os_dependent.h" @@ -85,11 +86,11 @@ public: uint64_t m_max_packet_size; uint64_t m_invoke_timeout; - int invoke(int command, const std::string& in_buff, std::string& buff_out, boost::uuids::uuid connection_id); + int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, boost::uuids::uuid connection_id); template<class callback_t> - int invoke_async(int command, const std::string& in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED); + int invoke_async(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED); - int notify(int command, const std::string& in_buff, boost::uuids::uuid connection_id); + int notify(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id); bool close(boost::uuids::uuid connection_id); bool update_connection_context(const t_connection_context& contxt); bool request_callback(boost::uuids::uuid connection_id); @@ -143,7 +144,7 @@ public: config_type& m_config; t_connection_context& m_connection_context; - std::string m_cache_in_buffer; + net_utils::buffer m_cache_in_buffer; stream_state m_state; int32_t m_oponent_protocol_ver; @@ -151,7 +152,7 @@ public: struct invoke_response_handler_base { - virtual bool handle(int res, const std::string& buff, connection_context& context)=0; + virtual bool handle(int res, const epee::span<const uint8_t> buff, connection_context& context)=0; virtual bool is_timer_started() const=0; virtual void cancel()=0; virtual bool cancel_timer()=0; @@ -173,7 +174,7 @@ public: if(ec == boost::asio::error::operation_aborted) return; MINFO(con.get_context_ref() << "Timeout on invoke operation happened, command: " << command << " timeout: " << timeout); - std::string fake; + epee::span<const uint8_t> fake; cb(LEVIN_ERROR_CONNECTION_TIMEDOUT, fake, con.get_context_ref()); con.close(); con.finish_outer_call(); @@ -191,7 +192,7 @@ public: bool m_timer_cancelled; uint64_t m_timeout; int m_command; - virtual bool handle(int res, const std::string& buff, typename async_protocol_handler::connection_context& context) + virtual bool handle(int res, const epee::span<const uint8_t> buff, typename async_protocol_handler::connection_context& context) { if(!cancel_timer()) return false; @@ -207,7 +208,7 @@ public: { if(cancel_timer()) { - std::string fake; + epee::span<const uint8_t> fake; m_cb(LEVIN_ERROR_CONNECTION_DESTROYED, fake, m_con.get_context_ref()); m_con.finish_outer_call(); } @@ -237,7 +238,7 @@ public: if(ec == boost::asio::error::operation_aborted) return; MINFO(con.get_context_ref() << "Timeout on invoke operation happened, command: " << command << " timeout: " << timeout); - std::string fake; + epee::span<const uint8_t> fake; cb(LEVIN_ERROR_CONNECTION_TIMEDOUT, fake, con.get_context_ref()); con.close(); con.finish_outer_call(); @@ -265,6 +266,7 @@ public: m_pservice_endpoint(psnd_hndlr), m_config(config), m_connection_context(conn_context), + m_cache_in_buffer(256 * 1024), m_state(stream_state_head) { m_close_called = 0; @@ -405,18 +407,11 @@ public: break; } { - std::string buff_to_invoke; - if(m_cache_in_buffer.size() == m_current_head.m_cb) - buff_to_invoke.swap(m_cache_in_buffer); - else - { - buff_to_invoke.assign(m_cache_in_buffer, 0, (std::string::size_type)m_current_head.m_cb); - m_cache_in_buffer.erase(0, (std::string::size_type)m_current_head.m_cb); - } + epee::span<const uint8_t> buff_to_invoke = m_cache_in_buffer.carve((std::string::size_type)m_current_head.m_cb); bool is_response = (m_oponent_protocol_ver == LEVIN_PROTOCOL_VER_1 && m_current_head.m_flags&LEVIN_PACKET_RESPONSE); - MDEBUG(m_connection_context << "LEVIN_PACKET_RECIEVED. [len=" << m_current_head.m_cb + MDEBUG(m_connection_context << "LEVIN_PACKET_RECEIVED. [len=" << m_current_head.m_cb << ", flags" << m_current_head.m_flags << ", r?=" << m_current_head.m_have_to_return_data <<", cmd = " << m_current_head.m_command @@ -449,8 +444,8 @@ public: }else { CRITICAL_REGION_BEGIN(m_local_inv_buff_lock); - buff_to_invoke.swap(m_local_inv_buff); - buff_to_invoke.clear(); + m_local_inv_buff = std::string((const char*)buff_to_invoke.data(), buff_to_invoke.size()); + buff_to_invoke = epee::span<const uint8_t>((const uint8_t*)NULL, 0); m_invoke_result_code = m_current_head.m_return_code; CRITICAL_REGION_END(); boost::interprocess::ipcdetail::atomic_write32(&m_invoke_buf_ready, 1); @@ -503,7 +498,7 @@ public: { if(m_cache_in_buffer.size() < sizeof(bucket_head2)) { - if(m_cache_in_buffer.size() >= sizeof(uint64_t) && *((uint64_t*)m_cache_in_buffer.data()) != SWAP64LE(LEVIN_SIGNATURE)) + if(m_cache_in_buffer.size() >= sizeof(uint64_t) && *((uint64_t*)m_cache_in_buffer.span(8).data()) != SWAP64LE(LEVIN_SIGNATURE)) { MWARNING(m_connection_context << "Signature mismatch, connection will be closed"); return false; @@ -513,9 +508,9 @@ public: } #if BYTE_ORDER == LITTLE_ENDIAN - bucket_head2& phead = *(bucket_head2*)m_cache_in_buffer.data(); + bucket_head2& phead = *(bucket_head2*)m_cache_in_buffer.span(sizeof(bucket_head2)).data(); #else - bucket_head2 phead = *(bucket_head2*)m_cache_in_buffer.data(); + bucket_head2 phead = *(bucket_head2*)m_cache_in_buffer.span(sizeof(bucket_head2)).data(); phead.m_signature = SWAP64LE(phead.m_signature); phead.m_cb = SWAP64LE(phead.m_cb); phead.m_command = SWAP32LE(phead.m_command); @@ -530,7 +525,7 @@ public: } m_current_head = phead; - m_cache_in_buffer.erase(0, sizeof(bucket_head2)); + m_cache_in_buffer.erase(sizeof(bucket_head2)); m_state = stream_state_body; m_oponent_protocol_ver = m_current_head.m_protocol_version; if(m_current_head.m_cb > m_config.m_max_packet_size) @@ -562,7 +557,7 @@ public: } template<class callback_t> - bool async_invoke(int command, const std::string& in_buff, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED) + bool async_invoke(int command, const epee::span<const uint8_t> in_buff, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED) { misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler( boost::bind(&async_protocol_handler::finish_outer_call, this)); @@ -606,7 +601,7 @@ public: break; } - if(!m_pservice_endpoint->do_send(in_buff.data(), (int)in_buff.size())) + if(!m_pservice_endpoint->do_send(in_buff.data(), in_buff.size())) { LOG_ERROR_CC(m_connection_context, "Failed to do_send"); err_code = LEVIN_ERROR_CONNECTION; @@ -623,7 +618,7 @@ public: if (LEVIN_OK != err_code) { - std::string stub_buff; + epee::span<const uint8_t> stub_buff{(const uint8_t*)"", 0}; // Never call callback inside critical section, that can cause deadlock cb(err_code, stub_buff, m_connection_context); return false; @@ -632,7 +627,7 @@ public: return true; } - int invoke(int command, const std::string& in_buff, std::string& buff_out) + int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out) { misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler( boost::bind(&async_protocol_handler::finish_outer_call, this)); @@ -662,7 +657,7 @@ public: return LEVIN_ERROR_CONNECTION; } - if(!m_pservice_endpoint->do_send(in_buff.data(), (int)in_buff.size())) + if(!m_pservice_endpoint->do_send(in_buff.data(), in_buff.size())) { LOG_ERROR_CC(m_connection_context, "Failed to do_send"); return LEVIN_ERROR_CONNECTION; @@ -706,7 +701,7 @@ public: return m_invoke_result_code; } - int notify(int command, const std::string& in_buff) + int notify(int command, const epee::span<const uint8_t> in_buff) { misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler( boost::bind(&async_protocol_handler::finish_outer_call, this)); @@ -734,7 +729,7 @@ public: return -1; } - if(!m_pservice_endpoint->do_send(in_buff.data(), (int)in_buff.size())) + if(!m_pservice_endpoint->do_send(in_buff.data(), in_buff.size())) { LOG_ERROR_CC(m_connection_context, "Failed to do_send()"); return -1; @@ -839,7 +834,7 @@ int async_protocol_handler_config<t_connection_context>::find_and_lock_connectio } //------------------------------------------------------------------------------------------ template<class t_connection_context> -int async_protocol_handler_config<t_connection_context>::invoke(int command, const std::string& in_buff, std::string& buff_out, boost::uuids::uuid connection_id) +int async_protocol_handler_config<t_connection_context>::invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, boost::uuids::uuid connection_id) { async_protocol_handler<t_connection_context>* aph; int r = find_and_lock_connection(connection_id, aph); @@ -847,7 +842,7 @@ int async_protocol_handler_config<t_connection_context>::invoke(int command, con } //------------------------------------------------------------------------------------------ template<class t_connection_context> template<class callback_t> -int async_protocol_handler_config<t_connection_context>::invoke_async(int command, const std::string& in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout) +int async_protocol_handler_config<t_connection_context>::invoke_async(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout) { async_protocol_handler<t_connection_context>* aph; int r = find_and_lock_connection(connection_id, aph); @@ -896,7 +891,7 @@ void async_protocol_handler_config<t_connection_context>::set_handler(levin_comm } //------------------------------------------------------------------------------------------ template<class t_connection_context> -int async_protocol_handler_config<t_connection_context>::notify(int command, const std::string& in_buff, boost::uuids::uuid connection_id) +int async_protocol_handler_config<t_connection_context>::notify(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id) { async_protocol_handler<t_connection_context>* aph; int r = find_and_lock_connection(connection_id, aph); diff --git a/contrib/epee/include/span.h b/contrib/epee/include/span.h index b1296a0b7..cfb5b1a17 100644 --- a/contrib/epee/include/span.h +++ b/contrib/epee/include/span.h @@ -163,4 +163,12 @@ namespace epee static_assert(!has_padding<T>(), "source type may have padding"); return {reinterpret_cast<std::uint8_t*>(std::addressof(src)), sizeof(T)}; } + + //! make a span from a std::string + template<typename T> + span<const T> strspan(const std::string &s) noexcept + { + static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected type"); + return {reinterpret_cast<const T*>(s.data()), s.size()}; + } } diff --git a/contrib/epee/include/storages/http_abstract_invoke.h b/contrib/epee/include/storages/http_abstract_invoke.h index d93084ab0..18b7f10c1 100644 --- a/contrib/epee/include/storages/http_abstract_invoke.h +++ b/contrib/epee/include/storages/http_abstract_invoke.h @@ -97,7 +97,7 @@ namespace epee return false; } - return serialization::load_t_from_binary(result_struct, pri->m_body); + return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body)); } template<class t_request, class t_response, class t_transport> diff --git a/contrib/epee/include/storages/levin_abstract_invoke2.h b/contrib/epee/include/storages/levin_abstract_invoke2.h index d77e7a1f8..06eb9bdaf 100644 --- a/contrib/epee/include/storages/levin_abstract_invoke2.h +++ b/contrib/epee/include/storages/levin_abstract_invoke2.h @@ -28,6 +28,7 @@ #include "portable_storage_template_helper.h" #include <boost/utility/value_init.hpp> +#include "span.h" #include "net/levin_base.h" #undef MONERO_DEFAULT_LOG_CATEGORY @@ -114,7 +115,7 @@ namespace epee const_cast<t_arg&>(out_struct).store(stg);//TODO: add true const support to searilzation std::string buff_to_send; stg.store_to_binary(buff_to_send); - int res = transport.invoke_async(command, buff_to_send, conn_id, [cb, command](int code, const std::string& buff, typename t_transport::connection_context& context)->bool + int res = transport.invoke_async(command, epee::strspan<uint8_t>(buff_to_send), conn_id, [cb, command](int code, const epee::span<const uint8_t> buff, typename t_transport::connection_context& context)->bool { t_result result_struct = AUTO_VAL_INIT(result_struct); if( code <=0 ) @@ -156,7 +157,7 @@ namespace epee std::string buff_to_send; stg.store_to_binary(buff_to_send); - int res = transport.notify(command, buff_to_send, conn_id); + int res = transport.notify(command, epee::strspan<uint8_t>(buff_to_send), conn_id); if(res <=0 ) { MERROR("Failed to notify command " << command << " return code " << res); @@ -167,7 +168,7 @@ namespace epee //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- template<class t_owner, class t_in_type, class t_out_type, class t_context, class callback_t> - int buff_to_t_adapter(int command, const std::string& in_buff, std::string& buff_out, callback_t cb, t_context& context ) + int buff_to_t_adapter(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, callback_t cb, t_context& context ) { serialization::portable_storage strg; if(!strg.load_from_binary(in_buff)) @@ -197,7 +198,7 @@ namespace epee } template<class t_owner, class t_in_type, class t_context, class callback_t> - int buff_to_t_adapter(t_owner* powner, int command, const std::string& in_buff, callback_t cb, t_context& context) + int buff_to_t_adapter(t_owner* powner, int command, const epee::span<const uint8_t> in_buff, callback_t cb, t_context& context) { serialization::portable_storage strg; if(!strg.load_from_binary(in_buff)) @@ -215,14 +216,14 @@ namespace epee } #define CHAIN_LEVIN_INVOKE_MAP2(context_type) \ - int invoke(int command, const std::string& in_buff, std::string& buff_out, context_type& context) \ + int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, context_type& context) \ { \ bool handled = false; \ return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \ } #define CHAIN_LEVIN_NOTIFY_MAP2(context_type) \ - int notify(int command, const std::string& in_buff, context_type& context) \ + int notify(int command, const epee::span<const uint8_t> in_buff, context_type& context) \ { \ bool handled = false; std::string fake_str;\ return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \ @@ -230,27 +231,27 @@ namespace epee #define CHAIN_LEVIN_INVOKE_MAP() \ - int invoke(int command, const std::string& in_buff, std::string& buff_out, epee::net_utils::connection_context_base& context) \ + int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, epee::net_utils::connection_context_base& context) \ { \ bool handled = false; \ return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \ } #define CHAIN_LEVIN_NOTIFY_MAP() \ - int notify(int command, const std::string& in_buff, epee::net_utils::connection_context_base& context) \ + int notify(int command, const epee::span<const uint8_t> in_buff, epee::net_utils::connection_context_base& context) \ { \ bool handled = false; std::string fake_str;\ return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \ } #define CHAIN_LEVIN_NOTIFY_STUB() \ - int notify(int command, const std::string& in_buff, epee::net_utils::connection_context_base& context) \ + int notify(int command, const epee::span<const uint8_t> in_buff, epee::net_utils::connection_context_base& context) \ { \ return -1; \ } #define BEGIN_INVOKE_MAP2(owner_type) \ - template <class t_context> int handle_invoke_map(bool is_notify, int command, const std::string& in_buff, std::string& buff_out, t_context& context, bool& handled) \ + template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_context& context, bool& handled) \ { \ typedef owner_type internal_owner_type_name; diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h index 31495ae13..d73fbde3a 100644 --- a/contrib/epee/include/storages/parserse_base_utils.h +++ b/contrib/epee/include/storages/parserse_base_utils.h @@ -91,11 +91,15 @@ namespace misc_utils */ inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val) { - val.clear(); - val.reserve(std::distance(star_end_string, buf_end)); bool escape_mode = false; std::string::const_iterator it = star_end_string; ++it; + std::string::const_iterator fi = it; + while (fi != buf_end && *fi != '\\' && *fi != '\"') + ++fi; + val.assign(it, fi); + val.reserve(std::distance(star_end_string, buf_end)); + it = fi; for(;it != buf_end;it++) { if(escape_mode/*prev_ch == '\\'*/) diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index 0f0c6210f..d0e40d606 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -35,6 +35,7 @@ #include "portable_storage_to_json.h" #include "portable_storage_from_json.h" #include "portable_storage_val_converters.h" +#include "span.h" #include "int-util.h" namespace epee @@ -81,7 +82,8 @@ namespace epee //------------------------------------------------------------------------------- bool store_to_binary(binarybuffer& target); - bool load_from_binary(const binarybuffer& target); + bool load_from_binary(const epee::span<const uint8_t> target); + bool load_from_binary(const std::string& target) { return load_from_binary(epee::strspan<uint8_t>(target)); } template<class trace_policy> bool dump_as_xml(std::string& targetObj, const std::string& root_name = ""); bool dump_as_json(std::string& targetObj, size_t indent = 0, bool insert_newlines = true); @@ -146,7 +148,7 @@ namespace epee CATCH_ENTRY("portable_storage::store_to_binary", false) } inline - bool portable_storage::load_from_binary(const binarybuffer& source) + bool portable_storage::load_from_binary(const epee::span<const uint8_t> source) { m_root.m_entries.clear(); if(source.size() < sizeof(storage_block_header)) diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/storages/portable_storage_template_helper.h index bbd8413fc..13c870d44 100644 --- a/contrib/epee/include/storages/portable_storage_template_helper.h +++ b/contrib/epee/include/storages/portable_storage_template_helper.h @@ -84,7 +84,7 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template<class t_struct> - bool load_t_from_binary(t_struct& out, const std::string& binary_buff) + bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff) { portable_storage ps; bool rs = ps.load_from_binary(binary_buff); @@ -95,6 +95,12 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template<class t_struct> + bool load_t_from_binary(t_struct& out, const std::string& binary_buff) + { + return load_t_from_binary(out, epee::strspan<uint8_t>(binary_buff)); + } + //----------------------------------------------------------------------------------------------------------- + template<class t_struct> bool load_t_from_binary_file(t_struct& out, const std::string& binary_file) { std::string f_buff; diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index 6a063cc36..f7539fb6c 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -40,8 +40,6 @@ #include <cstdlib> #include <string> #include <type_traits> -#include <boost/uuid/uuid.hpp> -#include <boost/uuid/uuid_io.hpp> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string/predicate.hpp> #include "hex.h" @@ -83,50 +81,18 @@ namespace epee { namespace string_tools { - //---------------------------------------------------------------------------- - inline std::string get_str_from_guid_a(const boost::uuids::uuid& rid) - { - return boost::lexical_cast<std::string>(rid); - } - //---------------------------------------------------------------------------- - inline bool get_guid_from_string(OUT boost::uuids::uuid& inetifer, const std::string& str_id) - { - std::string local_str_id = str_id; - if(local_str_id.size() < 36) - return false; - - if('{' == *local_str_id.begin()) - local_str_id.erase(0, 1); - - if('}' == *(--local_str_id.end())) - local_str_id.erase(--local_str_id.end()); - - try - { - inetifer = boost::lexical_cast<boost::uuids::uuid>(local_str_id); - return true; - } - catch(...) - { - return false; - } - } //---------------------------------------------------------------------------- inline std::string buff_to_hex_nodelimer(const std::string& src) { return to_hex::string(to_byte_span(to_span(src))); } //---------------------------------------------------------------------------- - template<class CharT> - bool parse_hexstr_to_binbuff(const std::basic_string<CharT>& s, std::basic_string<CharT>& res) + inline bool parse_hexstr_to_binbuff(const epee::span<const char> s, epee::span<char>& res) { - res.clear(); - if (s.size() & 1) - return false; - try - { - res.resize(s.size() / 2); - unsigned char *dst = (unsigned char *)res.data(); + if (s.size() != res.size() * 2) + return false; + + unsigned char *dst = (unsigned char *)&res[0]; const unsigned char *src = (const unsigned char *)s.data(); for(size_t i = 0; i < s.size(); i += 2) { @@ -140,28 +106,15 @@ namespace string_tools } return true; - } - catch(...) - { - return false; - } } //---------------------------------------------------------------------------- - template<class t_pod_type> - bool parse_tpod_from_hex_string(const std::string& str_hash, t_pod_type& t_pod) + inline bool parse_hexstr_to_binbuff(const std::string& s, std::string& res) { - static_assert(std::is_pod<t_pod_type>::value, "expected pod type"); - std::string buf; - bool res = epee::string_tools::parse_hexstr_to_binbuff(str_hash, buf); - if (!res || buf.size() != sizeof(t_pod_type)) - { + if (s.size() & 1) return false; - } - else - { - buf.copy(reinterpret_cast<char *>(&t_pod), sizeof(t_pod_type)); - return true; - } + res.resize(s.size() / 2); + epee::span<char> rspan((char*)&res[0], res.size()); + return parse_hexstr_to_binbuff(epee::to_span(s), rspan); } //---------------------------------------------------------------------------- PUSH_WARNINGS @@ -360,17 +313,10 @@ POP_WARNINGS bool hex_to_pod(const std::string& hex_str, t_pod_type& s) { static_assert(std::is_pod<t_pod_type>::value, "expected pod type"); - std::string hex_str_tr = trim(hex_str); if(sizeof(s)*2 != hex_str.size()) return false; - std::string bin_buff; - if(!parse_hexstr_to_binbuff(hex_str_tr, bin_buff)) - return false; - if(bin_buff.size()!=sizeof(s)) - return false; - - s = *(t_pod_type*)bin_buff.data(); - return true; + epee::span<char> rspan((char*)&s, sizeof(s)); + return parse_hexstr_to_binbuff(epee::to_span(hex_str), rspan); } //---------------------------------------------------------------------------- template<class t_pod_type> diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt index bc437deb9..cea50c9dd 100644 --- a/contrib/epee/src/CMakeLists.txt +++ b/contrib/epee/src/CMakeLists.txt @@ -27,7 +27,7 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp memwipe.c - connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp) + connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp) if (USE_READLINE AND GNU_READLINE_FOUND) add_library(epee_readline STATIC readline_buffer.cpp) endif() diff --git a/contrib/epee/src/buffer.cpp b/contrib/epee/src/buffer.cpp new file mode 100644 index 000000000..d637b905e --- /dev/null +++ b/contrib/epee/src/buffer.cpp @@ -0,0 +1,97 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <string.h> +#include "net/buffer.h" + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "net.buffer" + +namespace epee +{ +namespace net_utils +{ + +void buffer::append(const void *data, size_t sz) +{ + const size_t capacity = storage.capacity(); + const size_t avail = capacity - storage.size(); + + CHECK_AND_ASSERT_THROW_MES(storage.size() < std::numeric_limits<size_t>::max() - sz, "Too much data to append"); + + // decide when to move + if (sz > avail) + { + // we have to reallocate or move + const bool move = size() + sz <= capacity; + if (move) + { + const size_t bytes = storage.size() - offset; + NET_BUFFER_LOG("appending " << sz << " from " << size() << " by moving " << bytes << " from offset " << offset << " first (forced)"); + memmove(storage.data(), storage.data() + offset, bytes); + storage.resize(bytes); + offset = 0; + } + else + { + NET_BUFFER_LOG("appending " << sz << " from " << size() << " by reallocating"); + std::vector<uint8_t> new_storage; + size_t reserve = (((size() + sz) * 3 / 2) + 4095) & ~4095; + new_storage.reserve(reserve); + new_storage.resize(size()); + memcpy(new_storage.data(), storage.data() + offset, storage.size() - offset); + offset = 0; + std::swap(storage, new_storage); + } + } + else + { + // we have space already + if (size() <= 4096 && offset > 4096 * 16 && offset >= capacity / 2) + { + // we have little to move, and we're far enough into the buffer that it's probably a win to move anyway + const size_t pos = storage.size() - offset; + NET_BUFFER_LOG("appending " << sz << " from " << size() << " by moving " << pos << " from offset " << offset << " first (unforced)"); + memmove(storage.data(), storage.data() + offset, storage.size() - offset); + storage.resize(pos); + offset = 0; + } + else + { + NET_BUFFER_LOG("appending " << sz << " from " << size() << " by writing to existing capacity"); + } + } + + // add the new data + storage.insert(storage.end(), (const uint8_t*)data, (const uint8_t*)data + sz); + + NET_BUFFER_LOG("storage now " << offset << "/" << storage.size() << "/" << storage.capacity()); +} + +} +} diff --git a/contrib/epee/src/mlocker.cpp b/contrib/epee/src/mlocker.cpp index 078a84ce3..446fa3315 100644 --- a/contrib/epee/src/mlocker.cpp +++ b/contrib/epee/src/mlocker.cpp @@ -40,6 +40,9 @@ #include <atomic> +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "mlocker" + // did an mlock operation previously fail? we only // want to log an error once and be done with it static std::atomic<bool> previously_failed{ false }; diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index 00d848388..9b6b832d1 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -103,7 +103,7 @@ static const char *get_default_categories(int level) categories = "*:WARNING,net:FATAL,net.http:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO"; break; case 1: - categories = "*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO"; + categories = "*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO,perf.*:DEBUG"; break; case 2: categories = "*:DEBUG"; diff --git a/contrib/epee/src/net_utils_base.cpp b/contrib/epee/src/net_utils_base.cpp index 354c3d2c3..263b344b4 100644 --- a/contrib/epee/src/net_utils_base.cpp +++ b/contrib/epee/src/net_utils_base.cpp @@ -1,7 +1,9 @@ #include "net/net_utils_base.h" -#include "string_tools.h" +#include <boost/uuid/uuid_io.hpp> + +#include "string_tools.h" #include "net/local_ip.h" namespace epee { namespace net_utils @@ -73,7 +75,7 @@ namespace epee { namespace net_utils std::string print_connection_context(const connection_context_base& ctx) { std::stringstream ss; - ss << ctx.m_remote_address.str() << " " << epee::string_tools::get_str_from_guid_a(ctx.m_connection_id) << (ctx.m_is_income ? " INC":" OUT"); + ss << ctx.m_remote_address.str() << " " << ctx.m_connection_id << (ctx.m_is_income ? " INC":" OUT"); return ss.str(); } diff --git a/contrib/epee/tests/src/CMakeLists.txt b/contrib/epee/tests/src/CMakeLists.txt index c7d31735b..4807fa7ea 100644 --- a/contrib/epee/tests/src/CMakeLists.txt +++ b/contrib/epee/tests/src/CMakeLists.txt @@ -14,8 +14,8 @@ IF (MSVC) include_directories(SYSTEM platform/msvc) ELSE() # set stuff for other systems - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall -Werror") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror -Wno-reorder") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wno-reorder") ENDIF() diff --git a/contrib/gitian/gitian-linux.yml b/contrib/gitian/gitian-linux.yml index 473a7720d..3bb25c314 100644 --- a/contrib/gitian/gitian-linux.yml +++ b/contrib/gitian/gitian-linux.yml @@ -152,7 +152,7 @@ script: | for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir build && cd build - cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake + cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON make DISTNAME=monero-${i} mv bin ${DISTNAME} diff --git a/contrib/gitian/symbol-check.py b/contrib/gitian/symbol-check.py deleted file mode 100755 index 6808e77da..000000000 --- a/contrib/gitian/symbol-check.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2014 Wladimir J. van der Laan -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -A script to check that the (Linux) executables produced by gitian only contain -allowed gcc, glibc and libstdc++ version symbols. This makes sure they are -still compatible with the minimum supported Linux distribution versions. - -Example usage: - - find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py -''' -import subprocess -import re -import sys -import os - -# Debian 6.0.9 (Squeeze) has: -# -# - g++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=g%2B%2B) -# - libc version 2.11.3 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libc6) -# - libstdc++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libstdc%2B%2B6) -# -# Ubuntu 10.04.4 (Lucid Lynx) has: -# -# - g++ version 4.4.3 (http://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=lucid§ion=all) -# - libc version 2.11.1 (http://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=lucid§ion=all) -# - libstdc++ version 4.4.3 (http://packages.ubuntu.com/search?suite=lucid§ion=all&arch=any&keywords=libstdc%2B%2B&searchon=names) -# -# Taking the minimum of these as our target. -# -# According to GNU ABI document (http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to: -# GCC 4.4.0: GCC_4.4.0 -# GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3 -# (glibc) GLIBC_2_11 -# -MAX_VERSIONS = { -'GCC': (4,4,0), -'CXXABI': (1,3,3), -'GLIBCXX': (3,4,13), -'GLIBC': (2,11) -} -# See here for a description of _IO_stdin_used: -# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 - -# Ignore symbols that are exported as part of every executable -IGNORE_EXPORTS = { -'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr' -} -READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') -CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') -# Allowed NEEDED libraries -ALLOWED_LIBRARIES = { -# bitcoind and bitcoin-qt -'libgcc_s.so.1', # GCC base support -'libc.so.6', # C library -'libpthread.so.0', # threading -'libanl.so.1', # DNS resolve -'libm.so.6', # math library -'librt.so.1', # real-time (clock) -'ld-linux-x86-64.so.2', # 64-bit dynamic linker -'ld-linux.so.2', # 32-bit dynamic linker -# bitcoin-qt only -'libX11-xcb.so.1', # part of X11 -'libX11.so.6', # part of X11 -'libxcb.so.1', # part of X11 -'libfontconfig.so.1', # font support -'libfreetype.so.6', # font parsing -'libdl.so.2' # programming interface to dynamic linker -} - -class CPPFilt(object): - ''' - Demangle C++ symbol names. - - Use a pipe to the 'c++filt' command. - ''' - def __init__(self): - self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) - - def __call__(self, mangled): - self.proc.stdin.write(mangled + '\n') - self.proc.stdin.flush() - return self.proc.stdout.readline().rstrip() - - def close(self): - self.proc.stdin.close() - self.proc.stdout.close() - self.proc.wait() - -def read_symbols(executable, imports=True): - ''' - Parse an ELF executable and return a list of (symbol,version) tuples - for dynamic, imported symbols. - ''' - p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) - syms = [] - for line in stdout.splitlines(): - line = line.split() - if len(line)>7 and re.match('[0-9]+:$', line[0]): - (sym, _, version) = line[7].partition('@') - is_import = line[6] == 'UND' - if version.startswith('@'): - version = version[1:] - if is_import == imports: - syms.append((sym, version)) - return syms - -def check_version(max_versions, version): - if '_' in version: - (lib, _, ver) = version.rpartition('_') - else: - lib = version - ver = '0' - ver = tuple([int(x) for x in ver.split('.')]) - if not lib in max_versions: - return False - return ver <= max_versions[lib] - -def read_libraries(filename): - p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') - libraries = [] - for line in stdout.splitlines(): - tokens = line.split() - if len(tokens)>2 and tokens[1] == '(NEEDED)': - match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) - if match: - libraries.append(match.group(1)) - else: - raise ValueError('Unparseable (NEEDED) specification') - return libraries - -if __name__ == '__main__': - cppfilt = CPPFilt() - retval = 0 - for filename in sys.argv[1:]: - # Check imported symbols - for sym,version in read_symbols(filename, True): - if version and not check_version(MAX_VERSIONS, version): - print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version)) - retval = 1 - # Check exported symbols - for sym,version in read_symbols(filename, False): - if sym in IGNORE_EXPORTS: - continue - print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym))) - retval = 1 - # Check dependency libraries - for library_name in read_libraries(filename): - if library_name not in ALLOWED_LIBRARIES: - print('%s: NEEDED library %s is not allowed' % (filename, library_name)) - retval = 1 - - sys.exit(retval) - - |