My Project 4.4.0
C++ Distributed Hash Table
Loading...
Searching...
No Matches
default_types.h
1// Copyright (c) 2014-2026 Savoir-faire Linux Inc.
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "value.h"
6#include "sockaddr.h"
7
8namespace dht {
9enum class ImStatus : uint8_t { NONE = 0, TYPING, RECEIVED, READ };
10}
11MSGPACK_ADD_ENUM(dht::ImStatus)
12
13namespace dht {
14
15class OPENDHT_PUBLIC DhtMessage : public Value::Serializable<DhtMessage>
16{
17public:
18 static const ValueType TYPE;
19
20 DhtMessage(const std::string& s = {}, const Blob& msg = {})
21 : service(s)
22 , data(msg)
23 {}
24
25 std::string getService() const { return service; }
26
27 static Value::Filter getFilter() { return {}; }
28
29 static bool storePolicy(InfoHash key, std::shared_ptr<Value>& value, const InfoHash& from, const SockAddr&);
30
31 static Value::Filter ServiceFilter(const std::string& s);
32
34 friend std::ostream& operator<<(std::ostream&, const DhtMessage&);
35
36 std::string service;
37 Blob data;
38 MSGPACK_DEFINE(service, data)
39};
40
41template<typename T>
43{
44private:
45 using BaseClass = Value::Serializable<T>;
46
47public:
48 virtual void unpackValue(const Value& v) override
49 {
50 if (v.owner) {
51 owner = v.owner;
52 from = v.owner->getId();
53 } else {
54 throw std::runtime_error("Value has no owner");
55 }
56 BaseClass::unpackValue(v);
57 }
58
59 static Value::Filter getFilter()
60 {
61 return [](const Value& v) {
62 return v.isSigned();
63 };
64 }
65
66 Sp<crypto::PublicKey> owner;
67 dht::InfoHash from;
68};
69
70template<typename T>
71class EncryptedValue : public SignedValue<T>
72{
73public:
74 using BaseClass = SignedValue<T>;
75
76public:
77 virtual void unpackValue(const Value& v) override
78 {
79 if (!v.recipient) {
80 throw std::runtime_error("Value has no recipient");
81 }
82 to = v.recipient;
83 BaseClass::unpackValue(v);
84 }
85
86 static Value::Filter getFilter()
87 {
88 return Value::Filter::chain(BaseClass::getFilter(),
89 [](const Value& v) { return static_cast<bool>(v.recipient); });
90 }
91
92 dht::InfoHash to;
93};
94
95class OPENDHT_PUBLIC ImMessage : public SignedValue<ImMessage>
96{
97private:
98 using BaseClass = SignedValue<ImMessage>;
99
100public:
101 static const ValueType TYPE;
102
103 ImMessage() {}
104 ImMessage(dht::Value::Id id, std::string&& m, long d = 0)
105 : id(id)
106 , msg(std::move(m))
107 , date(d)
108 {}
109 ImMessage(dht::Value::Id id, std::string&& dt, std::string&& m, long d = 0)
110 : id(id)
111 , msg(std::move(m))
112 , datatype(std::move(dt))
113 , date(d)
114 {}
115 ImMessage(dht::Value::Id id, std::string&& dt, std::string&& m, std::map<std::string, std::string>&& md, long d = 0)
116 : id(id)
117 , msg(std::move(m))
118 , datatype(std::move(dt))
119 , metadatas(std::move(md))
120 , date(d)
121 {}
122
123 virtual void unpackValue(const Value& v) override
124 {
125 to = v.recipient;
126 SignedValue::unpackValue(v);
127 }
128
129 static Value::Filter getFilter() { return SignedValue::getFilter(); }
130
131 dht::InfoHash to;
132 dht::Value::Id id {0};
133 std::string msg;
134 std::string datatype;
135 std::map<std::string, std::string> metadatas;
136 long date {0};
137 ImStatus status {ImStatus::NONE};
138
139 MSGPACK_DEFINE_MAP(id, msg, date, status, datatype, metadatas)
140};
141
142class OPENDHT_PUBLIC TrustRequest : public EncryptedValue<TrustRequest>
143{
144private:
145 using BaseClass = EncryptedValue<TrustRequest>;
146
147public:
148 static const ValueType TYPE;
149
150 TrustRequest() {}
151 TrustRequest(std::string s, std::string ci = {})
152 : service(s)
153 , conversationId(ci)
154 {}
155 TrustRequest(std::string s, std::string ci, const Blob& d)
156 : service(s)
157 , conversationId(ci)
158 , payload(d)
159 {}
160
161 static Value::Filter getFilter() { return EncryptedValue::getFilter(); }
162 virtual void unpackValue(const dht::Value& v) override
163 {
164 BaseClass::unpackValue(v);
165 id = v.id;
166 }
167
168 dht::Value::Id id {0};
169 std::string service;
170 std::string conversationId;
171 Blob payload;
172 bool confirm {false};
173 MSGPACK_DEFINE_MAP(service, conversationId, payload, confirm)
174};
175
176class OPENDHT_PUBLIC IceCandidates : public EncryptedValue<IceCandidates>
177{
178private:
179 using BaseClass = EncryptedValue<IceCandidates>;
180
181public:
182 static const ValueType TYPE;
183
184 IceCandidates() {}
185 IceCandidates(Value::Id msg_id, Blob ice)
186 : id(msg_id)
187 , ice_data(ice)
188 {}
189
190 static Value::Filter getFilter() { return EncryptedValue::getFilter(); }
191
192 template<typename Packer>
193 void msgpack_pack(Packer& pk) const
194 {
195 pk.pack_array(2);
196 pk.pack(id);
197#if 1
198 pk.pack_bin(ice_data.size());
199 pk.pack_bin_body((const char*) ice_data.data(), ice_data.size());
200#else
201 // hack for backward compatibility with old opendht compiled with msgpack 1.0
202 // remove when enough people have moved to new versions
203 pk.pack_array(ice_data.size());
204 for (uint8_t b : ice_data)
205 pk.pack(b);
206#endif
207 }
208
209 virtual void msgpack_unpack(const msgpack::object& o)
210 {
211 if (o.type != msgpack::type::ARRAY)
212 throw msgpack::type_error();
213 if (o.via.array.size < 2)
214 throw msgpack::type_error();
215 id = o.via.array.ptr[0].as<Value::Id>();
216 ice_data = unpackBlob(o.via.array.ptr[1]);
217 }
218
219 Value::Id id {0};
220 Blob ice_data;
221};
222
223/* "Peer" announcement
224 */
225class OPENDHT_PUBLIC IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement>
226{
227private:
229
230public:
231 static const ValueType TYPE;
232
233 IpServiceAnnouncement(sa_family_t family = AF_UNSPEC, in_port_t p = 0)
234 {
235 addr.setFamily(family);
236 addr.setPort(p);
237 }
238
239 IpServiceAnnouncement(const SockAddr& sa)
240 : addr(sa)
241 {}
242
243 IpServiceAnnouncement(const Blob& b) { msgpack_unpack(unpackMsg(b).get()); }
244
245 template<typename Packer>
246 void msgpack_pack(Packer& pk) const
247 {
248 pk.pack_bin(addr.getLength());
249 pk.pack_bin_body((const char*) addr.get(), addr.getLength());
250 }
251
252 virtual void msgpack_unpack(const msgpack::object& o)
253 {
254 if (o.type == msgpack::type::BIN)
255 addr = {(sockaddr*) o.via.bin.ptr, (socklen_t) o.via.bin.size};
256 else
257 throw msgpack::type_error();
258 }
259
260 in_port_t getPort() const { return addr.getPort(); }
261 void setPort(in_port_t p) { addr.setPort(p); }
262
263 const SockAddr& getPeerAddr() const { return addr; }
264
265 virtual const ValueType& getType() const { return TYPE; }
266
267 static bool storePolicy(InfoHash, std::shared_ptr<Value>&, const InfoHash&, const SockAddr&);
268
270 friend std::ostream& operator<<(std::ostream&, const IpServiceAnnouncement&);
271
272private:
273 SockAddr addr;
274};
275
276OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
277
278OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
279
280} // namespace dht
friend std::ostream & operator<<(std::ostream &, const DhtMessage &)
friend std::ostream & operator<<(std::ostream &, const IpServiceAnnouncement &)
std::string service
Value ID of the trust request, used for deserialization only.
OPENDHT_PUBLIC Blob unpackBlob(const msgpack::object &o)
std::vector< uint8_t > Blob
Definition utils.h:166
std::shared_ptr< crypto::PublicKey > owner
Definition value.h:643
InfoHash recipient
Definition value.h:650