Electroneum
Loading...
Searching...
No Matches
p2p_protocol_defs.h
Go to the documentation of this file.
1// Copyrights(c) 2017-2021, The Electroneum Project
2// Copyrights(c) 2014-2019, The Monero Project
3//
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without modification, are
7// permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice, this list of
10// conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13// of conditions and the following disclaimer in the documentation and/or other
14// materials provided with the distribution.
15//
16// 3. Neither the name of the copyright holder nor the names of its contributors may be
17// used to endorse or promote products derived from this software without specific
18// prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31
32#pragma once
33
34#include <boost/uuid/uuid.hpp>
35#include <boost/serialization/version.hpp>
37#include "net/net_utils_base.h"
38#include "net/tor_address.h" // needed for serialization
39#include "net/i2p_address.h" // needed for serialization
40#include "misc_language.h"
41#include "string_tools.h"
42#include "time_helper.h"
43#include "cryptonote_config.h"
44#ifdef ALLOW_DEBUG_COMMANDS
45#include "crypto/crypto.h"
46#endif
47
48namespace nodetool
49{
50 typedef boost::uuids::uuid uuid;
52
53 static inline std::string peerid_to_string(peerid_type peer_id)
54 {
55 std::ostringstream s;
56 s << std::hex << peer_id;
57 return epee::string_tools::pad_string(s.str(), 16, '0', true);
58 }
59
60#pragma pack (push, 1)
61
72
73 template<typename AddressType>
91 typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry;
92
93 template<typename AddressType>
106 typedef anchor_peerlist_entry_base<epee::net_utils::network_address> anchor_peerlist_entry;
107
108 template<typename AddressType>
121 typedef connection_entry_base<epee::net_utils::network_address> connection_entry;
122
123#pragma pack(pop)
124
125 inline
126 std::string print_peerlist_to_string(const std::vector<peerlist_entry>& pl)
127 {
128 time_t now_time = 0;
129 time(&now_time);
130 std::stringstream ss;
131 ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
132 for(const peerlist_entry& pe: pl)
133 {
134 ss << pe.id << "\t" << pe.adr.str()
135 << " \trpc port " << (pe.rpc_port > 0 ? std::to_string(pe.rpc_port) : "-")
136 << " \tpruning seed " << pe.pruning_seed
137 << " \tlast_seen: " << (pe.last_seen == 0 ? std::string("never") : epee::misc_utils::get_time_interval_string(now_time - pe.last_seen))
138 << std::endl;
139 }
140 return ss.str();
141 }
142
143
163
180
181
182#define P2P_COMMANDS_POOL_BASE 1000
183
184 /************************************************************************/
185 /* */
186 /************************************************************************/
187 template<class t_playload_type>
189 {
190 const static int ID = P2P_COMMANDS_POOL_BASE + 1;
191
202 typedef epee::misc_utils::struct_init<request_t> request;
203
205 {
207 t_playload_type payload_data;
208 std::vector<peerlist_entry> local_peerlist_new;
209
213 if (is_store)
214 {
215 // saving: save both, so old and new peers can understand it
217 std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
218 for (const auto &p: this_ref.local_peerlist_new)
219 {
220 if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
221 {
222 const epee::net_utils::network_address &na = p.adr;
224 local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen, p.pruning_seed, p.rpc_port}));
225 }
226 else
227 MDEBUG("Not including in legacy peer list: " << p.adr.str());
228 }
229 epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
230 }
231 else
232 {
233 // loading: load old list only if there is no new one
234 if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
235 {
236 std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
237 epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
238 for (const auto &p: local_peerlist)
239 ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen, p.pruning_seed, p.rpc_port}));
240 }
241 }
243 };
245 };
246
247
248 /************************************************************************/
249 /* */
250 /************************************************************************/
251 template<class t_playload_type>
253 {
254 const static int ID = P2P_COMMANDS_POOL_BASE + 2;
255
263 typedef epee::misc_utils::struct_init<request_t> request;
264
266 {
268 t_playload_type payload_data;
269 std::vector<peerlist_entry> local_peerlist_new;
270
274 if (is_store)
275 {
276 // saving: save both, so old and new peers can understand it
278 std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
279 for (const auto &p: this_ref.local_peerlist_new)
280 {
281 if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
282 {
283 const epee::net_utils::network_address &na = p.adr;
285 local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen}));
286 }
287 else
288 MDEBUG("Not including in legacy peer list: " << p.adr.str());
289 }
290 epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
291 }
292 else
293 {
294 // loading: load old list only if there is no new one
295 if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
296 {
297 std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
298 epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
299 for (const auto &p: local_peerlist)
300 ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
301 }
302 }
304 };
306 };
307
308 /************************************************************************/
309 /* */
310 /************************************************************************/
311
313 {
314 /*
315 Used to make "callback" connection, to be sure that opponent node
316 have accessible connection point. Only other nodes can add peer to peerlist,
317 and ONLY in case when peer has accepted connection and answered to ping.
318 */
319 const static int ID = P2P_COMMANDS_POOL_BASE + 3;
320
321#define PING_OK_RESPONSE_STATUS_TEXT "OK"
322
324 {
325 /*actually we don't need to send any real data*/
326
329 };
331
342 typedef epee::misc_utils::struct_init<response_t> response;
343 };
344
345
346#ifdef ALLOW_DEBUG_COMMANDS
347 //These commands are considered as insecure, and made in debug purposes for a limited lifetime.
348 //Anyone who feel unsafe with this commands can disable the ALLOW_GET_STAT_COMMAND macro.
349
350 struct proof_of_trust
351 {
352 peerid_type peer_id;
355
357 KV_SERIALIZE(peer_id)
361 };
362
363
364 template<class payload_stat_info>
365 struct COMMAND_REQUEST_STAT_INFO_T
366 {
367 const static int ID = P2P_COMMANDS_POOL_BASE + 4;
368
369 struct request_t
370 {
371 proof_of_trust tr;
375 };
376 typedef epee::misc_utils::struct_init<request_t> request;
377
378 struct response_t
379 {
380 std::string version;
381 std::string os_version;
382 uint64_t connections_count;
383 uint64_t incoming_connections_count;
384 payload_stat_info payload_info;
385
388 KV_SERIALIZE(os_version)
389 KV_SERIALIZE(connections_count)
390 KV_SERIALIZE(incoming_connections_count)
391 KV_SERIALIZE(payload_info)
393 };
394 typedef epee::misc_utils::struct_init<response_t> response;
395 };
396
397
398 /************************************************************************/
399 /* */
400 /************************************************************************/
401 struct COMMAND_REQUEST_NETWORK_STATE
402 {
403 const static int ID = P2P_COMMANDS_POOL_BASE + 5;
404
405 struct request_t
406 {
407 proof_of_trust tr;
411 };
412 typedef epee::misc_utils::struct_init<request_t> request;
413
414 struct response_t
415 {
416 std::vector<peerlist_entry> local_peerlist_white;
417 std::vector<peerlist_entry> local_peerlist_gray;
418 std::vector<connection_entry> connections_list;
419 peerid_type my_id;
420 uint64_t local_time;
422 KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_white)
423 KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_gray)
424 KV_SERIALIZE_CONTAINER_POD_AS_BLOB(connections_list)
425 KV_SERIALIZE(my_id)
426 KV_SERIALIZE(local_time)
428 };
429 typedef epee::misc_utils::struct_init<response_t> response;
430 };
431
432 /************************************************************************/
433 /* */
434 /************************************************************************/
435 struct COMMAND_REQUEST_PEER_ID
436 {
437 const static int ID = P2P_COMMANDS_POOL_BASE + 6;
438
439 struct request_t
440 {
443 };
444 typedef epee::misc_utils::struct_init<request_t> request;
445
446 struct response_t
447 {
448 peerid_type my_id;
449
451 KV_SERIALIZE(my_id)
453 };
454 typedef epee::misc_utils::struct_init<response_t> response;
455 };
456
457 /************************************************************************/
458 /* */
459 /************************************************************************/
460 struct COMMAND_REQUEST_SUPPORT_FLAGS
461 {
462 const static int ID = P2P_COMMANDS_POOL_BASE + 7;
463
464 struct request_t
465 {
468 };
469 typedef epee::misc_utils::struct_init<request_t> request;
470
471 struct response_t
472 {
473 uint32_t support_flags;
474
476 KV_SERIALIZE(support_flags)
478 };
479 typedef epee::misc_utils::struct_init<response_t> response;
480 };
481
482#endif
483
484
485 inline crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust& pot)
486 {
487 std::string s;
488 s.append(reinterpret_cast<const char*>(&pot.peer_id), sizeof(pot.peer_id));
489 s.append(reinterpret_cast<const char*>(&pot.time), sizeof(pot.time));
490 return crypto::cn_fast_hash(s.data(), s.size());
491 }
492
493}
else if(0==res)
uint8_t version
time_t time
static constexpr address_type get_type_id() noexcept
#define tr(x)
#define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble)
#define KV_SERIALIZE(varialble)
#define KV_SERIALIZE_OPT(variable, default_value)
#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble)
#define END_KV_SERIALIZE_MAP()
#define BEGIN_KV_SERIALIZE_MAP()
#define MDEBUG(x)
Definition misc_log_ex.h:76
POD_CLASS signature
Definition crypto.h:108
void cn_fast_hash(const void *data, size_t length, char *hash)
POD_CLASS hash
Definition hash.h:50
std::string get_time_interval_string(const time_t &time_)
std::string pad_string(std::string s, size_t n, char c=' ', bool prepend=false)
connection_entry_base< epee::net_utils::network_address > connection_entry
boost::uuids::uuid uuid
uint64_t peerid_type
std::string print_peerlist_to_string(const std::vector< peerlist_entry > &pl)
crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust &pot)
anchor_peerlist_entry_base< epee::net_utils::network_address > anchor_peerlist_entry
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
#define P2P_COMMANDS_POOL_BASE
unsigned short uint16_t
Definition stdint.h:125
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
std::vector< peerlist_entry > local_peerlist_new
epee::misc_utils::struct_init< response_t > response
epee::misc_utils::struct_init< request_t > request
epee::misc_utils::struct_init< response_t > response
std::vector< peerlist_entry > local_peerlist_new
epee::misc_utils::struct_init< response_t > response
int64_t first_seen
epee::net_utils::network_address adr
peerid_type id
bool is_income
epee::net_utils::network_address adr
peerid_type id
uint32_t pruning_seed
epee::net_utils::network_address adr
uint16_t rpc_port
peerid_type id
int64_t last_seen