rippled
OverlayImpl.cpp
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 #include <ripple/app/ledger/LedgerMaster.h>
21 #include <ripple/app/misc/HashRouter.h>
22 #include <ripple/app/misc/NetworkOPs.h>
23 #include <ripple/app/misc/ValidatorList.h>
24 #include <ripple/app/misc/ValidatorSite.h>
25 #include <ripple/basics/base64.h>
26 #include <ripple/basics/make_SSLContext.h>
27 #include <ripple/beast/core/LexicalCast.h>
28 #include <ripple/core/DatabaseCon.h>
29 #include <ripple/nodestore/DatabaseShard.h>
30 #include <ripple/overlay/Cluster.h>
31 #include <ripple/overlay/impl/ConnectAttempt.h>
32 #include <ripple/overlay/impl/PeerImp.h>
33 #include <ripple/overlay/predicates.h>
34 #include <ripple/peerfinder/make_Manager.h>
35 #include <ripple/rpc/handlers/GetCounts.h>
36 #include <ripple/rpc/json_body.h>
37 #include <ripple/server/SimpleWriter.h>
38 
39 #include <boost/algorithm/string/predicate.hpp>
40 #include <boost/utility/in_place_factory.hpp>
41 
42 namespace ripple {
43 
46 {
48 
50 
51  get_peer_json() = default;
52 
53  void
55  {
56  json.append(peer->json());
57  }
58 
61  {
62  return json;
63  }
64 };
65 
66 namespace CrawlOptions {
67 enum {
68  Disabled = 0,
69  Overlay = (1 << 0),
70  ServerInfo = (1 << 1),
71  ServerCounts = (1 << 2),
72  Unl = (1 << 3)
73 };
74 }
75 
76 //------------------------------------------------------------------------------
77 
78 OverlayImpl::Child::Child(OverlayImpl& overlay) : overlay_(overlay)
79 {
80 }
81 
83 {
84  overlay_.remove(*this);
85 }
86 
87 //------------------------------------------------------------------------------
88 
90  : Child(overlay), timer_(overlay_.io_service_)
91 {
92 }
93 
94 void
96 {
97  error_code ec;
98  timer_.cancel(ec);
99 }
100 
101 void
103 {
104  timer_.expires_from_now(std::chrono::seconds(1));
105  timer_.async_wait(overlay_.strand_.wrap(std::bind(
106  &Timer::on_timer, shared_from_this(), std::placeholders::_1)));
107 }
108 
109 void
111 {
112  if (ec || overlay_.isStopping())
113  {
114  if (ec && ec != boost::asio::error::operation_aborted)
115  {
116  JLOG(overlay_.journal_.error()) << "on_timer: " << ec.message();
117  }
118  return;
119  }
120 
121  overlay_.m_peerFinder->once_per_second();
122  overlay_.sendEndpoints();
123  overlay_.autoConnect();
124 
125  if ((++overlay_.timer_count_ % Tuning::checkSeconds) == 0)
126  overlay_.check();
127 
128  timer_.expires_from_now(std::chrono::seconds(1));
129  timer_.async_wait(overlay_.strand_.wrap(std::bind(
130  &Timer::on_timer, shared_from_this(), std::placeholders::_1)));
131 }
132 
133 //------------------------------------------------------------------------------
134 
136  Application& app,
137  Setup const& setup,
138  Stoppable& parent,
141  Resolver& resolver,
142  boost::asio::io_service& io_service,
143  BasicConfig const& config,
144  beast::insight::Collector::ptr const& collector)
145  : Overlay(parent)
146  , app_(app)
147  , io_service_(io_service)
148  , work_(boost::in_place(std::ref(io_service_)))
150  , setup_(setup)
151  , journal_(app_.journal("Overlay"))
154  , m_peerFinder(PeerFinder::make_Manager(
155  *this,
156  io_service,
157  stopwatch(),
158  app_.journal("PeerFinder"),
159  config,
160  collector))
161  , m_resolver(resolver)
162  , next_id_(1)
163  , timer_count_(0)
164  , m_stats(
165  std::bind(&OverlayImpl::collect_metrics, this),
166  collector,
167  [counts = m_traffic.getCounts(), collector]() {
169  ret.reserve(counts.size());
170 
171  for (size_t i = 0; i < counts.size(); ++i)
172  {
173  ret.push_back(TrafficGauges(counts[i].name, collector));
174  }
175 
176  return ret;
177  }())
178 {
180 }
181 
183 {
184  stop();
185 
186  // Block until dependent objects have been destroyed.
187  // This is just to catch improper use of the Stoppable API.
188  //
189  std::unique_lock<decltype(mutex_)> lock(mutex_);
190  cond_.wait(lock, [this] { return list_.empty(); });
191 }
192 
193 //------------------------------------------------------------------------------
194 
195 Handoff
197  std::unique_ptr<stream_type>&& stream_ptr,
198  http_request_type&& request,
199  endpoint_type remote_endpoint)
200 {
201  auto const id = next_id_++;
202  beast::WrappedSink sink(app_.logs()["Peer"], makePrefix(id));
203  beast::Journal journal(sink);
204 
205  Handoff handoff;
206  if (processRequest(request, handoff))
207  return handoff;
208  if (!isPeerUpgrade(request))
209  return handoff;
210 
211  handoff.moved = true;
212 
213  JLOG(journal.debug()) << "Peer connection upgrade from " << remote_endpoint;
214 
215  error_code ec;
216  auto const local_endpoint(
217  stream_ptr->next_layer().socket().local_endpoint(ec));
218  if (ec)
219  {
220  JLOG(journal.debug()) << remote_endpoint << " failed: " << ec.message();
221  return handoff;
222  }
223 
224  auto consumer = m_resourceManager.newInboundEndpoint(
225  beast::IPAddressConversion::from_asio(remote_endpoint));
226  if (consumer.disconnect())
227  return handoff;
228 
229  auto const slot = m_peerFinder->new_inbound_slot(
231  beast::IPAddressConversion::from_asio(remote_endpoint));
232 
233  if (slot == nullptr)
234  {
235  // self-connect, close
236  handoff.moved = false;
237  return handoff;
238  }
239 
240  // TODO Validate HTTP request
241 
242  {
243  auto const types = beast::rfc2616::split_commas(request["Connect-As"]);
244  if (std::find_if(types.begin(), types.end(), [](std::string const& s) {
245  return boost::iequals(s, "peer");
246  }) == types.end())
247  {
248  handoff.moved = false;
249  handoff.response =
250  makeRedirectResponse(slot, request, remote_endpoint.address());
251  handoff.keep_alive = beast::rfc2616::is_keep_alive(request);
252  return handoff;
253  }
254  }
255 
256  auto const negotiatedVersion = negotiateProtocolVersion(request["Upgrade"]);
257  if (!negotiatedVersion)
258  {
259  m_peerFinder->on_closed(slot);
260  handoff.moved = false;
261  handoff.response = makeErrorResponse(
262  slot,
263  request,
264  remote_endpoint.address(),
265  "Unable to agree on a protocol version");
266  handoff.keep_alive = false;
267  return handoff;
268  }
269 
270  auto const sharedValue = makeSharedValue(*stream_ptr, journal);
271  if (!sharedValue)
272  {
273  m_peerFinder->on_closed(slot);
274  handoff.moved = false;
275  handoff.response = makeErrorResponse(
276  slot,
277  request,
278  remote_endpoint.address(),
279  "Incorrect security cookie");
280  handoff.keep_alive = false;
281  return handoff;
282  }
283 
284  try
285  {
286  auto publicKey = verifyHandshake(
287  request,
288  *sharedValue,
291  remote_endpoint.address(),
292  app_);
293 
294  {
295  // The node gets a reserved slot if it is in our cluster
296  // or if it has a reservation.
297  bool const reserved =
298  static_cast<bool>(app_.cluster().member(publicKey)) ||
299  app_.peerReservations().contains(publicKey);
300  auto const result =
301  m_peerFinder->activate(slot, publicKey, reserved);
302  if (result != PeerFinder::Result::success)
303  {
304  m_peerFinder->on_closed(slot);
305  JLOG(journal.debug())
306  << "Peer " << remote_endpoint << " redirected, slots full";
307  handoff.moved = false;
308  handoff.response = makeRedirectResponse(
309  slot, request, remote_endpoint.address());
310  handoff.keep_alive = false;
311  return handoff;
312  }
313  }
314 
315  auto const peer = std::make_shared<PeerImp>(
316  app_,
317  id,
318  slot,
319  std::move(request),
320  publicKey,
321  *negotiatedVersion,
322  consumer,
323  std::move(stream_ptr),
324  *this);
325  {
326  // As we are not on the strand, run() must be called
327  // while holding the lock, otherwise new I/O can be
328  // queued after a call to stop().
329  std::lock_guard<decltype(mutex_)> lock(mutex_);
330  {
331  auto const result = m_peers.emplace(peer->slot(), peer);
332  assert(result.second);
333  (void)result.second;
334  }
335  list_.emplace(peer.get(), peer);
336 
337  peer->run();
338  }
339  handoff.moved = true;
340  return handoff;
341  }
342  catch (std::exception const& e)
343  {
344  JLOG(journal.debug()) << "Peer " << remote_endpoint
345  << " fails handshake (" << e.what() << ")";
346 
347  m_peerFinder->on_closed(slot);
348  handoff.moved = false;
349  handoff.response = makeErrorResponse(
350  slot, request, remote_endpoint.address(), e.what());
351  handoff.keep_alive = false;
352  return handoff;
353  }
354 }
355 
356 //------------------------------------------------------------------------------
357 
358 bool
360 {
361  if (!is_upgrade(request))
362  return false;
363  auto const versions = parseProtocolVersions(request["Upgrade"]);
364  return !versions.empty();
365 }
366 
369 {
371  ss << "[" << std::setfill('0') << std::setw(3) << id << "] ";
372  return ss.str();
373 }
374 
378  http_request_type const& request,
379  address_type remote_address)
380 {
381  boost::beast::http::response<json_body> msg;
382  msg.version(request.version());
383  msg.result(boost::beast::http::status::service_unavailable);
384  msg.insert("Server", BuildInfo::getFullVersionString());
385  msg.insert("Remote-Address", remote_address);
386  msg.insert("Content-Type", "application/json");
387  msg.insert(boost::beast::http::field::connection, "close");
388  msg.body() = Json::objectValue;
389  {
390  auto const result = m_peerFinder->redirect(slot);
391  Json::Value& ips = (msg.body()["peer-ips"] = Json::arrayValue);
392  for (auto const& _ : m_peerFinder->redirect(slot))
393  ips.append(_.address.to_string());
394  }
395  msg.prepare_payload();
396  return std::make_shared<SimpleWriter>(msg);
397 }
398 
402  http_request_type const& request,
403  address_type remote_address,
404  std::string text)
405 {
406  boost::beast::http::response<boost::beast::http::empty_body> msg;
407  msg.version(request.version());
408  msg.result(boost::beast::http::status::bad_request);
409  msg.reason("Bad Request (" + text + ")");
410  msg.insert("Server", BuildInfo::getFullVersionString());
411  msg.insert("Remote-Address", remote_address.to_string());
412  msg.insert(boost::beast::http::field::connection, "close");
413  msg.prepare_payload();
414  return std::make_shared<SimpleWriter>(msg);
415 }
416 
417 //------------------------------------------------------------------------------
418 
419 void
421 {
422  assert(work_);
423 
424  auto usage = resourceManager().newOutboundEndpoint(remote_endpoint);
425  if (usage.disconnect())
426  {
427  JLOG(journal_.info()) << "Over resource limit: " << remote_endpoint;
428  return;
429  }
430 
431  auto const slot = peerFinder().new_outbound_slot(remote_endpoint);
432  if (slot == nullptr)
433  {
434  JLOG(journal_.debug()) << "Connect: No slot for " << remote_endpoint;
435  return;
436  }
437 
438  auto const p = std::make_shared<ConnectAttempt>(
439  app_,
440  io_service_,
442  usage,
443  setup_.context,
444  next_id_++,
445  slot,
446  app_.journal("Peer"),
447  *this);
448 
449  std::lock_guard lock(mutex_);
450  list_.emplace(p.get(), p);
451  p->run();
452 }
453 
454 //------------------------------------------------------------------------------
455 
456 // Adds a peer that is already handshaked and active
457 void
459 {
460  std::lock_guard lock(mutex_);
461 
462  {
463  auto const result = m_peers.emplace(peer->slot(), peer);
464  assert(result.second);
465  (void)result.second;
466  }
467 
468  {
469  auto const result = ids_.emplace(
470  std::piecewise_construct,
471  std::make_tuple(peer->id()),
472  std::make_tuple(peer));
473  assert(result.second);
474  (void)result.second;
475  }
476 
477  list_.emplace(peer.get(), peer);
478 
479  JLOG(journal_.debug()) << "activated " << peer->getRemoteAddress() << " ("
480  << peer->id() << ":"
481  << toBase58(
482  TokenType::NodePublic, peer->getNodePublic())
483  << ")";
484 
485  // As we are not on the strand, run() must be called
486  // while holding the lock, otherwise new I/O can be
487  // queued after a call to stop().
488  peer->run();
489 }
490 
491 void
493 {
494  std::lock_guard lock(mutex_);
495  auto const iter = m_peers.find(slot);
496  assert(iter != m_peers.end());
497  m_peers.erase(iter);
498 }
499 
500 //------------------------------------------------------------------------------
501 //
502 // Stoppable
503 //
504 //------------------------------------------------------------------------------
505 
506 // Caller must hold the mutex
507 void
509 {
510  if (isStopping() && areChildrenStopped() && list_.empty())
511  stopped();
512 }
513 
514 void
516 {
517  PeerFinder::Config config;
518 
519  if (app_.config().PEERS_MAX != 0)
520  config.maxPeers = app_.config().PEERS_MAX;
521 
522  config.outPeers = config.calcOutPeers();
523 
524  auto const port = serverHandler_.setup().overlay.port;
525 
526  config.peerPrivate = app_.config().PEER_PRIVATE;
527 
528  // Servers with peer privacy don't want to allow incoming connections
529  config.wantIncoming = (!config.peerPrivate) && (port != 0);
530 
531  // This will cause servers configured as validators to request that
532  // peers they connect to never report their IP address. We set this
533  // after we set the 'wantIncoming' because we want a "soft" version
534  // of peer privacy unless the operator explicitly asks for it.
536  config.peerPrivate = true;
537 
538  // if it's a private peer or we are running as standalone
539  // automatic connections would defeat the purpose.
540  config.autoConnect =
542  config.listeningPort = port;
543  config.features = "";
544  config.ipLimit = setup_.ipLimit;
545 
546  // Enforce business rules
547  config.applyTuning();
548 
549  m_peerFinder->setConfig(config);
550 
551  // Populate our boot cache: if there are no entries in [ips] then we use
552  // the entries in [ips_fixed].
553  auto bootstrapIps =
555 
556  // If nothing is specified, default to several well-known high-capacity
557  // servers to serve as bootstrap:
558  if (bootstrapIps.empty())
559  {
560  // Pool of servers operated by Ripple Labs Inc. - https://ripple.com
561  bootstrapIps.push_back("r.ripple.com 51235");
562 
563  // Pool of servers operated by Alloy Networks - https://www.alloy.ee
564  bootstrapIps.push_back("zaphod.alloy.ee 51235");
565 
566  // Pool of servers operated by ISRDC - https://isrdc.in
567  bootstrapIps.push_back("sahyadri.isrdc.in 51235");
568  }
569 
571  bootstrapIps,
572  [this](
573  std::string const& name,
574  std::vector<beast::IP::Endpoint> const& addresses) {
576  ips.reserve(addresses.size());
577  for (auto const& addr : addresses)
578  {
579  if (addr.port() == 0)
580  {
581  Throw<std::runtime_error>(
582  "Port not specified for "
583  "address:" +
584  addr.to_string());
585  }
586 
587  ips.push_back(to_string(addr));
588  }
589 
590  std::string const base("config: ");
591  if (!ips.empty())
592  m_peerFinder->addFallbackStrings(base + name, ips);
593  });
594 
595  // Add the ips_fixed from the rippled.cfg file
596  if (!app_.config().standalone() && !app_.config().IPS_FIXED.empty())
597  {
600  [this](
601  std::string const& name,
602  std::vector<beast::IP::Endpoint> const& addresses) {
603  if (!addresses.empty())
604  m_peerFinder->addFixedPeer(name, addresses);
605  });
606  }
607 }
608 
609 void
611 {
612  auto const timer = std::make_shared<Timer>(*this);
613  std::lock_guard lock(mutex_);
614  list_.emplace(timer.get(), timer);
615  timer_ = timer;
616  timer->run();
617 }
618 
619 void
621 {
622  strand_.dispatch(std::bind(&OverlayImpl::stop, this));
623 }
624 
625 void
627 {
628  std::lock_guard lock(mutex_);
629  checkStopped();
630 }
631 
632 //------------------------------------------------------------------------------
633 //
634 // PropertyStream
635 //
636 //------------------------------------------------------------------------------
637 
638 void
640 {
641  beast::PropertyStream::Set set("traffic", stream);
642  auto const stats = m_traffic.getCounts();
643  for (auto const& i : stats)
644  {
645  if (i)
646  {
648  item["category"] = i.name;
649  item["bytes_in"] = std::to_string(i.bytesIn.load());
650  item["messages_in"] = std::to_string(i.messagesIn.load());
651  item["bytes_out"] = std::to_string(i.bytesOut.load());
652  item["messages_out"] = std::to_string(i.messagesOut.load());
653  }
654  }
655 }
656 
657 //------------------------------------------------------------------------------
663 void
665 {
666  // Now track this peer
667  {
668  std::lock_guard lock(mutex_);
669  auto const result(ids_.emplace(
670  std::piecewise_construct,
671  std::make_tuple(peer->id()),
672  std::make_tuple(peer)));
673  assert(result.second);
674  (void)result.second;
675  }
676 
677  JLOG(journal_.debug()) << "activated " << peer->getRemoteAddress() << " ("
678  << peer->id() << ":"
679  << toBase58(
680  TokenType::NodePublic, peer->getNodePublic())
681  << ")";
682 
683  // We just accepted this peer so we have non-zero active peers
684  assert(size() != 0);
685 }
686 
687 void
689 {
690  std::lock_guard lock(mutex_);
691  ids_.erase(id);
692 }
693 
694 void
697  std::shared_ptr<PeerImp> const& from)
698 {
699  auto& hashRouter = app_.getHashRouter();
700  auto const n = m->list_size();
701  auto const& journal = from->pjournal();
702 
703  JLOG(journal.debug()) << "TMManifest, " << n
704  << (n == 1 ? " item" : " items");
705 
706  for (std::size_t i = 0; i < n; ++i)
707  {
708  auto& s = m->list().Get(i).stobject();
709 
710  if (auto mo = deserializeManifest(s))
711  {
712  uint256 const hash = mo->hash();
713  if (!hashRouter.addSuppressionPeer(hash, from->id()))
714  {
715  JLOG(journal.info()) << "Duplicate manifest #" << i + 1;
716  continue;
717  }
718 
719  if (!app_.validators().listed(mo->masterKey))
720  {
721  JLOG(journal.info()) << "Untrusted manifest #" << i + 1;
722  app_.getOPs().pubManifest(*mo);
723  continue;
724  }
725 
726  auto const serialized = mo->serialized;
727 
728  auto const result =
729  app_.validatorManifests().applyManifest(std::move(*mo));
730 
731  if (result == ManifestDisposition::accepted)
732  {
733  app_.getOPs().pubManifest(*deserializeManifest(serialized));
734  }
735 
736  if (result == ManifestDisposition::accepted)
737  {
738  auto db = app_.getWalletDB().checkoutDb();
739 
740  soci::transaction tr(*db);
741  static const char* const sql =
742  "INSERT INTO ValidatorManifests (RawData) VALUES "
743  "(:rawData);";
744  soci::blob rawData(*db);
745  convert(serialized, rawData);
746  *db << sql, soci::use(rawData);
747  tr.commit();
748 
749  protocol::TMManifests o;
750  o.add_list()->set_stobject(s);
751 
752  auto const toSkip = hashRouter.shouldRelay(hash);
753  if (toSkip)
754  foreach (send_if_not(
755  std::make_shared<Message>(o, protocol::mtMANIFESTS),
756  peer_in_set(*toSkip)))
757  ;
758  }
759  else
760  {
761  JLOG(journal.info())
762  << "Bad manifest #" << i + 1 << ": " << to_string(result);
763  }
764  }
765  else
766  {
767  JLOG(journal.warn()) << "Malformed manifest #" << i + 1;
768  continue;
769  }
770  }
771 }
772 
773 void
776  bool isInbound,
777  int number)
778 {
779  m_traffic.addCount(cat, isInbound, number);
780 }
781 
784 {
785  using namespace std::chrono;
786  using namespace std::chrono_literals;
787 
789  auto const numPeers{size()};
790  if (numPeers == 0)
791  return jv;
792 
793  // If greater than a hop away, we may need to gather or freshen data
794  if (hops > 0)
795  {
796  // Prevent crawl spamming
797  clock_type::time_point const last(csLast_.load());
798  if ((clock_type::now() - last) > 60s)
799  {
800  auto const timeout(seconds((hops * hops) * 10));
802 
803  // Check if already requested
804  if (csIDs_.empty())
805  {
806  {
807  std::lock_guard lock{mutex_};
808  for (auto& id : ids_)
809  csIDs_.emplace(id.first);
810  }
811 
812  // Relay request to active peers
813  protocol::TMGetPeerShardInfo tmGPS;
814  tmGPS.set_hops(hops);
815  foreach (send_always(std::make_shared<Message>(
816  tmGPS, protocol::mtGET_PEER_SHARD_INFO)))
817  ;
818 
819  if (csCV_.wait_for(l, timeout) == std::cv_status::timeout)
820  {
821  csIDs_.clear();
822  csCV_.notify_all();
823  }
824  csLast_ = duration_cast<seconds>(
825  clock_type::now().time_since_epoch());
826  }
827  else
828  csCV_.wait_for(l, timeout);
829  }
830  }
831 
832  // Combine the shard info from peers and their sub peers
834  for_each([&](std::shared_ptr<PeerImp> const& peer) {
835  if (auto psi = peer->getPeerShardInfo())
836  {
837  for (auto const& e : *psi)
838  {
839  auto it{peerShardInfo.find(e.first)};
840  if (it != peerShardInfo.end())
841  // The key exists so join the shard indexes.
842  it->second.shardIndexes += e.second.shardIndexes;
843  else
844  peerShardInfo.emplace(std::move(e));
845  }
846  }
847  });
848 
849  // Prepare json reply
850  auto& av = jv[jss::peers] = Json::Value(Json::arrayValue);
851  for (auto const& e : peerShardInfo)
852  {
853  auto& pv{av.append(Json::Value(Json::objectValue))};
854  if (pubKey)
855  pv[jss::public_key] = toBase58(TokenType::NodePublic, e.first);
856 
857  auto const& address{e.second.endpoint.address()};
858  if (!address.is_unspecified())
859  pv[jss::ip] = address.to_string();
860 
861  pv[jss::complete_shards] = to_string(e.second.shardIndexes);
862  }
863 
864  return jv;
865 }
866 
867 void
869 {
870  // Notify threads when every peer has received a last link.
871  // This doesn't account for every node that might reply but
872  // it is adequate.
874  if (csIDs_.erase(id) && csIDs_.empty())
875  csCV_.notify_all();
876 }
877 
880  PeerSet& set,
882  std::function<bool(std::shared_ptr<Peer> const&)> score)
883 {
885 
887  v.reserve(size());
888 
890  auto const s = e->getScore(score(e));
891  v.emplace_back(s, std::move(e));
892  });
893 
894  std::sort(v.begin(), v.end(), [](item const& lhs, item const& rhs) {
895  return lhs.first > rhs.first;
896  });
897 
898  std::size_t accepted = 0;
899  for (auto const& e : v)
900  {
901  if (set.insert(e.second) && ++accepted >= limit)
902  break;
903  }
904  return accepted;
905 }
906 
913 {
914  std::lock_guard lock(mutex_);
915  return ids_.size();
916 }
917 
918 int
920 {
921  return m_peerFinder->config().maxPeers;
922 }
923 
926 {
927  using namespace std::chrono;
928  Json::Value jv;
929  auto& av = jv["active"] = Json::Value(Json::arrayValue);
930 
932  auto& pv = av.append(Json::Value(Json::objectValue));
933  pv[jss::public_key] = base64_encode(
934  sp->getNodePublic().data(), sp->getNodePublic().size());
935  pv[jss::type] = sp->slot()->inbound() ? "in" : "out";
936  pv[jss::uptime] = static_cast<std::uint32_t>(
937  duration_cast<seconds>(sp->uptime()).count());
938  if (sp->crawl())
939  {
940  pv[jss::ip] = sp->getRemoteAddress().address().to_string();
941  if (sp->slot()->inbound())
942  {
943  if (auto port = sp->slot()->listening_port())
944  pv[jss::port] = *port;
945  }
946  else
947  {
948  pv[jss::port] = std::to_string(sp->getRemoteAddress().port());
949  }
950  }
951 
952  {
953  auto version{sp->getVersion()};
954  if (!version.empty())
955  pv[jss::version] = std::move(version);
956  }
957 
958  std::uint32_t minSeq, maxSeq;
959  sp->ledgerRange(minSeq, maxSeq);
960  if (minSeq != 0 || maxSeq != 0)
961  pv[jss::complete_ledgers] =
962  std::to_string(minSeq) + "-" + std::to_string(maxSeq);
963 
964  if (auto shardIndexes = sp->getShardIndexes())
965  pv[jss::complete_shards] = to_string(*shardIndexes);
966  });
967 
968  return jv;
969 }
970 
973 {
974  bool const humanReadable = false;
975  bool const admin = false;
976  bool const counters = false;
977 
978  Json::Value server_info =
979  app_.getOPs().getServerInfo(humanReadable, admin, counters);
980 
981  // Filter out some information
982  server_info.removeMember(jss::hostid);
983  server_info.removeMember(jss::load_factor_fee_escalation);
984  server_info.removeMember(jss::load_factor_fee_queue);
985  server_info.removeMember(jss::validation_quorum);
986 
987  if (server_info.isMember(jss::validated_ledger))
988  {
989  Json::Value& validated_ledger = server_info[jss::validated_ledger];
990 
991  validated_ledger.removeMember(jss::base_fee);
992  validated_ledger.removeMember(jss::reserve_base_xrp);
993  validated_ledger.removeMember(jss::reserve_inc_xrp);
994  }
995 
996  return server_info;
997 }
998 
1001 {
1002  return getCountsJson(app_, 10);
1003 }
1004 
1007 {
1008  Json::Value validators = app_.validators().getJson();
1009 
1010  if (validators.isMember(jss::publisher_lists))
1011  {
1012  Json::Value& publisher_lists = validators[jss::publisher_lists];
1013 
1014  for (auto& publisher : publisher_lists)
1015  {
1016  publisher.removeMember(jss::list);
1017  }
1018  }
1019 
1020  validators.removeMember(jss::signing_keys);
1021  validators.removeMember(jss::trusted_validator_keys);
1022  validators.removeMember(jss::validation_quorum);
1023 
1024  Json::Value validatorSites = app_.validatorSites().getJson();
1025 
1026  if (validatorSites.isMember(jss::validator_sites))
1027  {
1028  validators[jss::validator_sites] =
1029  std::move(validatorSites[jss::validator_sites]);
1030  }
1031 
1032  return validators;
1033 }
1034 
1035 // Returns information on verified peers.
1038 {
1039  return foreach (get_peer_json());
1040 }
1041 
1042 bool
1044 {
1045  if (req.target() != "/crawl" ||
1047  return false;
1048 
1049  boost::beast::http::response<json_body> msg;
1050  msg.version(req.version());
1051  msg.result(boost::beast::http::status::ok);
1052  msg.insert("Server", BuildInfo::getFullVersionString());
1053  msg.insert("Content-Type", "application/json");
1054  msg.insert("Connection", "close");
1055  msg.body()["version"] = Json::Value(2u);
1056 
1058  {
1059  msg.body()["overlay"] = getOverlayInfo();
1060  }
1062  {
1063  msg.body()["server"] = getServerInfo();
1064  }
1066  {
1067  msg.body()["counts"] = getServerCounts();
1068  }
1070  {
1071  msg.body()["unl"] = getUnlInfo();
1072  }
1073 
1074  msg.prepare_payload();
1075  handoff.response = std::make_shared<SimpleWriter>(msg);
1076  return true;
1077 }
1078 
1079 bool
1081  http_request_type const& req,
1082  Handoff& handoff)
1083 {
1084  // If the target is in the form "/vl/<validator_list_public_key>",
1085  // return the most recent validator list for that key.
1086  if (!req.target().starts_with("/vl/") || !setup_.vlEnabled)
1087  return false;
1088 
1089  auto key = req.target();
1090  if (key.starts_with("/vl/"))
1091  key.remove_prefix(strlen("/vl/"));
1092  else
1093  key.remove_prefix(strlen("/unl/"));
1094  if (key.empty())
1095  return false;
1096 
1097  // find the list
1098  auto vl = app_.validators().getAvailable(key);
1099 
1100  boost::beast::http::response<json_body> msg;
1101  msg.version(req.version());
1102  msg.insert("Server", BuildInfo::getFullVersionString());
1103  msg.insert("Content-Type", "application/json");
1104  msg.insert("Connection", "close");
1105 
1106  if (!vl)
1107  {
1108  // 404 not found
1109  msg.result(boost::beast::http::status::not_found);
1110  msg.insert("Content-Length", "0");
1111 
1112  msg.body() = Json::nullValue;
1113  }
1114  else
1115  {
1116  msg.result(boost::beast::http::status::ok);
1117 
1118  msg.body() = *vl;
1119  }
1120 
1121  msg.prepare_payload();
1122  handoff.response = std::make_shared<SimpleWriter>(msg);
1123  return true;
1124 }
1125 
1126 bool
1128 {
1129  // Take advantage of || short-circuiting
1130  return processCrawl(req, handoff) || processValidatorList(req, handoff);
1131 }
1132 
1135 {
1137  ret.reserve(size());
1138 
1139  for_each([&ret](std::shared_ptr<PeerImp>&& sp) {
1140  ret.emplace_back(std::move(sp));
1141  });
1142 
1143  return ret;
1144 }
1145 
1146 void
1148 {
1149  for_each(
1150  [index](std::shared_ptr<PeerImp>&& sp) { sp->checkSanity(index); });
1151 }
1152 
1153 void
1155 {
1156  for_each([](std::shared_ptr<PeerImp>&& sp) { sp->check(); });
1157 }
1158 
1161 {
1162  std::lock_guard lock(mutex_);
1163  auto const iter = ids_.find(id);
1164  if (iter != ids_.end())
1165  return iter->second.lock();
1166  return {};
1167 }
1168 
1169 // A public key hash map was not used due to the peer connect/disconnect
1170 // update overhead outweighing the performance of a small set linear search.
1173 {
1174  std::lock_guard lock(mutex_);
1175  for (auto const& e : ids_)
1176  {
1177  if (auto peer = e.second.lock())
1178  {
1179  if (peer->getNodePublic() == pubKey)
1180  return peer;
1181  }
1182  }
1183  return {};
1184 }
1185 
1186 void
1187 OverlayImpl::send(protocol::TMProposeSet& m)
1188 {
1189  if (setup_.expire)
1190  m.set_hops(0);
1191  auto const sm = std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER);
1192  for_each([&](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1193 }
1194 void
1195 OverlayImpl::send(protocol::TMValidation& m)
1196 {
1197  if (setup_.expire)
1198  m.set_hops(0);
1199  auto const sm = std::make_shared<Message>(m, protocol::mtVALIDATION);
1200  for_each([&](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1201 
1202  SerialIter sit(m.validation().data(), m.validation().size());
1203  auto val = std::make_shared<STValidation>(
1204  std::ref(sit),
1205  [this](PublicKey const& pk) {
1207  },
1208  false);
1209  app_.getOPs().pubValidation(val);
1210 }
1211 
1212 void
1213 OverlayImpl::relay(protocol::TMProposeSet& m, uint256 const& uid)
1214 {
1215  if (m.has_hops() && m.hops() >= maxTTL)
1216  return;
1217  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1218  {
1219  auto const sm =
1220  std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER);
1222  if (toSkip->find(p->id()) == toSkip->end())
1223  p->send(sm);
1224  });
1225  }
1226 }
1227 
1228 void
1229 OverlayImpl::relay(protocol::TMValidation& m, uint256 const& uid)
1230 {
1231  if (m.has_hops() && m.hops() >= maxTTL)
1232  return;
1233  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1234  {
1235  auto const sm = std::make_shared<Message>(m, protocol::mtVALIDATION);
1237  if (toSkip->find(p->id()) == toSkip->end())
1238  p->send(sm);
1239  });
1240  }
1241 }
1242 
1243 //------------------------------------------------------------------------------
1244 
1245 void
1247 {
1248  std::lock_guard lock(mutex_);
1249  list_.erase(&child);
1250  if (list_.empty())
1251  checkStopped();
1252 }
1253 
1254 void
1256 {
1257  // Calling list_[].second->stop() may cause list_ to be modified
1258  // (OverlayImpl::remove() may be called on this same thread). So
1259  // iterating directly over list_ to call child->stop() could lead to
1260  // undefined behavior.
1261  //
1262  // Therefore we copy all of the weak/shared ptrs out of list_ before we
1263  // start calling stop() on them. That guarantees OverlayImpl::remove()
1264  // won't be called until vector<> children leaves scope.
1266  {
1267  std::lock_guard lock(mutex_);
1268  if (!work_)
1269  return;
1270  work_ = boost::none;
1271 
1272  children.reserve(list_.size());
1273  for (auto const& element : list_)
1274  {
1275  children.emplace_back(element.second.lock());
1276  }
1277  } // lock released
1278 
1279  for (auto const& child : children)
1280  {
1281  if (child != nullptr)
1282  child->stop();
1283  }
1284 }
1285 
1286 void
1288 {
1289  auto const result = m_peerFinder->autoconnect();
1290  for (auto addr : result)
1291  connect(addr);
1292 }
1293 
1294 void
1296 {
1297  auto const result = m_peerFinder->buildEndpointsForPeers();
1298  for (auto const& e : result)
1299  {
1301  {
1302  std::lock_guard lock(mutex_);
1303  auto const iter = m_peers.find(e.first);
1304  if (iter != m_peers.end())
1305  peer = iter->second.lock();
1306  }
1307  if (peer)
1308  peer->sendEndpoints(e.second.begin(), e.second.end());
1309  }
1310 }
1311 
1312 //------------------------------------------------------------------------------
1313 
1314 bool
1316 {
1317  auto const& p = std::dynamic_pointer_cast<PeerImp>(bp);
1318  return p->hasLedger(hash_, seq_);
1319 }
1320 
1321 bool
1323 {
1324  auto const& p = std::dynamic_pointer_cast<PeerImp>(bp);
1325  return p->hasTxSet(hash_);
1326 }
1327 
1328 //------------------------------------------------------------------------------
1329 
1332 {
1334 
1335  {
1336  auto const& section = config.section("overlay");
1338  setup.expire = get<bool>(section, "expire", false);
1339 
1340  set(setup.ipLimit, "ip_limit", section);
1341  if (setup.ipLimit < 0)
1342  Throw<std::runtime_error>("Configured IP limit is invalid");
1343 
1344  std::string ip;
1345  set(ip, "public_ip", section);
1346  if (!ip.empty())
1347  {
1348  boost::system::error_code ec;
1349  setup.public_ip = beast::IP::Address::from_string(ip, ec);
1351  Throw<std::runtime_error>("Configured public IP is invalid");
1352  }
1353  }
1354 
1355  {
1356  auto const& section = config.section("crawl");
1357  auto const& values = section.values();
1358 
1359  if (values.size() > 1)
1360  {
1361  Throw<std::runtime_error>(
1362  "Configured [crawl] section is invalid, too many values");
1363  }
1364 
1365  bool crawlEnabled = true;
1366 
1367  // Only allow "0|1" as a value
1368  if (values.size() == 1)
1369  {
1370  try
1371  {
1372  crawlEnabled = boost::lexical_cast<bool>(values.front());
1373  }
1374  catch (boost::bad_lexical_cast const&)
1375  {
1376  Throw<std::runtime_error>(
1377  "Configured [crawl] section has invalid value: " +
1378  values.front());
1379  }
1380  }
1381 
1382  if (crawlEnabled)
1383  {
1384  if (get<bool>(section, "overlay", true))
1385  {
1387  }
1388  if (get<bool>(section, "server", true))
1389  {
1391  }
1392  if (get<bool>(section, "counts", false))
1393  {
1395  }
1396  if (get<bool>(section, "unl", true))
1397  {
1399  }
1400  }
1401  }
1402  {
1403  auto const& section = config.section("vl");
1404 
1405  set(setup.vlEnabled, "enabled", section);
1406  }
1407 
1408  try
1409  {
1410  auto id = config.legacy("network_id");
1411 
1412  if (!id.empty())
1413  {
1414  if (id == "main")
1415  id = "0";
1416 
1417  if (id == "testnet")
1418  id = "1";
1419 
1420  if (id == "devnet")
1421  id = "2";
1422 
1423  setup.networkID = beast::lexicalCastThrow<std::uint32_t>(id);
1424  }
1425  }
1426  catch (...)
1427  {
1428  Throw<std::runtime_error>(
1429  "Configured [network_id] section is invalid: must be a number "
1430  "or one of the strings 'main', 'testnet' or 'devnet'.");
1431  }
1432 
1433  return setup;
1434 }
1435 
1438  Application& app,
1439  Overlay::Setup const& setup,
1440  Stoppable& parent,
1443  Resolver& resolver,
1444  boost::asio::io_service& io_service,
1445  BasicConfig const& config,
1446  beast::insight::Collector::ptr const& collector)
1447 {
1448  return std::make_unique<OverlayImpl>(
1449  app,
1450  setup,
1451  parent,
1452  serverHandler,
1454  resolver,
1455  io_service,
1456  config,
1457  collector);
1458 }
1459 
1460 } // namespace ripple
beast::PropertyStream::Source::name
std::string const & name() const
Returns the name of this source.
Definition: beast_PropertyStream.cpp:190
ripple::Resource::Manager::newInboundEndpoint
virtual Consumer newInboundEndpoint(beast::IP::Endpoint const &address)=0
Create a new endpoint keyed by inbound IP address or the forwarded IP if proxied.
ripple::OverlayImpl::findPeerByShortID
std::shared_ptr< Peer > findPeerByShortID(Peer::id_t const &id) override
Returns the peer with the matching short id, or null.
Definition: OverlayImpl.cpp:1160
ripple::OverlayImpl::relay
void relay(protocol::TMProposeSet &m, uint256 const &uid) override
Relay a proposal.
Definition: OverlayImpl.cpp:1213
ripple::Resource::Manager::newOutboundEndpoint
virtual Consumer newOutboundEndpoint(beast::IP::Endpoint const &address)=0
Create a new endpoint keyed by outbound IP address and port.
ripple::Application
Definition: Application.h:94
ripple::OverlayImpl::getServerCounts
Json::Value getServerCounts()
Returns information about the local server's performance counters.
Definition: OverlayImpl.cpp:1000
ripple::OverlayImpl::selectPeers
std::size_t selectPeers(PeerSet &set, std::size_t limit, std::function< bool(std::shared_ptr< Peer > const &)> score) override
Select from active peers.
Definition: OverlayImpl.cpp:879
ripple::OverlayImpl::journal_
const beast::Journal journal_
Definition: OverlayImpl.h:106
ripple::CrawlOptions::Disabled
@ Disabled
Definition: OverlayImpl.cpp:68
std::make_tuple
T make_tuple(T... args)
ripple::OverlayImpl::address_type
boost::asio::ip::address address_type
Definition: OverlayImpl.h:77
ripple::Application::cluster
virtual Cluster & cluster()=0
ripple::OverlayImpl::Timer::run
void run()
Definition: OverlayImpl.cpp:102
ripple::NetworkOPs::getServerInfo
virtual Json::Value getServerInfo(bool human, bool admin, bool counters)=0
ripple::TrafficCount::getCounts
auto const & getCounts() const
An up-to-date copy of all the counters.
Definition: TrafficCount.h:179
std::bind
T bind(T... args)
ripple::get_peer_json::operator()
Json::Value operator()()
Definition: OverlayImpl.cpp:60
std::string
STL class.
std::shared_ptr
STL class.
ripple::ManifestCache::getMasterKey
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
Definition: app/misc/impl/Manifest.cpp:309
ripple::OverlayImpl::work_
boost::optional< boost::asio::io_service::work > work_
Definition: OverlayImpl.h:99
ripple::get_peer_json::operator()
void operator()(std::shared_ptr< Peer > const &peer)
Definition: OverlayImpl.cpp:54
std::exception
STL class.
ripple::calcNodeID
NodeID calcNodeID(PublicKey const &pk)
Calculate the 160-bit node ID from a node public key.
Definition: PublicKey.cpp:299
ripple::Stoppable::stopped
void stopped()
Called by derived classes to indicate that the stoppable has stopped.
Definition: Stoppable.cpp:72
beast::PropertyStream::Map
Definition: PropertyStream.h:236
ripple::OverlayImpl::collect_metrics
void collect_metrics()
Definition: OverlayImpl.h:526
ripple::InfoSub::Source::pubManifest
virtual void pubManifest(Manifest const &)=0
ripple::OverlayImpl::is_upgrade
static bool is_upgrade(boost::beast::http::header< true, Fields > const &req)
Definition: OverlayImpl.h:293
ripple::OverlayImpl::ids_
hash_map< Peer::id_t, std::weak_ptr< PeerImp > > ids_
Definition: OverlayImpl.h:112
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::maxTTL
constexpr std::uint32_t maxTTL
Definition: OverlayImpl.h:55
std::pair
ripple::http_request_type
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition: Handoff.h:31
std::vector::reserve
T reserve(T... args)
ripple::OverlayImpl::autoConnect
void autoConnect()
Definition: OverlayImpl.cpp:1287
ripple::ValidatorList::getAvailable
boost::optional< Json::Value > getAvailable(boost::beast::string_view const &pubKey)
Returns the current valid list for the given publisher key, if available, as a Json object.
Definition: ValidatorList.cpp:790
ripple::Application::validatorSites
virtual ValidatorSite & validatorSites()=0
ripple::Overlay::Setup::crawlOptions
std::uint32_t crawlOptions
Definition: Overlay.h:78
ripple::convert
void convert(soci::blob &from, std::vector< std::uint8_t > &to)
Definition: SociDB.cpp:155
ripple::OverlayImpl::csIDs_
std::set< std::uint32_t > csIDs_
Definition: OverlayImpl.h:125
ripple::OverlayImpl::m_resolver
Resolver & m_resolver
Definition: OverlayImpl.h:113
ripple::OverlayImpl::mutex_
std::recursive_mutex mutex_
Definition: OverlayImpl.h:101
ripple::OverlayImpl::Timer::on_timer
void on_timer(error_code ec)
Definition: OverlayImpl.cpp:110
std::vector
STL class.
std::find_if
T find_if(T... args)
std::vector::size
T size(T... args)
ripple::Application::peerReservations
virtual PeerReservationTable & peerReservations()=0
ripple::OverlayImpl::next_id_
std::atomic< Peer::id_t > next_id_
Definition: OverlayImpl.h:114
ripple::base64_encode
std::string base64_encode(std::uint8_t const *data, std::size_t len)
Definition: base64.cpp:236
ripple::PublicKey::empty
bool empty() const noexcept
Definition: PublicKey.h:117
ripple::make_SSLContext
std::shared_ptr< boost::asio::ssl::context > make_SSLContext(std::string const &cipherList)
Create a self-signed SSL context that allows anonymous Diffie Hellman.
Definition: make_SSLContext.cpp:450
ripple::make_Overlay
std::unique_ptr< Overlay > make_Overlay(Application &app, Overlay::Setup const &setup, Stoppable &parent, ServerHandler &serverHandler, Resource::Manager &resourceManager, Resolver &resolver, boost::asio::io_service &io_service, BasicConfig const &config, beast::insight::Collector::ptr const &collector)
Creates the implementation of Overlay.
Definition: OverlayImpl.cpp:1437
ripple::OverlayImpl::makePrefix
static std::string makePrefix(std::uint32_t id)
Definition: OverlayImpl.cpp:368
ripple::PeerFinder::Config::features
std::string features
The set of features we advertise.
Definition: PeerfinderManager.h:73
ripple::OverlayImpl::onHandoff
Handoff onHandoff(std::unique_ptr< stream_type > &&bundle, http_request_type &&request, endpoint_type remote_endpoint) override
Conditionally accept an incoming HTTP request.
Definition: OverlayImpl.cpp:196
std::chrono::seconds
ripple::Config::PEER_PRIVATE
bool PEER_PRIVATE
Definition: Config.h:141
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::CrawlOptions::ServerCounts
@ ServerCounts
Definition: OverlayImpl.cpp:71
std::set::emplace
T emplace(T... args)
ripple::OverlayImpl::csCV_
std::condition_variable csCV_
Definition: OverlayImpl.h:123
std::stringstream
STL class.
ripple::ServerHandlerImp::setup
void setup(Setup const &setup, beast::Journal journal)
Definition: ServerHandlerImp.cpp:132
ripple::OverlayImpl::strand_
boost::asio::io_service::strand strand_
Definition: OverlayImpl.h:100
std::shared_ptr::get
T get(T... args)
ripple::OverlayImpl::getServerInfo
Json::Value getServerInfo()
Returns information about the local server.
Definition: OverlayImpl.cpp:972
std::lock_guard
STL class.
ripple::OverlayImpl::onStart
void onStart() override
Override called during start.
Definition: OverlayImpl.cpp:610
ripple::parseProtocolVersions
std::vector< ProtocolVersion > parseProtocolVersions(boost::beast::string_view const &value)
Parse a set of protocol versions.
Definition: ProtocolVersion.cpp:76
boost
Definition: IPAddress.h:117
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:86
std::setfill
T setfill(T... args)
std::function
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::PeerFinder::Manager::new_outbound_slot
virtual std::shared_ptr< Slot > new_outbound_slot(beast::IP::Endpoint const &remote_endpoint)=0
Create a new outbound slot with the specified remote endpoint.
ripple::OverlayImpl::connect
void connect(beast::IP::Endpoint const &remote_endpoint) override
Establish a peer connection to the specified endpoint.
Definition: OverlayImpl.cpp:420
ripple::OverlayImpl::json
Json::Value json() override
Return diagnostics on the status of all peers.
Definition: OverlayImpl.cpp:1037
ripple::OverlayImpl::setup
Setup const & setup() const
Definition: OverlayImpl.h:168
ripple::OverlayImpl::timer_count_
int timer_count_
Definition: OverlayImpl.h:115
ripple::PeerFinder::Config::peerPrivate
bool peerPrivate
true if we want our IP address kept private.
Definition: PeerfinderManager.h:61
ripple::OverlayImpl::processValidatorList
bool processValidatorList(http_request_type const &req, Handoff &handoff)
Handles validator list requests.
Definition: OverlayImpl.cpp:1080
beast::PropertyStream::Set
Definition: PropertyStream.h:308
ripple::peer_in_set
Select all peers that are in the specified set.
Definition: predicates.h:160
std::sort
T sort(T... args)
ripple::Application::getOPs
virtual NetworkOPs & getOPs()=0
ripple::Application::getWalletDB
virtual DatabaseCon & getWalletDB()=0
Retrieve the "wallet database".
ripple::OverlayImpl::m_traffic
TrafficCount m_traffic
Definition: OverlayImpl.h:110
ripple::OverlayImpl::setup_
Setup setup_
Definition: OverlayImpl.h:105
ripple::Section::values
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition: BasicConfig.h:76
std::set::clear
T clear(T... args)
beast::IP::is_private
bool is_private(AddressV4 const &addr)
Returns true if the address is a private unroutable address.
Definition: IPAddressV4.cpp:29
ripple::send_always
Sends a message to all peers.
Definition: predicates.h:31
ripple::OverlayImpl::onChildrenStopped
void onChildrenStopped() override
Override called when all children have stopped.
Definition: OverlayImpl.cpp:626
ripple::OverlayImpl::cond_
std::condition_variable_any cond_
Definition: OverlayImpl.h:102
ripple::negotiateProtocolVersion
boost::optional< ProtocolVersion > negotiateProtocolVersion(std::vector< ProtocolVersion > const &versions)
Given a list of supported protocol versions, choose the one we prefer.
Definition: ProtocolVersion.cpp:129
ripple::OverlayImpl::for_each
void for_each(UnaryFunc &&f)
Definition: OverlayImpl.h:245
ripple::verifyHandshake
PublicKey verifyHandshake(boost::beast::http::fields const &headers, ripple::uint256 const &sharedValue, boost::optional< std::uint32_t > networkID, beast::IP::Address public_ip, beast::IP::Address remote, Application &app)
Validate header fields necessary for upgrading the link to the peer protocol.
Definition: Handshake.cpp:152
ripple::TrafficCount::category
category
Definition: TrafficCount.h:67
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::Cluster::member
boost::optional< std::string > member(PublicKey const &node) const
Determines whether a node belongs in the cluster.
Definition: Cluster.cpp:39
ripple::PeerFinder::Result::success
@ success
ripple::OverlayImpl::peerFinder
PeerFinder::Manager & peerFinder()
Definition: OverlayImpl.h:150
ripple::base_uint< 256 >
ripple::OverlayImpl::send
void send(protocol::TMProposeSet &m) override
Broadcast a proposal.
Definition: OverlayImpl.cpp:1187
beast::rfc2616::is_keep_alive
bool is_keep_alive(boost::beast::http::message< isRequest, Body, Fields > const &m)
Definition: rfc2616.h:475
ripple::setup_Overlay
Overlay::Setup setup_Overlay(BasicConfig const &config)
Definition: OverlayImpl.cpp:1331
ripple::OverlayImpl::csMutex_
std::mutex csMutex_
Definition: OverlayImpl.h:122
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::CrawlOptions::Unl
@ Unl
Definition: OverlayImpl.cpp:72
ripple::OverlayImpl::onManifests
void onManifests(std::shared_ptr< protocol::TMManifests > const &m, std::shared_ptr< PeerImp > const &from)
Definition: OverlayImpl.cpp:695
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:200
ripple::Overlay::Setup::public_ip
beast::IP::Address public_ip
Definition: Overlay.h:76
ripple::PeerFinder::Config::wantIncoming
bool wantIncoming
true if we want to accept incoming connections.
Definition: PeerfinderManager.h:64
ripple::DatabaseCon::checkoutDb
LockedSociSession checkoutDb()
Definition: DatabaseCon.h:129
ripple::OverlayImpl::resourceManager
Resource::Manager & resourceManager()
Definition: OverlayImpl.h:156
ripple::OverlayImpl::getActivePeers
PeerSequence getActivePeers() override
Returns a sequence representing the current list of peers.
Definition: OverlayImpl.cpp:1134
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
beast::PropertyStream::Source::add
void add(Source &source)
Add a child source.
Definition: beast_PropertyStream.cpp:196
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
std::atomic::load
T load(T... args)
ripple::OverlayImpl::getOverlayInfo
Json::Value getOverlayInfo()
Returns information about peers on the overlay network.
Definition: OverlayImpl.cpp:925
ripple::OverlayImpl::io_service_
boost::asio::io_service & io_service_
Definition: OverlayImpl.h:98
ripple::Application::config
virtual Config & config()=0
ripple::ValidatorSite::getJson
Json::Value getJson() const
Return JSON representation of configured validator sites.
Definition: ValidatorSite.cpp:587
ripple::Config::IPS_FIXED
std::vector< std::string > IPS_FIXED
Definition: Config.h:119
ripple::ServerHandlerImp
Definition: ServerHandlerImp.h:46
ripple::Config::standalone
bool standalone() const
Definition: Config.h:216
std::unique_lock
STL class.
ripple::Resolver
Definition: Resolver.h:30
ripple::Stoppable::areChildrenStopped
bool areChildrenStopped() const
Returns true if all children have stopped.
Definition: Stoppable.cpp:66
ripple::OverlayImpl::m_stats
Stats m_stats
Definition: OverlayImpl.h:521
ripple::OverlayImpl::serverHandler
ServerHandler & serverHandler()
Definition: OverlayImpl.h:162
std::to_string
T to_string(T... args)
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:276
ripple::OverlayImpl::getUnlInfo
Json::Value getUnlInfo()
Returns information about the local server's UNL.
Definition: OverlayImpl.cpp:1006
ripple::OverlayImpl::checkStopped
void checkStopped()
Definition: OverlayImpl.cpp:508
ripple::ValidatorList::listed
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
Definition: ValidatorList.cpp:551
ripple::makeSharedValue
boost::optional< uint256 > makeSharedValue(stream_type &ssl, beast::Journal journal)
Computes a shared value based on the SSL connection state.
Definition: Handshake.cpp:70
ripple::PeerFinder::Config::outPeers
double outPeers
The number of automatic outbound connections to maintain.
Definition: PeerfinderManager.h:58
ripple::PeerFinder::Config::maxPeers
int maxPeers
The largest number of public peer slots to allow.
Definition: PeerfinderManager.h:46
beast::Journal::info
Stream info() const
Definition: Journal.h:321
std::set::erase
T erase(T... args)
ripple::BasicConfig::legacy
void legacy(std::string const &section, std::string value)
Set a value that is not a key/value pair.
Definition: BasicConfig.cpp:175
ripple::Application::logs
virtual Logs & logs()=0
ripple::get_peer_json::json
Json::Value json
Definition: OverlayImpl.cpp:49
ripple::OverlayImpl::app_
Application & app_
Definition: OverlayImpl.h:97
ripple::SerialIter
Definition: Serializer.h:368
ripple::OverlayImpl::m_peerFinder
std::unique_ptr< PeerFinder::Manager > m_peerFinder
Definition: OverlayImpl.h:109
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::OverlayImpl::serverHandler_
ServerHandler & serverHandler_
Definition: OverlayImpl.h:107
ripple::OverlayImpl::onPrepare
void onPrepare() override
Override called during preparation.
Definition: OverlayImpl.cpp:515
std::uint32_t
std::condition_variable_any::wait
T wait(T... args)
ripple::OverlayImpl::TrafficGauges
Definition: OverlayImpl.h:485
ripple::OverlayImpl::Child::Child
Child(OverlayImpl &overlay)
Definition: OverlayImpl.cpp:78
ripple::HashRouter::shouldRelay
boost::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:112
beast::rfc2616::split_commas
Result split_commas(FwdIt first, FwdIt last)
Definition: rfc2616.h:288
ripple::OverlayImpl::size
std::size_t size() override
The number of active peers on the network Active peers are only those peers that have completed the h...
Definition: OverlayImpl.cpp:912
ripple::Application::getValidationPublicKey
virtual PublicKey const & getValidationPublicKey() const =0
ripple::Handoff::moved
bool moved
Definition: Handoff.h:41
ripple::OverlayImpl::OverlayImpl
OverlayImpl(Application &app, Setup const &setup, Stoppable &parent, ServerHandler &serverHandler, Resource::Manager &resourceManager, Resolver &resolver, boost::asio::io_service &io_service, BasicConfig const &config, beast::insight::Collector::ptr const &collector)
Definition: OverlayImpl.cpp:135
std::condition_variable::wait_for
T wait_for(T... args)
ripple::Application::validators
virtual ValidatorList & validators()=0
ripple::OverlayImpl::processRequest
bool processRequest(http_request_type const &req, Handoff &handoff)
Handles non-peer protocol requests.
Definition: OverlayImpl.cpp:1127
ripple::ManifestDisposition::accepted
@ accepted
Manifest is valid.
ripple::Resource::Manager
Tracks load and resource consumption.
Definition: ResourceManager.h:36
ripple::BuildInfo::getFullVersionString
std::string const & getFullVersionString()
Full server version string.
Definition: BuildInfo.cpp:73
ripple::PeerFinder::Config::applyTuning
void applyTuning()
Adjusts the values so they follow the business rules.
Definition: PeerfinderConfig.cpp:44
ripple::Config::PEERS_MAX
std::size_t PEERS_MAX
Definition: Config.h:142
ripple::OverlayImpl::~OverlayImpl
~OverlayImpl()
Definition: OverlayImpl.cpp:182
ripple::getCountsJson
Json::Value getCountsJson(Application &app, int minObjectCount)
Definition: GetCounts.cpp:64
ripple::OverlayImpl::Child::~Child
virtual ~Child()
Definition: OverlayImpl.cpp:82
ripple::OverlayImpl::m_resourceManager
Resource::Manager & m_resourceManager
Definition: OverlayImpl.h:108
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::deserializeManifest
boost::optional< Manifest > deserializeManifest(Slice s)
Constructs Manifest from serialized string.
Definition: app/misc/impl/Manifest.cpp:38
ripple::OverlayImpl::checkSanity
void checkSanity(std::uint32_t) override
Calls the checkSanity function on each peer.
Definition: OverlayImpl.cpp:1147
ripple::Overlay::Setup::ipLimit
int ipLimit
Definition: Overlay.h:77
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::Application::validatorManifests
virtual ManifestCache & validatorManifests()=0
Json::Value::removeMember
Value removeMember(const char *key)
Remove and return the named member.
Definition: json_value.cpp:907
ripple::PeerFinder::Config::listeningPort
std::uint16_t listeningPort
The listening port number.
Definition: PeerfinderManager.h:70
ripple::send_if_not
send_if_not_pred< Predicate > send_if_not(std::shared_ptr< Message > const &m, Predicate const &f)
Helper function to aid in type deduction.
Definition: predicates.h:107
ripple::Overlay::Setup::vlEnabled
bool vlEnabled
Definition: Overlay.h:80
ripple::OverlayImpl::remove
void remove(std::shared_ptr< PeerFinder::Slot > const &slot)
Definition: OverlayImpl.cpp:492
ripple::Overlay
Manages the set of connected peers.
Definition: Overlay.h:52
ripple::CrawlOptions::Overlay
@ Overlay
Definition: OverlayImpl.cpp:69
std::vector::begin
T begin(T... args)
std
STL namespace.
ripple::get_peer_json::get_peer_json
get_peer_json()=default
ripple::OverlayImpl::activate
void activate(std::shared_ptr< PeerImp > const &peer)
Called when a peer has connected successfully This is called after the peer handshake has been comple...
Definition: OverlayImpl.cpp:664
ripple::PeerFinder::Config::calcOutPeers
double calcOutPeers() const
Returns a suitable value for outPeers according to the rules.
Definition: PeerfinderConfig.cpp:37
ripple::PeerSet
Supports data retrieval by managing a set of peers.
Definition: PeerSet.h:48
ripple::OverlayImpl::onPeerDeactivate
void onPeerDeactivate(Peer::id_t id)
Definition: OverlayImpl.cpp:688
ripple::Overlay::Setup::networkID
boost::optional< std::uint32_t > networkID
Definition: Overlay.h:79
Json::nullValue
@ nullValue
'null' value
Definition: json_value.h:36
ripple::OverlayImpl::list_
boost::container::flat_map< Child *, std::weak_ptr< Child > > list_
Definition: OverlayImpl.h:104
ripple::OverlayImpl::lastLink
void lastLink(std::uint32_t id)
Called when the last link from a peer chain is received.
Definition: OverlayImpl.cpp:868
ripple::OverlayImpl::check
void check() override
Calls the check function on each peer.
Definition: OverlayImpl.cpp:1154
ripple::OverlayImpl::Timer::Timer
Timer(OverlayImpl &overlay)
Definition: OverlayImpl.cpp:89
ripple::ScoreHasLedger::operator()
bool operator()(std::shared_ptr< Peer > const &) const
Definition: OverlayImpl.cpp:1315
beast::WrappedSink
Wraps a Journal::Sink to prefix its output with a string.
Definition: WrappedSink.h:33
std::vector::empty
T empty(T... args)
ripple::Handoff
Used to indicate the result of a server connection handoff.
Definition: Handoff.h:37
ripple::TokenType::NodePublic
@ NodePublic
ripple::Overlay::Setup
Definition: Overlay.h:70
ripple::OverlayImpl::Timer::stop
void stop() override
Definition: OverlayImpl.cpp:95
ripple::OverlayImpl::findPeerByPublicKey
std::shared_ptr< Peer > findPeerByPublicKey(PublicKey const &pubKey) override
Returns the peer with the matching public key, or null.
Definition: OverlayImpl.cpp:1172
ripple::ValidatorList::getJson
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
Definition: ValidatorList.cpp:658
ripple::PeerReservationTable::contains
bool contains(PublicKey const &nodeId)
Definition: PeerReservationTable.h:92
std::stringstream::str
T str(T... args)
ripple::get_peer_json
A functor to visit all active peers and retrieve their JSON data.
Definition: OverlayImpl.cpp:45
ripple::ScoreHasTxSet::operator()
bool operator()(std::shared_ptr< Peer > const &) const
Definition: OverlayImpl.cpp:1322
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::Config::IPS
std::vector< std::string > IPS
Definition: Config.h:118
std::size_t
ripple::OverlayImpl::makeRedirectResponse
std::shared_ptr< Writer > makeRedirectResponse(std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type const &request, address_type remote_address)
Definition: OverlayImpl.cpp:376
beast::IP::Endpoint
A version-independent IP address and port combination.
Definition: IPEndpoint.h:39
ripple::OverlayImpl::timer_
std::weak_ptr< Timer > timer_
Definition: OverlayImpl.h:103
ripple::Overlay::Setup::context
std::shared_ptr< boost::asio::ssl::context > context
Definition: Overlay.h:74
std::vector::end
T end(T... args)
ripple::Handoff::response
std::shared_ptr< Writer > response
Definition: Handoff.h:47
beast::IPAddressConversion::to_asio_endpoint
static boost::asio::ip::tcp::endpoint to_asio_endpoint(IP::Endpoint const &address)
Definition: IPAddressConversion.h:78
ripple::PeerFinder::Config::autoConnect
bool autoConnect
true if we want to establish connections automatically
Definition: PeerfinderManager.h:67
ripple::PeerFinder::Config
PeerFinder configuration settings.
Definition: PeerfinderManager.h:40
ripple::OverlayImpl::csLast_
std::atomic< std::chrono::seconds > csLast_
Definition: OverlayImpl.h:121
std::setw
T setw(T... args)
ripple::OverlayImpl
Definition: OverlayImpl.h:57
ripple::Overlay::Setup::expire
bool expire
Definition: Overlay.h:75
ripple::OverlayImpl::reportTraffic
void reportTraffic(TrafficCount::category cat, bool isInbound, int bytes)
Definition: OverlayImpl.cpp:774
ripple::OverlayImpl::crawlShards
Json::Value crawlShards(bool pubKey, std::uint32_t hops) override
Returns information reported to the crawl shard RPC command.
Definition: OverlayImpl.cpp:783
ripple::TrafficCount::addCount
void addCount(category cat, bool inbound, int bytes)
Account for traffic associated with the given category.
Definition: TrafficCount.h:156
ripple::OverlayImpl::Child
Definition: OverlayImpl.h:60
ripple::CrawlOptions::ServerInfo
@ ServerInfo
Definition: OverlayImpl.cpp:70
std::unique_ptr< stream_type >
ripple::ManifestCache::applyManifest
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
Definition: app/misc/impl/Manifest.cpp:369
ripple::OverlayImpl::makeErrorResponse
std::shared_ptr< Writer > makeErrorResponse(std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type const &request, address_type remote_address, std::string msg)
Definition: OverlayImpl.cpp:400
ripple::Tuning::checkSeconds
@ checkSeconds
How often we check connections (seconds)
Definition: overlay/impl/Tuning.h:54
ripple::OverlayImpl::m_peers
hash_map< std::shared_ptr< PeerFinder::Slot >, std::weak_ptr< PeerImp > > m_peers
Definition: OverlayImpl.h:111
ripple::Resolver::resolve
void resolve(std::vector< std::string > const &names, Handler handler)
resolve all hostnames on the list
Definition: Resolver.h:57
std::unordered_map
STL class.
ripple::OverlayImpl::isPeerUpgrade
static bool isPeerUpgrade(http_request_type const &request)
Definition: OverlayImpl.cpp:359
ripple::OverlayImpl::add_active
void add_active(std::shared_ptr< PeerImp > const &peer)
Definition: OverlayImpl.cpp:458
ripple::OverlayImpl::error_code
boost::system::error_code error_code
Definition: OverlayImpl.h:79
ripple::PeerFinder::Config::ipLimit
int ipLimit
Limit how many incoming connections we allow per IP.
Definition: PeerfinderManager.h:76
std::condition_variable::notify_all
T notify_all(T... args)
ripple::OverlayImpl::onWrite
void onWrite(beast::PropertyStream::Map &stream) override
Subclass override.
Definition: OverlayImpl.cpp:639
ripple::Application::getHashRouter
virtual HashRouter & getHashRouter()=0
ripple::BasicConfig
Holds unparsed configuration information.
Definition: BasicConfig.h:178
ripple::OverlayImpl::sendEndpoints
void sendEndpoints()
Definition: OverlayImpl.cpp:1295
ripple::OverlayImpl::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: OverlayImpl.cpp:620
std::ref
T ref(T... args)
ripple::OverlayImpl::stop
void stop()
Definition: OverlayImpl.cpp:1255
std::exception::what
T what(T... args)
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:138
ripple::NetworkOPs::pubValidation
virtual void pubValidation(STValidation::ref val)=0
ripple::OverlayImpl::limit
int limit() override
Returns the maximum number of peers we are configured to allow.
Definition: OverlayImpl.cpp:919
ripple::OverlayImpl::processCrawl
bool processCrawl(http_request_type const &req, Handoff &handoff)
Handles crawl requests.
Definition: OverlayImpl.cpp:1043
ripple::OverlayImpl::endpoint_type
boost::asio::ip::tcp::endpoint endpoint_type
Definition: OverlayImpl.h:78
ripple::Handoff::keep_alive
bool keep_alive
Definition: Handoff.h:44
ripple::Stoppable::isStopping
bool isStopping() const
Returns true if the stoppable should stop.
Definition: Stoppable.cpp:54
std::chrono
std::chrono::steady_clock::now
T now(T... args)