98 static bool DEFAULT_EDIT_POLICY(
InfoHash,
const std::shared_ptr<Value>&, std::shared_ptr<Value>&,
const InfoHash&,
const SockAddr&) {
104 ValueType (Id
id, std::string name, duration e = std::chrono::minutes(10))
105 : id(
id), name(name), expiration(e) {}
108 : id(
id), name(name), expiration(e), storePolicy(sp), editPolicy(ep) {}
122 duration expiration {std::chrono::minutes(10)};
153 enum class Field :
int {
165 static const constexpr Id INVALID_ID {0};
167 class Filter :
public std::function<bool(const Value&)> {
171 template<
typename Functor>
172 Filter(Functor f) : std::function<bool(
const Value&)>::function(f) {}
176 return chain(std::move(f1), std::move(f2));
180 return chainOr(std::move(f1), std::move(f2));
183 if (not f1)
return std::move(f2);
184 if (not f2)
return std::move(f1);
185 return [f1 = std::move(f1), f2 = std::move(f2)](
const Value& v) {
186 return f1(v) and f2(v);
190 if (not f1)
return f2;
191 if (not f2)
return f1;
192 return [f1,f2](
const Value& v) {
193 return f1(v) and f2(v);
196 static inline Filter chainAll(std::vector<Filter>&& set) {
197 if (set.empty())
return {};
198 return [set = std::move(set)](
const Value& v) {
199 for (
const auto& f : set)
205 static inline Filter chain(std::initializer_list<Filter> l) {
206 return chainAll(std::vector<Filter>(l.begin(), l.end()));
209 if (not f1 or not f2)
return {};
210 return [f1=std::move(f1),f2=std::move(f2)](
const Value& v) {
211 return f1(v) or f2(v);
215 if (not f)
return [](
const Value&) {
return false; };
216 return [f = std::move(f)](
const Value& v) {
return not f(v); };
218 std::vector<Sp<Value>> filter(
const std::vector<Sp<Value>>& values) {
221 std::vector<Sp<Value>> ret;
222 for (
const auto& v : values)
231 static inline Filter AllFilter() {
235 static inline Filter TypeFilter(
const ValueType& t) {
236 return [tid = t.id](
const Value& v) {
237 return v.type == tid;
240 static inline Filter TypeFilter(
const ValueType::Id& tid) {
241 return [tid](
const Value& v) {
242 return v.type == tid;
246 static inline Filter IdFilter(
const Id
id) {
247 return [id](
const Value& v) {
252 static inline Filter RecipientFilter(
const InfoHash& r) {
253 return [r](
const Value& v) {
254 return v.recipient == r;
258 static inline Filter OwnerFilter(
const crypto::PublicKey& pk) {
259 return OwnerFilter(pk.getId());
262 static inline Filter OwnerFilter(
const InfoHash& pkh) {
263 return [pkh](
const Value& v) {
264 return v.owner and v.owner->getId() == pkh;
268 static inline Filter SeqNumFilter(uint16_t seq_no) {
269 return [seq_no](
const Value& v) {
270 return v.seq == seq_no;
274 static inline Filter UserTypeFilter(std::string ut) {
275 return [ut = std::move(ut)](
const Value& v) {
276 return v.user_type == ut;
285 virtual const ValueType& getType()
const = 0;
286 virtual void unpackValue(
const Value& v) = 0;
287 virtual Value packValue()
const = 0;
290 template <
typename Derived,
typename Base=SerializableBase>
296 virtual const ValueType& getType()
const {
297 return Derived::TYPE;
300 virtual void unpackValue(
const Value& v) {
301 auto msg = msgpack::unpack((
const char*)v.data.data(), v.data.size());
302 msg.get().convert(*
static_cast<Derived*
>(
this));
305 virtual Value packValue()
const {
306 return Value {getType(),
static_cast<const Derived&
>(*this)};
310 template <
typename T,
311 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
312 static Value pack(
const T& obj)
314 return obj.packValue();
317 template <
typename T,
318 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
319 static Value pack(
const T& obj)
321 return {ValueType::USER_DATA.id, packMsg<T>(obj)};
324 template <
typename T,
325 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
326 static T unpack(
const Value& v)
333 template <
typename T,
334 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
335 static T unpack(
const Value& v)
337 return unpackMsg<T>(v.data);
340 template <
typename T>
343 return unpack<T>(*
this);
346 inline bool isEncrypted()
const {
347 return not cypher.empty();
349 inline bool isSigned()
const {
350 return owner and not signature.empty();
365 return isSigned() and owner->checkSignature(getToSign(), signature);
368 inline std::shared_ptr<crypto::PublicKey> getOwner()
const {
379 Value (Id
id) : id(id) {}
382 Value(ValueType::Id t,
const Blob& data, Id
id = INVALID_ID)
383 : id(id), type(t), data(data) {}
384 Value(ValueType::Id t,
Blob&& data, Id
id = INVALID_ID)
385 : id(id), type(t), data(std::move(data)) {}
386 Value(ValueType::Id t,
const uint8_t* dat_ptr,
size_t dat_len, Id
id = INVALID_ID)
387 : id(id), type(t), data(dat_ptr, dat_ptr+dat_len) {}
389#ifdef OPENDHT_JSONCPP
394 Value(
const Json::Value& json);
397 template <
typename Type>
398 Value(ValueType::Id t,
const Type& d, Id
id = INVALID_ID)
399 : id(id), type(t), data(packMsg(d)) {}
401 template <
typename Type>
402 Value(
const ValueType& t,
const Type& d, Id
id = INVALID_ID)
403 : id(id), type(t.id), data(packMsg(d)) {}
407 Value(
Blob&& userdata) : data(std::move(userdata)) {}
408 Value(
const uint8_t* dat_ptr,
size_t dat_len) : data(dat_ptr, dat_ptr+dat_len) {}
410 Value(Value&& o) noexcept
411 : id(o.id), owner(std::move(o.owner)), recipient(o.recipient),
412 type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq)
413 , signature(std::move(o.signature)), cypher(std::move(o.cypher))
414 , priority(o.priority) {}
416 template <
typename Type>
417 Value(
const Type& vs)
418 : Value(pack<Type>(vs)) {}
431 return isEncrypted() ? cypher == o.cypher :
432 ((owner == o.owner || (owner and o.owner and *owner == *o.owner))
435 && user_type == o.user_type
436 && signature == o.signature);
439 inline bool operator== (
const Value& o)
const {
440 return id == o.id and contentEquals(o);
442 inline bool operator!= (
const Value& o)
const {
443 return !(*
this == o);
446 inline void setRecipient(
const InfoHash& r) {
450 inline void setCypher(Blob&& c) {
451 cypher = std::move(c);
458 msgpack::sbuffer buffer;
459 msgpack::packer<msgpack::sbuffer> pk(&buffer);
460 msgpack_pack_to_sign(pk);
461 return {buffer.data(), buffer.data()+buffer.size()};
468 msgpack::sbuffer buffer;
469 msgpack::packer<msgpack::sbuffer> pk(&buffer);
470 msgpack_pack_to_encrypt(pk);
471 return {buffer.data(), buffer.data()+buffer.size()};
475 OPENDHT_PUBLIC
friend std::ostream& operator<< (std::ostream& s,
const Value& v);
477 inline std::string toString()
const {
478 std::ostringstream ss;
483#ifdef OPENDHT_JSONCPP
492 Json::Value toJson()
const;
498 template <
typename Packer>
499 void msgpack_pack_to_sign(Packer& pk)
const
501 bool has_owner = owner && *owner;
502 pk.pack_map((user_type.empty()?0:1) + (has_owner?(recipient ? 5 : 4):2));
504 pk.pack(VALUE_KEY_SEQ); pk.pack(seq);
505 pk.pack(VALUE_KEY_OWNER); owner->msgpack_pack(pk);
507 pk.pack(VALUE_KEY_TO); pk.pack(recipient);
510 pk.pack(VALUE_KEY_TYPE); pk.pack(type);
511 pk.pack(VALUE_KEY_DATA); pk.pack_bin(data.size());
512 pk.pack_bin_body((
const char*)data.data(), data.size());
513 if (not user_type.empty()) {
514 pk.pack(VALUE_KEY_USERTYPE); pk.pack(user_type);
518 template <
typename Packer>
519 void msgpack_pack_to_encrypt(Packer& pk)
const
522 pk.pack_bin(cypher.size());
523 pk.pack_bin_body((
const char*)cypher.data(), cypher.size());
525 pk.pack_map(isSigned() ? 2 : 1);
526 pk.pack(VALUE_KEY_BODY); msgpack_pack_to_sign(pk);
528 pk.pack(VALUE_KEY_SIGNATURE); pk.pack_bin(signature.size());
529 pk.pack_bin_body((
const char*)signature.data(), signature.size());
534 template <
typename Packer>
535 void msgpack_pack(Packer& pk)
const
537 pk.pack_map(2 + (priority?1:0));
538 pk.pack(VALUE_KEY_ID); pk.pack(
id);
539 pk.pack(VALUE_KEY_DAT); msgpack_pack_to_encrypt(pk);
541 pk.pack(VALUE_KEY_PRIO); pk.pack(priority);
545 template <
typename Packer>
546 void msgpack_pack_fields(
const std::set<Value::Field>& fields, Packer& pk)
const
548 for (
const auto& field : fields)
550 case Value::Field::Id:
551 pk.pack(
static_cast<uint64_t
>(
id));
553 case Value::Field::ValueType:
554 pk.pack(
static_cast<uint64_t
>(type));
556 case Value::Field::OwnerPk:
558 owner->msgpack_pack(pk);
560 InfoHash().msgpack_pack(pk);
562 case Value::Field::SeqNum:
563 pk.pack(
static_cast<uint64_t
>(seq));
565 case Value::Field::UserType:
573 void msgpack_unpack(
const msgpack::object& o);
574 void msgpack_unpack_body(
const msgpack::object& o);
575 Blob getPacked()
const {
576 msgpack::sbuffer buffer;
577 msgpack::packer<msgpack::sbuffer> pk(&buffer);
579 return {buffer.data(), buffer.data()+buffer.size()};
582 void msgpack_unpack_fields(
const std::set<Value::Field>& fields,
const msgpack::object& o,
unsigned offset);
589 std::shared_ptr<crypto::PublicKey> owner {};
601 ValueType::Id type {ValueType::USER_DATA.id};
607 std::string user_type {};
629 unsigned priority {0};
631 inline bool isSignatureChecked()
const {
632 return signatureChecked;
634 inline bool isDecrypted()
const {
637 bool checkSignature();
638 Sp<Value> decrypt(
const crypto::PrivateKey& key);
642 bool signatureChecked {
false};
643 bool signatureValid {
false};
644 bool decrypted {
false};
645 Sp<Value> decryptedValue {};