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