My Project 3.7.1
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
163 std::string service;
164 std::string conversationId;
165 Blob payload;
166 bool confirm {false};
167 MSGPACK_DEFINE_MAP(service, conversationId, payload, confirm)
168};
169
170class OPENDHT_PUBLIC IceCandidates : public EncryptedValue<IceCandidates>
171{
172private:
173 using BaseClass = EncryptedValue<IceCandidates>;
174
175public:
176 static const ValueType TYPE;
177
178 IceCandidates() {}
179 IceCandidates(Value::Id msg_id, Blob ice)
180 : id(msg_id)
181 , ice_data(ice)
182 {}
183
184 static Value::Filter getFilter() { return EncryptedValue::getFilter(); }
185
186 template<typename Packer>
187 void msgpack_pack(Packer& pk) const
188 {
189 pk.pack_array(2);
190 pk.pack(id);
191#if 1
192 pk.pack_bin(ice_data.size());
193 pk.pack_bin_body((const char*) ice_data.data(), ice_data.size());
194#else
195 // hack for backward compatibility with old opendht compiled with msgpack 1.0
196 // remove when enough people have moved to new versions
197 pk.pack_array(ice_data.size());
198 for (uint8_t b : ice_data)
199 pk.pack(b);
200#endif
201 }
202
203 virtual void msgpack_unpack(const msgpack::object& o)
204 {
205 if (o.type != msgpack::type::ARRAY)
206 throw msgpack::type_error();
207 if (o.via.array.size < 2)
208 throw msgpack::type_error();
209 id = o.via.array.ptr[0].as<Value::Id>();
210 ice_data = unpackBlob(o.via.array.ptr[1]);
211 }
212
213 Value::Id id {0};
214 Blob ice_data;
215};
216
217/* "Peer" announcement
218 */
219class OPENDHT_PUBLIC IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement>
220{
221private:
223
224public:
225 static const ValueType TYPE;
226
227 IpServiceAnnouncement(sa_family_t family = AF_UNSPEC, in_port_t p = 0)
228 {
229 addr.setFamily(family);
230 addr.setPort(p);
231 }
232
233 IpServiceAnnouncement(const SockAddr& sa)
234 : addr(sa)
235 {}
236
237 IpServiceAnnouncement(const Blob& b) { msgpack_unpack(unpackMsg(b).get()); }
238
239 template<typename Packer>
240 void msgpack_pack(Packer& pk) const
241 {
242 pk.pack_bin(addr.getLength());
243 pk.pack_bin_body((const char*) addr.get(), addr.getLength());
244 }
245
246 virtual void msgpack_unpack(const msgpack::object& o)
247 {
248 if (o.type == msgpack::type::BIN)
249 addr = {(sockaddr*) o.via.bin.ptr, (socklen_t) o.via.bin.size};
250 else
251 throw msgpack::type_error();
252 }
253
254 in_port_t getPort() const { return addr.getPort(); }
255 void setPort(in_port_t p) { addr.setPort(p); }
256
257 const SockAddr& getPeerAddr() const { return addr; }
258
259 virtual const ValueType& getType() const { return TYPE; }
260
261 static bool storePolicy(InfoHash, std::shared_ptr<Value>&, const InfoHash&, const SockAddr&);
262
264 friend std::ostream& operator<<(std::ostream&, const IpServiceAnnouncement&);
265
266private:
267 SockAddr addr;
268};
269
270OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
271
272OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
273
274} // namespace dht
friend std::ostream & operator<<(std::ostream &, const DhtMessage &)
friend std::ostream & operator<<(std::ostream &, const IpServiceAnnouncement &)
OPENDHT_PUBLIC Blob unpackBlob(const msgpack::object &o)
std::vector< uint8_t > Blob
Definition utils.h:156
std::shared_ptr< crypto::PublicKey > owner
Definition value.h:632
InfoHash recipient
Definition value.h:639