Electroneum
nodetool::peerlist_manager Class Reference

#include <net_peerlist.h>

Public Member Functions

bool init (peerlist_types &&peers, bool allow_local_ip)
 
size_t get_white_peers_count ()
 
size_t get_gray_peers_count ()
 
bool merge_peerlist (const std::vector< peerlist_entry > &outer_bs)
 
bool get_peerlist_head (std::vector< peerlist_entry > &bs_head, bool anonymize, uint32_t depth=P2P_DEFAULT_PEERS_IN_HANDSHAKE)
 
void get_peerlist (std::vector< peerlist_entry > &pl_gray, std::vector< peerlist_entry > &pl_white)
 
void get_peerlist (peerlist_types &peers)
 
bool get_white_peer_by_index (peerlist_entry &p, size_t i)
 
bool get_gray_peer_by_index (peerlist_entry &p, size_t i)
 
template<typename F >
bool foreach (bool white, const F &f)
 
bool append_with_peer_white (const peerlist_entry &pr)
 
bool append_with_peer_gray (const peerlist_entry &pr)
 
bool append_with_peer_anchor (const anchor_peerlist_entry &ple)
 
bool set_peer_just_seen (peerid_type peer, const epee::net_utils::network_address &addr, uint32_t pruning_seed, uint16_t rpc_port)
 
bool set_peer_unreachable (const peerlist_entry &pr)
 
bool is_host_allowed (const epee::net_utils::network_address &address)
 
bool get_random_gray_peer (peerlist_entry &pe)
 
bool remove_from_peer_gray (const peerlist_entry &pe)
 
bool get_and_empty_anchor_peerlist (std::vector< anchor_peerlist_entry > &apl)
 
bool remove_from_peer_anchor (const epee::net_utils::network_address &addr)
 
bool remove_from_peer_white (const peerlist_entry &pe)
 

Friends

class boost::serialization::access
 

Detailed Description

Definition at line 99 of file net_peerlist.h.

Member Function Documentation

◆ append_with_peer_anchor()

bool nodetool::peerlist_manager::append_with_peer_anchor ( const anchor_peerlist_entry ple)
inline

Definition at line 403 of file net_peerlist.h.

404  {
405  TRY_ENTRY();
406 
407  CRITICAL_REGION_LOCAL(m_peerlist_lock);
408 
409  auto by_addr_it_anchor = m_peers_anchor.get<by_addr>().find(ple.adr);
410 
411  if(by_addr_it_anchor == m_peers_anchor.get<by_addr>().end()) {
412  m_peers_anchor.insert(ple);
413  }
414 
415  return true;
416 
417  CATCH_ENTRY_L0("peerlist_manager::append_with_peer_anchor()", false);
418  }
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ append_with_peer_gray()

bool nodetool::peerlist_manager::append_with_peer_gray ( const peerlist_entry pr)
inline

Definition at line 368 of file net_peerlist.h.

369  {
370  TRY_ENTRY();
371  if(!is_host_allowed(ple.adr))
372  return true;
373 
374  CRITICAL_REGION_LOCAL(m_peerlist_lock);
375  //find in white list
376  auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
377  if(by_addr_it_wt != m_peers_white.get<by_addr>().end())
378  return true;
379 
380  //update gray list
381  auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
382  if(by_addr_it_gr == m_peers_gray.get<by_addr>().end())
383  {
384  //put new record into white list
385  m_peers_gray.insert(ple);
386  trim_gray_peerlist();
387  }else
388  {
389  //update record in gray list
390  peerlist_entry new_ple = ple;
391  if (by_addr_it_gr->pruning_seed && ple.pruning_seed == 0) // guard against older nodes not passing pruning info around
392  new_ple.pruning_seed = by_addr_it_gr->pruning_seed;
393  if (by_addr_it_gr->rpc_port && ple.rpc_port == 0) // guard against older nodes not passing RPC port around
394  new_ple.rpc_port = by_addr_it_gr->rpc_port;
395  new_ple.last_seen = by_addr_it_gr->last_seen; // do not overwrite the last seen timestamp, incoming peer list are untrusted
396  m_peers_gray.replace(by_addr_it_gr, new_ple);
397  }
398  return true;
399  CATCH_ENTRY_L0("peerlist_manager::append_with_peer_gray()", false);
400  }
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
bool is_host_allowed(const epee::net_utils::network_address &address)
Definition: net_peerlist.h:254
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ append_with_peer_white()

bool nodetool::peerlist_manager::append_with_peer_white ( const peerlist_entry pr)
inline

Definition at line 332 of file net_peerlist.h.

