rippled
peerfinder/impl/Logic.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_PEERFINDER_LOGIC_H_INCLUDED
21 #define RIPPLE_PEERFINDER_LOGIC_H_INCLUDED
22 
23 #include <ripple/basics/Log.h>
24 #include <ripple/basics/contract.h>
25 #include <ripple/basics/random.h>
26 #include <ripple/beast/container/aged_container_utility.h>
27 #include <ripple/beast/net/IPAddressConversion.h>
28 #include <ripple/peerfinder/PeerfinderManager.h>
29 #include <ripple/peerfinder/impl/Bootcache.h>
30 #include <ripple/peerfinder/impl/Counts.h>
31 #include <ripple/peerfinder/impl/Fixed.h>
32 #include <ripple/peerfinder/impl/Handouts.h>
33 #include <ripple/peerfinder/impl/Livecache.h>
34 #include <ripple/peerfinder/impl/Reporting.h>
35 #include <ripple/peerfinder/impl/SlotImp.h>
36 #include <ripple/peerfinder/impl/Source.h>
37 #include <ripple/peerfinder/impl/Store.h>
38 #include <ripple/peerfinder/impl/iosformat.h>
39 
40 #include <algorithm>
41 #include <functional>
42 #include <map>
43 #include <memory>
44 #include <set>
45 
46 namespace ripple {
47 namespace PeerFinder {
48 
53 template <class Checker>
54 class Logic
55 {
56 public:
57  // Maps remote endpoints to slots. Since a slot has a
58  // remote endpoint upon construction, this holds all counts.
59  //
61 
66 
68 
69  // True if we are stopping.
70  bool stopping_ = false;
71 
72  // The source we are currently fetching.
73  // This is used to cancel I/O during program exit.
75 
76  // Configuration settings
78 
79  // Slot counts and other aggregate statistics.
81 
82  // A list of slots that should always be connected
84 
85  // Live livecache from mtENDPOINTS messages
87 
88  // LiveCache of addresses suitable for gaining initial connections
90 
91  // Holds all counts
93 
94  // The addresses (but not port) we are connected to. This includes
95  // outgoing connection attempts. Note that this set can contain
96  // duplicates (since the port is not set)
98 
99  // Set of public keys belonging to active peers
101 
102  // A list of dynamic sources to consult as a fallback
104 
106 
108 
109  //--------------------------------------------------------------------------
110 
112  clock_type& clock,
113  Store& store,
114  Checker& checker,
115  beast::Journal journal)
116  : m_journal(journal)
117  , m_clock(clock)
118  , m_store(store)
119  , m_checker(checker)
120  , livecache_(m_clock, journal)
121  , bootcache_(store, m_clock, journal)
122  , m_whenBroadcast(m_clock.now())
124  {
125  config({});
126  }
127 
128  // Load persistent state information from the Store
129  //
130  void
132  {
134  bootcache_.load();
135  }
136 
143  void
145  {
147  stopping_ = true;
148  if (fetchSource_ != nullptr)
149  fetchSource_->cancel();
150  }
151 
152  //--------------------------------------------------------------------------
153  //
154  // Manager
155  //
156  //--------------------------------------------------------------------------
157 
158  void
159  config(Config const& c)
160  {
162  config_ = c;
164  }
165 
166  Config
168  {
170  return config_;
171  }
172 
173  void
175  {
177  v.push_back(ep);
178  addFixedPeer(name, v);
179  }
180 
181  void
183  std::string const& name,
184  std::vector<beast::IP::Endpoint> const& addresses)
185  {
187 
188  if (addresses.empty())
189  {
190  JLOG(m_journal.info())
191  << "Could not resolve fixed slot '" << name << "'";
192  return;
193  }
194 
195  for (auto const& remote_address : addresses)
196  {
197  if (remote_address.port() == 0)
198  {
199  Throw<std::runtime_error>(
200  "Port not specified for address:" +
201  remote_address.to_string());
202  }
203 
204  auto result(fixed_.emplace(
205  std::piecewise_construct,
206  std::forward_as_tuple(remote_address),
208 
209  if (result.second)
210  {
211  JLOG(m_journal.debug())
212  << beast::leftw(18) << "Logic add fixed '" << name
213  << "' at " << remote_address;
214  return;
215  }
216  }
217  }
218 
219  //--------------------------------------------------------------------------
220 
221  // Called when the Checker completes a connectivity test
222  void
224  beast::IP::Endpoint const& remoteAddress,
225  beast::IP::Endpoint const& checkedAddress,
226  boost::system::error_code ec)
227  {
228  if (ec == boost::asio::error::operation_aborted)
229  return;
230 
232  auto const iter(slots_.find(remoteAddress));
233  if (iter == slots_.end())
234  {
235  // The slot disconnected before we finished the check
236  JLOG(m_journal.debug())
237  << beast::leftw(18) << "Logic tested " << checkedAddress
238  << " but the connection was closed";
239  return;
240  }
241 
242  SlotImp& slot(*iter->second);
243  slot.checked = true;
244  slot.connectivityCheckInProgress = false;
245 
246  if (ec)
247  {
248  // VFALCO TODO Should we retry depending on the error?
249  slot.canAccept = false;
250  JLOG(m_journal.error())
251  << beast::leftw(18) << "Logic testing " << iter->first
252  << " with error, " << ec.message();
253  bootcache_.on_failure(checkedAddress);
254  return;
255  }
256 
257  slot.canAccept = true;
258  slot.set_listening_port(checkedAddress.port());
259  JLOG(m_journal.debug()) << beast::leftw(18) << "Logic testing "
260  << checkedAddress << " succeeded";
261  }
262 
263  //--------------------------------------------------------------------------
264 
267  beast::IP::Endpoint const& local_endpoint,
268  beast::IP::Endpoint const& remote_endpoint)
269  {
270  JLOG(m_journal.debug())
271  << beast::leftw(18) << "Logic accept" << remote_endpoint
272  << " on local " << local_endpoint;
273 
275 
276  // Check for duplicate connection
277  if (is_public(remote_endpoint))
278  {
279  auto const count =
280  connectedAddresses_.count(remote_endpoint.address());
281  if (count > config_.ipLimit)
282  {
283  JLOG(m_journal.debug())
284  << beast::leftw(18) << "Logic dropping inbound "
285  << remote_endpoint << " because of ip limits.";
286  return SlotImp::ptr();
287  }
288  }
289 
290  // Create the slot
291  SlotImp::ptr const slot(std::make_shared<SlotImp>(
292  local_endpoint,
293  remote_endpoint,
294  fixed(remote_endpoint.address()),
295  m_clock));
296  // Add slot to table
297  auto const result(slots_.emplace(slot->remote_endpoint(), slot));
298  // Remote address must not already exist
299  assert(result.second);
300  // Add to the connected address list
301  connectedAddresses_.emplace(remote_endpoint.address());
302 
303  // Update counts
304  counts_.add(*slot);
305 
306  return result.first->second;
307  }
308 
309  // Can't check for self-connect because we don't know the local endpoint
311  new_outbound_slot(beast::IP::Endpoint const& remote_endpoint)
312  {
313  JLOG(m_journal.debug())
314  << beast::leftw(18) << "Logic connect " << remote_endpoint;
315 
317 
318  // Check for duplicate connection
319  if (slots_.find(remote_endpoint) != slots_.end())
320  {
321  JLOG(m_journal.debug())
322  << beast::leftw(18) << "Logic dropping " << remote_endpoint
323  << " as duplicate connect";
324  return SlotImp::ptr();
325  }
326 
327  // Create the slot
328  SlotImp::ptr const slot(std::make_shared<SlotImp>(
329  remote_endpoint, fixed(remote_endpoint), m_clock));
330 
331  // Add slot to table
332  auto const result = slots_.emplace(slot->remote_endpoint(), slot);
333  // Remote address must not already exist
334  assert(result.second);
335 
336  // Add to the connected address list
337  connectedAddresses_.emplace(remote_endpoint.address());
338 
339  // Update counts
340  counts_.add(*slot);
341 
342  return result.first->second;
343  }
344 
345  bool
347  SlotImp::ptr const& slot,
348  beast::IP::Endpoint const& local_endpoint)
349  {
350  JLOG(m_journal.trace())
351  << beast::leftw(18) << "Logic connected" << slot->remote_endpoint()
352  << " on local " << local_endpoint;
353 
355 
356  // The object must exist in our table
357  assert(slots_.find(slot->remote_endpoint()) != slots_.end());
358  // Assign the local endpoint now that it's known
359  slot->local_endpoint(local_endpoint);
360 
361  // Check for self-connect by address
362  {
363  auto const iter(slots_.find(local_endpoint));
364  if (iter != slots_.end())
365  {
366  assert(
367  iter->second->local_endpoint() == slot->remote_endpoint());
368  JLOG(m_journal.warn())
369  << beast::leftw(18) << "Logic dropping "
370  << slot->remote_endpoint() << " as self connect";
371  return false;
372  }
373  }
374 
375  // Update counts
376  counts_.remove(*slot);
377  slot->state(Slot::connected);
378  counts_.add(*slot);
379  return true;
380  }
381 
382  Result
383  activate(SlotImp::ptr const& slot, PublicKey const& key, bool reserved)
384  {
385  JLOG(m_journal.debug())
386  << beast::leftw(18) << "Logic handshake " << slot->remote_endpoint()
387  << " with " << (reserved ? "reserved " : "") << "key " << key;
388 
390 
391  // The object must exist in our table
392  assert(slots_.find(slot->remote_endpoint()) != slots_.end());
393  // Must be accepted or connected
394  assert(
395  slot->state() == Slot::accept || slot->state() == Slot::connected);
396 
397  // Check for duplicate connection by key
398  if (keys_.find(key) != keys_.end())
399  return Result::duplicate;
400 
401  // If the peer belongs to a cluster or is reserved,
402  // update the slot to reflect that.
403  counts_.remove(*slot);
404  slot->reserved(reserved);
405  counts_.add(*slot);
406 
407  // See if we have an open space for this slot
408  if (!counts_.can_activate(*slot))
409  {
410  if (!slot->inbound())
411  bootcache_.on_success(slot->remote_endpoint());
412  return Result::full;
413  }
414 
415  // Set the key right before adding to the map, otherwise we might
416  // assert later when erasing the key.
417  slot->public_key(key);
418  {
419  [[maybe_unused]] bool const inserted = keys_.insert(key).second;
420  // Public key must not already exist
421  assert(inserted);
422  }
423 
424  // Change state and update counts
425  counts_.remove(*slot);
426  slot->activate(m_clock.now());
427  counts_.add(*slot);
428 
429  if (!slot->inbound())
430  bootcache_.on_success(slot->remote_endpoint());
431 
432  // Mark fixed slot success
433  if (slot->fixed() && !slot->inbound())
434  {
435  auto iter(fixed_.find(slot->remote_endpoint()));
436  if (iter == fixed_.end())
437  LogicError(
438  "PeerFinder::Logic::activate(): remote_endpoint "
439  "missing from fixed_");
440 
441  iter->second.success(m_clock.now());
442  JLOG(m_journal.trace()) << beast::leftw(18) << "Logic fixed "
443  << slot->remote_endpoint() << " success";
444  }
445 
446  return Result::success;
447  }
448 
454  redirect(SlotImp::ptr const& slot)
455  {
457  RedirectHandouts h(slot);
459  handout(&h, (&h) + 1, livecache_.hops.begin(), livecache_.hops.end());
460  return std::move(h.list());
461  }
462 
466  // VFALCO TODO This should add the returned addresses to the
467  // squelch list in one go once the list is built,
468  // rather than having each module add to the squelch list.
471  {
473 
475 
476  // Count how many more outbound attempts to make
477  //
478  auto needed(counts_.attempts_needed());
479  if (needed == 0)
480  return none;
481 
482  ConnectHandouts h(needed, m_squelches);
483 
484  // Make sure we don't connect to already-connected entries.
485  for (auto const& s : slots_)
486  {
487  auto const result(
488  m_squelches.insert(s.second->remote_endpoint().address()));
489  if (!result.second)
490  m_squelches.touch(result.first);
491  }
492 
493  // 1. Use Fixed if:
494  // Fixed active count is below fixed count AND
495  // ( There are eligible fixed addresses to try OR
496  // Any outbound attempts are in progress)
497  //
498  if (counts_.fixed_active() < fixed_.size())
499  {
500  get_fixed(needed, h.list(), m_squelches);
501 
502  if (!h.list().empty())
503  {
504  JLOG(m_journal.debug()) << beast::leftw(18) << "Logic connect "
505  << h.list().size() << " fixed";
506  return h.list();
507  }
508 
509  if (counts_.attempts() > 0)
510  {
511  JLOG(m_journal.debug())
512  << beast::leftw(18) << "Logic waiting on "
513  << counts_.attempts() << " attempts";
514  return none;
515  }
516  }
517 
518  // Only proceed if auto connect is enabled and we
519  // have less than the desired number of outbound slots
520  //
522  return none;
523 
524  // 2. Use Livecache if:
525  // There are any entries in the cache OR
526  // Any outbound attempts are in progress
527  //
528  {
530  handout(
531  &h, (&h) + 1, livecache_.hops.rbegin(), livecache_.hops.rend());
532  if (!h.list().empty())
533  {
534  JLOG(m_journal.debug())
535  << beast::leftw(18) << "Logic connect " << h.list().size()
536  << " live "
537  << ((h.list().size() > 1) ? "endpoints" : "endpoint");
538  return h.list();
539  }
540  else if (counts_.attempts() > 0)
541  {
542  JLOG(m_journal.debug())
543  << beast::leftw(18) << "Logic waiting on "
544  << counts_.attempts() << " attempts";
545  return none;
546  }
547  }
548 
549  /* 3. Bootcache refill
550  If the Bootcache is empty, try to get addresses from the current
551  set of Sources and add them into the Bootstrap cache.
552 
553  Pseudocode:
554  If ( domainNames.count() > 0 AND (
555  unusedBootstrapIPs.count() == 0
556  OR activeNameResolutions.count() > 0) )
557  ForOneOrMore (DomainName that hasn't been resolved recently)
558  Contact DomainName and add entries to the
559  unusedBootstrapIPs return;
560  */
561 
562  // 4. Use Bootcache if:
563  // There are any entries we haven't tried lately
564  //
565  for (auto iter(bootcache_.begin());
566  !h.full() && iter != bootcache_.end();
567  ++iter)
568  h.try_insert(*iter);
569 
570  if (!h.list().empty())
571  {
572  JLOG(m_journal.debug())
573  << beast::leftw(18) << "Logic connect " << h.list().size()
574  << " boot "
575  << ((h.list().size() > 1) ? "addresses" : "address");
576  return h.list();
577  }
578 
579  // If we get here we are stuck
580  return none;
581  }
582 
585  {
587  result;
588 
590 
591  clock_type::time_point const now = m_clock.now();
592  if (m_whenBroadcast <= now)
593  {
595 
596  {
597  // build list of active slots
599  slots.reserve(slots_.size());
601  slots_.cbegin(),
602  slots_.cend(),
603  [&slots](Slots::value_type const& value) {
604  if (value.second->state() == Slot::active)
605  slots.emplace_back(value.second);
606  });
607  std::shuffle(slots.begin(), slots.end(), default_prng());
608 
609  // build target vector
610  targets.reserve(slots.size());
612  slots.cbegin(),
613  slots.cend(),
614  [&targets](SlotImp::ptr const& slot) {
615  targets.emplace_back(slot);
616  });
617  }
618 
619  /* VFALCO NOTE
620  This is a temporary measure. Once we know our own IP
621  address, the correct solution is to put it into the Livecache
622  at hops 0, and go through the regular handout path. This way
623  we avoid handing our address out too frequenty, which this code
624  suffers from.
625  */
626  // Add an entry for ourselves if:
627  // 1. We want incoming
628  // 2. We have slots
629  // 3. We haven't failed the firewalled test
630  //
632  {
633  Endpoint ep;
634  ep.hops = 0;
635  // we use the unspecified (0) address here because the value is
636  // irrelevant to recipients. When peers receive an endpoint
637  // with 0 hops, they use the socket remote_addr instead of the
638  // value in the message. Furthermore, since the address value
639  // is ignored, the type/version (ipv4 vs ipv6) doesn't matter
640  // either. ipv6 has a slightly more compact string
641  // representation of 0, so use that for self entries.
644  for (auto& t : targets)
645  t.insert(ep);
646  }
647 
648  // build sequence of endpoints by hops
650  handout(
651  targets.begin(),
652  targets.end(),
654  livecache_.hops.end());
655 
656  // broadcast
657  for (auto const& t : targets)
658  {
659  SlotImp::ptr const& slot = t.slot();
660  auto const& list = t.list();
661  JLOG(m_journal.trace())
662  << beast::leftw(18) << "Logic sending "
663  << slot->remote_endpoint() << " with " << list.size()
664  << ((list.size() == 1) ? " endpoint" : " endpoints");
665  result.push_back(std::make_pair(slot, list));
666  }
667 
669  }
670 
671  return result;
672  }
673 
674  void
676  {
678 
679  // Expire the Livecache
680  livecache_.expire();
681 
682  // Expire the recent cache in each slot
683  for (auto const& entry : slots_)
684  entry.second->expire();
685 
686  // Expire the recent attempts table
688 
690  }
691 
692  //--------------------------------------------------------------------------
693 
694  // Validate and clean up the list that we received from the slot.
695  void
696  preprocess(SlotImp::ptr const& slot, Endpoints& list)
697  {
698  bool neighbor(false);
699  for (auto iter = list.begin(); iter != list.end();)
700  {
701  Endpoint& ep(*iter);
702 
703  // Enforce hop limit
704  if (ep.hops > Tuning::maxHops)
705  {
706  JLOG(m_journal.debug())
707  << beast::leftw(18) << "Endpoints drop " << ep.address
708  << " for excess hops " << ep.hops;
709  iter = list.erase(iter);
710  continue;
711  }
712 
713  // See if we are directly connected
714  if (ep.hops == 0)
715  {
716  if (!neighbor)
717  {
718  // Fill in our neighbors remote address
719  neighbor = true;
720  ep.address =
721  slot->remote_endpoint().at_port(ep.address.port());
722  }
723  else
724  {
725  JLOG(m_journal.debug())
726  << beast::leftw(18) << "Endpoints drop " << ep.address
727  << " for extra self";
728  iter = list.erase(iter);
729  continue;
730  }
731  }
732 
733  // Discard invalid addresses
734  if (!is_valid_address(ep.address))
735  {
736  JLOG(m_journal.debug()) << beast::leftw(18) << "Endpoints drop "
737  << ep.address << " as invalid";
738  iter = list.erase(iter);
739  continue;
740  }
741 
742  // Filter duplicates
743  if (std::any_of(
744  list.begin(),
745  iter,
746  [ep](Endpoints::value_type const& other) {
747  return ep.address == other.address;
748  }))
749  {
750  JLOG(m_journal.debug()) << beast::leftw(18) << "Endpoints drop "
751  << ep.address << " as duplicate";
752  iter = list.erase(iter);
753  continue;
754  }
755 
756  // Increment hop count on the incoming message, so
757  // we store it at the hop count we will send it at.
758  //
759  ++ep.hops;
760 
761  ++iter;
762  }
763  }
764 
765  void
767  {
768  // If we're sent too many endpoints, sample them at random:
769  if (list.size() > Tuning::numberOfEndpointsMax)
770  {
771  std::shuffle(list.begin(), list.end(), default_prng());
773  }
774 
775  JLOG(m_journal.trace())
776  << beast::leftw(18) << "Endpoints from " << slot->remote_endpoint()
777  << " contained " << list.size()
778  << ((list.size() > 1) ? " entries" : " entry");
779 
781 
782  // The object must exist in our table
783  assert(slots_.find(slot->remote_endpoint()) != slots_.end());
784 
785  // Must be handshaked!
786  assert(slot->state() == Slot::active);
787 
788  clock_type::time_point const now(m_clock.now());
789 
790  // Limit how often we accept new endpoints
791  if (slot->whenAcceptEndpoints > now)
792  return;
793 
794  preprocess(slot, list);
795 
796  for (auto const& ep : list)
797  {
798  assert(ep.hops != 0);
799 
800  slot->recent.insert(ep.address, ep.hops);
801 
802  // Note hops has been incremented, so 1
803  // means a directly connected neighbor.
804  //
805  if (ep.hops == 1)
806  {
807  if (slot->connectivityCheckInProgress)
808  {
809  JLOG(m_journal.debug())
810  << beast::leftw(18) << "Logic testing " << ep.address
811  << " already in progress";
812  continue;
813  }
814 
815  if (!slot->checked)
816  {
817  // Mark that a check for this slot is now in progress.
818  slot->connectivityCheckInProgress = true;
819 
820  // Test the slot's listening port before
821  // adding it to the livecache for the first time.
822  //
824  ep.address,
825  std::bind(
827  this,
828  slot->remote_endpoint(),
829  ep.address,
830  std::placeholders::_1));
831 
832  // Note that we simply discard the first Endpoint
833  // that the neighbor sends when we perform the
834  // listening test. They will just send us another
835  // one in a few seconds.
836 
837  continue;
838  }
839 
840  // If they failed the test then skip the address
841  if (!slot->canAccept)
842  continue;
843  }
844 
845  // We only add to the livecache if the neighbor passed the
846  // listening test, else we silently drop neighbor endpoint
847  // since their listening port is misconfigured.
848  //
849  livecache_.insert(ep);
850  bootcache_.insert(ep.address);
851  }
852 
853  slot->whenAcceptEndpoints = now + Tuning::secondsPerMessage;
854  }
855 
856  //--------------------------------------------------------------------------
857 
858  void
859  remove(SlotImp::ptr const& slot)
860  {
861  {
862  auto const iter = slots_.find(slot->remote_endpoint());
863  // The slot must exist in the table
864  if (iter == slots_.end())
865  LogicError(
866  "PeerFinder::Logic::remove(): remote_endpoint "
867  "missing from slots_");
868 
869  // Remove from slot by IP table
870  slots_.erase(iter);
871  }
872  // Remove the key if present
873  if (slot->public_key() != std::nullopt)
874  {
875  auto const iter = keys_.find(*slot->public_key());
876  // Key must exist
877  if (iter == keys_.end())
878  LogicError(
879  "PeerFinder::Logic::remove(): public_key missing "
880  "from keys_");
881 
882  keys_.erase(iter);
883  }
884  // Remove from connected address table
885  {
886  auto const iter(
887  connectedAddresses_.find(slot->remote_endpoint().address()));
888  // Address must exist
889  if (iter == connectedAddresses_.end())
890  LogicError(
891  "PeerFinder::Logic::remove(): remote_endpont "
892  "address missing from connectedAddresses_");
893 
895  }
896 
897  // Update counts
898  counts_.remove(*slot);
899  }
900 
901  void
902  on_closed(SlotImp::ptr const& slot)
903  {
905 
906  remove(slot);
907 
908  // Mark fixed slot failure
909  if (slot->fixed() && !slot->inbound() && slot->state() != Slot::active)
910  {
911  auto iter(fixed_.find(slot->remote_endpoint()));
912  if (iter == fixed_.end())
913  LogicError(
914  "PeerFinder::Logic::on_closed(): remote_endpont "
915  "missing from fixed_");
916 
917  iter->second.failure(m_clock.now());
918  JLOG(m_journal.debug()) << beast::leftw(18) << "Logic fixed "
919  << slot->remote_endpoint() << " failed";
920  }
921 
922  // Do state specific bookkeeping
923  switch (slot->state())
924  {
925  case Slot::accept:
926  JLOG(m_journal.trace()) << beast::leftw(18) << "Logic accept "
927  << slot->remote_endpoint() << " failed";
928  break;
929 
930  case Slot::connect:
931  case Slot::connected:
932  bootcache_.on_failure(slot->remote_endpoint());
933  // VFALCO TODO If the address exists in the ephemeral/live
934  // endpoint livecache then we should mark the
935  // failure
936  // as if it didn't pass the listening test. We should also
937  // avoid propagating the address.
938  break;
939 
940  case Slot::active:
941  JLOG(m_journal.trace()) << beast::leftw(18) << "Logic close "
942  << slot->remote_endpoint();
943  break;
944 
945  case Slot::closing:
946  JLOG(m_journal.trace()) << beast::leftw(18) << "Logic finished "
947  << slot->remote_endpoint();
948  break;
949 
950  default:
951  assert(false);
952  break;
953  }
954  }
955 
956  void
958  {
960 
961  bootcache_.on_failure(slot->remote_endpoint());
962  }
963 
964  // Insert a set of redirect IP addresses into the Bootcache
965  template <class FwdIter>
966  void
967  onRedirects(
968  FwdIter first,
969  FwdIter last,
970  boost::asio::ip::tcp::endpoint const& remote_address);
971 
972  //--------------------------------------------------------------------------
973 
974  // Returns `true` if the address matches a fixed slot address
975  // Must have the lock held
976  bool
977  fixed(beast::IP::Endpoint const& endpoint) const
978  {
979  for (auto const& entry : fixed_)
980  if (entry.first == endpoint)
981  return true;
982  return false;
983  }
984 
985  // Returns `true` if the address matches a fixed slot address
986  // Note that this does not use the port information in the IP::Endpoint
987  // Must have the lock held
988  bool
989  fixed(beast::IP::Address const& address) const
990  {
991  for (auto const& entry : fixed_)
992  if (entry.first.address() == address)
993  return true;
994  return false;
995  }
996 
997  //--------------------------------------------------------------------------
998  //
999  // Connection Strategy
1000  //
1001  //--------------------------------------------------------------------------
1002 
1004  template <class Container>
1005  void
1007  std::size_t needed,
1008  Container& c,
1009  typename ConnectHandouts::Squelches& squelches)
1010  {
1011  auto const now(m_clock.now());
1012  for (auto iter = fixed_.begin(); needed && iter != fixed_.end(); ++iter)
1013  {
1014  auto const& address(iter->first.address());
1015  if (iter->second.when() <= now &&
1016  squelches.find(address) == squelches.end() &&
1017  std::none_of(
1018  slots_.cbegin(),
1019  slots_.cend(),
1020  [address](Slots::value_type const& v) {
1021  return address == v.first.address();
1022  }))
1023  {
1024  squelches.insert(iter->first.address());
1025  c.push_back(iter->first);
1026  --needed;
1027  }
1028  }
1029  }
1030 
1031  //--------------------------------------------------------------------------
1032 
1033  void
1035  {
1036  fetch(source);
1037  }
1038 
1039  void
1041  {
1042  m_sources.push_back(source);
1043  }
1044 
1045  //--------------------------------------------------------------------------
1046  //
1047  // Bootcache livecache sources
1048  //
1049  //--------------------------------------------------------------------------
1050 
1051  // Add a set of addresses.
1052  // Returns the number of addresses added.
1053  //
1054  int
1056  {
1057  int count(0);
1059  for (auto addr : list)
1060  {
1061  if (bootcache_.insertStatic(addr))
1062  ++count;
1063  }
1064  return count;
1065  }
1066 
1067  // Fetch bootcache addresses from the specified source.
1068  void
1070  {
1071  Source::Results results;
1072 
1073  {
1074  {
1076  if (stopping_)
1077  return;
1078  fetchSource_ = source;
1079  }
1080 
1081  // VFALCO NOTE The fetch is synchronous,
1082  // not sure if that's a good thing.
1083  //
1084  source->fetch(results, m_journal);
1085 
1086  {
1088  if (stopping_)
1089  return;
1090  fetchSource_ = nullptr;
1091  }
1092  }
1093 
1094  if (!results.error)
1095  {
1096  int const count(addBootcacheAddresses(results.addresses));
1097  JLOG(m_journal.info())
1098  << beast::leftw(18) << "Logic added " << count << " new "
1099  << ((count == 1) ? "address" : "addresses") << " from "
1100  << source->name();
1101  }
1102  else
1103  {
1104  JLOG(m_journal.error()) << beast::leftw(18) << "Logic failed "
1105  << "'" << source->name() << "' fetch, "
1106  << results.error.message();
1107  }
1108  }
1109 
1110  //--------------------------------------------------------------------------
1111  //
1112  // Endpoint message handling
1113  //
1114  //--------------------------------------------------------------------------
1115 
1116  // Returns true if the IP::Endpoint contains no invalid data.
1117  bool
1119  {
1120  if (is_unspecified(address))
1121  return false;
1122  if (!is_public(address))
1123  return false;
1124  if (address.port() == 0)
1125  return false;
1126  return true;
1127  }
1128 
1129  //--------------------------------------------------------------------------
1130  //
1131  // PropertyStream
1132  //
1133  //--------------------------------------------------------------------------
1134 
1135  void
1137  {
1138  for (auto const& entry : slots)
1139  {
1141  SlotImp const& slot(*entry.second);
1142  if (slot.local_endpoint() != std::nullopt)
1143  item["local_address"] = to_string(*slot.local_endpoint());
1144  item["remote_address"] = to_string(slot.remote_endpoint());
1145  if (slot.inbound())
1146  item["inbound"] = "yes";
1147  if (slot.fixed())
1148  item["fixed"] = "yes";
1149  if (slot.reserved())
1150  item["reserved"] = "yes";
1151 
1152  item["state"] = stateString(slot.state());
1153  }
1154  }
1155 
1156  void
1158  {
1160 
1161  // VFALCO NOTE These ugly casts are needed because
1162  // of how std::size_t is declared on some linuxes
1163  //
1164  map["bootcache"] = std::uint32_t(bootcache_.size());
1165  map["fixed"] = std::uint32_t(fixed_.size());
1166 
1167  {
1168  beast::PropertyStream::Set child("peers", map);
1169  writeSlots(child, slots_);
1170  }
1171 
1172  {
1173  beast::PropertyStream::Map child("counts", map);
1174  counts_.onWrite(child);
1175  }
1176 
1177  {
1178  beast::PropertyStream::Map child("config", map);
1179  config_.onWrite(child);
1180  }
1181 
1182  {
1183  beast::PropertyStream::Map child("livecache", map);
1184  livecache_.onWrite(child);
1185  }
1186 
1187  {
1188  beast::PropertyStream::Map child("bootcache", map);
1189  bootcache_.onWrite(child);
1190  }
1191  }
1192 
1193  //--------------------------------------------------------------------------
1194  //
1195  // Diagnostics
1196  //
1197  //--------------------------------------------------------------------------
1198 
1199  Counts const&
1200  counts() const
1201  {
1202  return counts_;
1203  }
1204 
1205  static std::string
1207  {
1208  switch (state)
1209  {
1210  case Slot::accept:
1211  return "accept";
1212  case Slot::connect:
1213  return "connect";
1214  case Slot::connected:
1215  return "connected";
1216  case Slot::active:
1217  return "active";
1218  case Slot::closing:
1219  return "closing";
1220  default:
1221  break;
1222  };
1223  return "?";
1224  }
1225 };
1226 
1227 //------------------------------------------------------------------------------
1228 
1229 template <class Checker>
1230 template <class FwdIter>
1231 void
1233  FwdIter first,
1234  FwdIter last,
1235  boost::asio::ip::tcp::endpoint const& remote_address)
1236 {
1237  std::lock_guard _(lock_);
1238  std::size_t n = 0;
1239  for (; first != last && n < Tuning::maxRedirects; ++first, ++n)
1240  bootcache_.insert(beast::IPAddressConversion::from_asio(*first));
1241  if (n > 0)
1242  {
1243  JLOG(m_journal.trace()) << beast::leftw(18) << "Logic add " << n
1244  << " redirect IPs from " << remote_address;
1245  }
1246 }
1247 
1248 } // namespace PeerFinder
1249 } // namespace ripple
1250 
1251 #endif
ripple::PeerFinder::Checker
Tests remote listening sockets to make sure they are connectible.
Definition: Checker.h:39
ripple::PeerFinder::ConnectHandouts::full
bool full() const
Definition: Handouts.h:299
ripple::PeerFinder::Result::duplicate
@ duplicate
ripple::PeerFinder::Bootcache::insertStatic
bool insertStatic(beast::IP::Endpoint const &endpoint)
Add a staticallyconfigured address to the cache.
Definition: Bootcache.cpp:125
ripple::PeerFinder::Logic::m_clock
clock_type & m_clock
Definition: peerfinder/impl/Logic.h:63
std::vector::resize
T resize(T... args)
std::make_tuple
T make_tuple(T... args)
std::for_each
T for_each(T... args)
ripple::PeerFinder::Logic::m_sources
std::vector< std::shared_ptr< Source > > m_sources
Definition: peerfinder/impl/Logic.h:103
std::bind
T bind(T... args)
ripple::PeerFinder::SlotImp::inbound
bool inbound() const override
Returns true if this is an inbound connection.
Definition: SlotImp.h:52
std::string
STL class.
std::shared_ptr
STL class.
ripple::PeerFinder::Slot::accept
@ accept
Definition: peerfinder/Slot.h:37
ripple::PeerFinder::Logic::get_fixed
void get_fixed(std::size_t needed, Container &c, typename ConnectHandouts::Squelches &squelches)
Adds eligible Fixed addresses for outbound attempts.
Definition: peerfinder/impl/Logic.h:1006
ripple::PeerFinder::Logic::load
void load()
Definition: peerfinder/impl/Logic.h:131
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:308
beast::PropertyStream::Map
Definition: PropertyStream.h:224
ripple::PeerFinder::Tuning::maxRedirects
@ maxRedirects
Definition: peerfinder/impl/Tuning.h:70
ripple::PeerFinder::ConnectHandouts
Receives handouts for making automatic connections.
Definition: Handouts.h:270
ripple::PeerFinder::Logic
The Logic for maintaining the list of Slot addresses.
Definition: peerfinder/impl/Logic.h:54
functional
ripple::PeerFinder::Slot::active
@ active
Definition: peerfinder/Slot.h:37
ripple::PeerFinder::Logic::keys_
std::set< PublicKey > keys_
Definition: peerfinder/impl/Logic.h:100
std::vector::reserve
T reserve(T... args)
ripple::PeerFinder::Logic::new_outbound_slot
SlotImp::ptr new_outbound_slot(beast::IP::Endpoint const &remote_endpoint)
Definition: peerfinder/impl/Logic.h:311
std::vector
STL class.
std::map::find
T find(T... args)
std::vector::size
T size(T... args)
ripple::PeerFinder::Logic::on_failure
void on_failure(SlotImp::ptr const &slot)
Definition: peerfinder/impl/Logic.h:957
ripple::PeerFinder::Logic::Logic
Logic(clock_type &clock, Store &store, Checker &checker, beast::Journal journal)
Definition: peerfinder/impl/Logic.h:111
ripple::PeerFinder::Livecache::onWrite
void onWrite(beast::PropertyStream::Map &map)
Output statistics.
Definition: Livecache.h:472
ripple::PeerFinder::Tuning::secondsPerMessage
constexpr std::chrono::seconds secondsPerMessage(151)
ripple::PeerFinder::Logic::m_whenBroadcast
clock_type::time_point m_whenBroadcast
Definition: peerfinder/impl/Logic.h:105
ripple::PeerFinder::RedirectHandouts
Receives handouts for redirecting a connection.
Definition: Handouts.h:102
ripple::PeerFinder::Logic::bootcache_
Bootcache bootcache_
Definition: peerfinder/impl/Logic.h:89
ripple::PeerFinder::Bootcache::on_failure
void on_failure(beast::IP::Endpoint const &endpoint)
Called when an outbound connection attempt fails to handshake.
Definition: Bootcache.cpp:173
ripple::PeerFinder::SlotImp::checked
bool checked
Definition: SlotImp.h:192
ripple::PeerFinder::Logic::fixed_
std::map< beast::IP::Endpoint, Fixed > fixed_
Definition: peerfinder/impl/Logic.h:83
beast::IP::Endpoint::address
Address const & address() const
Returns the address portion of this endpoint.
Definition: IPEndpoint.h:76
beast::detail::aged_ordered_container::insert
auto insert(value_type const &value) -> typename std::enable_if<!maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_ordered_container.h:1747
std::map::emplace
T emplace(T... args)
ripple::PeerFinder::Logic::onRedirects
void onRedirects(FwdIter first, FwdIter last, boost::asio::ip::tcp::endpoint const &remote_address)
Definition: peerfinder/impl/Logic.h:1232
ripple::PeerFinder::Logic::addFixedPeer
void addFixedPeer(std::string const &name, std::vector< beast::IP::Endpoint > const &addresses)
Definition: peerfinder/impl/Logic.h:182
beast::Journal::warn
Stream warn() const
Definition: Journal.h:326
std::recursive_mutex
STL class.
std::lock_guard
STL class.
ripple::PeerFinder::Tuning::numberOfEndpointsMax
constexpr std::uint32_t numberOfEndpointsMax
Definition: peerfinder/impl/Tuning.h:116
ripple::PeerFinder::Logic::counts
Counts const & counts() const
Definition: peerfinder/impl/Logic.h:1200
ripple::PeerFinder::Logic::config_
Config config_
Definition: peerfinder/impl/Logic.h:77
ripple::PeerFinder::Bootcache::periodicActivity
void periodicActivity()
Stores the cache in the persistent database on a timer.
Definition: Bootcache.cpp:199
std::any_of
T any_of(T... args)
ripple::PeerFinder::Store
Abstract persistence for PeerFinder data.
Definition: Store.h:27
beast::PropertyStream::Set
Definition: PropertyStream.h:296
ripple::PeerFinder::Counts::can_activate
bool can_activate(Slot const &s) const
Returns true if the slot can become active.
Definition: Counts.h:71
algorithm
ripple::PeerFinder::Source::Results::addresses
IPAddresses addresses
Definition: Source.h:49
ripple::PeerFinder::Counts::inboundSlots
int inboundSlots() const
Returns the total number of inbound slots.
Definition: Counts.h:165
ripple::PeerFinder::Bootcache::load
void load()
Load the persisted data from the Store into the container.
Definition: Bootcache.cpp:88
beast::abstract_clock::now
virtual time_point now() const =0
Returns the current time.
std::multiset< beast::IP::Address >
std::vector::push_back
T push_back(T... args)
beast::IPAddressConversion::from_asio
static IP::Endpoint from_asio(boost::asio::ip::address const &address)
Definition: IPAddressConversion.h:63
ripple::PeerFinder::Result::success
@ success
ripple::PeerFinder::Livecache::insert
void insert(Endpoint const &ep)
Creates or updates an existing Element based on a new message.
Definition: Livecache.h:427
ripple::PeerFinder::Counts::out_max
int out_max() const
Returns the total number of outbound slots.
Definition: Counts.h:103
ripple::PeerFinder::Logic::m_checker
Checker & m_checker
Definition: peerfinder/impl/Logic.h:65
ripple::PeerFinder::Counts
Manages the count of available connections for the various slots.
Definition: Counts.h:34
ripple::PeerFinder::RedirectHandouts::list
std::vector< Endpoint > & list()
Definition: Handouts.h:125
ripple::PeerFinder::Bootcache::size
map_type::size_type size() const
Returns the number of entries in the cache.
Definition: Bootcache.cpp:49
ripple::PeerFinder::Config::wantIncoming
bool wantIncoming
true if we want to accept incoming connections.
Definition: PeerfinderManager.h:64
ripple::PeerFinder::Logic::onConnected
bool onConnected(SlotImp::ptr const &slot, beast::IP::Endpoint const &local_endpoint)
Definition: peerfinder/impl/Logic.h:346
beast::detail::aged_ordered_container::find
iterator find(K const &k)
Definition: aged_ordered_container.h:1015
beast::IP::Address
boost::asio::ip::address Address
Definition: IPAddress.h:41
ripple::PublicKey
A public key.
Definition: PublicKey.h:61
ripple::PeerFinder::Logic::addStaticSource
void addStaticSource(std::shared_ptr< Source > const &source)
Definition: peerfinder/impl/Logic.h:1034
ripple::PeerFinder::Logic::lock_
std::recursive_mutex lock_
Definition: peerfinder/impl/Logic.h:67
ripple::PeerFinder::Bootcache
Stores IP addresses useful for gaining initial connections.
Definition: Bootcache.h:51
ripple::PeerFinder::Logic::buildEndpointsForPeers
std::vector< std::pair< std::shared_ptr< Slot >, std::vector< Endpoint > > > buildEndpointsForPeers()
Definition: peerfinder/impl/Logic.h:584
ripple::PeerFinder::Bootcache::insert
bool insert(beast::IP::Endpoint const &endpoint)
Add a newly-learned address to the cache.
Definition: Bootcache.cpp:111
ripple::PeerFinder::Logic::redirect
std::vector< Endpoint > redirect(SlotImp::ptr const &slot)
Return a list of addresses suitable for redirection.
Definition: peerfinder/impl/Logic.h:454
ripple::PeerFinder::Logic::onWrite
void onWrite(beast::PropertyStream::Map &map)
Definition: peerfinder/impl/Logic.h:1157
ripple::PeerFinder::ConnectHandouts::list
list_type & list()
Definition: Handouts.h:311
ripple::JsonOptions::none
@ none
ripple::PeerFinder::Counts::out_active
int out_active() const
Returns the number of outbound peers assigned an open slot.
Definition: Counts.h:112
ripple::PeerFinder::Bootcache::end
const_iterator end() const
Definition: Bootcache.cpp:67
ripple::PeerFinder::Livecache::hops_t::shuffle
void shuffle()
Shuffle each hop list.
Definition: Livecache.h:495
ripple::PeerFinder::Slot::connected
@ connected
Definition: peerfinder/Slot.h:37
ripple::PeerFinder::SlotImp::canAccept
bool canAccept
Definition: SlotImp.h:196
ripple::PeerFinder::Livecache::hops_t::rbegin
reverse_iterator rbegin()
Definition: Livecache.h:305
ripple::PeerFinder::Logic::connectedAddresses_
std::multiset< beast::IP::Address > connectedAddresses_
Definition: peerfinder/impl/Logic.h:97
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:313
ripple::default_prng
beast::xor_shift_engine & default_prng()
Return the default random engine.
Definition: ripple/basics/random.h:65
ripple::PeerFinder::Logic::stop
void stop()
Stop the logic.
Definition: peerfinder/impl/Logic.h:144
ripple::PeerFinder::Logic::counts_
Counts counts_
Definition: peerfinder/impl/Logic.h:80
beast::Journal::error
Stream error() const
Definition: Journal.h:332
beast::Journal::info
Stream info() const
Definition: Journal.h:320
ripple::PeerFinder::Logic::autoconnect
std::vector< beast::IP::Endpoint > autoconnect()
Create new outbound connection attempts as needed.
Definition: peerfinder/impl/Logic.h:470
std::vector::erase
T erase(T... args)
ripple::PeerFinder::Endpoint::hops
std::uint32_t hops
Definition: PeerfinderManager.h:119
beast::IP::Endpoint::port
Port port() const
Returns the port number on the endpoint.
Definition: IPEndpoint.h:62
ripple::PeerFinder::Counts::onConfig
void onConfig(Config const &config)
Called when the config is set or changed.
Definition: Counts.h:135
ripple::PeerFinder::Logic::fixed
bool fixed(beast::IP::Address const &address) const
Definition: peerfinder/impl/Logic.h:989
ripple::PeerFinder::Livecache
The Livecache holds the short-lived relayed Endpoint messages.
Definition: Livecache.h:39
ripple::PeerFinder::SlotImp::local_endpoint
std::optional< beast::IP::Endpoint > const & local_endpoint() const override
The local endpoint of the socket, when known.
Definition: SlotImp.h:82
ripple::PeerFinder::Logic::addFixedPeer
void addFixedPeer(std::string const &name, beast::IP::Endpoint const &ep)
Definition: peerfinder/impl/Logic.h:174
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
beast::expire
std::enable_if< is_aged_container< AgedContainer >::value, std::size_t >::type expire(AgedContainer &c, std::chrono::duration< Rep, Period > const &age)
Expire aged container items past the specified age.
Definition: aged_container_utility.h:33
std::uint32_t
ripple::PeerFinder::Slot::closing
@ closing
Definition: peerfinder/Slot.h:37
std::forward_as_tuple
T forward_as_tuple(T... args)
map
ripple::PeerFinder::Tuning::recentAttemptDuration
constexpr std::chrono::seconds recentAttemptDuration(60)
ripple::PeerFinder::Logic::checkComplete
void checkComplete(beast::IP::Endpoint const &remoteAddress, beast::IP::Endpoint const &checkedAddress, boost::system::error_code ec)
Definition: peerfinder/impl/Logic.h:223
ripple::PeerFinder::Logic::fetchSource_
std::shared_ptr< Source > fetchSource_
Definition: peerfinder/impl/Logic.h:74
ripple::PeerFinder::Logic::activate
Result activate(SlotImp::ptr const &slot, PublicKey const &key, bool reserved)
Definition: peerfinder/impl/Logic.h:383
ripple::PeerFinder::Logic::addSource
void addSource(std::shared_ptr< Source > const &source)
Definition: peerfinder/impl/Logic.h:1040
beast::IP::AddressV6
boost::asio::ip::address_v6 AddressV6
Definition: IPAddressV6.h:34
ripple::PeerFinder::Slot::State
State
Definition: peerfinder/Slot.h:37
ripple::PeerFinder::Source::Results::error
boost::system::error_code error
Definition: Source.h:46
ripple::PeerFinder::Logic::fetch
void fetch(std::shared_ptr< Source > const &source)
Definition: peerfinder/impl/Logic.h:1069
beast::abstract_clock< std::chrono::steady_clock >
memory
ripple::PeerFinder::Bootcache::onWrite
void onWrite(beast::PropertyStream::Map &map)
Write the cache state to the property stream.
Definition: Bootcache.cpp:207
ripple::PeerFinder::Logic::stateString
static std::string stateString(Slot::State state)
Definition: peerfinder/impl/Logic.h:1206
ripple::PeerFinder::Bootcache::on_success
void on_success(beast::IP::Endpoint const &endpoint)
Called when an outbound connection handshake completes.
Definition: Bootcache.cpp:147
ripple::PeerFinder::Logic::remove
void remove(SlotImp::ptr const &slot)
Definition: peerfinder/impl/Logic.h:859
ripple::PeerFinder::Livecache::hops
class ripple::PeerFinder::Livecache::hops_t hops
ripple::PeerFinder::Logic::once_per_second
void once_per_second()
Definition: peerfinder/impl/Logic.h:675
beast::leftw
Left justifies a field at the specified width.
Definition: iosformat.h:33
ripple::PeerFinder::handout
void handout(TargetFwdIter first, TargetFwdIter last, SeqFwdIter seq_first, SeqFwdIter seq_last)
Distributes objects to targets according to business rules.
Definition: Handouts.h:67
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
beast::detail::aged_ordered_container::end
iterator end()
Definition: aged_ordered_container.h:728
ripple::PeerFinder::Livecache::hops_t::end
iterator end()
Definition: Livecache.h:287
ripple::PeerFinder::Logic::m_journal
beast::Journal m_journal
Definition: peerfinder/impl/Logic.h:62
ripple::PeerFinder::Config::listeningPort
std::uint16_t listeningPort
The listening port number.
Definition: PeerfinderManager.h:70
beast::detail::aged_ordered_container
Associative container where each element is also indexed by time.
Definition: aged_ordered_container.h:82
ripple::PeerFinder::Counts::fixed_active
std::size_t fixed_active() const
Returns the number of active fixed connections.
Definition: Counts.h:126
ripple::PeerFinder::Logic::fixed
bool fixed(beast::IP::Endpoint const &endpoint) const
Definition: peerfinder/impl/Logic.h:977
ripple::PeerFinder::ConnectHandouts::try_insert
bool try_insert(beast::IP::Endpoint const &endpoint)
Definition: Handouts.h:332
std::map::cbegin
T cbegin(T... args)
ripple::PeerFinder::Counts::attempts
std::size_t attempts() const
Returns the number of outbound connection attempts.
Definition: Counts.h:96
ripple::PeerFinder::Checker::async_connect
void async_connect(beast::IP::Endpoint const &endpoint, Handler &&handler)
Performs an async connection test on the specified endpoint.
Definition: Checker.h:207
ripple::LogicError
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:48
ripple::PeerFinder::SlotImp::set_listening_port
void set_listening_port(std::uint16_t port)
Definition: SlotImp.h:103
ripple::PeerFinder::Counts::add
void add(Slot const &s)
Adds the slot state and properties to the slot counts.
Definition: Counts.h:57
ripple::PeerFinder::Livecache::expire
void expire()
Erase entries whose time has expired.
Definition: Livecache.h:405
ripple::PeerFinder::Logic::new_inbound_slot
SlotImp::ptr new_inbound_slot(beast::IP::Endpoint const &local_endpoint, beast::IP::Endpoint const &remote_endpoint)
Definition: peerfinder/impl/Logic.h:266
ripple::PeerFinder::Logic::config
Config config()
Definition: peerfinder/impl/Logic.h:167
beast::detail::aged_ordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator > pos)
Definition: aged_ordered_container.h:989
ripple::PeerFinder::Counts::onWrite
void onWrite(beast::PropertyStream::Map &map)
Output statistics.
Definition: Counts.h:227
std::multiset::count
T count(T... args)
ripple::PeerFinder::Logic::writeSlots
void writeSlots(beast::PropertyStream::Set &set, Slots const &slots)
Definition: peerfinder/impl/Logic.h:1136
ripple::PeerFinder::Logic::stopping_
bool stopping_
Definition: peerfinder/impl/Logic.h:70
ripple::PeerFinder::Logic::m_store
Store & m_store
Definition: peerfinder/impl/Logic.h:64
std::vector::empty
T empty(T... args)
ripple::PeerFinder::Logic::preprocess
void preprocess(SlotImp::ptr const &slot, Endpoints &list)
Definition: peerfinder/impl/Logic.h:696
ripple::PeerFinder::Logic::slots_
Slots slots_
Definition: peerfinder/impl/Logic.h:92
beast::Journal::debug
Stream debug() const
Definition: Journal.h:314
std::size_t
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::PeerFinder::Bootcache::begin
const_iterator begin() const
IP::Endpoint iterators that traverse in decreasing valence.
Definition: Bootcache.cpp:55
std::make_pair
T make_pair(T... args)
ripple::PeerFinder::Logic::is_valid_address
bool is_valid_address(beast::IP::Endpoint const &address)
Definition: peerfinder/impl/Logic.h:1118
beast::IP::Endpoint
A version-independent IP address and port combination.
Definition: IPEndpoint.h:38
std::map::end
T end(T... args)
ripple::PeerFinder::SlotImp::ptr
std::shared_ptr< SlotImp > ptr
Definition: SlotImp.h:36
ripple::PeerFinder::Config::autoConnect
bool autoConnect
true if we want to establish connections automatically
Definition: PeerfinderManager.h:67
ripple::PeerFinder::Tuning::maxHops
constexpr std::uint32_t maxHops
Definition: peerfinder/impl/Tuning.h:110
ripple::PeerFinder::Config
PeerFinder configuration settings.
Definition: PeerfinderManager.h:40
ripple::PeerFinder::Counts::attempts_needed
std::size_t attempts_needed() const
Returns the number of attempts needed to bring us to the max.
Definition: Counts.h:87
ripple::PeerFinder::Logic::on_closed
void on_closed(SlotImp::ptr const &slot)
Definition: peerfinder/impl/Logic.h:902
ripple::PeerFinder::SlotImp::state
State state() const override
Returns the state of the connection.
Definition: SlotImp.h:70
beast::IP::Endpoint::at_port
Endpoint at_port(Port port) const
Returns a new Endpoint with a different port.
Definition: IPEndpoint.h:69
ripple::PeerFinder::Logic::livecache_
Livecache livecache_
Definition: peerfinder/impl/Logic.h:86
ripple::PeerFinder::SlotImp
Definition: SlotImp.h:33
ripple::PeerFinder::Source::Results
The results of a fetch.
Definition: Source.h:41
ripple::PeerFinder::Slot::connect
@ connect
Definition: peerfinder/Slot.h:37
ripple::PeerFinder::Endpoint
Describes a connectible peer address along with some metadata.
Definition: PeerfinderManager.h:113
ripple::PeerFinder::Logic::config
void config(Config const &c)
Definition: peerfinder/impl/Logic.h:159
ripple::PeerFinder::SlotImp::reserved
bool reserved() const override
Returns true if this is a reserved connection.
Definition: SlotImp.h:64
std::shuffle
T shuffle(T... args)
ripple::PeerFinder::Counts::remove
void remove(Slot const &s)
Removes the slot state and properties from the slot counts.
Definition: Counts.h:64
ripple::PeerFinder::Result::full
@ full
beast::abstract_clock::time_point
typename Clock::time_point time_point
Definition: abstract_clock.h:63
ripple::PeerFinder::Logic::m_squelches
ConnectHandouts::Squelches m_squelches
Definition: peerfinder/impl/Logic.h:107
ripple::PeerFinder::Livecache::hops_t::rend
reverse_iterator rend()
Definition: Livecache.h:323
ripple::PeerFinder::Config::onWrite
void onWrite(beast::PropertyStream::Map &map)
Write the configuration into a property stream.
Definition: PeerfinderConfig.cpp:66
ripple::PeerFinder::Endpoint::address
beast::IP::Endpoint address
Definition: PeerfinderManager.h:120
ripple::PeerFinder::Config::ipLimit
int ipLimit
Limit how many incoming connections we allow per IP.
Definition: PeerfinderManager.h:76
ripple::PeerFinder::SlotImp::connectivityCheckInProgress
bool connectivityCheckInProgress
Definition: SlotImp.h:200
set
std::ref
T ref(T... args)
ripple::PeerFinder::SlotImp::fixed
bool fixed() const override
Returns true if this is a fixed connection.
Definition: SlotImp.h:58
ripple::PeerFinder::SlotImp::remote_endpoint
beast::IP::Endpoint const & remote_endpoint() const override
The remote endpoint of socket.
Definition: SlotImp.h:76
ripple::PeerFinder::Logic::addBootcacheAddresses
int addBootcacheAddresses(IPAddresses const &list)
Definition: peerfinder/impl/Logic.h:1055
ripple::PeerFinder::Logic::on_endpoints
void on_endpoints(SlotImp::ptr const &slot, Endpoints list)
Definition: peerfinder/impl/Logic.h:766
ripple::PeerFinder::Result
Result
Possible results from activating a slot.
Definition: PeerfinderManager.h:135
ripple::PeerFinder::Livecache::hops_t::begin
iterator begin()
Definition: Livecache.h:269