94struct OPENDHT_PUBLIC ValueType {
97 static bool DEFAULT_STORE_POLICY(InfoHash,
const std::shared_ptr<Value>& v,
const InfoHash&,
const SockAddr&);
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) {}
110 virtual ~ValueType() {}
112 bool operator==(
const ValueType& o) {
117 static const ValueType USER_DATA;
122 duration expiration {std::chrono::minutes(10)};
149struct OPENDHT_PUBLIC Value
151 enum class Field :
int {
163 static const constexpr Id INVALID_ID {0};
165 class Filter :
public std::function<bool(const Value&)> {
169 template<
typename Functor>
170 Filter(Functor f) : std::function<bool(
const Value&)>::function(f) {}
172 inline Filter chain(Filter&& f2) {
174 return chain(std::move(f1), std::move(f2));
176 inline Filter chainOr(Filter&& f2) {
178 return chainOr(std::move(f1), std::move(f2));
180 static inline Filter chain(Filter&& f1, Filter&& f2) {
181 if (not f1)
return std::move(f2);
182 if (not f2)
return std::move(f1);
183 return [f1 = std::move(f1), f2 = std::move(f2)](
const Value& v) {
184 return f1(v) and f2(v);
187 static inline Filter chain(
const Filter& f1,
const Filter& f2) {
188 if (not f1)
return f2;
189 if (not f2)
return f1;
190 return [f1,f2](
const Value& v) {
191 return f1(v) and f2(v);
194 static inline Filter chainAll(std::vector<Filter>&& set) {
195 if (set.empty())
return {};
196 return [set = std::move(set)](
const Value& v) {
197 for (
const auto& f : set)
203 static inline Filter chain(std::initializer_list<Filter> l) {
204 return chainAll(std::vector<Filter>(l.begin(), l.end()));
206 static inline Filter chainOr(Filter&& f1, Filter&& f2) {
207 if (not f1 or not f2)
return {};
208 return [f1=std::move(f1),f2=std::move(f2)](
const Value& v) {
209 return f1(v) or f2(v);
212 static inline Filter notFilter(Filter&& f) {
213 if (not f)
return [](
const Value&) {
return false; };
214 return [f = std::move(f)](
const Value& v) {
return not f(v); };
216 std::vector<Sp<Value>> filter(
const std::vector<Sp<Value>>& values) {
219 std::vector<Sp<Value>> ret;
220 for (
const auto& v : values)
229 static inline Filter AllFilter() {
233 static inline Filter TypeFilter(
const ValueType& t) {
234 return [tid = t.id](
const Value& v) {
235 return v.type == tid;
238 static inline Filter TypeFilter(
const ValueType::Id& tid) {
239 return [tid](
const Value& v) {
240 return v.type == tid;
244 static inline Filter IdFilter(
const Id
id) {
245 return [id](
const Value& v) {
250 static inline Filter RecipientFilter(
const InfoHash& r) {
251 return [r](
const Value& v) {
252 return v.recipient == r;
256 static inline Filter OwnerFilter(
const crypto::PublicKey& pk) {
257 return OwnerFilter(pk.getId());
260 static inline Filter OwnerFilter(
const InfoHash& pkh) {
261 return [pkh](
const Value& v) {
262 return v.owner and v.owner->getId() == pkh;
266 static inline Filter SeqNumFilter(uint16_t seq_no) {
267 return [seq_no](
const Value& v) {
268 return v.seq == seq_no;
272 static inline Filter UserTypeFilter(std::string ut) {
273 return [ut = std::move(ut)](
const Value& v) {
274 return v.user_type == ut;
278 class SerializableBase
281 SerializableBase() {}
282 virtual ~SerializableBase() {};
283 virtual const ValueType& getType()
const = 0;
284 virtual void unpackValue(
const Value& v) = 0;
285 virtual Value packValue()
const = 0;
288 template <
typename Derived,
typename Base=SerializableBase>
294 virtual const ValueType& getType()
const {
295 return Derived::TYPE;
298 virtual void unpackValue(
const Value& v) {
299 auto msg = msgpack::unpack((
const char*)v.data.data(), v.data.size());
300 msg.get().convert(*
static_cast<Derived*
>(
this));
303 virtual Value packValue()
const {
304 return Value {getType(),
static_cast<const Derived&
>(*this)};
308 template <
typename T,
309 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>
::type* =
nullptr>
310 static Value pack(
const T& obj)
312 return obj.packValue();
315 template <
typename T,
316 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
317 static Value pack(
const T& obj)
319 return {ValueType::USER_DATA.id, packMsg<T>(obj)};
322 template <
typename T,
323 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
324 static T unpack(
const Value& v)
331 template <
typename T,
332 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
333 static T unpack(
const Value& v)
335 return unpackMsg<T>(v.data);
338 template <
typename T>
341 return unpack<T>(*
this);
344 inline bool isEncrypted()
const {
345 return not cypher.empty();
347 inline bool isSigned()
const {
348 return owner and not signature.empty();
366 inline std::shared_ptr<crypto::PublicKey> getOwner()
const {
377 Value (Id
id) : id(id) {}
380 Value(ValueType::Id t,
const Blob& data, Id
id = INVALID_ID)
381 : id(id),
type(t), data(data) {}
382 Value(ValueType::Id t,
Blob&& data, Id
id = INVALID_ID)
383 : id(id), type(t), data(std::move(data)) {}
384 Value(ValueType::Id t,
const uint8_t* dat_ptr,
size_t dat_len, Id
id = INVALID_ID)
385 : id(id), type(t), data(dat_ptr, dat_ptr+dat_len) {}
387#ifdef OPENDHT_JSONCPP
392 Value(
const Json::Value& json);
395 template <
typename Type>
396 Value(ValueType::Id t,
const Type& d, Id
id = INVALID_ID)
397 : id(id), type(t), data(packMsg(d)) {}
399 template <
typename Type>
400 Value(
const ValueType& t,
const Type& d, Id
id = INVALID_ID)
401 : id(id), type(t.id), data(packMsg(d)) {}
405 Value(
Blob&& userdata) : data(std::move(userdata)) {}
406 Value(
const uint8_t* dat_ptr,
size_t dat_len) : data(dat_ptr, dat_ptr+dat_len) {}
408 Value(Value&& o) noexcept
409 : id(o.id), owner(std::move(o.owner)), recipient(o.recipient),
410 type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq)
411 , signature(std::move(o.signature)), cypher(std::move(o.cypher))
412 , priority(o.priority) {}
414 template <
typename Type>
415 Value(
const Type& vs)
416 : Value(pack<Type>(vs)) {}
437 inline bool operator== (
const Value& o)
const {
438 return id == o.id and contentEquals(o);
440 inline bool operator!= (
const Value& o)
const {
441 return !(*
this == o);
444 inline void setRecipient(
const InfoHash& r) {
448 inline void setCypher(Blob&& c) {
449 cypher = std::move(c);
456 msgpack::sbuffer buffer;
457 msgpack::packer<msgpack::sbuffer> pk(&buffer);
458 msgpack_pack_to_sign(pk);
459 return {buffer.data(), buffer.data()+buffer.size()};
466 msgpack::sbuffer buffer;
467 msgpack::packer<msgpack::sbuffer> pk(&buffer);
468 msgpack_pack_to_encrypt(pk);
469 return {buffer.data(), buffer.data()+buffer.size()};
473 OPENDHT_PUBLIC
friend std::ostream& operator<< (std::ostream& s,
const Value& v);
475 inline std::string toString()
const {
476 std::ostringstream ss;
481#ifdef OPENDHT_JSONCPP
490 Json::Value toJson()
const;
496 template <
typename Packer>
497 void msgpack_pack_to_sign(Packer& pk)
const
502 pk.pack(VALUE_KEY_SEQ); pk.pack(
seq);
503 pk.pack(VALUE_KEY_OWNER);
owner->msgpack_pack(pk);
505 pk.pack(VALUE_KEY_TO); pk.pack(
recipient);
508 pk.pack(VALUE_KEY_TYPE); pk.pack(type);
509 pk.pack(VALUE_KEY_DATA); pk.pack_bin(data.size());
510 pk.pack_bin_body((
const char*)data.data(), data.size());
511 if (not user_type.empty()) {
512 pk.pack(VALUE_KEY_USERTYPE); pk.pack(user_type);
516 template <
typename Packer>
517 void msgpack_pack_to_encrypt(Packer& pk)
const
520 pk.pack_bin(cypher.size());
521 pk.pack_bin_body((
const char*)cypher.data(), cypher.size());
523 pk.pack_map(isSigned() ? 2 : 1);
524 pk.pack(VALUE_KEY_BODY); msgpack_pack_to_sign(pk);
526 pk.pack(VALUE_KEY_SIGNATURE); pk.pack_bin(signature.size());
527 pk.pack_bin_body((
const char*)signature.data(), signature.size());
532 template <
typename Packer>
533 void msgpack_pack(Packer& pk)
const
535 pk.pack_map(2 + (priority?1:0));
536 pk.pack(VALUE_KEY_ID); pk.pack(
id);
537 pk.pack(VALUE_KEY_DAT); msgpack_pack_to_encrypt(pk);
539 pk.pack(VALUE_KEY_PRIO); pk.pack(priority);
543 template <
typename Packer>
544 void msgpack_pack_fields(
const std::set<Value::Field>& fields, Packer& pk)
const
546 for (
const auto& field : fields)
548 case Value::Field::Id:
549 pk.pack(
static_cast<uint64_t
>(
id));
551 case Value::Field::ValueType:
552 pk.pack(
static_cast<uint64_t
>(type));
554 case Value::Field::OwnerPk:
556 owner->msgpack_pack(pk);
558 InfoHash().msgpack_pack(pk);
560 case Value::Field::SeqNum:
561 pk.pack(
static_cast<uint64_t
>(seq));
563 case Value::Field::UserType:
571 void msgpack_unpack(
const msgpack::object& o);
572 void msgpack_unpack_body(
const msgpack::object& o);
573 Blob getPacked()
const {
574 msgpack::sbuffer buffer;
575 msgpack::packer<msgpack::sbuffer> pk(&buffer);
577 return {buffer.data(), buffer.data()+buffer.size()};
580 void msgpack_unpack_fields(
const std::set<Value::Field>& fields,
const msgpack::object& o,
unsigned offset);
587 std::shared_ptr<crypto::PublicKey>
owner {};
599 ValueType::Id
type {ValueType::USER_DATA.id};
629 inline bool isSignatureChecked()
const {
630 return signatureChecked;
632 inline bool isDecrypted()
const {
635 bool checkSignature();
636 Sp<Value> decrypt(
const crypto::PrivateKey& key);
640 bool signatureChecked {
false};
641 bool signatureValid {
false};
642 bool decrypted {
false};
643 Sp<Value> decryptedValue {};
655struct OPENDHT_PUBLIC FieldValue
658 FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
659 FieldValue(Value::Field f, InfoHash hash_value) : field(f), hashValue(hash_value) {}
660 FieldValue(Value::Field f,
Blob blob_value) : field(f), blobValue(std::move(blob_value)) {}
662 bool operator==(
const FieldValue& fd)
const;
665 Value::Field getField()
const {
return field; }
666 uint64_t getInt()
const {
return intValue; }
667 InfoHash getHash()
const {
return hashValue; }
668 Blob getBlob()
const {
return blobValue; }
670 template <
typename Packer>
671 void msgpack_pack(Packer& p)
const {
673 p.pack(
"f"sv); p.pack(
static_cast<uint8_t
>(field));
677 case Value::Field::Id:
678 case Value::Field::ValueType:
681 case Value::Field::OwnerPk:
684 case Value::Field::UserType:
685 p.pack_bin(blobValue.size());
686 p.pack_bin_body((
const char*)blobValue.data(), blobValue.size());
689 throw msgpack::type_error();
693 void msgpack_unpack(
const msgpack::object& msg) {
697 if (
auto f = findMapValue(msg,
"f"sv))
698 field = (Value::Field)f->as<
unsigned>();
700 throw msgpack::type_error();
702 auto v = findMapValue(msg,
"v"sv);
704 throw msgpack::type_error();
707 case Value::Field::Id:
708 case Value::Field::ValueType:
709 intValue = v->as<
decltype(intValue)>();
711 case Value::Field::OwnerPk:
712 hashValue = v->as<
decltype(hashValue)>();
714 case Value::Field::UserType:
718 throw msgpack::type_error();
725 Value::Field field {Value::Field::None};
727 uint64_t intValue {};
728 InfoHash hashValue {};