333  {
334  TRY_ENTRY();
335  if(!is_host_allowed(ple.adr))
336  return true;
337 
338  CRITICAL_REGION_LOCAL(m_peerlist_lock);
339  //find in white list
340  auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
341  if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
342  {
343  //put new record into white list
344  m_peers_white.insert(ple);
345  trim_white_peerlist();
346  }else
347  {
348  //update record in white list
349  peerlist_entry new_ple = ple;
350  if (by_addr_it_wt->pruning_seed && ple.pruning_seed == 0) // guard against older nodes not passing pruning info around
351  new_ple.pruning_seed = by_addr_it_wt->pruning_seed;
352  if (by_addr_it_wt->rpc_port && ple.rpc_port == 0) // guard against older nodes not passing RPC port around
353  new_ple.rpc_port = by_addr_it_wt->rpc_port;
354  new_ple.last_seen = by_addr_it_wt->last_seen; // do not overwrite the last seen timestamp, incoming peer list are untrusted
355  m_peers_white.replace(by_addr_it_wt, new_ple);
356  }
357  //remove from gray list, if need
358  auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
359  if(by_addr_it_gr != m_peers_gray.get<by_addr>().end())
360  {
361  m_peers_gray.erase(by_addr_it_gr);
362  }
363  return true;
364  CATCH_ENTRY_L0("peerlist_manager::append_with_peer_white()", false);
365  }
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
bool is_host_allowed(const epee::net_utils::network_address &address)
Definition: net_peerlist.h:254
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ foreach()

template<typename F >
bool nodetool::peerlist_manager::foreach ( bool  white,
const F f 
)
inline

Definition at line 305 of file net_peerlist.h.

306  {
307  CRITICAL_REGION_LOCAL(m_peerlist_lock);
308  peers_indexed::index<by_time>::type& by_time_index = white ? m_peers_white.get<by_time>() : m_peers_gray.get<by_time>();
309  for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
310  if (!f(vl))
311  return false;
312  return true;
313  }
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228

◆ get_and_empty_anchor_peerlist()

bool nodetool::peerlist_manager::get_and_empty_anchor_peerlist ( std::vector< anchor_peerlist_entry > &  apl)
inline

Definition at line 478 of file net_peerlist.h.

479  {
480  TRY_ENTRY();
481 
482  CRITICAL_REGION_LOCAL(m_peerlist_lock);
483 
484  auto begin = m_peers_anchor.get<by_time>().begin();
485  auto end = m_peers_anchor.get<by_time>().end();
486 
487  std::for_each(begin, end, [&apl](const anchor_peerlist_entry &a) {
488  apl.push_back(a);
489  });
490 
491  m_peers_anchor.get<by_time>().clear();
492 
493  return true;
494 
495  CATCH_ENTRY_L0("peerlist_manager::get_and_empty_anchor_peerlist()", false);
496  }
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
anchor_peerlist_entry_base< epee::net_utils::network_address > anchor_peerlist_entry
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ get_gray_peer_by_index()

bool nodetool::peerlist_manager::get_gray_peer_by_index ( peerlist_entry p,
size_t  i 
)
inline

Definition at line 242 of file net_peerlist.h.

243  {
244  CRITICAL_REGION_LOCAL(m_peerlist_lock);
245  if(i >= m_peers_gray.size())
246  return false;
247 
248  peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
249  p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
250  return true;
251  }
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
t_iterator move_it_backward(t_iterator it, size_t count)
Definition: misc_language.h:73
Here is the call graph for this function:

◆ get_gray_peers_count()

size_t nodetool::peerlist_manager::get_gray_peers_count ( )
inline

Definition at line 104 of file net_peerlist.h.

104 {CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_gray.size();}
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228

◆ get_peerlist() [1/2]

void nodetool::peerlist_manager::get_peerlist ( std::vector< peerlist_entry > &  pl_gray,
std::vector< peerlist_entry > &  pl_white 
)

Definition at line 273 of file net_peerlist.cpp.

274  {
275  CRITICAL_REGION_LOCAL(m_peerlist_lock);
276  copy_peers(pl_gray, m_peers_gray.get<by_addr>());
277  copy_peers(pl_white, m_peers_white.get<by_addr>());
278  }
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228

◆ get_peerlist() [2/2]

void nodetool::peerlist_manager::get_peerlist ( peerlist_types peers)

Definition at line 280 of file net_peerlist.cpp.

