Electroneum
net_peerlist.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 <list>
35 #include <set>
36 #include <map>
37 //#include <boost/bimap.hpp>
38 //#include <boost/bimap/multiset_of.hpp>
39 #include <boost/archive/binary_iarchive.hpp>
40 #include <boost/archive/portable_binary_oarchive.hpp>
41 #include <boost/archive/portable_binary_iarchive.hpp>
42 #include <boost/serialization/version.hpp>
43 
44 #include <boost/multi_index_container.hpp>
45 #include <boost/multi_index/ordered_index.hpp>
46 #include <boost/multi_index/identity.hpp>
47 #include <boost/multi_index/member.hpp>
48 #include <boost/range/adaptor/reversed.hpp>
49 
50 
51 #include "syncobj.h"
52 #include "net/local_ip.h"
53 #include "p2p_protocol_defs.h"
54 #include "cryptonote_config.h"
56 
57 
58 #define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 6
59 
60 namespace nodetool
61 {
62 
63 
64  /************************************************************************/
65  /* */
66  /************************************************************************/
68  {
69  public:
70  bool init(bool allow_local_ip);
71  bool deinit();
72  size_t get_white_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_white.size();}
73  size_t get_gray_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_gray.size();}
74  bool merge_peerlist(const std::list<peerlist_entry>& outer_bs);
75  bool get_peerlist_head(std::list<peerlist_entry>& bs_head, uint32_t depth = P2P_DEFAULT_PEERS_IN_HANDSHAKE);
76  bool get_peerlist_full(std::list<peerlist_entry>& pl_gray, std::list<peerlist_entry>& pl_white);
77  bool get_white_peer_by_index(peerlist_entry& p, size_t i);
78  bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
79  bool append_with_peer_white(const peerlist_entry& pr);
80  bool append_with_peer_gray(const peerlist_entry& pr);
82  bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr);
83  bool set_peer_unreachable(const peerlist_entry& pr);
84  bool is_host_allowed(const epee::net_utils::network_address &address);
86  bool remove_from_peer_gray(const peerlist_entry& pe);
87  bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
88  bool remove_from_peer_anchor(const epee::net_utils::network_address& addr);
89 
90  private:
91  struct by_time{};
92  struct by_id{};
93  struct by_addr{};
94 
96  {
99  {
100  e.id = m_ple.id;
101  }
102  private:
104  };
105 
106  struct modify_all
107  {
108  modify_all(const peerlist_entry& ple):m_ple(ple){}
110  {
111  e = m_ple;
112  }
113  private:
115  };
116 
118  {
119  modify_last_seen(time_t last_seen):m_last_seen(last_seen){}
121  {
123  }
124  private:
125  time_t m_last_seen;
126  };
127 
128 
129  typedef boost::multi_index_container<
131  boost::multi_index::indexed_by<
132  // access by peerlist_entry::net_adress
133  boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,epee::net_utils::network_address,&peerlist_entry::adr> >,
134  // sort by peerlist_entry::last_seen<
135  boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
136  >
138 
139  typedef boost::multi_index_container<
141  boost::multi_index::indexed_by<
142  // access by peerlist_entry::id<
143  boost::multi_index::ordered_unique<boost::multi_index::tag<by_id>, boost::multi_index::member<peerlist_entry,uint64_t,&peerlist_entry::id> >,
144  // access by peerlist_entry::net_adress
145  boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,epee::net_utils::network_address,&peerlist_entry::adr> >,
146  // sort by peerlist_entry::last_seen<
147  boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
148  >
150 
151  typedef boost::multi_index_container<
153  boost::multi_index::indexed_by<
154  // access by anchor_peerlist_entry::net_adress
155  boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<anchor_peerlist_entry,epee::net_utils::network_address,&anchor_peerlist_entry::adr> >,
156  // sort by anchor_peerlist_entry::first_seen
157  boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<anchor_peerlist_entry,int64_t,&anchor_peerlist_entry::first_seen> >
158  >
160  public:
161 
162  template <class Archive, class List, class Element, class t_version_type>
163  void serialize_peers(Archive &a, List &list, Element ple, const t_version_type ver)
164  {
165  if (typename Archive::is_saving())
166  {
167  uint64_t size = list.size();
168  a & size;
169  for (auto p: list)
170  {
171  a & p;
172  }
173  }
174  else
175  {
176  uint64_t size;
177  a & size;
178  list.clear();
179  while (size--)
180  {
181  a & ple;
182  list.insert(ple);
183  }
184  }
185  }
186 
187  template <class Archive, class t_version_type>
188  void serialize(Archive &a, const t_version_type ver)
189  {
190  // at v6, we drop existing peerlists, because annoying change
191  if (ver < 6)
192  return;
193 
194  if(ver < 3)
195  return;
196  CRITICAL_REGION_LOCAL(m_peerlist_lock);
197  if(ver < 4)
198  {
199  //loading data from old storage
200  peers_indexed_old pio;
201  a & pio;
203  return;
204  }
205 
206 #if 0
207  // trouble loading more than one peer, can't find why
208  a & m_peers_white;
209  a & m_peers_gray;
210 #else
213 #endif
214 
215  if(ver < 5) {
216  return;
217  }
218 
219 #if 0
220  // trouble loading more than one peer, can't find why
221  a & m_peers_anchor;
222 #else
224 #endif
225  }
226 
227  private:
229  void trim_white_peerlist();
230  void trim_gray_peerlist();
231 
233  epee::critical_section m_peerlist_lock;
234  std::string m_config_folder;
236 
237 
241  };
242  //--------------------------------------------------------------------------------------------------
243  inline
244  bool peerlist_manager::init(bool allow_local_ip)
245  {
246  m_allow_local_ip = allow_local_ip;
247  return true;
248  }
249  //--------------------------------------------------------------------------------------------------
250  inline
252  {
253  return true;
254  }
255  //--------------------------------------------------------------------------------------------------
256  inline
258  {
259  for(auto x: pio)
260  {
261  auto by_addr_it = pi.get<by_addr>().find(x.adr);
262  if(by_addr_it == pi.get<by_addr>().end())
263  {
264  pi.insert(x);
265  }
266  }
267 
268  return true;
269  }
270  //--------------------------------------------------------------------------------------------------
272  {
274  {
276  sorted_index.erase(sorted_index.begin());
277  }
278  }
279  //--------------------------------------------------------------------------------------------------
281  {
283  {
285  sorted_index.erase(sorted_index.begin());
286  }
287  }
288  //--------------------------------------------------------------------------------------------------
289  inline
290  bool peerlist_manager::merge_peerlist(const std::list<peerlist_entry>& outer_bs)
291  {
292  CRITICAL_REGION_LOCAL(m_peerlist_lock);
293  for(const peerlist_entry& be: outer_bs)
294  {
296  }
297  // delete extra elements
299  return true;
300  }
301  //--------------------------------------------------------------------------------------------------
302  inline
304  {
305  CRITICAL_REGION_LOCAL(m_peerlist_lock);
306  if(i >= m_peers_white.size())
307  return false;
308 
310  p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
311  return true;
312  }
313  //--------------------------------------------------------------------------------------------------
314  inline
316  {
317  CRITICAL_REGION_LOCAL(m_peerlist_lock);
318  if(i >= m_peers_gray.size())
319  return false;
320 
322  p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
323  return true;
324  }
325  //--------------------------------------------------------------------------------------------------
326  inline
327  bool peerlist_manager::is_host_allowed(const epee::net_utils::network_address &address)
328  {
329  //never allow loopback ip
330  if(address.is_loopback())
331  return false;
332 
333  if(!m_allow_local_ip && address.is_local())
334  return false;
335 
336  return true;
337  }
338  //--------------------------------------------------------------------------------------------------
339  inline
340  bool peerlist_manager::get_peerlist_head(std::list<peerlist_entry>& bs_head, uint32_t depth)
341  {
342 
343  CRITICAL_REGION_LOCAL(m_peerlist_lock);
345  uint32_t cnt = 0;
346  for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
347  {
348  if(!vl.last_seen)
349  continue;
350 
351  if(cnt++ >= depth)
352  break;
353 
354  bs_head.push_back(vl);
355  }
356  return true;
357  }
358  //--------------------------------------------------------------------------------------------------
359  inline
360  bool peerlist_manager::get_peerlist_full(std::list<peerlist_entry>& pl_gray, std::list<peerlist_entry>& pl_white)
361  {
362  CRITICAL_REGION_LOCAL(m_peerlist_lock);
364  for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_gr))
365  {
366  pl_gray.push_back(vl);
367  }
368 
370  for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_wt))
371  {
372  pl_white.push_back(vl);
373  }
374 
375  return true;
376  }
377  //--------------------------------------------------------------------------------------------------
378  inline
379  bool peerlist_manager::set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr)
380  {
381  TRY_ENTRY();
382  CRITICAL_REGION_LOCAL(m_peerlist_lock);
383  //find in white list
384  peerlist_entry ple;
385  ple.adr = addr;
386  ple.id = peer;
387  ple.last_seen = time(NULL);
388  return append_with_peer_white(ple);
389  CATCH_ENTRY_L0("peerlist_manager::set_peer_just_seen()", false);
390  }
391  //--------------------------------------------------------------------------------------------------
392  inline
394  {
395  TRY_ENTRY();
396  if(!is_host_allowed(ple.adr))
397  return true;
398 
399  CRITICAL_REGION_LOCAL(m_peerlist_lock);
400  //find in white list
401  auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
402  if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
403  {
404  //put new record into white list
405  m_peers_white.insert(ple);
407  }else
408  {
409  //update record in white list
410  m_peers_white.replace(by_addr_it_wt, ple);
411  }
412  //remove from gray list, if need
413  auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
414  if(by_addr_it_gr != m_peers_gray.get<by_addr>().end())
415  {
416  m_peers_gray.erase(by_addr_it_gr);
417  }
418  return true;
419  CATCH_ENTRY_L0("peerlist_manager::append_with_peer_white()", false);
420  }
421  //--------------------------------------------------------------------------------------------------
422  inline
424  {
425  TRY_ENTRY();
426  if(!is_host_allowed(ple.adr))
427  return true;
428 
429  CRITICAL_REGION_LOCAL(m_peerlist_lock);
430  //find in white list
431  auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
432  if(by_addr_it_wt != m_peers_white.get<by_addr>().end())
433  return true;
434 
435  //update gray list
436  auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
437  if(by_addr_it_gr == m_peers_gray.get<by_addr>().end())
438  {
439  //put new record into white list
440  m_peers_gray.insert(ple);
442  }else
443  {
444  //update record in white list
445  m_peers_gray.replace(by_addr_it_gr, ple);
446  }
447  return true;
448  CATCH_ENTRY_L0("peerlist_manager::append_with_peer_gray()", false);
449  }
450  //--------------------------------------------------------------------------------------------------
451  inline
453  {
454  TRY_ENTRY();
455 
456  CRITICAL_REGION_LOCAL(m_peerlist_lock);
457 
458  auto by_addr_it_anchor = m_peers_anchor.get<by_addr>().find(ple.adr);
459 
460  if(by_addr_it_anchor == m_peers_anchor.get<by_addr>().end()) {
461  m_peers_anchor.insert(ple);
462  }
463 
464  return true;
465 
466  CATCH_ENTRY_L0("peerlist_manager::append_with_peer_anchor()", false);
467  }
468  //--------------------------------------------------------------------------------------------------
469  inline
471  {
472  TRY_ENTRY();
473 
474  CRITICAL_REGION_LOCAL(m_peerlist_lock);
475 
476  if (m_peers_gray.empty()) {
477  return false;
478  }
479 
480  size_t random_index = crypto::rand<size_t>() % m_peers_gray.size();
481 
483  pe = *epee::misc_utils::move_it_backward(--by_time_index.end(), random_index);
484 
485  return true;
486 
487  CATCH_ENTRY_L0("peerlist_manager::get_random_gray_peer()", false);
488  }
489  //--------------------------------------------------------------------------------------------------
490  inline
492  {
493  TRY_ENTRY();
494 
495  CRITICAL_REGION_LOCAL(m_peerlist_lock);
496 
498 
499  if (iterator != m_peers_gray.get<by_addr>().end()) {
500  m_peers_gray.erase(iterator);
501  }
502 
503  return true;
504 
505  CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false);
506  }
507  //--------------------------------------------------------------------------------------------------
508  inline
509  bool peerlist_manager::get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl)
510  {
511  TRY_ENTRY();
512 
513  CRITICAL_REGION_LOCAL(m_peerlist_lock);
514 
515  auto begin = m_peers_anchor.get<by_time>().begin();
516  auto end = m_peers_anchor.get<by_time>().end();
517 
518  std::for_each(begin, end, [&apl](const anchor_peerlist_entry &a) {
519  apl.push_back(a);
520  });
521 
522  m_peers_anchor.get<by_time>().clear();
523 
524  return true;
525 
526  CATCH_ENTRY_L0("peerlist_manager::get_and_empty_anchor_peerlist()", false);
527  }
528  //--------------------------------------------------------------------------------------------------
529  inline
530  bool peerlist_manager::remove_from_peer_anchor(const epee::net_utils::network_address& addr)
531  {
532  TRY_ENTRY();
533 
534  CRITICAL_REGION_LOCAL(m_peerlist_lock);
535 
537 
538  if (iterator != m_peers_anchor.get<by_addr>().end()) {
539  m_peers_anchor.erase(iterator);
540  }
541 
542  return true;
543 
544  CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false);
545  }
546  //--------------------------------------------------------------------------------------------------
547 }
548 
size_t get_white_peers_count()
Definition: net_peerlist.h:72
int64_t last_seen
Definition: p2p_protocol_defs.h:73
Definition: net_peerlist.h:106
friend class boost::serialization::access
Definition: net_peerlist.h:232
void serialize(Archive &a, const t_version_type ver)
Definition: net_peerlist.h:188
bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address &addr)
Definition: net_peerlist.h:379
bool append_with_peer_anchor(const anchor_peerlist_entry &ple)
Definition: net_peerlist.h:452
bool get_and_empty_anchor_peerlist(std::vector< anchor_peerlist_entry > &apl)
Definition: net_peerlist.h:509
bool get_peerlist_head(std::list< peerlist_entry > &bs_head, uint32_t depth=P2P_DEFAULT_PEERS_IN_HANDSHAKE)
Definition: net_peerlist.h:340
AddressType adr
Definition: p2p_protocol_defs.h:71
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
Definition: p2p_protocol_defs.h:81
AddressType adr
Definition: p2p_protocol_defs.h:86
time_t m_last_seen
Definition: net_peerlist.h:125
bool remove_from_peer_anchor(const epee::net_utils::network_address &addr)
Definition: net_peerlist.h:530
modify_all(const peerlist_entry &ple)
Definition: net_peerlist.h:108
modify_all_but_id(const peerlist_entry &ple)
Definition: net_peerlist.h:97
const peerlist_entry & m_ple
Definition: net_peerlist.h:114
void operator()(peerlist_entry &e)
Definition: net_peerlist.h:120
bool append_with_peer_gray(const peerlist_entry &pr)
Definition: net_peerlist.h:423
modify_last_seen(time_t last_seen)
Definition: net_peerlist.h:119
Definition: net_peerlist.h:91
Definition: net_peerlist.h:92
void operator()(peerlist_entry &e)
Definition: net_peerlist.h:109
boost::multi_index_container< anchor_peerlist_entry, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< by_addr >, boost::multi_index::member< anchor_peerlist_entry, epee::net_utils::network_address,&anchor_peerlist_entry::adr > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< by_time >, boost::multi_index::member< anchor_peerlist_entry, int64_t,&anchor_peerlist_entry::first_seen > > > > anchor_peers_indexed
Definition: net_peerlist.h:159
boost::multi_index_container< peerlist_entry, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< by_id >, boost::multi_index::member< peerlist_entry, uint64_t,&peerlist_entry::id > >, boost::multi_index::ordered_unique< boost::multi_index::tag< by_addr >, boost::multi_index::member< peerlist_entry, epee::net_utils::network_address,&peerlist_entry::adr > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< by_time >, boost::multi_index::member< peerlist_entry, int64_t,&peerlist_entry::last_seen > > > > peers_indexed_old
Definition: net_peerlist.h:149
bool get_white_peer_by_index(peerlist_entry &p, size_t i)
Definition: net_peerlist.h:303
BOOST_CLASS_VERSION(nodetool::node_server< cryptonote::t_cryptonote_protocol_handler< cryptonote::core > >, 1)
#define P2P_DEFAULT_PEERS_IN_HANDSHAKE
Definition: cryptonote_config.h:120
peerid_type id
Definition: p2p_protocol_defs.h:72
time_t time
Definition: blockchain.cpp:89
bool deinit()
Definition: net_peerlist.h:251
void serialize_peers(Archive &a, List &list, Element ple, const t_version_type ver)
Definition: net_peerlist.h:163
size_t get_gray_peers_count()
Definition: net_peerlist.h:73
Definition: p2p_protocol_defs.h:84
bool remove_from_peer_gray(const peerlist_entry &pe)
Definition: net_peerlist.h:491
uint64_t peerid_type
Definition: p2p_protocol_defs.h:46
anchor_peers_indexed m_peers_anchor
Definition: net_peerlist.h:240
type
Definition: json.h:74
void operator()(peerlist_entry &e)
Definition: net_peerlist.h:98
Definition: net_peerlist.h:117
#define P2P_LOCAL_GRAY_PEERLIST_LIMIT
Definition: cryptonote_config.h:115
bool set_peer_unreachable(const peerlist_entry &pr)
Definition: net_peerlist.h:67
const peerlist_entry & m_ple
Definition: net_peerlist.h:103
bool is_host_allowed(const epee::net_utils::network_address &address)
Definition: net_peerlist.h:327
bool get_random_gray_peer(peerlist_entry &pe)
Definition: net_peerlist.h:470
void trim_white_peerlist()
Definition: net_peerlist.h:280
anchor_peerlist_entry_base< epee::net_utils::network_address > anchor_peerlist_entry
Definition: p2p_protocol_defs.h:96
std::string m_config_folder
Definition: net_peerlist.h:234
string a
Definition: MakeCryptoOps.py:15
bool append_with_peer_white(const peerlist_entry &pr)
Definition: net_peerlist.h:393
Definition: net_node.h:60
void trim_gray_peerlist()
Definition: net_peerlist.h:271
bool get_gray_peer_by_index(peerlist_entry &p, size_t i)
Definition: net_peerlist.h:315
Definition: net_peerlist.h:93
bool peers_indexed_from_old(const peers_indexed_old &pio, peers_indexed &pi)
Definition: net_peerlist.h:257
criter reverse(citer it)
Definition: utils.cpp:16
bool init(bool allow_local_ip)
Definition: net_peerlist.h:244
peers_indexed m_peers_white
Definition: net_peerlist.h:239
void clear(std::string &pass) noexcept
Definition: password.cpp:169
epee::critical_section m_peerlist_lock
Definition: net_peerlist.h:233
bool merge_peerlist(const std::list< peerlist_entry > &outer_bs)
Definition: net_peerlist.h:290
bool m_allow_local_ip
Definition: net_peerlist.h:235
boost::multi_index_container< peerlist_entry, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< by_addr >, boost::multi_index::member< peerlist_entry, epee::net_utils::network_address,&peerlist_entry::adr > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< by_time >, boost::multi_index::member< peerlist_entry, int64_t,&peerlist_entry::last_seen > > > > peers_indexed
Definition: net_peerlist.h:137
peers_indexed m_peers_gray
Definition: net_peerlist.h:238
#define P2P_LOCAL_WHITE_PEERLIST_LIMIT
Definition: cryptonote_config.h:114
Definition: p2p_protocol_defs.h:69
bool get_peerlist_full(std::list< peerlist_entry > &pl_gray, std::list< peerlist_entry > &pl_white)
Definition: net_peerlist.h:360
#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER
Definition: net_peerlist.h:58