29using namespace std::literals;
31static constexpr auto VALUE_KEY_ID(
"id");
32static const std::string VALUE_KEY_DAT(
"dat");
33static const std::string VALUE_KEY_PRIO(
"p");
34static const std::string VALUE_KEY_SIGNATURE(
"sig");
36static const std::string VALUE_KEY_SEQ(
"seq");
37static const std::string VALUE_KEY_DATA(
"data");
38static const std::string VALUE_KEY_OWNER(
"owner");
39static const std::string VALUE_KEY_TYPE(
"type");
40static const std::string VALUE_KEY_TO(
"to");
41static const std::string VALUE_KEY_BODY(
"body");
42static const std::string VALUE_KEY_USERTYPE(
"utype");
58 = std::function<bool(InfoHash key, std::shared_ptr<Value>& value,
const InfoHash& from,
const SockAddr& addr)>;
74using EditPolicy = std::function<bool(InfoHash key,
75 const std::shared_ptr<Value>& old_val,
76 std::shared_ptr<Value>& new_val,
80static constexpr const size_t MAX_VALUE_SIZE {1024 * 64};
81static constexpr const duration DEFAULT_VALUE_EXPIRATION {std::chrono::minutes(10)};
87 OPENDHT_PUBLIC
static bool DEFAULT_STORE_POLICY(InfoHash,
88 const std::shared_ptr<Value>& v,
91 static inline bool DEFAULT_EDIT_POLICY(
92 InfoHash,
const std::shared_ptr<Value>&, std::shared_ptr<Value>&,
const InfoHash&,
const SockAddr&)
99 ValueType(Id
id, std::string name, duration e = DEFAULT_VALUE_EXPIRATION)
113 virtual ~ValueType() {}
115 bool operator==(
const ValueType& o) {
return id == o.id; }
118 OPENDHT_PUBLIC
static const ValueType USER_DATA;
122 duration expiration {DEFAULT_VALUE_EXPIRATION};
130 void registerType(
const ValueType& type) { types[type.id] = type; }
131 const ValueType& getType(ValueType::Id type_id)
const
133 const auto& t_it = types.find(type_id);
134 return (t_it == types.end()) ? ValueType::USER_DATA : t_it->second;
138 std::map<ValueType::Id, ValueType> types {};
150struct OPENDHT_PUBLIC Value
152 enum class Field :
int {
164 static const constexpr Id INVALID_ID {0};
166 class Filter :
public std::function<bool(const Value&)>
171 template<
typename Functor>
173 : std::function<bool(
const Value&)>::function(f)
176 inline Filter chain(Filter&& f2)
179 return chain(std::move(f1), std::move(f2));
181 inline Filter chainOr(Filter&& f2)
184 return chainOr(std::move(f1), std::move(f2));
186 static inline Filter chain(Filter&& f1, Filter&& f2)
189 return std::move(f2);
191 return std::move(f1);
192 return [f1 = std::move(f1), f2 = std::move(f2)](
const Value& v) {
193 return f1(v) and f2(v);
196 static inline Filter chain(
const Filter& f1,
const Filter& f2)
202 return [f1, f2](
const Value& v) {
203 return f1(v) and f2(v);
206 static inline Filter chainAll(std::vector<Filter>&& set)
210 return [set = std::move(set)](
const Value& v) {
211 for (
const auto& f : set)
217 static inline Filter chain(std::initializer_list<Filter> l)
219 return chainAll(std::vector<Filter>(l.begin(), l.end()));
221 static inline Filter chainOr(Filter&& f1, Filter&& f2)
223 if (not f1 or not f2)
225 return [f1 = std::move(f1), f2 = std::move(f2)](
const Value& v) {
226 return f1(v) or f2(v);
229 static inline Filter notFilter(Filter&& f)
232 return [](
const Value&) {
235 return [f = std::move(f)](
const Value& v) {
239 std::vector<Sp<Value>> filter(
const std::vector<Sp<Value>>& values)
243 std::vector<Sp<Value>> ret;
244 for (
const auto& v : values)
253 static inline Filter AllFilter() {
return {}; }
255 static inline Filter TypeFilter(
const ValueType& t)
257 return [tid = t.id](
const Value& v) {
258 return v.type == tid;
261 static inline Filter TypeFilter(
const ValueType::Id& tid)
263 return [tid](
const Value& v) {
264 return v.type == tid;
268 static inline Filter IdFilter(
const Id
id)
270 return [id](
const Value& v) {
275 static inline Filter RecipientFilter(
const InfoHash& r)
277 return [r](
const Value& v) {
278 return v.recipient == r;
282 static inline Filter OwnerFilter(
const crypto::PublicKey& pk) {
return OwnerFilter(pk.getId()); }
284 static inline Filter OwnerFilter(
const InfoHash& pkh)
286 return [pkh](
const Value& v) {
287 return v.owner and v.owner->getId() == pkh;
291 static inline Filter SeqNumFilter(uint16_t seq_no)
293 return [seq_no](
const Value& v) {
294 return v.seq == seq_no;
298 static inline Filter UserTypeFilter(std::string ut)
300 return [ut = std::move(ut)](
const Value& v) {
301 return v.user_type == ut;
305 class SerializableBase
308 SerializableBase() {}
309 virtual ~SerializableBase() {};
310 virtual const ValueType& getType()
const = 0;
311 virtual void unpackValue(
const Value& v) = 0;
312 virtual Value packValue()
const = 0;
315 template<
typename Derived,
typename Base = SerializableBase>
321 virtual const ValueType& getType()
const {
return Derived::TYPE; }
323 virtual void unpackValue(
const Value& v)
325 auto msg = msgpack::unpack((
const char*) v.data.data(), v.data.size());
326 msg.get().convert(*
static_cast<Derived*
>(
this));
329 virtual Value packValue()
const {
return Value {getType(),
static_cast<const Derived&
>(*this)}; }
332 template<typename T, typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>
::type* =
nullptr>
333 static Value pack(
const T& obj)
335 return obj.packValue();
338 template<typename T, typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
339 static Value pack(
const T& obj)
341 return {ValueType::USER_DATA.id, packMsg<T>(obj)};
344 template<typename T, typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
345 static T unpack(
const Value& v)
352 template<typename T, typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
353 static T unpack(
const Value& v)
355 return unpackMsg<T>(v.data);
361 return unpack<T>(*
this);
364 inline bool isEncrypted()
const {
return not cypher.empty(); }
365 inline bool isSigned()
const {
return owner and not signature.empty(); }
380 inline std::shared_ptr<crypto::PublicKey> getOwner()
const {
return owner; }
394 Value(ValueType::Id t,
const Blob& data, Id
id = INVALID_ID)
399 Value(ValueType::Id t,
Blob&& data, Id
id = INVALID_ID)
402 , data(std::move(data))
404 Value(ValueType::Id t,
const uint8_t* dat_ptr,
size_t dat_len, Id
id = INVALID_ID)
407 , data(dat_ptr, dat_ptr + dat_len)
410#ifdef OPENDHT_JSONCPP
415 Value(
const Json::Value& json);
418 template<
typename Type>
419 Value(ValueType::Id t,
const Type& d, Id
id = INVALID_ID)
425 template<
typename Type>
426 Value(
const ValueType& t,
const Type& d, Id
id = INVALID_ID)
433 Value(
const Blob& userdata)
437 : data(std::move(userdata))
439 Value(
const uint8_t* dat_ptr,
size_t dat_len)
440 : data(dat_ptr, dat_ptr + dat_len)
443 Value(Value&& o) noexcept
445 , owner(std::move(o.owner))
446 , recipient(o.recipient)
448 , data(std::move(o.data))
449 , user_type(std::move(o.user_type))
451 , signature(std::move(o.signature))
452 , cypher(std::move(o.cypher))
453 , priority(o.priority)
456 template<
typename Type>
457 Value(
const Type& vs)
458 : Value(pack<Type>(vs))
464 Value(
const msgpack::object& o) { msgpack_unpack(o); }
476 inline bool operator==(
const Value& o)
const {
return id == o.id and contentEquals(o); }
477 inline bool operator!=(
const Value& o)
const {
return !(*
this == o); }
479 inline void setRecipient(
const InfoHash& r) { recipient = r; }
481 inline void setCypher(Blob&& c) { cypher = std::move(c); }
488 msgpack::sbuffer buffer;
489 msgpack::packer<msgpack::sbuffer> pk(&buffer);
490 msgpack_pack_to_sign(pk);
491 return {buffer.data(), buffer.data() + buffer.size()};
499 msgpack::sbuffer buffer;
500 msgpack::packer<msgpack::sbuffer> pk(&buffer);
501 msgpack_pack_to_encrypt(pk);
502 return {buffer.data(), buffer.data() + buffer.size()};
506 OPENDHT_PUBLIC
friend std::ostream&
operator<<(std::ostream& s,
const Value& v);
508 inline std::string toString()
const
510 std::ostringstream ss;
515#ifdef OPENDHT_JSONCPP
524 Json::Value toJson()
const;
530 template<
typename Packer>
531 void msgpack_pack_to_sign(Packer& pk)
const
536 pk.pack(VALUE_KEY_SEQ);
538 pk.pack(VALUE_KEY_OWNER);
539 owner->msgpack_pack(pk);
541 pk.pack(VALUE_KEY_TO);
545 pk.pack(VALUE_KEY_TYPE);
547 pk.pack(VALUE_KEY_DATA);
548 pk.pack_bin(data.size());
549 pk.pack_bin_body((
const char*) data.data(), data.size());
550 if (not user_type.empty()) {
551 pk.pack(VALUE_KEY_USERTYPE);
556 template<
typename Packer>
557 void msgpack_pack_to_encrypt(Packer& pk)
const
560 pk.pack_bin(cypher.size());
561 pk.pack_bin_body((
const char*) cypher.data(), cypher.size());
563 pk.pack_map(isSigned() ? 2 : 1);
564 pk.pack(VALUE_KEY_BODY);
565 msgpack_pack_to_sign(pk);
567 pk.pack(VALUE_KEY_SIGNATURE);
568 pk.pack_bin(signature.size());
569 pk.pack_bin_body((
const char*) signature.data(), signature.size());
574 template<
typename Packer>
575 void msgpack_pack(Packer& pk)
const
577 pk.pack_map(2 + (priority ? 1 : 0));
578 pk.pack(VALUE_KEY_ID);
580 pk.pack(VALUE_KEY_DAT);
581 msgpack_pack_to_encrypt(pk);
583 pk.pack(VALUE_KEY_PRIO);
588 template<
typename Packer>
589 void msgpack_pack_fields(
const std::set<Value::Field>& fields, Packer& pk)
const
591 for (
const auto& field : fields)
593 case Value::Field::Id:
594 pk.pack(
static_cast<uint64_t
>(
id));
596 case Value::Field::ValueType:
597 pk.pack(
static_cast<uint64_t
>(type));
599 case Value::Field::OwnerPk:
601 owner->msgpack_pack(pk);
603 InfoHash().msgpack_pack(pk);
605 case Value::Field::SeqNum:
606 pk.pack(
static_cast<uint64_t
>(seq));
608 case Value::Field::UserType:
616 void msgpack_unpack(
const msgpack::object& o);
617 void msgpack_unpack_body(
const msgpack::object& o);
618 Blob getPacked()
const
620 msgpack::sbuffer buffer;
621 msgpack::packer<msgpack::sbuffer> pk(&buffer);
623 return {buffer.data(), buffer.data() + buffer.size()};
626 void msgpack_unpack_fields(
const std::set<Value::Field>& fields,
const msgpack::object& o,
unsigned offset);
633 std::shared_ptr<crypto::PublicKey>
owner {};
645 ValueType::Id
type {ValueType::USER_DATA.id};
675 inline bool isSignatureChecked()
const {
return signatureChecked; }
676 inline bool isDecrypted()
const {
return decrypted; }
677 bool checkSignature();
678 Sp<Value> decrypt(
const crypto::PrivateKey& key);
682 bool signatureChecked {
false};
683 bool signatureValid {
false};
684 bool decrypted {
false};
685 Sp<Value> decryptedValue {};
688using ValuesExport = std::pair<InfoHash, Blob>;
697struct OPENDHT_PUBLIC FieldValue
700 FieldValue(Value::Field f, uint64_t int_value)
702 , intValue(int_value)
704 FieldValue(Value::Field f, InfoHash hash_value)
706 , hashValue(hash_value)
708 FieldValue(Value::Field f,
Blob blob_value)
710 , blobValue(std::move(blob_value))
713 bool operator==(
const FieldValue& fd)
const;
716 Value::Field getField()
const {
return field; }
717 uint64_t getInt()
const {
return intValue; }
718 InfoHash getHash()
const {
return hashValue; }
719 Blob getBlob()
const {
return blobValue; }
721 template<
typename Packer>
722 void msgpack_pack(Packer& p)
const
726 p.pack(
static_cast<uint8_t
>(field));
730 case Value::Field::Id:
731 case Value::Field::ValueType:
734 case Value::Field::OwnerPk:
737 case Value::Field::UserType:
738 p.pack_bin(blobValue.size());
739 p.pack_bin_body((
const char*) blobValue.data(), blobValue.size());
742 throw msgpack::type_error();
746 void msgpack_unpack(
const msgpack::object& msg)
751 if (
auto f = findMapValue(msg,
"f"sv))
752 field = (Value::Field) f->as<
unsigned>();
754 throw msgpack::type_error();
756 auto v = findMapValue(msg,
"v"sv);
758 throw msgpack::type_error();
761 case Value::Field::Id:
762 case Value::Field::ValueType:
763 intValue = v->as<
decltype(intValue)>();
765 case Value::Field::OwnerPk:
766 hashValue = v->as<
decltype(hashValue)>();
768 case Value::Field::UserType:
772 throw msgpack::type_error();
779 Value::Field field {Value::Field::None};
781 uint64_t intValue {};
782 InfoHash hashValue {};
793struct OPENDHT_PUBLIC Select
796 Select(std::string_view q_str);
798 bool isSatisfiedBy(
const Select& os)
const;
809 if (std::find(fieldSelection_.begin(), fieldSelection_.end(),
field) == fieldSelection_.end())
810 fieldSelection_.emplace_back(
field);
819 std::set<Value::Field>
getSelection()
const {
return {fieldSelection_.begin(), fieldSelection_.end()}; }
821 template<
typename Packer>
822 void msgpack_pack(Packer& pk)
const
824 pk.pack(fieldSelection_);
826 void msgpack_unpack(
const msgpack::object& o) { fieldSelection_ = o.as<
decltype(fieldSelection_)>(); }
828 std::string toString()
const
830 std::ostringstream ss;
835 bool empty()
const {
return fieldSelection_.empty(); }
837 OPENDHT_PUBLIC
friend std::ostream& operator<<(std::ostream& s,
const dht::Select& q);
840 std::vector<Value::Field> fieldSelection_ {};
850struct OPENDHT_PUBLIC Where
853 Where(std::string_view q_str);
855 bool isSatisfiedBy(
const Where& where)
const;
864 Where&&
id(Value::Id
id)
867 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
868 filters_.emplace_back(std::move(fv));
869 return std::move(*
this);
881 FieldValue fv {Value::Field::ValueType, type};
882 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
883 filters_.emplace_back(std::move(fv));
884 return std::move(*
this);
894 Where&&
owner(InfoHash owner_pk_hash)
896 FieldValue fv {Value::Field::OwnerPk, owner_pk_hash};
897 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
898 filters_.emplace_back(std::move(fv));
899 return std::move(*
this);
909 Where&&
seq(uint16_t seq_no)
912 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
913 filters_.emplace_back(std::move(fv));
914 return std::move(*
this);
924 Where&&
userType(std::string_view user_type)
927 Value::Field::UserType,
Blob {user_type.begin(), user_type.end()}
929 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
930 filters_.emplace_back(std::move(fv));
931 return std::move(*
this);
941 if (filters_.empty())
943 if (filters_.size() == 1)
944 return filters_[0].getLocalFilter();
945 std::vector<Value::Filter> fset;
946 fset.reserve(filters_.size());
947 for (
const auto& f : filters_) {
948 if (
auto lf = f.getLocalFilter())
949 fset.emplace_back(std::move(lf));
951 return Value::Filter::chainAll(std::move(fset));
954 template<
typename Packer>
955 void msgpack_pack(Packer& pk)
const
959 void msgpack_unpack(
const msgpack::object& o)
962 filters_ = o.as<
decltype(filters_)>();
965 std::string toString()
const
967 std::ostringstream ss;
972 bool empty()
const {
return filters_.empty(); }
974 OPENDHT_PUBLIC
friend std::ostream& operator<<(std::ostream& s,
const dht::Where& q);
977 std::vector<FieldValue> filters_;
988struct OPENDHT_PUBLIC Query
990 static const std::string QUERY_PARSE_ERROR;
992 Query(
Select s = {},
Where w = {},
bool none =
false)
993 : select(std::move(s))
994 , where(std::move(w))
1010 Query(std::string_view q_str)
1012 auto pos_W = q_str.find(
"WHERE");
1013 auto pos_w = q_str.find(
"where");
1014 auto pos = std::min(pos_W != std::string_view::npos ? pos_W : q_str.size(),
1015 pos_w != std::string_view::npos ? pos_w : q_str.size());
1016 select = q_str.substr(0, pos);
1017 where = q_str.substr(pos, q_str.size() - pos);
1025 template<
typename Packer>
1026 void msgpack_pack(Packer& pk)
const
1035 void msgpack_unpack(
const msgpack::object& o);
1037 std::string toString()
const
1039 std::ostringstream ss;
1044 friend std::ostream& operator<<(std::ostream& s,
const dht::Query& q)
1046 return s <<
"Query[" << q.select <<
" " << q.where <<
"]";
1061struct OPENDHT_PUBLIC FieldValueIndex
1063 FieldValueIndex() {}
1064 FieldValueIndex(
const Value& v,
const Select& s = {});
1071 bool containedIn(
const FieldValueIndex& other)
const;
1073 OPENDHT_PUBLIC
friend std::ostream& operator<<(std::ostream& os,
const FieldValueIndex& fvi);
1075 void msgpack_unpack_fields(
const std::set<Value::Field>& fields,
const msgpack::object& o,
unsigned offset);
1077 std::map<Value::Field, FieldValue> index {};
1080template<typename T, typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
1082getFilterSet(Value::Filter f)
1084 return Value::Filter::chain({Value::TypeFilter(T::TYPE), T::getFilter(), std::move(f)});
1087template<typename T, typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
1094template<typename T, typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
1098 return Value::Filter::chain({Value::TypeFilter(T::TYPE), T::getFilter()});
1101template<typename T, typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
1110unpackVector(
const std::vector<std::shared_ptr<Value>>& vals)
1113 ret.reserve(vals.size());
1114 for (
const auto& v : vals) {
1116 ret.emplace_back(Value::unpack<T>(*v));
1117 }
catch (
const std::exception&) {
1123#ifdef OPENDHT_JSONCPP
1124uint64_t unpackId(
const Json::Value& json,
const std::string& key);
1129MSGPACK_ADD_ENUM(dht::Value::Field)
std::function< bool(InfoHash key, std::shared_ptr< Value > &value, const InfoHash &from, const SockAddr &addr)> StorePolicy
std::function< bool(InfoHash key, const std::shared_ptr< Value > &old_val, std::shared_ptr< Value > &new_val, const InfoHash &from, const SockAddr &addr)> EditPolicy
OPENDHT_PUBLIC Blob unpackBlob(const msgpack::object &o)
std::vector< uint8_t > Blob
bool containedIn(const FieldValueIndex &other) const
Describes a value filter.
Describes a query destined to another peer.
bool isSatisfiedBy(const Query &q) const
Serializable Value field selection.
std::set< Value::Field > getSelection() const
Select & field(Value::Field field)
bool contentEquals(const Value &o) const
bool checkSignature() const
std::shared_ptr< crypto::PublicKey > owner
Value encrypt(const crypto::PrivateKey &from, const crypto::PublicKey &to)
OPENDHT_PUBLIC friend std::ostream & operator<<(std::ostream &s, const Value &v)
Blob getToEncrypt() const
void sign(const crypto::PrivateKey &key)
Serializable dht::Value filter.
Value::Filter getFilter() const
Where && userType(std::string_view user_type)
Where && seq(uint16_t seq_no)
Where && id(Value::Id id)
Where && valueType(ValueType::Id type)
Where && owner(InfoHash owner_pk_hash)