281  {
282  CRITICAL_REGION_LOCAL(m_peerlist_lock);
283  peers.white.reserve(peers.white.size() + m_peers_white.size());
284  peers.gray.reserve(peers.gray.size() + m_peers_gray.size());
285  peers.anchor.reserve(peers.anchor.size() + m_peers_anchor.size());
286 
287  copy_peers(peers.white, m_peers_white.get<by_addr>());
288  copy_peers(peers.gray, m_peers_gray.get<by_addr>());
289  copy_peers(peers.anchor, m_peers_anchor.get<by_addr>());
290  }
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228

◆ get_peerlist_head()

bool nodetool::peerlist_manager::get_peerlist_head ( std::vector< peerlist_entry > &  bs_head,
bool  anonymize,
uint32_t  depth = P2P_DEFAULT_PEERS_IN_HANDSHAKE 
)
inline

Definition at line 267 of file net_peerlist.h.

268  {
269  CRITICAL_REGION_LOCAL(m_peerlist_lock);
270  peers_indexed::index<by_time>::type& by_time_index=m_peers_white.get<by_time>();
271  uint32_t cnt = 0;
272 
273  // picks a random set of peers within the first 120%, rather than a set of the first 100%.
274  // The intent is that if someone asks twice, they can't easily tell:
275  // - this address was not in the first list, but is in the second, so the only way this can be
276  // is if its last_seen was recently reset, so this means the target node recently had a new
277  // connection to that address
278  // - this address was in the first list, and not in the second, which means either the address
279  // was moved to the gray list (if it's not accessibe, which the attacker can check if
280  // the address accepts incoming connections) or it was the oldest to still fit in the 250 items,
281  // so its last_seen is old.
282  const uint32_t pick_depth = anonymize ? depth + depth / 5 : depth;
283  bs_head.reserve(pick_depth);
284  for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
285  {
286  if(cnt++ >= pick_depth)
287  break;
288 
289  bs_head.push_back(vl);
290  }
291 
292  if (anonymize)
293  {
294  std::random_shuffle(bs_head.begin(), bs_head.end());
295  if (bs_head.size() > depth)
296  bs_head.resize(depth);
297  for (auto &e: bs_head)
298  e.last_seen = 0;
299  }
300 
301  return true;
302  }
unsigned int uint32_t
Definition: stdint.h:126
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228

◆ get_random_gray_peer()

bool nodetool::peerlist_manager::get_random_gray_peer ( peerlist_entry pe)
inline

Definition at line 421 of file net_peerlist.h.

422  {
423  TRY_ENTRY();
424 
425  CRITICAL_REGION_LOCAL(m_peerlist_lock);
426 
427  if (m_peers_gray.empty()) {
428  return false;
429  }
430 
431  size_t random_index = crypto::rand_idx(m_peers_gray.size());
432 
433  peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
434  pe = *epee::misc_utils::move_it_backward(--by_time_index.end(), random_index);
435 
436  return true;
437 
438  CATCH_ENTRY_L0("peerlist_manager::get_random_gray_peer()", false);
439  }
std::enable_if< std::is_unsigned< T >::value, T >::type rand_idx(T sz)
Definition: crypto.h:244
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
t_iterator move_it_backward(t_iterator it, size_t count)
Definition: misc_language.h:73
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165
Here is the call graph for this function:

◆ get_white_peer_by_index()

bool nodetool::peerlist_manager::get_white_peer_by_index ( peerlist_entry p,
size_t  i 
)
inline

Definition at line 230 of file net_peerlist.h.

231  {
232  CRITICAL_REGION_LOCAL(m_peerlist_lock);
233  if(i >= m_peers_white.size())
234  return false;
235 
236  peers_indexed::index<by_time>::type& by_time_index = m_peers_white.get<by_time>();
237  p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
238  return true;
239  }
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
t_iterator move_it_backward(t_iterator it, size_t count)
Definition: misc_language.h:73
Here is the call graph for this function:

◆ get_white_peers_count()

size_t nodetool::peerlist_manager::get_white_peers_count ( )
inline

Definition at line 103 of file net_peerlist.h.

103 {CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_white.size();}
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228

◆ init()

bool nodetool::peerlist_manager::init ( peerlist_types &&  peers,
bool  allow_local_ip 
)

Definition at line 259 of file net_peerlist.cpp.

260  {
261  CRITICAL_REGION_LOCAL(m_peerlist_lock);
262 
263  if (!m_peers_white.empty() || !m_peers_gray.empty() || !m_peers_anchor.empty())
264  return false;
265 
266  add_peers(m_peers_white.get<by_addr>(), std::move(peers.white));
267  add_peers(m_peers_gray.get<by_addr>(), std::move(peers.gray));
268  add_peers(m_peers_anchor.get<by_addr>(), std::move(peers.anchor));
269  m_allow_local_ip = allow_local_ip;
270  return true;
271  }
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
const T & move(const T &t)
Definition: gtest-port.h:1317
Here is the call graph for this function:

