C++ Distributed Hash Table
default_types.h
1 /*
2  * Copyright (C) 2014-2017 Savoir-faire Linux Inc.
3  * Author : Adrien BĂ©raud <adrien.beraud@savoirfairelinux.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include "value.h"
22 #include "sockaddr.h"
23 
24 namespace dht {
25 enum class ImStatus : uint8_t {
26  NONE = 0,
27  TYPING,
28  RECEIVED,
29  READ
30 };
31 }
32 MSGPACK_ADD_ENUM(dht::ImStatus)
33 
34 namespace dht {
35 
36 class OPENDHT_PUBLIC DhtMessage : public Value::Serializable<DhtMessage>
37 {
38 public:
39  static const ValueType TYPE;
40 
41  DhtMessage(std::string s = {}, Blob msg = {}) : service(s), data(msg) {}
42 
43  std::string getService() const {
44  return service;
45  }
46 
47  static Value::Filter getFilter() { return {}; }
48 
49  static bool storePolicy(InfoHash key, std::shared_ptr<Value>& value, const InfoHash& from, const SockAddr&);
50 
51  static Value::Filter ServiceFilter(std::string s);
52 
54  friend std::ostream& operator<< (std::ostream&, const DhtMessage&);
55 
56  std::string service;
57  Blob data;
58  MSGPACK_DEFINE(service, data)
59 };
60 
61 template <typename T>
62 class OPENDHT_PUBLIC SignedValue : public Value::Serializable<T>
63 {
64 private:
66 
67 public:
68  virtual void unpackValue(const Value& v) override {
69  if (v.owner)
70  from = v.owner->getId();
71  BaseClass::unpackValue(v);
72  }
73 
74  static Value::Filter getFilter() {
75  return [](const Value& v){ return v.isSigned(); };
76  }
77 
78  dht::InfoHash from;
79 };
80 
81 template <typename T>
82 class OPENDHT_PUBLIC EncryptedValue : public SignedValue<T>
83 {
84 public:
85  using BaseClass = SignedValue<T>;
86 
87 public:
88  virtual void unpackValue(const Value& v) override {
89  to = v.recipient;
90  BaseClass::unpackValue(v);
91  }
92 
93  static Value::Filter getFilter() {
94  return Value::Filter::chain(
95  BaseClass::getFilter(),
96  [](const Value& v) { return static_cast<bool>(v.recipient); }
97  );
98  }
99 
100  dht::InfoHash to;
101 };
102 
103 
104 
105 
106 class OPENDHT_PUBLIC ImMessage : public SignedValue<ImMessage>
107 {
108 private:
110 
111 public:
112  static const ValueType TYPE;
113 
114  ImMessage() {}
115  ImMessage(dht::Value::Id id, std::string&& m, long d = 0)
116  : id(id), msg(std::move(m)), date(d) {}
117  ImMessage(dht::Value::Id id, std::string&& dt, std::string&& m, long d = 0)
118  : id(id), msg(std::move(m)), datatype(std::move(dt)), date(d) {}
119 
120  virtual void unpackValue(const Value& v) override {
121  to = v.recipient;
122  SignedValue::unpackValue(v);
123  }
124 
125  dht::InfoHash to;
126  dht::Value::Id id {0};
127  std::string msg;
128  std::string datatype;
129  long date {0};
130  ImStatus status {ImStatus::NONE};
131 
132  MSGPACK_DEFINE_MAP(id, msg, date, status, datatype)
133 };
134 
135 class OPENDHT_PUBLIC TrustRequest : public EncryptedValue<TrustRequest>
136 {
137 private:
139 
140 public:
141  static const ValueType TYPE;
142 
143  TrustRequest() {}
144  TrustRequest(std::string s) : service(s) {}
145  TrustRequest(std::string s, const Blob& d) : service(s), payload(d) {}
146 
147  static Value::Filter getFilter() {
148  return EncryptedValue::getFilter();
149  }
150 
151  std::string service;
152  Blob payload;
153  bool confirm {false};
154  MSGPACK_DEFINE_MAP(service, payload, confirm)
155 };
156 
157 class OPENDHT_PUBLIC IceCandidates : public EncryptedValue<IceCandidates>
158 {
159 private:
161 
162 public:
163  static const ValueType TYPE;
164 
165  IceCandidates() {}
166  IceCandidates(Value::Id msg_id, Blob ice) : id(msg_id), ice_data(ice) {}
167 
168  static Value::Filter getFilter() {
169  return EncryptedValue::getFilter();
170  }
171 
172  template <typename Packer>
173  void msgpack_pack(Packer& pk) const
174  {
175  pk.pack_array(2);
176  pk.pack(id);
177 #if 1
178  pk.pack_bin(ice_data.size());
179  pk.pack_bin_body((const char*)ice_data.data(), ice_data.size());
180 #else
181  // hack for backward compatibility with old opendht compiled with msgpack 1.0
182  // remove when enough people have moved to new versions
183  pk.pack_array(ice_data.size());
184  for (uint8_t b : ice_data)
185  pk.pack(b);
186 #endif
187  }
188 
189  virtual void msgpack_unpack(msgpack::object o)
190  {
191  if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
192  if (o.via.array.size < 2) throw msgpack::type_error();
193  id = o.via.array.ptr[0].as<Value::Id>();
194  ice_data = unpackBlob(o.via.array.ptr[1]);
195  }
196 
197  Value::Id id {0};
198  Blob ice_data;
199 };
200 
201 /* "Peer" announcement
202  */
203 class OPENDHT_PUBLIC IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement>
204 {
205 private:
207 
208 public:
209  static const ValueType TYPE;
210 
211  IpServiceAnnouncement(sa_family_t family = AF_UNSPEC, in_port_t p = 0) {
212  addr.setFamily(family);
213  addr.setPort(p);
214  }
215 
216  IpServiceAnnouncement(const SockAddr& sa) : addr(sa) {}
217 
218  IpServiceAnnouncement(const Blob& b) {
219  msgpack_unpack(unpackMsg(b).get());
220  }
221 
222  template <typename Packer>
223  void msgpack_pack(Packer& pk) const
224  {
225  pk.pack_bin(addr.getLength());
226  pk.pack_bin_body((const char*)addr.get(), addr.getLength());
227  }
228 
229  virtual void msgpack_unpack(msgpack::object o)
230  {
231  if (o.type == msgpack::type::BIN)
232  addr = {(sockaddr*)o.via.bin.ptr, (socklen_t)o.via.bin.size};
233  else
234  throw msgpack::type_error();
235  }
236 
237  in_port_t getPort() const {
238  return addr.getPort();
239  }
240  void setPort(in_port_t p) {
241  addr.setPort(p);
242  }
243 
244  const SockAddr& getPeerAddr() const {
245  return addr;
246  }
247 
248  virtual const ValueType& getType() const {
249  return TYPE;
250  }
251 
252  static bool storePolicy(InfoHash, std::shared_ptr<Value>&, const InfoHash&, const SockAddr&);
253 
255  friend std::ostream& operator<< (std::ostream&, const IpServiceAnnouncement&);
256 
257 private:
258  SockAddr addr;
259 };
260 
261 
262 OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
263 
264 OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
265 
266 }
std::shared_ptr< const crypto::PublicKey > owner
Definition: value.h:559
std::vector< uint8_t > Blob
Definition: utils.h:114
OPENDHT_PUBLIC Blob unpackBlob(msgpack::object &o)
InfoHash recipient
Definition: value.h:566
Definition: callbacks.h:34