diff --git a/CMakeLists.txt b/CMakeLists.txt index 764db875d661e0d85c6df2a81c38c9b769948a93..2d0d17bad32def0837666bcd6f6ff90a27f43c2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ if (OPENDHT_TOOLS) endif () list (APPEND opendht_SOURCES + src/utils.cpp src/infohash.cpp src/crypto.cpp src/default_types.cpp @@ -35,6 +36,7 @@ list (APPEND opendht_SOURCES ) list (APPEND opendht_HEADERS + include/opendht/utils.h include/opendht/rng.h include/opendht/crypto.h include/opendht/infohash.h diff --git a/include/opendht/crypto.h b/include/opendht/crypto.h index e1daf2560d978a6b091b38cb875e7af487d82df0..16990f9ce7e3a95961906833cdde6955af5cf072 100644 --- a/include/opendht/crypto.h +++ b/include/opendht/crypto.h @@ -31,6 +31,7 @@ #pragma once #include "infohash.h" +#include "utils.h" extern "C" { #include <gnutls/gnutls.h> @@ -41,8 +42,6 @@ extern "C" { #include <vector> #include <memory> -typedef std::vector<uint8_t> Blob; - namespace dht { namespace crypto { diff --git a/include/opendht/infohash.h b/include/opendht/infohash.h index 953d51f89e018c89edf5f6dd1fb9fb843135dbc7..01a2c306dbad8fc9b8556f17681f6bf9cb61808f 100644 --- a/include/opendht/infohash.h +++ b/include/opendht/infohash.h @@ -45,13 +45,6 @@ namespace dht { -class DhtException : public std::runtime_error { - public: - DhtException(const std::string &str = "") : - std::runtime_error("DhtException occured: " + str) {} -}; - - /** * Represents an InfoHash. * An InfoHash is a byte array of HASH_LEN bytes. diff --git a/include/opendht/utils.h b/include/opendht/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..c6ce5a993857b159b5dc8a83a9c4f4bd41918813 --- /dev/null +++ b/include/opendht/utils.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2014-2015 Savoir-faire Linux Inc. + * Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include <msgpack.hpp> + +#include <chrono> +#include <random> +#include <functional> + +#include <cstdarg> + +namespace dht { + +class DhtException : public std::runtime_error { + public: + DhtException(const std::string &str = "") : + std::runtime_error("DhtException occured: " + str) {} +}; + + +// Time related definitions and utility functions + +using clock = std::chrono::steady_clock; +using time_point = clock::time_point; +using duration = clock::duration; + +time_point from_time_t(std::time_t t); +std::time_t to_time_t(time_point t); + +static /*constexpr*/ const time_point TIME_INVALID = {time_point::min()}; +static /*constexpr*/ const time_point TIME_MAX {time_point::max()}; + +template <typename Duration = duration> +class uniform_duration_distribution : public std::uniform_int_distribution<typename Duration::rep> { + using Base = std::uniform_int_distribution<typename Duration::rep>; + using param_type = typename Base::param_type; +public: + uniform_duration_distribution(Duration min, Duration max) : Base(min.count(), max.count()) {} + template <class Generator> + Duration operator()(Generator && g) { + return Duration(Base::operator()(g)); + } + template< class Generator > + Duration operator()( Generator && g, const param_type& params ) { + return Duration(Base::operator()(g, params)); + } +}; + +// Logging related utility functions + +/** + * Dummy function used to disable logging + */ +inline void NOLOG(char const*, va_list) {} + +/** + * Wrapper for logging methods + */ +struct LogMethod { + LogMethod() = default; + + template<typename T> + LogMethod(T&& t) : func(std::forward<T>(t)) {} + + void operator()(char const* format, ...) const { + va_list args; + va_start(args, format); + func(format, args); + va_end(args); + } + + void logPrintable(const uint8_t *buf, size_t buflen) const { + std::string buf_clean(buflen, '\0'); + for (size_t i=0; i<buflen; i++) + buf_clean[i] = buf[i] >= 32 && buf[i] <= 126 ? buf[i] : '.'; + (*this)("%s", buf_clean.c_str()); + } +private: + std::function<void(char const*, va_list)> func; +}; + +// Serialization related definitions and utility functions + +typedef std::vector<uint8_t> Blob; + +/** + * Provides backward compatibility with msgpack 1.0 + */ +Blob unpackBlob(msgpack::object& o); + +template <typename Type> +Blob +packMsg(const Type& t) { + msgpack::sbuffer buffer; + msgpack::packer<msgpack::sbuffer> pk(&buffer); + pk.pack(t); + return {buffer.data(), buffer.data()+buffer.size()}; +} + +template <typename Type> +Type +unpackMsg(Blob b) { + msgpack::unpacked msg_res = msgpack::unpack((const char*)b.data(), b.size()); + return msg_res.get().as<Type>(); +} + +msgpack::unpacked unpackMsg(Blob b); + +} diff --git a/include/opendht/value.h b/include/opendht/value.h index c2f08513bae9e4ae6864557b5f4370391b9d3cb3..b79f8b349792bc615b536ab429ec30fd256b6e5f 100644 --- a/include/opendht/value.h +++ b/include/opendht/value.h @@ -32,6 +32,8 @@ #include "infohash.h" #include "crypto.h" +#include "utils.h" + #include <msgpack.hpp> #ifndef _WIN32 @@ -56,68 +58,8 @@ typedef uint16_t in_port_t; #include <memory> #include <chrono> -#include <cstdarg> - namespace dht { -using clock = std::chrono::steady_clock; -using time_point = clock::time_point; -using duration = clock::duration; - -time_point from_time_t(std::time_t t); -std::time_t to_time_t(time_point t); - -static /*constexpr*/ const time_point TIME_INVALID = {time_point::min()}; -static /*constexpr*/ const time_point TIME_MAX {time_point::max()}; - -template <typename Duration = duration> -class uniform_duration_distribution : public std::uniform_int_distribution<typename Duration::rep> { - using Base = std::uniform_int_distribution<typename Duration::rep>; - using param_type = typename Base::param_type; -public: - uniform_duration_distribution(Duration min, Duration max) : Base(min.count(), max.count()) {} - template <class Generator> - Duration operator()(Generator && g) { - return Duration(Base::operator()(g)); - } - template< class Generator > - Duration operator()( Generator && g, const param_type& params ) { - return Duration(Base::operator()(g, params)); - } -}; - -/** - * Wrapper for logging methods - */ -struct LogMethod { - LogMethod() = default; - - template<typename T> - LogMethod( T&& t) : func(std::forward<T>(t)) {} - - void operator()(char const* format, ...) const { - va_list args; - va_start(args, format); - func(format, args); - va_end(args); - } - - void logPrintable(const uint8_t *buf, size_t buflen) const { - std::string buf_clean(buflen, '\0'); - for (size_t i=0; i<buflen; i++) - buf_clean[i] = buf[i] >= 32 && buf[i] <= 126 ? buf[i] : '.'; - (*this)("%s", buf_clean.c_str()); - } -private: - std::function<void(char const*, va_list)> func; -}; - -/** - * Dummy function used to disable logging - */ -inline void NOLOG(char const*, va_list) {} - - struct Value; typedef std::function<bool(InfoHash, std::shared_ptr<Value>&, InfoHash, const sockaddr*, socklen_t)> StorePolicy; @@ -156,24 +98,6 @@ struct ValueType { EditPolicy editPolicy {DEFAULT_EDIT_POLICY}; }; -template <typename Type> -Blob -packMsg(const Type& t) { - msgpack::sbuffer buffer; - msgpack::packer<msgpack::sbuffer> pk(&buffer); - pk.pack(t); - return {buffer.data(), buffer.data()+buffer.size()}; -} - -template <typename Type> -Type -unpackMsg(Blob b) { - msgpack::unpacked msg_res = msgpack::unpack((const char*)b.data(), b.size()); - return msg_res.get().as<Type>(); -} - -msgpack::unpacked unpackMsg(Blob b); - /** * A "value" is data potentially stored on the Dht, with some metadata. * @@ -508,9 +432,4 @@ unpackVector(const std::vector<std::shared_ptr<Value>>& vals) { return ret; } -/** - * Provides backward compatibility with msgpack 1.0 - */ -Blob unpackBlob(msgpack::object& o); - } diff --git a/src/Makefile.am b/src/Makefile.am index 727c4b50ba33405e98e92c2954d16e86f6fd5dab..d066626914410fdaa324f0c3819e5cea823cf205 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,7 @@ libopendht_la_LDFLAGS = @LDFLAGS@ @GNUTLS_LIBS@ @nettle_LIBS@ libopendht_la_SOURCES = \ dht.cpp \ + utils.cpp \ infohash.cpp \ value.cpp \ crypto.cpp \ @@ -20,6 +21,7 @@ endif nobase_include_HEADERS = \ ../include/opendht.h \ ../include/opendht/dht.h \ + ../include/opendht/utils.h \ ../include/opendht/infohash.h \ ../include/opendht/value.h \ ../include/opendht/crypto.h \ diff --git a/src/crypto.cpp b/src/crypto.cpp index 4735fd3514851041921f864e858ca448ff630361..ca836e8c030598b9108210702e708d1309150f26 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -30,7 +30,6 @@ #include "crypto.h" #include "rng.h" -#include "value.h" extern "C" { #include <gnutls/gnutls.h> diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37561e28329c3a4f315ce4927da077b642f1c8ae --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014-2015 Savoir-faire Linux Inc. + * Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "utils.h" + +namespace dht { + +time_point from_time_t(std::time_t t) { + return clock::now() + (std::chrono::system_clock::from_time_t(t) - std::chrono::system_clock::now()); +} + +std::time_t to_time_t(time_point t) { + return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + + (t - clock::now())); +} + +Blob +unpackBlob(msgpack::object& o) { + switch (o.type) { + case msgpack::type::BIN: + return {o.via.bin.ptr, o.via.bin.ptr+o.via.bin.size}; + case msgpack::type::STR: + return {o.via.str.ptr, o.via.str.ptr+o.via.str.size}; + case msgpack::type::ARRAY: { + Blob ret(o.via.array.size); + std::transform(o.via.array.ptr, o.via.array.ptr+o.via.array.size, ret.begin(), [](const msgpack::object& b) { + return b.as<uint8_t>(); + }); + return ret; + } + default: + throw msgpack::type_error(); + } +} + +msgpack::unpacked +unpackMsg(Blob b) { + return msgpack::unpack((const char*)b.data(), b.size()); +} + +} diff --git a/src/value.cpp b/src/value.cpp index 5d22f259b57c462be73949af17dfe3f0619f7e81..16b6380156153a020d6296978e3604e9188ec743 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -35,16 +35,6 @@ namespace dht { -time_point from_time_t(std::time_t t) { - return clock::now() + (std::chrono::system_clock::from_time_t(t) - std::chrono::system_clock::now()); -} - -std::time_t to_time_t(time_point t) { - return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + - (t - clock::now())); -} - - std::ostream& operator<< (std::ostream& s, const Value& v) { s << "Value[id:" << std::hex << v.id << std::dec << " "; @@ -169,23 +159,4 @@ Value::msgpack_unpack_body(const msgpack::object& o) } } -Blob -unpackBlob(msgpack::object& o) { - switch (o.type) { - case msgpack::type::BIN: - return {o.via.bin.ptr, o.via.bin.ptr+o.via.bin.size}; - case msgpack::type::STR: - return {o.via.str.ptr, o.via.str.ptr+o.via.str.size}; - case msgpack::type::ARRAY: { - Blob ret(o.via.array.size); - std::transform(o.via.array.ptr, o.via.array.ptr+o.via.array.size, ret.begin(), [](const msgpack::object& b) { - return b.as<uint8_t>(); - }); - return ret; - } - default: - throw msgpack::type_error(); - } -} - }