◆ is_host_allowed()

bool nodetool::peerlist_manager::is_host_allowed ( const epee::net_utils::network_address address)
inline

Definition at line 254 of file net_peerlist.h.

255  {
256  //never allow loopback ip
257  if(address.is_loopback())
258  return false;
259 
260  if(!m_allow_local_ip && address.is_local())
261  return false;
262 
263  return true;
264  }
const char * address
Definition: multisig.cpp:37

◆ merge_peerlist()

bool nodetool::peerlist_manager::merge_peerlist ( const std::vector< peerlist_entry > &  outer_bs)
inline

Definition at line 217 of file net_peerlist.h.

218  {
219  CRITICAL_REGION_LOCAL(m_peerlist_lock);
220  for(const peerlist_entry& be: outer_bs)
221  {
223  }
224  // delete extra elements
225  trim_gray_peerlist();
226  return true;
227  }
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
bool append_with_peer_gray(const peerlist_entry &pr)
Definition: net_peerlist.h:368
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228

◆ remove_from_peer_anchor()

bool nodetool::peerlist_manager::remove_from_peer_anchor ( const epee::net_utils::network_address addr)
inline

Definition at line 499 of file net_peerlist.h.

500  {
501  TRY_ENTRY();
502 
503  CRITICAL_REGION_LOCAL(m_peerlist_lock);
504 
505  anchor_peers_indexed::index_iterator<by_addr>::type iterator = m_peers_anchor.get<by_addr>().find(addr);
506 
507  if (iterator != m_peers_anchor.get<by_addr>().end()) {
508  m_peers_anchor.erase(iterator);
509  }
510 
511  return true;
512 
513  CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false);
514  }
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ remove_from_peer_gray()

bool nodetool::peerlist_manager::remove_from_peer_gray ( const peerlist_entry pe)
inline

Definition at line 460 of file net_peerlist.h.

461  {
462  TRY_ENTRY();
463 
464  CRITICAL_REGION_LOCAL(m_peerlist_lock);
465 
466  peers_indexed::index_iterator<by_addr>::type iterator = m_peers_gray.get<by_addr>().find(pe.adr);
467 
468  if (iterator != m_peers_gray.get<by_addr>().end()) {
469  m_peers_gray.erase(iterator);
470  }
471 
472  return true;
473 
474  CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false);
475  }
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ remove_from_peer_white()

bool nodetool::peerlist_manager::remove_from_peer_white ( const peerlist_entry pe)
inline

Definition at line 442 of file net_peerlist.h.

443  {
444  TRY_ENTRY();
445 
446  CRITICAL_REGION_LOCAL(m_peerlist_lock);
447 
448  peers_indexed::index_iterator<by_addr>::type iterator = m_peers_white.get<by_addr>().find(pe.adr);
449 
450  if (iterator != m_peers_white.get<by_addr>().end()) {
451  m_peers_white.erase(iterator);
452  }
453 
454  return true;
455 
456  CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_white()", false);
457  }
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ set_peer_just_seen()

bool nodetool::peerlist_manager::set_peer_just_seen ( peerid_type  peer,
const epee::net_utils::network_address addr,
uint32_t  pruning_seed,
uint16_t  rpc_port 
)
inline

Definition at line 316 of file net_peerlist.h.

317  {
318  TRY_ENTRY();
319  CRITICAL_REGION_LOCAL(m_peerlist_lock);
320  //find in white list
321  peerlist_entry ple;
322  ple.adr = addr;
323  ple.id = peer;
324  ple.last_seen = time(NULL);
325  ple.pruning_seed = pruning_seed;
326  ple.rpc_port = rpc_port;
327  return append_with_peer_white(ple);
328  CATCH_ENTRY_L0("peerlist_manager::set_peer_just_seen()", false);
329  }
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
time_t time
Definition: blockchain.cpp:93
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
bool append_with_peer_white(const peerlist_entry &pr)
Definition: net_peerlist.h:332
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165

◆ set_peer_unreachable()

bool nodetool::peerlist_manager::set_peer_unreachable ( const peerlist_entry pr)

Friends And Related Function Documentation

◆ boost::serialization::access

friend class boost::serialization::access
friend

Definition at line 187 of file net_peerlist.h.


The documentation for this class was generated from the following files: