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