C++ Distributed Hash Table
value.h
1 /*
2  * Copyright (C) 2014-2022 Savoir-faire Linux Inc.
3  * Author(s) : Adrien BĂ©raud <adrien.beraud@savoirfairelinux.com>
4  * Simon DĂ©saulniers <simon.desaulniers@savoirfairelinux.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #pragma once
21 
22 #include "infohash.h"
23 #include "crypto.h"
24 #include "utils.h"
25 #include "sockaddr.h"
26 
27 #include <msgpack.hpp>
28 
29 #include <string>
30 #include <string_view>
31 #include <sstream>
32 #include <bitset>
33 #include <vector>
34 #include <iostream>
35 #include <algorithm>
36 #include <functional>
37 #include <memory>
38 #include <chrono>
39 #include <set>
40 
41 #ifdef OPENDHT_JSONCPP
42 #include <json/json.h>
43 #endif
44 
45 namespace dht {
46 using namespace std::literals;
47 
48 static constexpr auto VALUE_KEY_ID("id");
49 static const std::string VALUE_KEY_DAT("dat");
50 static const std::string VALUE_KEY_PRIO("p");
51 static const std::string VALUE_KEY_SIGNATURE("sig");
52 
53 static const std::string VALUE_KEY_SEQ("seq");
54 static const std::string VALUE_KEY_DATA("data");
55 static const std::string VALUE_KEY_OWNER("owner");
56 static const std::string VALUE_KEY_TYPE("type");
57 static const std::string VALUE_KEY_TO("to");
58 static const std::string VALUE_KEY_BODY("body");
59 static const std::string VALUE_KEY_USERTYPE("utype");
60 
61 struct Value;
62 struct Query;
63 
74 using StorePolicy = std::function<bool(InfoHash key, std::shared_ptr<Value>& value, const InfoHash& from, const SockAddr& addr)>;
75 
90 using EditPolicy = std::function<bool(InfoHash key, const std::shared_ptr<Value>& old_val, std::shared_ptr<Value>& new_val, const InfoHash& from, const SockAddr& addr)>;
91 
92 static constexpr const size_t MAX_VALUE_SIZE {1024 * 64};
93 
94 struct OPENDHT_PUBLIC ValueType {
95  typedef uint16_t Id;
96 
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&) {
99  return false;
100  }
101 
102  ValueType () {}
103 
104  ValueType (Id id, std::string name, duration e = std::chrono::minutes(10))
105  : id(id), name(name), expiration(e) {}
106 
107  ValueType (Id id, std::string name, duration e, StorePolicy sp, EditPolicy ep = DEFAULT_EDIT_POLICY)
108  : id(id), name(name), expiration(e), storePolicy(sp), editPolicy(ep) {}
109 
110  virtual ~ValueType() {}
111 
112  bool operator==(const ValueType& o) {
113  return id == o.id;
114  }
115 
116  // Generic value type
117  static const ValueType USER_DATA;
118 
119 
120  Id id {0};
121  std::string name {};
122  duration expiration {std::chrono::minutes(10)};
123  StorePolicy storePolicy {DEFAULT_STORE_POLICY};
124  EditPolicy editPolicy {DEFAULT_EDIT_POLICY};
125 };
126 
127 class TypeStore {
128 public:
129  void registerType(const ValueType& type) {
130  types[type.id] = type;
131  }
132  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;
135  }
136 private:
137  std::map<ValueType::Id, ValueType> types {};
138 };
139 
140 struct CryptoValueCache;
141 
151 struct OPENDHT_PUBLIC Value
152 {
153  enum class Field : int {
154  None = 0,
155  Id, /* Value::id */
156  ValueType, /* Value::type */
157  OwnerPk, /* Value::owner */
158  SeqNum, /* Value::seq */
159  UserType, /* Value::user_type */
160 
161  COUNT /* the total number of fields */
162  };
163 
164  typedef uint64_t Id;
165  static const constexpr Id INVALID_ID {0};
166 
167  class Filter : public std::function<bool(const Value&)> {
168  public:
169  Filter() {}
170 
171  template<typename Functor>
172  Filter(Functor f) : std::function<bool(const Value&)>::function(f) {}
173 
174  Filter chain(Filter&& f2) {
175  auto f1 = *this;
176  return chain(std::move(f1), std::move(f2));
177  }
178  Filter chainOr(Filter&& f2) {
179  auto f1 = *this;
180  return chainOr(std::move(f1), std::move(f2));
181  }
182  static Filter chain(Filter&& f1, Filter&& 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);
187  };
188  }
189  static Filter chain(const Filter& f1, const Filter& f2) {
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);
194  };
195  }
196  static 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)
200  if (f and not f(v))
201  return false;
202  return true;
203  };
204  }
205  static Filter chain(std::initializer_list<Filter> l) {
206  return chainAll(std::vector<Filter>(l.begin(), l.end()));
207  }
208  static Filter chainOr(Filter&& f1, Filter&& f2) {
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);
212  };
213  }
214  static Filter notFilter(Filter&& f) {
215  if (not f) return [](const Value&) { return false; };
216  return [f](const Value& v) { return not f(v); };
217  }
218  std::vector<Sp<Value>> filter(const std::vector<Sp<Value>>& values) {
219  if (not (*this))
220  return values;
221  std::vector<Sp<Value>> ret;
222  for (const auto& v : values)
223  if ((*this)(v))
224  ret.emplace_back(v);
225  return ret;
226  }
227  };
228 
229  /* Sneaky functions disguised in classes */
230 
231  static const Filter AllFilter() {
232  return {};
233  }
234 
235  static Filter TypeFilter(const ValueType& t) {
236  return [tid = t.id](const Value& v) {
237  return v.type == tid;
238  };
239  }
240  static Filter TypeFilter(const ValueType::Id& tid) {
241  return [tid](const Value& v) {
242  return v.type == tid;
243  };
244  }
245 
246  static Filter IdFilter(const Id id) {
247  return [id](const Value& v) {
248  return v.id == id;
249  };
250  }
251 
252  static Filter RecipientFilter(const InfoHash& r) {
253  return [r](const Value& v) {
254  return v.recipient == r;
255  };
256  }
257 
258  static Filter OwnerFilter(const crypto::PublicKey& pk) {
259  return OwnerFilter(pk.getId());
260  }
261 
262  static Filter OwnerFilter(const InfoHash& pkh) {
263  return [pkh](const Value& v) {
264  return v.owner and v.owner->getId() == pkh;
265  };
266  }
267 
268  static Filter SeqNumFilter(uint16_t seq_no) {
269  return [seq_no](const Value& v) {
270  return v.seq == seq_no;
271  };
272  }
273 
274  static Filter UserTypeFilter(std::string ut) {
275  return [ut = std::move(ut)](const Value& v) {
276  return v.user_type == ut;
277  };
278  }
279 
281  {
282  public:
283  SerializableBase() {}
284  virtual ~SerializableBase() {};
285  virtual const ValueType& getType() const = 0;
286  virtual void unpackValue(const Value& v) = 0;
287  virtual Value packValue() const = 0;
288  };
289 
290  template <typename Derived, typename Base=SerializableBase>
291  class Serializable : public Base
292  {
293  public:
294  using Base::Base;
295 
296  virtual const ValueType& getType() const {
297  return Derived::TYPE;
298  }
299 
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));
303  }
304 
305  virtual Value packValue() const {
306  return Value {getType(), static_cast<const Derived&>(*this)};
307  }
308  };
309 
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)
313  {
314  return obj.packValue();
315  }
316 
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)
320  {
321  return {ValueType::USER_DATA.id, packMsg<T>(obj)};
322  }
323 
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)
327  {
328  T msg;
329  msg.unpackValue(v);
330  return msg;
331  }
332 
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)
336  {
337  return unpackMsg<T>(v.data);
338  }
339 
340  template <typename T>
341  T unpack()
342  {
343  return unpack<T>(*this);
344  }
345 
346  bool isEncrypted() const {
347  return not cypher.empty();
348  }
349  bool isSigned() const {
350  return owner and not signature.empty();
351  }
352 
358  void sign(const crypto::PrivateKey& key) {
359  if (isEncrypted())
360  throw DhtException("Can't sign encrypted data.");
361  owner = key.getSharedPublicKey();
362  signature = key.sign(getToSign());
363  }
364 
369  bool checkSignature() const {
370  return isSigned() and owner->checkSignature(getToSign(), signature);
371  }
372 
373  std::shared_ptr<crypto::PublicKey> getOwner() const {
374  return std::static_pointer_cast<crypto::PublicKey>(owner);
375  }
376 
381  if (isEncrypted())
382  throw DhtException("Data is already encrypted.");
383  setRecipient(to.getId());
384  sign(from);
385  Value nv {id};
386  nv.setCypher(to.encrypt(getToEncrypt()));
387  return nv;
388  }
389 
390  Value() {}
391 
392  Value (Id id) : id(id) {}
393 
395  Value(ValueType::Id t, const Blob& data, Id id = INVALID_ID)
396  : id(id), type(t), data(data) {}
397  Value(ValueType::Id t, Blob&& data, Id id = INVALID_ID)
398  : id(id), type(t), data(std::move(data)) {}
399  Value(ValueType::Id t, const uint8_t* dat_ptr, size_t dat_len, Id id = INVALID_ID)
400  : id(id), type(t), data(dat_ptr, dat_ptr+dat_len) {}
401 
402 #ifdef OPENDHT_JSONCPP
403 
407  Value(const Json::Value& json);
408 #endif
409 
410  template <typename Type>
411  Value(ValueType::Id t, const Type& d, Id id = INVALID_ID)
412  : id(id), type(t), data(packMsg(d)) {}
413 
414  template <typename Type>
415  Value(const ValueType& t, const Type& d, Id id = INVALID_ID)
416  : id(id), type(t.id), data(packMsg(d)) {}
417 
419  Value(const Blob& userdata) : data(userdata) {}
420  Value(Blob&& userdata) : data(std::move(userdata)) {}
421  Value(const uint8_t* dat_ptr, size_t dat_len) : data(dat_ptr, dat_ptr+dat_len) {}
422 
423  Value(Value&& o) noexcept
424  : id(o.id), owner(std::move(o.owner)), recipient(o.recipient),
425  type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq)
426  , signature(std::move(o.signature)), cypher(std::move(o.cypher))
427  , priority(o.priority) {}
428 
429  template <typename Type>
430  Value(const Type& vs)
431  : Value(pack<Type>(vs)) {}
432 
436  Value(const msgpack::object& o) {
437  msgpack_unpack(o);
438  }
439 
443  inline bool contentEquals(const Value& o) {
444  return isEncrypted() ? cypher == o.cypher :
445  ((owner == o.owner || (owner and o.owner and *owner == *o.owner))
446  && type == o.type
447  && data == o.data
448  && user_type == o.user_type
449  && signature == o.signature);
450  }
451 
452  inline bool operator== (const Value& o) {
453  return id == o.id and contentEquals(o);
454  }
455 
456  void setRecipient(const InfoHash& r) {
457  recipient = r;
458  }
459 
460  void setCypher(Blob&& c) {
461  cypher = std::move(c);
462  }
463 
467  Blob getToSign() const {
468  msgpack::sbuffer buffer;
469  msgpack::packer<msgpack::sbuffer> pk(&buffer);
470  msgpack_pack_to_sign(pk);
471  return {buffer.data(), buffer.data()+buffer.size()};
472  }
473 
477  Blob getToEncrypt() const {
478  msgpack::sbuffer buffer;
479  msgpack::packer<msgpack::sbuffer> pk(&buffer);
480  msgpack_pack_to_encrypt(pk);
481  return {buffer.data(), buffer.data()+buffer.size()};
482  }
483 
485  OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Value& v);
486 
487  std::string toString() const {
488  std::stringstream ss;
489  ss << *this;
490  return ss.str();
491  }
492 
493 #ifdef OPENDHT_JSONCPP
494 
502  Json::Value toJson() const;
503 #endif
504 
506  size_t size() const;
507 
508  template <typename Packer>
509  void msgpack_pack_to_sign(Packer& pk) const
510  {
511  bool has_owner = owner && *owner;
512  pk.pack_map((user_type.empty()?0:1) + (has_owner?(recipient ? 5 : 4):2));
513  if (has_owner) { // isSigned
514  pk.pack(VALUE_KEY_SEQ); pk.pack(seq);
515  pk.pack(VALUE_KEY_OWNER); owner->msgpack_pack(pk);
516  if (recipient) {
517  pk.pack(VALUE_KEY_TO); pk.pack(recipient);
518  }
519  }
520  pk.pack(VALUE_KEY_TYPE); pk.pack(type);
521  pk.pack(VALUE_KEY_DATA); pk.pack_bin(data.size());
522  pk.pack_bin_body((const char*)data.data(), data.size());
523  if (not user_type.empty()) {
524  pk.pack(VALUE_KEY_USERTYPE); pk.pack(user_type);
525  }
526  }
527 
528  template <typename Packer>
529  void msgpack_pack_to_encrypt(Packer& pk) const
530  {
531  if (isEncrypted()) {
532  pk.pack_bin(cypher.size());
533  pk.pack_bin_body((const char*)cypher.data(), cypher.size());
534  } else {
535  pk.pack_map(isSigned() ? 2 : 1);
536  pk.pack(VALUE_KEY_BODY); msgpack_pack_to_sign(pk);
537  if (isSigned()) {
538  pk.pack(VALUE_KEY_SIGNATURE); pk.pack_bin(signature.size());
539  pk.pack_bin_body((const char*)signature.data(), signature.size());
540  }
541  }
542  }
543 
544  template <typename Packer>
545  void msgpack_pack(Packer& pk) const
546  {
547  pk.pack_map(2 + (priority?1:0));
548  pk.pack(VALUE_KEY_ID); pk.pack(id);
549  pk.pack(VALUE_KEY_DAT); msgpack_pack_to_encrypt(pk);
550  if (priority) {
551  pk.pack(VALUE_KEY_PRIO); pk.pack(priority);
552  }
553  }
554 
555  template <typename Packer>
556  void msgpack_pack_fields(const std::set<Value::Field>& fields, Packer& pk) const
557  {
558  for (const auto& field : fields)
559  switch (field) {
560  case Value::Field::Id:
561  pk.pack(static_cast<uint64_t>(id));
562  break;
563  case Value::Field::ValueType:
564  pk.pack(static_cast<uint64_t>(type));
565  break;
566  case Value::Field::OwnerPk:
567  if (owner)
568  owner->msgpack_pack(pk);
569  else
570  InfoHash().msgpack_pack(pk);
571  break;
572  case Value::Field::SeqNum:
573  pk.pack(static_cast<uint64_t>(seq));
574  break;
575  case Value::Field::UserType:
576  pk.pack(user_type);
577  break;
578  default:
579  break;
580  }
581  }
582 
583  void msgpack_unpack(const msgpack::object& o);
584  void msgpack_unpack_body(const msgpack::object& o);
585  Blob getPacked() const {
586  msgpack::sbuffer buffer;
587  msgpack::packer<msgpack::sbuffer> pk(&buffer);
588  pk.pack(*this);
589  return {buffer.data(), buffer.data()+buffer.size()};
590  }
591 
592  void msgpack_unpack_fields(const std::set<Value::Field>& fields, const msgpack::object& o, unsigned offset);
593 
594  Id id {INVALID_ID};
595 
599  std::shared_ptr<crypto::PublicKey> owner {};
600 
606  InfoHash recipient {};
607 
611  ValueType::Id type {ValueType::USER_DATA.id};
612  Blob data {};
613 
617  std::string user_type {};
618 
622  uint16_t seq {0};
623 
627  Blob signature {};
628 
632  Blob cypher {};
633 
639  unsigned priority {0};
640 
641  bool checkSignature();
642  Sp<Value> decrypt(const crypto::PrivateKey& key);
643 
644 private:
645  /* Cache for crypto ops */
646  bool signatureChecked {false};
647  bool signatureValid {false};
648  bool decrypted {false};
649  Sp<Value> decryptedValue {};
650 };
651 
652 using ValuesExport = std::pair<InfoHash, Blob>;
653 
661 struct OPENDHT_PUBLIC FieldValue
662 {
663  FieldValue() {}
664  FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
665  FieldValue(Value::Field f, InfoHash hash_value) : field(f), hashValue(hash_value) {}
666  FieldValue(Value::Field f, Blob blob_value) : field(f), blobValue(std::move(blob_value)) {}
667 
668  bool operator==(const FieldValue& fd) const;
669 
670  // accessors
671  Value::Field getField() const { return field; }
672  uint64_t getInt() const { return intValue; }
673  InfoHash getHash() const { return hashValue; }
674  Blob getBlob() const { return blobValue; }
675 
676  template <typename Packer>
677  void msgpack_pack(Packer& p) const {
678  p.pack_map(2);
679  p.pack("f"sv); p.pack(static_cast<uint8_t>(field));
680 
681  p.pack("v"sv);
682  switch (field) {
683  case Value::Field::Id:
684  case Value::Field::ValueType:
685  p.pack(intValue);
686  break;
687  case Value::Field::OwnerPk:
688  p.pack(hashValue);
689  break;
690  case Value::Field::UserType:
691  p.pack_bin(blobValue.size());
692  p.pack_bin_body((const char*)blobValue.data(), blobValue.size());
693  break;
694  default:
695  throw msgpack::type_error();
696  }
697  }
698 
699  void msgpack_unpack(const msgpack::object& msg) {
700  hashValue = {};
701  blobValue.clear();
702 
703  if (auto f = findMapValue(msg, "f"sv))
704  field = (Value::Field)f->as<unsigned>();
705  else
706  throw msgpack::type_error();
707 
708  auto v = findMapValue(msg, "v"sv);
709  if (not v)
710  throw msgpack::type_error();
711  else
712  switch (field) {
713  case Value::Field::Id:
714  case Value::Field::ValueType:
715  intValue = v->as<decltype(intValue)>();
716  break;
717  case Value::Field::OwnerPk:
718  hashValue = v->as<decltype(hashValue)>();
719  break;
720  case Value::Field::UserType:
721  blobValue = unpackBlob(*v);
722  break;
723  default:
724  throw msgpack::type_error();
725  }
726  }
727 
728  Value::Filter getLocalFilter() const;
729 
730 private:
731  Value::Field field {Value::Field::None};
732  // three possible value types
733  uint64_t intValue {};
734  InfoHash hashValue {};
735  Blob blobValue {};
736 };
737 
745 struct OPENDHT_PUBLIC Select
746 {
747  Select() { }
748  Select(std::string_view q_str);
749 
750  bool isSatisfiedBy(const Select& os) const;
751 
759  Select& field(Value::Field field) {
760  if (std::find(fieldSelection_.begin(), fieldSelection_.end(), field) == fieldSelection_.end())
761  fieldSelection_.emplace_back(field);
762  return *this;
763  }
764 
770  std::set<Value::Field> getSelection() const {
771  return {fieldSelection_.begin(), fieldSelection_.end()};
772  }
773 
774  template <typename Packer>
775  void msgpack_pack(Packer& pk) const { pk.pack(fieldSelection_); }
776  void msgpack_unpack(const msgpack::object& o) {
777  fieldSelection_ = o.as<decltype(fieldSelection_)>();
778  }
779 
780  std::string toString() const {
781  std::stringstream ss;
782  ss << *this;
783  return ss.str();
784  }
785 
786  bool empty() const { return fieldSelection_.empty(); }
787 
788  OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Select& q);
789 private:
790  std::vector<Value::Field> fieldSelection_ {};
791 };
792 
800 struct OPENDHT_PUBLIC Where
801 {
802  Where() { }
803  Where(std::string_view q_str);
804 
805  bool isSatisfiedBy(const Where& where) const;
806 
814  Where& id(Value::Id id) {
815  FieldValue fv {Value::Field::Id, id};
816  if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
817  filters_.emplace_back(std::move(fv));
818  return *this;
819  }
820 
828  Where& valueType(ValueType::Id type) {
829  FieldValue fv {Value::Field::ValueType, type};
830  if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
831  filters_.emplace_back(std::move(fv));
832  return *this;
833  }
834 
842  Where& owner(InfoHash owner_pk_hash) {
843  FieldValue fv {Value::Field::OwnerPk, owner_pk_hash};
844  if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
845  filters_.emplace_back(std::move(fv));
846  return *this;
847  }
848 
856  Where& seq(uint16_t seq_no) {
857  FieldValue fv {Value::Field::SeqNum, seq_no};
858  if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
859  filters_.emplace_back(std::move(fv));
860  return *this;
861  }
862 
870  Where& userType(std::string_view user_type) {
871  FieldValue fv {Value::Field::UserType, Blob {user_type.begin(), user_type.end()}};
872  if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
873  filters_.emplace_back(std::move(fv));
874  return *this;
875  }
876 
883  if (filters_.empty()) return {};
884  std::vector<Value::Filter> fset;
885  fset.reserve(filters_.size());
886  for (const auto& f : filters_) {
887  if (auto lf = f.getLocalFilter())
888  fset.emplace_back(std::move(lf));
889  }
890  return Value::Filter::chainAll(std::move(fset));
891  }
892 
893  template <typename Packer>
894  void msgpack_pack(Packer& pk) const { pk.pack(filters_); }
895  void msgpack_unpack(const msgpack::object& o) {
896  filters_.clear();
897  filters_ = o.as<decltype(filters_)>();
898  }
899 
900  std::string toString() const {
901  std::stringstream ss;
902  ss << *this;
903  return ss.str();
904  }
905 
906  bool empty() const {
907  return filters_.empty();
908  }
909 
910  OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Where& q);
911 
912 private:
913  std::vector<FieldValue> filters_;
914 };
915 
924 struct OPENDHT_PUBLIC Query
925 {
926  static const std::string QUERY_PARSE_ERROR;
927 
928  Query(Select s = {}, Where w = {}, bool none = false) : select(std::move(s)), where(std::move(w)), none(none) { };
929 
943  Query(std::string_view q_str) {
944  auto pos_W = q_str.find("WHERE");
945  auto pos_w = q_str.find("where");
946  auto pos = std::min(pos_W != std::string_view::npos ? pos_W : q_str.size(),
947  pos_w != std::string_view::npos ? pos_w : q_str.size());
948  select = q_str.substr(0, pos);
949  where = q_str.substr(pos, q_str.size()-pos);
950  }
951 
955  bool isSatisfiedBy(const Query& q) const;
956 
957  template <typename Packer>
958  void msgpack_pack(Packer& pk) const {
959  pk.pack_map(2);
960  pk.pack(std::string("s")); pk.pack(select); /* packing field selectors */
961  pk.pack(std::string("w")); pk.pack(where); /* packing filters */
962  }
963 
964  void msgpack_unpack(const msgpack::object& o);
965 
966  std::string toString() const {
967  std::stringstream ss;
968  ss << *this;
969  return ss.str();
970  }
971 
972  OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Query& q) {
973  return s << "Query[" << q.select << " " << q.where << "]";
974  }
975 
976  Select select {};
977  Where where {};
978  bool none {false}; /* When true, any query satisfies this. */
979 };
980 
988 struct OPENDHT_PUBLIC FieldValueIndex {
989  FieldValueIndex() {}
990  FieldValueIndex(const Value& v, const Select& s = {});
997  bool containedIn(const FieldValueIndex& other) const;
998 
999  OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& os, const FieldValueIndex& fvi);
1000 
1001  void msgpack_unpack_fields(const std::set<Value::Field>& fields,
1002  const msgpack::object& o,
1003  unsigned offset);
1004 
1005  std::map<Value::Field, FieldValue> index {};
1006 };
1007 
1008 template <typename T,
1009  typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr>
1011 getFilterSet(Value::Filter f)
1012 {
1013  return Value::Filter::chain({
1014  Value::TypeFilter(T::TYPE),
1015  T::getFilter(),
1016  f
1017  });
1018 }
1019 
1020 template <typename T,
1021  typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr>
1022 Value::Filter
1023 getFilterSet(Value::Filter f)
1024 {
1025  return f;
1026 }
1027 
1028 template <typename T,
1029  typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr>
1030 Value::Filter
1031 getFilterSet()
1032 {
1033  return Value::Filter::chain({
1034  Value::TypeFilter(T::TYPE),
1035  T::getFilter()
1036  });
1037 }
1038 
1039 template <typename T,
1040  typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr>
1041 Value::Filter
1042 getFilterSet()
1043 {
1044  return {};
1045 }
1046 
1047 template <class T>
1048 std::vector<T>
1049 unpackVector(const std::vector<std::shared_ptr<Value>>& vals) {
1050  std::vector<T> ret;
1051  ret.reserve(vals.size());
1052  for (const auto& v : vals) {
1053  try {
1054  ret.emplace_back(Value::unpack<T>(*v));
1055  } catch (const std::exception&) {}
1056  }
1057  return ret;
1058 }
1059 
1060 #ifdef OPENDHT_JSONCPP
1061 uint64_t unpackId(const Json::Value& json, const std::string& key);
1062 #endif
1063 
1064 }
1065 
1066 MSGPACK_ADD_ENUM(dht::Value::Field)
Blob getToEncrypt() const
Definition: value.h:477
Describes a value filter.
Definition: value.h:661
An index for field values.
Definition: value.h:988
bool checkSignature() const
Definition: value.h:369
Value::Filter getFilter() const
Definition: value.h:882
Where & valueType(ValueType::Id type)
Definition: value.h:828
STL namespace.
Value(const Blob &userdata)
Definition: value.h:419
std::string user_type
Definition: value.h:617
Blob cypher
Definition: value.h:632
Serializable Value field selection.
Definition: value.h:745
OPENDHT_PUBLIC Blob unpackBlob(const msgpack::object &o)
Blob sign(const uint8_t *data, size_t data_len) const
Select & field(Value::Field field)
Definition: value.h:759
bool contentEquals(const Value &o)
Definition: value.h:443
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
Definition: value.h:90
std::shared_ptr< crypto::PublicKey > owner
Definition: value.h:599
Where & owner(InfoHash owner_pk_hash)
Definition: value.h:842
Value(ValueType::Id t, const Blob &data, Id id=INVALID_ID)
Definition: value.h:395
Blob signature
Definition: value.h:627
std::vector< uint8_t > Blob
Definition: utils.h:151
Blob getToSign() const
Definition: value.h:467
std::function< bool(InfoHash key, std::shared_ptr< Value > &value, const InfoHash &from, const SockAddr &addr)> StorePolicy
Definition: value.h:74
ValueType::Id type
Definition: value.h:611
Where & userType(std::string_view user_type)
Definition: value.h:870
InfoHash getId() const
Describes a query destined to another peer.
Definition: value.h:924
Where & id(Value::Id id)
Definition: value.h:814
Serializable dht::Value filter.
Definition: value.h:800
Value(const msgpack::object &o)
Definition: value.h:436
std::set< Value::Field > getSelection() const
Definition: value.h:770
Where & seq(uint16_t seq_no)
Definition: value.h:856
Query(std::string_view q_str)
Definition: value.h:943
void sign(const crypto::PrivateKey &key)
Definition: value.h:358
Value encrypt(const crypto::PrivateKey &from, const crypto::PublicKey &to)
Definition: value.h:380
Definition: callbacks.h:35