Electroneum
p2p_protocol_defs.h
Go to the documentation of this file.
1 // Copyrights(c) 2017-2019, The Electroneum Project
2 // Copyrights(c) 2014-2017, 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 "serialization/keyvalue_serialization.h"
36 #include "net/net_utils_base.h"
37 #include "misc_language.h"
38 #include "cryptonote_config.h"
39 #ifdef ALLOW_DEBUG_COMMANDS
40 #include "crypto/crypto.h"
41 #endif
42 
43 namespace nodetool
44 {
45  typedef boost::uuids::uuid uuid;
46  typedef uint64_t peerid_type;
47 
48  static inline std::string peerid_to_string(peerid_type peer_id)
49  {
50  std::ostringstream s;
51  s << std::hex << peer_id;
52  return epee::string_tools::pad_string(s.str(), 16, '0', true);
53  }
54 
55 #pragma pack (push, 1)
56 
58  {
59  uint32_t ip;
60  uint32_t port;
61 
62  BEGIN_KV_SERIALIZE_MAP()
63  KV_SERIALIZE(ip)
64  KV_SERIALIZE(port)
65  END_KV_SERIALIZE_MAP()
66  };
67 
68  template<typename AddressType>
70  {
71  AddressType adr;
73  int64_t last_seen;
74 
75  BEGIN_KV_SERIALIZE_MAP()
76  KV_SERIALIZE(adr)
77  KV_SERIALIZE(id)
78  KV_SERIALIZE(last_seen)
79  END_KV_SERIALIZE_MAP()
80  };
81  typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry;
82 
83  template<typename AddressType>
85  {
86  AddressType adr;
88  int64_t first_seen;
89 
90  BEGIN_KV_SERIALIZE_MAP()
91  KV_SERIALIZE(adr)
92  KV_SERIALIZE(id)
93  KV_SERIALIZE(first_seen)
94  END_KV_SERIALIZE_MAP()
95  };
96  typedef anchor_peerlist_entry_base<epee::net_utils::network_address> anchor_peerlist_entry;
97 
98  template<typename AddressType>
100  {
101  AddressType adr;
103  bool is_income;
104 
105  BEGIN_KV_SERIALIZE_MAP()
106  KV_SERIALIZE(adr)
107  KV_SERIALIZE(id)
108  KV_SERIALIZE(is_income)
109  END_KV_SERIALIZE_MAP()
110  };
111  typedef connection_entry_base<epee::net_utils::network_address> connection_entry;
112 
113 #pragma pack(pop)
114 
115  inline
116  std::string print_peerlist_to_string(const std::list<peerlist_entry>& pl)
117  {
118  time_t now_time = 0;
119  time(&now_time);
120  std::stringstream ss;
121  ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
122  for(const peerlist_entry& pe: pl)
123  {
124  ss << pe.id << "\t" << pe.adr->str() << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl;
125  }
126  return ss.str();
127  }
128 
129 
131  {
132  BEGIN_KV_SERIALIZE_MAP()
133  KV_SERIALIZE(connections_count)
134  KV_SERIALIZE(handshake_interval)
135  KV_SERIALIZE(packet_max_size)
136  KV_SERIALIZE(config_id)
137  END_KV_SERIALIZE_MAP()
138 
139  uint32_t connections_count;
140  uint32_t connection_timeout;
141  uint32_t ping_connection_timeout;
142  uint32_t handshake_interval;
143  uint32_t packet_max_size;
144  uint32_t config_id;
145  uint32_t send_peerlist_sz;
146  };
147 
149  {
151  uint64_t local_time;
152  uint32_t my_port;
154 
155  BEGIN_KV_SERIALIZE_MAP()
156  KV_SERIALIZE_VAL_POD_AS_BLOB(network_id)
157  KV_SERIALIZE(peer_id)
158  KV_SERIALIZE(local_time)
159  KV_SERIALIZE(my_port)
160  END_KV_SERIALIZE_MAP()
161  };
162 
163 
164 #define P2P_COMMANDS_POOL_BASE 1000
165 
166  /************************************************************************/
167  /* */
168  /************************************************************************/
169  template<class t_playload_type>
171  {
172  const static int ID = P2P_COMMANDS_POOL_BASE + 1;
173 
174  struct request
175  {
177  t_playload_type payload_data;
178 
179  BEGIN_KV_SERIALIZE_MAP()
180  KV_SERIALIZE(node_data)
181  KV_SERIALIZE(payload_data)
182  END_KV_SERIALIZE_MAP()
183  };
184 
185  struct response
186  {
188  t_playload_type payload_data;
189  std::list<peerlist_entry> local_peerlist_new;
190 
191  BEGIN_KV_SERIALIZE_MAP()
192  KV_SERIALIZE(node_data)
193  KV_SERIALIZE(payload_data)
194  if (is_store)
195  {
196  // saving: save both, so old and new peers can understand it
197  KV_SERIALIZE(local_peerlist_new)
198  std::list<peerlist_entry_base<network_address_old>> local_peerlist;
199  for (const auto &p: this_ref.local_peerlist_new)
200  {
201  if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID)
202  {
203  const epee::net_utils::network_address &na = p.adr;
204  const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
205  local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen}));
206  }
207  else
208  MDEBUG("Not including in legacy peer list: " << p.adr.str());
209  }
210  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
211  }
212  else
213  {
214  // loading: load old list only if there is no new one
215  if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
216  {
217  std::list<peerlist_entry_base<network_address_old>> local_peerlist;
218  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
219  for (const auto &p: local_peerlist)
220  ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({new epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
221  }
222  }
223  END_KV_SERIALIZE_MAP()
224  };
225  };
226 
227 
228  /************************************************************************/
229  /* */
230  /************************************************************************/
231  template<class t_playload_type>
233  {
234  const static int ID = P2P_COMMANDS_POOL_BASE + 2;
235 
236  struct request
237  {
238  t_playload_type payload_data;
239  BEGIN_KV_SERIALIZE_MAP()
240  KV_SERIALIZE(payload_data)
241  END_KV_SERIALIZE_MAP()
242  };
243 
244  struct response
245  {
246  uint64_t local_time;
247  t_playload_type payload_data;
248  std::list<peerlist_entry> local_peerlist_new;
249 
250  BEGIN_KV_SERIALIZE_MAP()
251  KV_SERIALIZE(local_time)
252  KV_SERIALIZE(payload_data)
253  if (is_store)
254  {
255  // saving: save both, so old and new peers can understand it
256  KV_SERIALIZE(local_peerlist_new)
257  std::list<peerlist_entry_base<network_address_old>> local_peerlist;
258  for (const auto &p: this_ref.local_peerlist_new)
259  {
260  if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID)
261  {
262  const epee::net_utils::network_address &na = p.adr;
263  const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
264  local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen}));
265  }
266  else
267  MDEBUG("Not including in legacy peer list: " << p.adr.str());
268  }
269  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
270  }
271  else
272  {
273  // loading: load old list only if there is no new one
274  if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
275  {
276  std::list<peerlist_entry_base<network_address_old>> local_peerlist;
277  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
278  for (const auto &p: local_peerlist)
279  ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({new epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
280  }
281  }
282  END_KV_SERIALIZE_MAP()
283  };
284  };
285 
286  /************************************************************************/
287  /* */
288  /************************************************************************/
289 
291  {
292  /*
293  Used to make "callback" connection, to be sure that opponent node
294  have accessible connection point. Only other nodes can add peer to peerlist,
295  and ONLY in case when peer has accepted connection and answered to ping.
296  */
297  const static int ID = P2P_COMMANDS_POOL_BASE + 3;
298 
299 #define PING_OK_RESPONSE_STATUS_TEXT "OK"
300 
301  struct request
302  {
303  /*actually we don't need to send any real data*/
304 
305  BEGIN_KV_SERIALIZE_MAP()
306  END_KV_SERIALIZE_MAP()
307  };
308 
309  struct response
310  {
311  std::string status;
313 
314  BEGIN_KV_SERIALIZE_MAP()
315  KV_SERIALIZE(status)
316  KV_SERIALIZE(peer_id)
317  END_KV_SERIALIZE_MAP()
318  };
319  };
320 
321 
322 #ifdef ALLOW_DEBUG_COMMANDS
323  //These commands are considered as insecure, and made in debug purposes for a limited lifetime.
324  //Anyone who feel unsafe with this commands can disable the ALLOW_GET_STAT_COMMAND macro.
325 
326  struct proof_of_trust
327  {
328  peerid_type peer_id;
329  uint64_t time;
330  crypto::signature sign;
331 
332  BEGIN_KV_SERIALIZE_MAP()
333  KV_SERIALIZE(peer_id)
334  KV_SERIALIZE(time)
335  KV_SERIALIZE_VAL_POD_AS_BLOB(sign)
336  END_KV_SERIALIZE_MAP()
337  };
338 
339 
340  template<class payload_stat_info>
341  struct COMMAND_REQUEST_STAT_INFO_T
342  {
343  const static int ID = P2P_COMMANDS_POOL_BASE + 4;
344 
345  struct request
346  {
347  proof_of_trust tr;
348  BEGIN_KV_SERIALIZE_MAP()
349  KV_SERIALIZE(tr)
350  END_KV_SERIALIZE_MAP()
351  };
352 
353  struct response
354  {
355  std::string version;
356  std::string os_version;
357  uint64_t connections_count;
358  uint64_t incoming_connections_count;
359  payload_stat_info payload_info;
360 
361  BEGIN_KV_SERIALIZE_MAP()
362  KV_SERIALIZE(version)
363  KV_SERIALIZE(os_version)
364  KV_SERIALIZE(connections_count)
365  KV_SERIALIZE(incoming_connections_count)
366  KV_SERIALIZE(payload_info)
367  END_KV_SERIALIZE_MAP()
368  };
369  };
370 
371 
372  /************************************************************************/
373  /* */
374  /************************************************************************/
375  struct COMMAND_REQUEST_NETWORK_STATE
376  {
377  const static int ID = P2P_COMMANDS_POOL_BASE + 5;
378 
379  struct request
380  {
381  proof_of_trust tr;
382  BEGIN_KV_SERIALIZE_MAP()
383  KV_SERIALIZE(tr)
384  END_KV_SERIALIZE_MAP()
385  };
386 
387  struct response
388  {
389  std::list<peerlist_entry> local_peerlist_white;
390  std::list<peerlist_entry> local_peerlist_gray;
391  std::list<connection_entry> connections_list;
392  peerid_type my_id;
393  uint64_t local_time;
394  BEGIN_KV_SERIALIZE_MAP()
395  KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_white)
396  KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_gray)
397  KV_SERIALIZE_CONTAINER_POD_AS_BLOB(connections_list)
398  KV_SERIALIZE(my_id)
399  KV_SERIALIZE(local_time)
400  END_KV_SERIALIZE_MAP()
401  };
402  };
403 
404  /************************************************************************/
405  /* */
406  /************************************************************************/
407  struct COMMAND_REQUEST_PEER_ID
408  {
409  const static int ID = P2P_COMMANDS_POOL_BASE + 6;
410 
411  struct request
412  {
413  BEGIN_KV_SERIALIZE_MAP()
414  END_KV_SERIALIZE_MAP()
415  };
416 
417  struct response
418  {
419  peerid_type my_id;
420 
421  BEGIN_KV_SERIALIZE_MAP()
422  KV_SERIALIZE(my_id)
423  END_KV_SERIALIZE_MAP()
424  };
425  };
426 
427  /************************************************************************/
428  /* */
429  /************************************************************************/
430  struct COMMAND_REQUEST_SUPPORT_FLAGS
431  {
432  const static int ID = P2P_COMMANDS_POOL_BASE + 7;
433 
434  struct request
435  {
436  BEGIN_KV_SERIALIZE_MAP()
437  END_KV_SERIALIZE_MAP()
438  };
439 
440  struct response
441  {
442  uint32_t support_flags;
443 
444  BEGIN_KV_SERIALIZE_MAP()
445  KV_SERIALIZE(support_flags)
446  END_KV_SERIALIZE_MAP()
447  };
448  };
449 
450 #endif
451 
452 
453  inline crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust& pot)
454  {
455  std::string s;
456  s.append(reinterpret_cast<const char*>(&pot.peer_id), sizeof(pot.peer_id));
457  s.append(reinterpret_cast<const char*>(&pot.time), sizeof(pot.time));
458  return crypto::cn_fast_hash(s.data(), s.size());
459  }
460 
461 }
462 
463 
464 
std::list< peerlist_entry > local_peerlist_new
Definition: p2p_protocol_defs.h:189
#define tr(x)
Definition: common_defines.h:4
int64_t last_seen
Definition: p2p_protocol_defs.h:73
Definition: p2p_protocol_defs.h:185
t_playload_type payload_data
Definition: p2p_protocol_defs.h:247
crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust &pot)
Definition: p2p_protocol_defs.h:453
boost::uuids::uuid uuid
Definition: net_node_common.h:41
AddressType adr
Definition: p2p_protocol_defs.h:101
IntFormatSpec< int, TypeSpec< 'x'> > hex(int value)
AddressType adr
Definition: p2p_protocol_defs.h:71
basic_node_data node_data
Definition: p2p_protocol_defs.h:187
void serialize(Archive &a, std::unordered_map< h_key, hval > &x, const boost::serialization::version_type ver)
Definition: unordered_containers_boost_serialization.h:127
#define P2P_COMMANDS_POOL_BASE
Definition: p2p_protocol_defs.h:164
Definition: p2p_protocol_defs.h:236
uint64_t local_time
Definition: p2p_protocol_defs.h:151
Definition: p2p_protocol_defs.h:309
t_playload_type payload_data
Definition: p2p_protocol_defs.h:188
Definition: p2p_protocol_defs.h:244
Definition: p2p_protocol_defs.h:57
peerid_type peer_id
Definition: p2p_protocol_defs.h:312
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
Definition: p2p_protocol_defs.h:81
peerid_type id
Definition: p2p_protocol_defs.h:102
Definition: p2p_protocol_defs.h:290
AddressType adr
Definition: p2p_protocol_defs.h:86
Definition: p2p_protocol_defs.h:170
basic_node_data node_data
Definition: p2p_protocol_defs.h:176
uint32_t my_port
Definition: p2p_protocol_defs.h:152
int64_t first_seen
Definition: p2p_protocol_defs.h:88
static std::string peerid_to_string(peerid_type peer_id)
Definition: p2p_protocol_defs.h:48
peerid_type id
Definition: p2p_protocol_defs.h:72
Definition: p2p_protocol_defs.h:99
time_t time
Definition: blockchain.cpp:89
t_playload_type payload_data
Definition: p2p_protocol_defs.h:177
uint32_t port
Definition: p2p_protocol_defs.h:60
peerid_type id
Definition: p2p_protocol_defs.h:87
bool is_income
Definition: p2p_protocol_defs.h:103
std::string print_peerlist_to_string(const std::list< peerlist_entry > &pl)
Definition: p2p_protocol_defs.h:116
Definition: p2p_protocol_defs.h:84
Definition: p2p_protocol_defs.h:148
uint64_t peerid_type
Definition: p2p_protocol_defs.h:46
void cn_fast_hash(const void *data, size_t length, char *hash)
Definition: hash.c:47
uint8_t version
Definition: blockchain.cpp:86
std::list< peerlist_entry > local_peerlist_new
Definition: p2p_protocol_defs.h:248
t_playload_type payload_data
Definition: p2p_protocol_defs.h:238
Definition: connection_basic.cpp:91
POD_CLASS signature
Definition: crypto.h:99
peerid_type peer_id
Definition: p2p_protocol_defs.h:153
std::string status
Definition: p2p_protocol_defs.h:311
uuid network_id
Definition: p2p_protocol_defs.h:150
Definition: net_node.h:60
uint32_t ip
Definition: p2p_protocol_defs.h:59
Definition: p2p_protocol_defs.h:174
POD_CLASS hash
Definition: hash.h:46
Definition: p2p_protocol_defs.h:232
Definition: p2p_protocol_defs.h:301
Definition: p2p_protocol_defs.h:130
#define s(x, c)
Definition: aesb.c:46
uint64_t local_time
Definition: p2p_protocol_defs.h:246
Definition: p2p_protocol_defs.h:69