77static constexpr const size_t MAX_VALUE_SIZE {1024 * 64};
83 static bool DEFAULT_EDIT_POLICY(
InfoHash,
const std::shared_ptr<Value>&, std::shared_ptr<Value>&,
const InfoHash&,
const SockAddr&) {
89 ValueType (Id
id, std::string name, duration e = std::chrono::minutes(10))
90 : id(
id), name(name), expiration(e) {}
93 : id(
id), name(name), expiration(e), storePolicy(sp), editPolicy(ep) {}
107 duration expiration {60 * 10};
114 void registerType(
const ValueType& type) {
115 types[type.id] = type;
117 const ValueType& getType(ValueType::Id type_id)
const {
118 const auto& t_it = types.find(type_id);
119 return (t_it == types.end()) ? ValueType::USER_DATA : t_it->second;
122 std::map<ValueType::Id, ValueType> types {};
136 enum class Field :
int {
148 static const constexpr Id INVALID_ID {0};
150 class Filter :
public std::function<bool(const Value&)> {
154 template<
typename Functor>
155 Filter(Functor f) : std::function<bool(
const Value&)>::function(f) {}
159 return chain(std::move(f1), std::move(f2));
163 return chainOr(std::move(f1), std::move(f2));
166 if (not f1)
return f2;
167 if (not f2)
return f1;
168 return [f1,f2](
const Value& v) {
169 return f1(v) and f2(v);
172 static Filter chainAll(std::vector<Filter>&& set) {
173 if (set.empty())
return {};
174 return std::bind([](
const Value& v, std::vector<Filter>& s) {
175 for (
const auto& f : s)
179 }, std::placeholders::_1, std::move(set));
181 static Filter chain(std::initializer_list<Filter> l) {
182 return chainAll(std::vector<Filter>(l.begin(), l.end()));
185 if (not f1 or not f2)
return AllFilter();
186 return [f1,f2](
const Value& v) {
187 return f1(v) or f2(v);
190 std::vector<Sp<Value>> filter(
const std::vector<Sp<Value>>& values) {
193 std::vector<Sp<Value>> ret;
194 for (
const auto& v : values)
203 static const Filter AllFilter() {
207 static Filter TypeFilter(
const ValueType& t) {
208 const auto tid = t.id;
209 return [tid](
const Value& v) {
210 return v.type == tid;
213 static Filter TypeFilter(
const ValueType::Id& tid) {
214 return [tid](
const Value& v) {
215 return v.type == tid;
219 static Filter IdFilter(
const Id
id) {
220 return [id](
const Value& v) {
225 static Filter RecipientFilter(
const InfoHash& r) {
226 return [r](
const Value& v) {
227 return v.recipient == r;
231 static Filter OwnerFilter(
const crypto::PublicKey& pk) {
232 return OwnerFilter(pk.getId());
235 static Filter OwnerFilter(
const InfoHash& pkh) {
236 return [pkh](
const Value& v) {
237 return v.owner and v.owner->getId() == pkh;
241 static Filter SeqNumFilter(uint16_t seq_no) {
242 return [seq_no](
const Value& v) {
243 return v.seq == seq_no;
247 static Filter UserTypeFilter(
const std::string& ut) {
248 return [ut](
const Value& v) {
249 return v.user_type == ut;
258 virtual const ValueType& getType()
const = 0;
259 virtual void unpackValue(
const Value& v) = 0;
260 virtual Value packValue()
const = 0;
263 template <
typename Derived,
typename Base=SerializableBase>
269 virtual const ValueType& getType()
const {
270 return Derived::TYPE;
273 virtual void unpackValue(
const Value& v) {
274 auto msg = msgpack::unpack((
const char*)v.data.data(), v.data.size());
275 msg.get().convert(*
static_cast<Derived*
>(
this));
278 virtual Value packValue()
const {
279 return Value {getType(),
static_cast<const Derived&
>(*this)};
283 template <
typename T,
284 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
285 static Value pack(
const T& obj)
287 return obj.packValue();
290 template <
typename T,
291 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
292 static Value pack(
const T& obj)
294 return {ValueType::USER_DATA.id, packMsg<T>(obj)};
297 template <
typename T,
298 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
299 static T unpack(
const Value& v)
306 template <
typename T,
307 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
308 static T unpack(
const Value& v)
310 return unpackMsg<T>(v.data);
313 template <
typename T>
316 return unpack<T>(*
this);
319 bool isEncrypted()
const {
320 return not cypher.empty();
322 bool isSigned()
const {
323 return owner and not signature.empty();
334 owner = std::make_shared<const crypto::PublicKey>(key.getPublicKey());
335 signature = key.
sign(getToSign());
343 return isSigned() and owner->checkSignature(getToSign(), signature);
346 std::shared_ptr<const crypto::PublicKey> getOwner()
const {
347 return std::static_pointer_cast<const crypto::PublicKey>(owner);
356 setRecipient(to.getId());
359 nv.setCypher(to.encrypt(getToEncrypt()));
365 Value (Id
id) : id(id) {}
368 Value(ValueType::Id t,
const Blob& data, Id
id = INVALID_ID)
369 : id(id), type(t), data(data) {}
370 Value(ValueType::Id t,
Blob&& data, Id
id = INVALID_ID)
371 : id(id), type(t), data(std::move(data)) {}
372 Value(ValueType::Id t,
const uint8_t* dat_ptr,
size_t dat_len, Id
id = INVALID_ID)
373 : id(id), type(t), data(dat_ptr, dat_ptr+dat_len) {}
375#ifdef OPENDHT_JSONCPP
380 Value(Json::Value& json);
383 template <
typename Type>
384 Value(ValueType::Id t,
const Type& d, Id
id = INVALID_ID)
385 : id(id), type(t), data(packMsg(d)) {}
387 template <
typename Type>
388 Value(
const ValueType& t,
const Type& d, Id
id = INVALID_ID)
389 : id(id), type(t.id), data(packMsg(d)) {}
393 Value(
Blob&& userdata) : data(std::move(userdata)) {}
394 Value(
const uint8_t* dat_ptr,
size_t dat_len) : data(dat_ptr, dat_ptr+dat_len) {}
396 Value(Value&& o) noexcept
397 : id(o.id), owner(std::move(o.owner)), recipient(o.recipient),
398 type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq), signature(std::move(o.signature)), cypher(std::move(o.cypher)) {}
400 template <
typename Type>
401 Value(
const Type& vs)
402 : Value(pack<Type>(vs)) {}
411 inline bool operator== (
const Value& o) {
413 (isEncrypted() ? cypher == o.
cypher :
417 void setRecipient(
const InfoHash& r) {
421 void setCypher(
Blob&& c) {
422 cypher = std::move(c);
429 msgpack::sbuffer buffer;
430 msgpack::packer<msgpack::sbuffer> pk(&buffer);
431 msgpack_pack_to_sign(pk);
432 return {buffer.data(), buffer.data()+buffer.size()};
439 msgpack::sbuffer buffer;
440 msgpack::packer<msgpack::sbuffer> pk(&buffer);
441 msgpack_pack_to_encrypt(pk);
442 return {buffer.data(), buffer.data()+buffer.size()};
446 OPENDHT_PUBLIC
friend std::ostream& operator<< (std::ostream& s,
const Value& v);
448 std::string toString()
const {
449 std::stringstream ss;
454#ifdef OPENDHT_JSONCPP
463 Json::Value toJson()
const;
469 template <
typename Packer>
470 void msgpack_pack_to_sign(Packer& pk)
const
472 bool has_owner = owner && *owner;
473 pk.pack_map((user_type.empty()?0:1) + (has_owner?(recipient ? 5 : 4):2));
475 pk.pack(std::string(
"seq")); pk.pack(seq);
476 pk.pack(std::string(
"owner")); owner->msgpack_pack(pk);
478 pk.pack(std::string(
"to")); pk.pack(recipient);
481 pk.pack(std::string(
"type")); pk.pack(type);
482 pk.pack(std::string(
"data")); pk.pack_bin(data.size());
483 pk.pack_bin_body((
const char*)data.data(), data.size());
484 if (not user_type.empty()) {
485 pk.pack(std::string(
"utype")); pk.pack(user_type);
489 template <
typename Packer>
490 void msgpack_pack_to_encrypt(Packer& pk)
const
493 pk.pack_bin(cypher.size());
494 pk.pack_bin_body((
const char*)cypher.data(), cypher.size());
496 pk.pack_map(isSigned() ? 2 : 1);
497 pk.pack(std::string(
"body")); msgpack_pack_to_sign(pk);
499 pk.pack(std::string(
"sig")); pk.pack_bin(signature.size());
500 pk.pack_bin_body((
const char*)signature.data(), signature.size());
505 template <
typename Packer>
506 void msgpack_pack(Packer& pk)
const
509 pk.pack(std::string(
"id")); pk.pack(
id);
510 pk.pack(std::string(
"dat")); msgpack_pack_to_encrypt(pk);
513 template <
typename Packer>
514 void msgpack_pack_fields(
const std::set<Value::Field>& fields, Packer& pk)
const
516 for (
const auto& field : fields)
518 case Value::Field::Id:
519 pk.pack(
static_cast<uint64_t
>(
id));
521 case Value::Field::ValueType:
522 pk.pack(
static_cast<uint64_t
>(type));
524 case Value::Field::OwnerPk:
526 owner->msgpack_pack(pk);
528 InfoHash().msgpack_pack(pk);
530 case Value::Field::SeqNum:
531 pk.pack(
static_cast<uint64_t
>(seq));
533 case Value::Field::UserType:
541 void msgpack_unpack(msgpack::object o);
542 void msgpack_unpack_body(
const msgpack::object& o);
543 Blob getPacked()
const {
544 msgpack::sbuffer buffer;
545 msgpack::packer<msgpack::sbuffer> pk(&buffer);
547 return {buffer.data(), buffer.data()+buffer.size()};
550 void msgpack_unpack_fields(
const std::set<Value::Field>& fields,
const msgpack::object& o,
unsigned offset);
557 std::shared_ptr<const crypto::PublicKey> owner {};
569 ValueType::Id type {ValueType::USER_DATA.id};
575 std::string user_type {};
593using ValuesExport = std::pair<InfoHash, Blob>;
605 FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
607 FieldValue(Value::Field f,
Blob blob_value) : field(f), blobValue(blob_value) {}
612 Value::Field getField()
const {
return field; }
613 uint64_t getInt()
const {
return intValue; }
614 InfoHash getHash()
const {
return hashValue; }
615 Blob getBlob()
const {
return blobValue; }
617 template <
typename Packer>
618 void msgpack_pack(Packer& p)
const {
620 p.pack(std::string(
"f")); p.pack(
static_cast<uint8_t
>(field));
622 p.pack(std::string(
"v"));
624 case Value::Field::Id:
625 case Value::Field::ValueType:
628 case Value::Field::OwnerPk:
631 case Value::Field::UserType:
632 p.pack_bin(blobValue.size());
633 p.pack_bin_body((
const char*)blobValue.data(), blobValue.size());
636 throw msgpack::type_error();
640 void msgpack_unpack(msgpack::object msg) {
644 if (
auto f = findMapValue(msg,
"f"))
645 field = (Value::Field)f->as<
unsigned>();
647 throw msgpack::type_error();
649 auto v = findMapValue(msg,
"v");
651 throw msgpack::type_error();
654 case Value::Field::Id:
655 case Value::Field::ValueType:
656 intValue = v->as<
decltype(intValue)>();
658 case Value::Field::OwnerPk:
659 hashValue = v->as<
decltype(hashValue)>();
661 case Value::Field::UserType:
665 throw msgpack::type_error();
672 Value::Field field {Value::Field::None};
674 uint64_t intValue {};
689 Select(
const std::string& q_str);
691 bool isSatisfiedBy(
const Select& os)
const;
701 if (std::find(fieldSelection_.begin(), fieldSelection_.end(), field) == fieldSelection_.end())
702 fieldSelection_.emplace_back(field);
712 return {fieldSelection_.begin(), fieldSelection_.end()};
715 template <
typename Packer>
716 void msgpack_pack(Packer& pk)
const { pk.pack(fieldSelection_); }
717 void msgpack_unpack(
const msgpack::object& o) {
718 fieldSelection_ = o.as<
decltype(fieldSelection_)>();
721 std::string toString()
const {
722 std::stringstream ss;
727 OPENDHT_PUBLIC
friend std::ostream& operator<<(std::ostream& s,
const dht::Select& q);
729 std::vector<Value::Field> fieldSelection_ {};
742 Where(
const std::string& q_str);
744 bool isSatisfiedBy(
const Where& where)
const;
755 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
756 filters_.emplace_back(std::move(fv));
768 FieldValue fv {Value::Field::ValueType, type};
769 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
770 filters_.emplace_back(std::move(fv));
782 FieldValue fv {Value::Field::OwnerPk, owner_pk_hash};
783 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
784 filters_.emplace_back(std::move(fv));
797 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
798 filters_.emplace_back(std::move(fv));
810 FieldValue fv {Value::Field::UserType,
Blob {user_type.begin(), user_type.end()}};
811 if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
812 filters_.emplace_back(std::move(fv));
822 if (filters_.empty())
return {};
823 std::vector<Value::Filter> fset;
824 fset.reserve(filters_.size());
825 for (
const auto& f : filters_) {
826 if (
auto lf = f.getLocalFilter())
827 fset.emplace_back(std::move(lf));
829 return Value::Filter::chainAll(std::move(fset));
832 template <
typename Packer>
833 void msgpack_pack(Packer& pk)
const { pk.pack(filters_); }
834 void msgpack_unpack(
const msgpack::object& o) {
836 filters_ = o.as<
decltype(filters_)>();
839 std::string toString()
const {
840 std::stringstream ss;
846 return filters_.empty();
849 OPENDHT_PUBLIC
friend std::ostream& operator<<(std::ostream& s,
const dht::Where& q);
852 std::vector<FieldValue> filters_;
865 static const std::string QUERY_PARSE_ERROR;
867 Query(
Select s = {},
Where w = {},
bool none =
false) : select(s), where(w), none(none) { };
883 auto pos_W = q_str.find(
"WHERE");
884 auto pos_w = q_str.find(
"where");
885 auto pos = std::min(pos_W != std::string::npos ? pos_W : q_str.size(),
886 pos_w != std::string::npos ? pos_w : q_str.size());
887 select = q_str.substr(0, pos);
888 where = q_str.substr(pos, q_str.size()-pos);
896 template <
typename Packer>
897 void msgpack_pack(Packer& pk)
const {
899 pk.pack(std::string(
"s")); pk.pack(select);
900 pk.pack(std::string(
"w")); pk.pack(where);
903 void msgpack_unpack(
const msgpack::object& o);
905 std::string toString()
const {
906 std::stringstream ss;
911 OPENDHT_PUBLIC
friend std::ostream& operator<<(std::ostream& s,
const dht::Query& q) {
912 return s <<
"Query[" << q.select <<
" " << q.where <<
"]";
938 OPENDHT_PUBLIC
friend std::ostream& operator<<(std::ostream& os,
const FieldValueIndex& fvi);
940 void msgpack_unpack_fields(
const std::set<Value::Field>& fields,
941 const msgpack::object& o,
944 std::map<Value::Field, FieldValue> index {};
948 typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
950getFilterSet(Value::Filter f)
952 return Value::Filter::chain({
953 Value::TypeFilter(T::TYPE),
960 typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
962getFilterSet(Value::Filter f)
968 typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
972 return Value::Filter::chain({
973 Value::TypeFilter(T::TYPE),
979 typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* =
nullptr>
983 return Value::AllFilter();
988unpackVector(
const std::vector<std::shared_ptr<Value>>& vals) {
990 ret.reserve(vals.size());
991 for (
const auto& v : vals) {
993 ret.emplace_back(Value::unpack<T>(*v));
994 }
catch (
const std::exception&) {}
999#ifdef OPENDHT_JSONCPP
1000uint64_t unpackId(
const Json::Value& json,
const std::string& key);
1005MSGPACK_ADD_ENUM(dht::Value::Field)
OPENDHT_PUBLIC Blob unpackBlob(msgpack::object &o)
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
std::vector< uint8_t > Blob
std::function< bool(InfoHash key, std::shared_ptr< Value > &value, const InfoHash &from, const SockAddr &addr)> StorePolicy
An index for field values.
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 checkSignature() const
std::shared_ptr< const crypto::PublicKey > owner
Value(const msgpack::object &o)
Value(ValueType::Id t, const Blob &data, Id id=INVALID_ID)
Value encrypt(const crypto::PrivateKey &from, const crypto::PublicKey &to)
Blob getToEncrypt() const
Value(const Blob &userdata)
void sign(const crypto::PrivateKey &key)
Serializable dht::Value filter.
Value::Filter getFilter() const
Where & seq(uint16_t seq_no)
Where & valueType(ValueType::Id type)
Where & userType(std::string user_type)
Where & owner(InfoHash owner_pk_hash)
Blob sign(const Blob &) const