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 
44 namespace CrawlOptions {
45 enum {
46  Disabled = 0,
47  Overlay = (1 << 0),
48  ServerInfo = (1 << 1),
49  ServerCounts = (1 << 2),
50  Unl = (1 << 3)
51 };
52 }
53 
54 //------------------------------------------------------------------------------
55 
56 OverlayImpl::Child::Child(OverlayImpl& overlay) : overlay_(overlay)
57 {
58 }
59 
61 {
62  overlay_.remove(*this);
63 }
64 
65 //------------------------------------------------------------------------------
66 
68  : Child(overlay), timer_(overlay_.io_service_)
69 {
70 }
71 
72 void
74 {
75  error_code ec;
76  timer_.cancel(ec);
77 }
78 
79 void
81 {
82  timer_.expires_from_now(std::chrono::seconds(1));
83  timer_.async_wait(overlay_.strand_.wrap(std::bind(
84  &Timer::on_timer, shared_from_this(), std::placeholders::_1)));
85 }
86 
87 void
89 {
90  if (ec || overlay_.isStopping())
91  {
92  if (ec && ec != boost::asio::error::operation_aborted)
93  {
94  JLOG(overlay_.journal_.error()) << "on_timer: " << ec.message();
95  }
96  return;
97  }
98 
99  overlay_.m_peerFinder->once_per_second();
100  overlay_.sendEndpoints();
101  overlay_.autoConnect();
102 
103  if ((overlay_.timer_count_ % Tuning::checkIdlePeers) == 0)
104  overlay_.deleteIdlePeers();
105 
106  timer_.expires_from_now(std::chrono::seconds(1));
107  timer_.async_wait(overlay_.strand_.wrap(std::bind(
108  &Timer::on_timer, shared_from_this(), std::placeholders::_1)));
109 }
110 
111 //------------------------------------------------------------------------------
112 
114  Application& app,
115  Setup const& setup,
116  Stoppable& parent,
119  Resolver& resolver,
120  boost::asio::io_service& io_service,
121  BasicConfig const& config,
122  beast::insight::Collector::ptr const& collector)
123  : Overlay(parent)
124  , app_(app)
125  , io_service_(io_service)
126  , work_(boost::in_place(std::ref(io_service_)))
128  , setup_(setup)
129  , journal_(app_.journal("Overlay"))
132  , m_peerFinder(PeerFinder::make_Manager(
133  *this,
134  io_service,
135  stopwatch(),
136  app_.journal("PeerFinder"),
137  config,
138  collector))
139  , m_resolver(resolver)
140  , next_id_(1)
141  , timer_count_(0)
142  , slots_(app, *this)
143  , m_stats(
144  std::bind(&OverlayImpl::collect_metrics, this),
145  collector,
146  [counts = m_traffic.getCounts(), collector]() {
148  ret.reserve(counts.size());
149 
150  for (size_t i = 0; i < counts.size(); ++i)
151  {
152  ret.push_back(TrafficGauges(counts[i].name, collector));
153  }
154 
155  return ret;
156  }())
157 {
159 }
160 
162 {
163  stop();
164 
165  // Block until dependent objects have been destroyed.
166  // This is just to catch improper use of the Stoppable API.
167  //
168  std::unique_lock<decltype(mutex_)> lock(mutex_);
169  cond_.wait(lock, [this] { return list_.empty(); });
170 }
171 
172 //------------------------------------------------------------------------------
173 
174 Handoff
176  std::unique_ptr<stream_type>&& stream_ptr,
177  http_request_type&& request,
178  endpoint_type remote_endpoint)
179 {
180  auto const id = next_id_++;
181  beast::WrappedSink sink(app_.logs()["Peer"], makePrefix(id));
182  beast::Journal journal(sink);
183 
184  Handoff handoff;
185  if (processRequest(request, handoff))
186  return handoff;
187  if (!isPeerUpgrade(request))
188  return handoff;
189 
190  handoff.moved = true;
191 
192  JLOG(journal.debug()) << "Peer connection upgrade from " << remote_endpoint;
193 
194  error_code ec;
195  auto const local_endpoint(
196  stream_ptr->next_layer().socket().local_endpoint(ec));
197  if (ec)
198  {
199  JLOG(journal.debug()) << remote_endpoint << " failed: " << ec.message();
200  return handoff;
201  }
202 
203  auto consumer = m_resourceManager.newInboundEndpoint(
204  beast::IPAddressConversion::from_asio(remote_endpoint));
205  if (consumer.disconnect())
206  return handoff;
207 
208  auto const slot = m_peerFinder->new_inbound_slot(
210  beast::IPAddressConversion::from_asio(remote_endpoint));
211 
212  if (slot == nullptr)
213  {
214  // self-connect, close
215  handoff.moved = false;
216  return handoff;
217  }
218 
219  // Validate HTTP request
220 
221  {
222  auto const types = beast::rfc2616::split_commas(request["Connect-As"]);
223  if (std::find_if(types.begin(), types.end(), [](std::string const& s) {
224  return boost::iequals(s, "peer");
225  }) == types.end())
226  {
227  handoff.moved = false;
228  handoff.response =
229  makeRedirectResponse(slot, request, remote_endpoint.address());
230  handoff.keep_alive = beast::rfc2616::is_keep_alive(request);
231  return handoff;
232  }
233  }
234 
235  auto const negotiatedVersion = negotiateProtocolVersion(request["Upgrade"]);
236  if (!negotiatedVersion)
237  {
238  m_peerFinder->on_closed(slot);
239  handoff.moved = false;
240  handoff.response = makeErrorResponse(
241  slot,
242  request,
243  remote_endpoint.address(),
244  "Unable to agree on a protocol version");
245  handoff.keep_alive = false;
246  return handoff;
247  }
248 
249  auto const sharedValue = makeSharedValue(*stream_ptr, journal);
250  if (!sharedValue)
251  {
252  m_peerFinder->on_closed(slot);
253  handoff.moved = false;
254  handoff.response = makeErrorResponse(
255  slot,
256  request,
257  remote_endpoint.address(),
258  "Incorrect security cookie");
259  handoff.keep_alive = false;
260  return handoff;
261  }
262 
263  try
264  {
265  auto publicKey = verifyHandshake(
266  request,
267  *sharedValue,
270  remote_endpoint.address(),
271  app_);
272 
273  {
274  // The node gets a reserved slot if it is in our cluster
275  // or if it has a reservation.
276  bool const reserved =
277  static_cast<bool>(app_.cluster().member(publicKey)) ||
278  app_.peerReservations().contains(publicKey);
279  auto const result =
280  m_peerFinder->activate(slot, publicKey, reserved);
281  if (result != PeerFinder::Result::success)
282  {
283  m_peerFinder->on_closed(slot);
284  JLOG(journal.debug())
285  << "Peer " << remote_endpoint << " redirected, slots full";
286  handoff.moved = false;
287  handoff.response = makeRedirectResponse(
288  slot, request, remote_endpoint.address());
289  handoff.keep_alive = false;
290  return handoff;
291  }
292  }
293 
294  auto const peer = std::make_shared<PeerImp>(
295  app_,
296  id,
297  slot,
298  std::move(request),
299  publicKey,
300  *negotiatedVersion,
301  consumer,
302  std::move(stream_ptr),
303  *this);
304  {
305  // As we are not on the strand, run() must be called
306  // while holding the lock, otherwise new I/O can be
307  // queued after a call to stop().
308  std::lock_guard<decltype(mutex_)> lock(mutex_);
309  {
310  auto const result = m_peers.emplace(peer->slot(), peer);
311  assert(result.second);
312  (void)result.second;
313  }
314  list_.emplace(peer.get(), peer);
315 
316  peer->run();
317  }
318  handoff.moved = true;
319  return handoff;
320  }
321  catch (std::exception const& e)
322  {
323  JLOG(journal.debug()) << "Peer " << remote_endpoint
324  << " fails handshake (" << e.what() << ")";
325 
326  m_peerFinder->on_closed(slot);
327  handoff.moved = false;
328  handoff.response = makeErrorResponse(
329  slot, request, remote_endpoint.address(), e.what());
330  handoff.keep_alive = false;
331  return handoff;
332  }
333 }
334 
335 //------------------------------------------------------------------------------
336 
337 bool
339 {
340  if (!is_upgrade(request))
341  return false;
342  auto const versions = parseProtocolVersions(request["Upgrade"]);
343  return !versions.empty();
344 }
345 
348 {
350  ss << "[" << std::setfill('0') << std::setw(3) << id << "] ";
351  return ss.str();
352 }
353 
357  http_request_type const& request,
358  address_type remote_address)
359 {
360  boost::beast::http::response<json_body> msg;
361  msg.version(request.version());
362  msg.result(boost::beast::http::status::service_unavailable);
363  msg.insert("Server", BuildInfo::getFullVersionString());
364  {
365  std::ostringstream ostr;
366  ostr << remote_address;
367  msg.insert("Remote-Address", ostr.str());
368  }
369  msg.insert("Content-Type", "application/json");
370  msg.insert(boost::beast::http::field::connection, "close");
371  msg.body() = Json::objectValue;
372  {
373  Json::Value& ips = (msg.body()["peer-ips"] = Json::arrayValue);
374  for (auto const& _ : m_peerFinder->redirect(slot))
375  ips.append(_.address.to_string());
376  }
377  msg.prepare_payload();
378  return std::make_shared<SimpleWriter>(msg);
379 }
380 
384  http_request_type const& request,
385  address_type remote_address,
386  std::string text)
387 {
388  boost::beast::http::response<boost::beast::http::empty_body> msg;
389  msg.version(request.version());
390  msg.result(boost::beast::http::status::bad_request);
391  msg.reason("Bad Request (" + text + ")");
392  msg.insert("Server", BuildInfo::getFullVersionString());
393  msg.insert("Remote-Address", remote_address.to_string());
394  msg.insert(boost::beast::http::field::connection, "close");
395  msg.prepare_payload();
396  return std::make_shared<SimpleWriter>(msg);
397 }
398 
399 //------------------------------------------------------------------------------
400 
401 void
403 {
404  assert(work_);
405 
406  auto usage = resourceManager().newOutboundEndpoint(remote_endpoint);
407  if (usage.disconnect())
408  {
409  JLOG(journal_.info()) << "Over resource limit: " << remote_endpoint;
410  return;
411  }
412 
413  auto const slot = peerFinder().new_outbound_slot(remote_endpoint);
414  if (slot == nullptr)
415  {
416  JLOG(journal_.debug()) << "Connect: No slot for " << remote_endpoint;
417  return;
418  }
419 
420  auto const p = std::make_shared<ConnectAttempt>(
421  app_,
422  io_service_,
424  usage,
425  setup_.context,
426  next_id_++,
427  slot,
428  app_.journal("Peer"),
429  *this);
430 
431  std::lock_guard lock(mutex_);
432  list_.emplace(p.get(), p);
433  p->run();
434 }
435 
436 //------------------------------------------------------------------------------
437 
438 // Adds a peer that is already handshaked and active
439 void
441 {
442  std::lock_guard lock(mutex_);
443 
444  {
445  auto const result = m_peers.emplace(peer->slot(), peer);
446  assert(result.second);
447  (void)result.second;
448  }
449 
450  {
451  auto const result = ids_.emplace(
452  std::piecewise_construct,
453  std::make_tuple(peer->id()),
454  std::make_tuple(peer));
455  assert(result.second);
456  (void)result.second;
457  }
458 
459  list_.emplace(peer.get(), peer);
460 
461  JLOG(journal_.debug()) << "activated " << peer->getRemoteAddress() << " ("
462  << peer->id() << ":"
463  << toBase58(
464  TokenType::NodePublic, peer->getNodePublic())
465  << ")";
466 
467  // As we are not on the strand, run() must be called
468  // while holding the lock, otherwise new I/O can be
469  // queued after a call to stop().
470  peer->run();
471 }
472 
473 void
475 {
476  std::lock_guard lock(mutex_);
477  auto const iter = m_peers.find(slot);
478  assert(iter != m_peers.end());
479  m_peers.erase(iter);
480 }
481 
482 //------------------------------------------------------------------------------
483 //
484 // Stoppable
485 //
486 //------------------------------------------------------------------------------
487 
488 // Caller must hold the mutex
489 void
491 {
492  if (isStopping() && areChildrenStopped() && list_.empty())
493  stopped();
494 }
495 
496 void
498 {
500  app_.config(),
501  serverHandler_.setup().overlay.port,
503  setup_.ipLimit);
504 
505  m_peerFinder->setConfig(config);
506 
507  // Populate our boot cache: if there are no entries in [ips] then we use
508  // the entries in [ips_fixed].
509  auto bootstrapIps =
511 
512  // If nothing is specified, default to several well-known high-capacity
513  // servers to serve as bootstrap:
514  if (bootstrapIps.empty())
515  {
516  // Pool of servers operated by Ripple Labs Inc. - https://ripple.com
517  bootstrapIps.push_back("r.ripple.com 51235");
518 
519  // Pool of servers operated by Alloy Networks - https://www.alloy.ee
520  bootstrapIps.push_back("zaphod.alloy.ee 51235");
521 
522  // Pool of servers operated by ISRDC - https://isrdc.in
523  bootstrapIps.push_back("sahyadri.isrdc.in 51235");
524  }
525 
527  bootstrapIps,
528  [this](
529  std::string const& name,
530  std::vector<beast::IP::Endpoint> const& addresses) {
532  ips.reserve(addresses.size());
533  for (auto const& addr : addresses)
534  {
535  if (addr.port() == 0)
536  ips.push_back(to_string(addr.at_port(DEFAULT_PEER_PORT)));
537  else
538  ips.push_back(to_string(addr));
539  }
540 
541  std::string const base("config: ");
542  if (!ips.empty())
543  m_peerFinder->addFallbackStrings(base + name, ips);
544  });
545 
546  // Add the ips_fixed from the rippled.cfg file
547  if (!app_.config().standalone() && !app_.config().IPS_FIXED.empty())
548  {
551  [this](
552  std::string const& name,
553  std::vector<beast::IP::Endpoint> const& addresses) {
555  ips.reserve(addresses.size());
556 
557  for (auto& addr : addresses)
558  {
559  if (addr.port() == 0)
560  ips.emplace_back(addr.address(), DEFAULT_PEER_PORT);
561  else
562  ips.emplace_back(addr);
563  }
564 
565  if (!ips.empty())
566  m_peerFinder->addFixedPeer(name, ips);
567  });
568  }
569 }
570 
571 void
573 {
574  auto const timer = std::make_shared<Timer>(*this);
575  std::lock_guard lock(mutex_);
576  list_.emplace(timer.get(), timer);
577  timer_ = timer;
578  timer->run();
579 }
580 
581 void
583 {
584  strand_.dispatch(std::bind(&OverlayImpl::stop, this));
585 }
586 
587 void
589 {
590  std::lock_guard lock(mutex_);
591  checkStopped();
592 }
593 
594 //------------------------------------------------------------------------------
595 //
596 // PropertyStream
597 //
598 //------------------------------------------------------------------------------
599 
600 void
602 {
603  beast::PropertyStream::Set set("traffic", stream);
604  auto const stats = m_traffic.getCounts();
605  for (auto const& i : stats)
606  {
607  if (i)
608  {
610  item["category"] = i.name;
611  item["bytes_in"] = std::to_string(i.bytesIn.load());
612  item["messages_in"] = std::to_string(i.messagesIn.load());
613  item["bytes_out"] = std::to_string(i.bytesOut.load());
614  item["messages_out"] = std::to_string(i.messagesOut.load());
615  }
616  }
617 }
618 
619 //------------------------------------------------------------------------------
625 void
627 {
628  // Now track this peer
629  {
630  std::lock_guard lock(mutex_);
631  auto const result(ids_.emplace(
632  std::piecewise_construct,
633  std::make_tuple(peer->id()),
634  std::make_tuple(peer)));
635  assert(result.second);
636  (void)result.second;
637  }
638 
639  JLOG(journal_.debug()) << "activated " << peer->getRemoteAddress() << " ("
640  << peer->id() << ":"
641  << toBase58(
642  TokenType::NodePublic, peer->getNodePublic())
643  << ")";
644 
645  // We just accepted this peer so we have non-zero active peers
646  assert(size() != 0);
647 }
648 
649 void
651 {
652  std::lock_guard lock(mutex_);
653  ids_.erase(id);
654 }
655 
656 void
659  std::shared_ptr<PeerImp> const& from)
660 {
661  auto const n = m->list_size();
662  auto const& journal = from->pjournal();
663 
664  protocol::TMManifests relay;
665 
666  for (std::size_t i = 0; i < n; ++i)
667  {
668  auto& s = m->list().Get(i).stobject();
669 
670  if (auto mo = deserializeManifest(s))
671  {
672  auto const serialized = mo->serialized;
673 
674  auto const result =
675  app_.validatorManifests().applyManifest(std::move(*mo));
676 
677  if (result == ManifestDisposition::accepted)
678  {
679  relay.add_list()->set_stobject(s);
680 
681  // N.B.: this is important; the applyManifest call above moves
682  // the loaded Manifest out of the optional so we need to
683  // reload it here.
684  mo = deserializeManifest(serialized);
685  assert(mo);
686 
687  app_.getOPs().pubManifest(*mo);
688 
689  if (app_.validators().listed(mo->masterKey))
690  {
691  auto db = app_.getWalletDB().checkoutDb();
692 
693  soci::transaction tr(*db);
694  static const char* const sql =
695  "INSERT INTO ValidatorManifests (RawData) VALUES "
696  "(:rawData);";
697  soci::blob rawData(*db);
698  convert(serialized, rawData);
699  *db << sql, soci::use(rawData);
700  tr.commit();
701  }
702  }
703  }
704  else
705  {
706  JLOG(journal.debug())
707  << "Malformed manifest #" << i + 1 << ": " << strHex(s);
708  continue;
709  }
710  }
711 
712  if (!relay.list().empty())
713  for_each([m2 = std::make_shared<Message>(relay, protocol::mtMANIFESTS)](
714  std::shared_ptr<PeerImp>&& p) { p->send(m2); });
715 }
716 
717 void
720  bool isInbound,
721  int number)
722 {
723  m_traffic.addCount(cat, isInbound, number);
724 }
725 
728 {
729  using namespace std::chrono;
730  using namespace std::chrono_literals;
731 
733  auto const numPeers{size()};
734  if (numPeers == 0)
735  return jv;
736 
737  // If greater than a hop away, we may need to gather or freshen data
738  if (hops > 0)
739  {
740  // Prevent crawl spamming
741  clock_type::time_point const last(csLast_.load());
742  if ((clock_type::now() - last) > 60s)
743  {
744  auto const timeout(seconds((hops * hops) * 10));
746 
747  // Check if already requested
748  if (csIDs_.empty())
749  {
750  {
751  std::lock_guard lock{mutex_};
752  for (auto& id : ids_)
753  csIDs_.emplace(id.first);
754  }
755 
756  // Relay request to active peers
757  protocol::TMGetPeerShardInfo tmGPS;
758  tmGPS.set_hops(hops);
759  foreach(send_always(std::make_shared<Message>(
760  tmGPS, protocol::mtGET_PEER_SHARD_INFO)));
761 
762  if (csCV_.wait_for(l, timeout) == std::cv_status::timeout)
763  {
764  csIDs_.clear();
765  csCV_.notify_all();
766  }
767  csLast_ = duration_cast<seconds>(
768  clock_type::now().time_since_epoch());
769  }
770  else
771  csCV_.wait_for(l, timeout);
772  }
773  }
774 
775  // Combine the shard info from peers and their sub peers
777  for_each([&](std::shared_ptr<PeerImp> const& peer) {
778  if (auto psi = peer->getPeerShardInfo())
779  {
780  // e is non-const so it may be moved from
781  for (auto& e : *psi)
782  {
783  auto it{peerShardInfo.find(e.first)};
784  if (it != peerShardInfo.end())
785  // The key exists so join the shard indexes.
786  it->second.shardIndexes += e.second.shardIndexes;
787  else
788  peerShardInfo.emplace(std::move(e));
789  }
790  }
791  });
792 
793  // Prepare json reply
794  auto& av = jv[jss::peers] = Json::Value(Json::arrayValue);
795  for (auto const& e : peerShardInfo)
796  {
797  auto& pv{av.append(Json::Value(Json::objectValue))};
798  if (pubKey)
799  pv[jss::public_key] = toBase58(TokenType::NodePublic, e.first);
800 
801  auto const& address{e.second.endpoint.address()};
802  if (!address.is_unspecified())
803  pv[jss::ip] = address.to_string();
804 
805  pv[jss::complete_shards] = to_string(e.second.shardIndexes);
806  }
807 
808  return jv;
809 }
810 
811 void
813 {
814  // Notify threads when every peer has received a last link.
815  // This doesn't account for every node that might reply but
816  // it is adequate.
818  if (csIDs_.erase(id) && csIDs_.empty())
819  csCV_.notify_all();
820 }
821 
828 {
829  std::lock_guard lock(mutex_);
830  return ids_.size();
831 }
832 
833 int
835 {
836  return m_peerFinder->config().maxPeers;
837 }
838 
841 {
842  using namespace std::chrono;
843  Json::Value jv;
844  auto& av = jv["active"] = Json::Value(Json::arrayValue);
845 
847  auto& pv = av.append(Json::Value(Json::objectValue));
848  pv[jss::public_key] = base64_encode(
849  sp->getNodePublic().data(), sp->getNodePublic().size());
850  pv[jss::type] = sp->slot()->inbound() ? "in" : "out";
851  pv[jss::uptime] = static_cast<std::uint32_t>(
852  duration_cast<seconds>(sp->uptime()).count());
853  if (sp->crawl())
854  {
855  pv[jss::ip] = sp->getRemoteAddress().address().to_string();
856  if (sp->slot()->inbound())
857  {
858  if (auto port = sp->slot()->listening_port())
859  pv[jss::port] = *port;
860  }
861  else
862  {
863  pv[jss::port] = std::to_string(sp->getRemoteAddress().port());
864  }
865  }
866 
867  {
868  auto version{sp->getVersion()};
869  if (!version.empty())
870  // Could move here if Json::value supported moving from strings
871  pv[jss::version] = version;
872  }
873 
874  std::uint32_t minSeq, maxSeq;
875  sp->ledgerRange(minSeq, maxSeq);
876  if (minSeq != 0 || maxSeq != 0)
877  pv[jss::complete_ledgers] =
878  std::to_string(minSeq) + "-" + std::to_string(maxSeq);
879 
880  if (auto shardIndexes = sp->getShardIndexes())
881  pv[jss::complete_shards] = to_string(*shardIndexes);
882  });
883 
884  return jv;
885 }
886 
889 {
890  bool const humanReadable = false;
891  bool const admin = false;
892  bool const counters = false;
893 
894  Json::Value server_info =
895  app_.getOPs().getServerInfo(humanReadable, admin, counters);
896 
897  // Filter out some information
898  server_info.removeMember(jss::hostid);
899  server_info.removeMember(jss::load_factor_fee_escalation);
900  server_info.removeMember(jss::load_factor_fee_queue);
901  server_info.removeMember(jss::validation_quorum);
902 
903  if (server_info.isMember(jss::validated_ledger))
904  {
905  Json::Value& validated_ledger = server_info[jss::validated_ledger];
906 
907  validated_ledger.removeMember(jss::base_fee);
908  validated_ledger.removeMember(jss::reserve_base_xrp);
909  validated_ledger.removeMember(jss::reserve_inc_xrp);
910  }
911 
912  return server_info;
913 }
914 
917 {
918  return getCountsJson(app_, 10);
919 }
920 
923 {
924  Json::Value validators = app_.validators().getJson();
925 
926  if (validators.isMember(jss::publisher_lists))
927  {
928  Json::Value& publisher_lists = validators[jss::publisher_lists];
929 
930  for (auto& publisher : publisher_lists)
931  {
932  publisher.removeMember(jss::list);
933  }
934  }
935 
936  validators.removeMember(jss::signing_keys);
937  validators.removeMember(jss::trusted_validator_keys);
938  validators.removeMember(jss::validation_quorum);
939 
940  Json::Value validatorSites = app_.validatorSites().getJson();
941 
942  if (validatorSites.isMember(jss::validator_sites))
943  {
944  validators[jss::validator_sites] =
945  std::move(validatorSites[jss::validator_sites]);
946  }
947 
948  return validators;
949 }
950 
951 // Returns information on verified peers.
954 {
956  for (auto const& peer : getActivePeers())
957  {
958  json.append(peer->json());
959  }
960  return json;
961 }
962 
963 bool
965 {
966  if (req.target() != "/crawl" ||
968  return false;
969 
970  boost::beast::http::response<json_body> msg;
971  msg.version(req.version());
972  msg.result(boost::beast::http::status::ok);
973  msg.insert("Server", BuildInfo::getFullVersionString());
974  msg.insert("Content-Type", "application/json");
975  msg.insert("Connection", "close");
976  msg.body()["version"] = Json::Value(2u);
977 
979  {
980  msg.body()["overlay"] = getOverlayInfo();
981  }
983  {
984  msg.body()["server"] = getServerInfo();
985  }
987  {
988  msg.body()["counts"] = getServerCounts();
989  }
991  {
992  msg.body()["unl"] = getUnlInfo();
993  }
994 
995  msg.prepare_payload();
996  handoff.response = std::make_shared<SimpleWriter>(msg);
997  return true;
998 }
999 
1000 bool
1002  http_request_type const& req,
1003  Handoff& handoff)
1004 {
1005  // If the target is in the form "/vl/<validator_list_public_key>",
1006  // return the most recent validator list for that key.
1007  constexpr std::string_view prefix("/vl/");
1008 
1009  if (!req.target().starts_with(prefix.data()) || !setup_.vlEnabled)
1010  return false;
1011 
1012  std::uint32_t version = 1;
1013 
1014  boost::beast::http::response<json_body> msg;
1015  msg.version(req.version());
1016  msg.insert("Server", BuildInfo::getFullVersionString());
1017  msg.insert("Content-Type", "application/json");
1018  msg.insert("Connection", "close");
1019 
1020  auto fail = [&msg, &handoff](auto status) {
1021  msg.result(status);
1022  msg.insert("Content-Length", "0");
1023 
1024  msg.body() = Json::nullValue;
1025 
1026  msg.prepare_payload();
1027  handoff.response = std::make_shared<SimpleWriter>(msg);
1028  return true;
1029  };
1030 
1031  auto key = req.target().substr(prefix.size());
1032 
1033  if (auto slash = key.find('/'); slash != boost::string_view::npos)
1034  {
1035  auto verString = key.substr(0, slash);
1036  if (!boost::conversion::try_lexical_convert(verString, version))
1037  return fail(boost::beast::http::status::bad_request);
1038  key = key.substr(slash + 1);
1039  }
1040 
1041  if (key.empty())
1042  return fail(boost::beast::http::status::bad_request);
1043 
1044  // find the list
1045  auto vl = app_.validators().getAvailable(key, version);
1046 
1047  if (!vl)
1048  {
1049  // 404 not found
1050  return fail(boost::beast::http::status::not_found);
1051  }
1052  else if (!*vl)
1053  {
1054  return fail(boost::beast::http::status::bad_request);
1055  }
1056  else
1057  {
1058  msg.result(boost::beast::http::status::ok);
1059 
1060  msg.body() = *vl;
1061 
1062  msg.prepare_payload();
1063  handoff.response = std::make_shared<SimpleWriter>(msg);
1064  return true;
1065  }
1066 }
1067 
1068 bool
1070 {
1071  if (req.target() != "/health")
1072  return false;
1073  boost::beast::http::response<json_body> msg;
1074  msg.version(req.version());
1075  msg.insert("Server", BuildInfo::getFullVersionString());
1076  msg.insert("Content-Type", "application/json");
1077  msg.insert("Connection", "close");
1078 
1079  auto info = getServerInfo();
1080 
1081  int last_validated_ledger_age = -1;
1082  if (info.isMember("validated_ledger"))
1083  last_validated_ledger_age = info["validated_ledger"]["age"].asInt();
1084  bool amendment_blocked = false;
1085  if (info.isMember("amendment_blocked"))
1086  amendment_blocked = true;
1087  int number_peers = info["peers"].asInt();
1088  std::string server_state = info["server_state"].asString();
1089  auto load_factor =
1090  info["load_factor"].asDouble() / info["load_base"].asDouble();
1091 
1092  enum { healthy, warning, critical };
1093  int health = healthy;
1094  auto set_health = [&health](int state) {
1095  if (health < state)
1096  health = state;
1097  };
1098 
1099  msg.body()[jss::info] = Json::objectValue;
1100  if (last_validated_ledger_age >= 7 || last_validated_ledger_age < 0)
1101  {
1102  msg.body()[jss::info]["validated_ledger"] = last_validated_ledger_age;
1103  if (last_validated_ledger_age < 20)
1104  set_health(warning);
1105  else
1106  set_health(critical);
1107  }
1108 
1109  if (amendment_blocked)
1110  {
1111  msg.body()[jss::info]["amendment_blocked"] = true;
1112  set_health(critical);
1113  }
1114 
1115  if (number_peers <= 7)
1116  {
1117  msg.body()[jss::info]["peers"] = number_peers;
1118  if (number_peers != 0)
1119  set_health(warning);
1120  else
1121  set_health(critical);
1122  }
1123 
1124  if (!(server_state == "full" || server_state == "validating" ||
1125  server_state == "proposing"))
1126  {
1127  msg.body()[jss::info]["server_state"] = server_state;
1128  if (server_state == "syncing" || server_state == "tracking" ||
1129  server_state == "connected")
1130  {
1131  set_health(warning);
1132  }
1133  else
1134  set_health(critical);
1135  }
1136 
1137  if (load_factor > 100)
1138  {
1139  msg.body()[jss::info]["load_factor"] = load_factor;
1140  if (load_factor < 1000)
1141  set_health(warning);
1142  else
1143  set_health(critical);
1144  }
1145 
1146  switch (health)
1147  {
1148  case healthy:
1149  msg.result(boost::beast::http::status::ok);
1150  break;
1151  case warning:
1152  msg.result(boost::beast::http::status::service_unavailable);
1153  break;
1154  case critical:
1155  msg.result(boost::beast::http::status::internal_server_error);
1156  break;
1157  }
1158 
1159  msg.prepare_payload();
1160  handoff.response = std::make_shared<SimpleWriter>(msg);
1161  return true;
1162 }
1163 
1164 bool
1166 {
1167  // Take advantage of || short-circuiting
1168  return processCrawl(req, handoff) || processValidatorList(req, handoff) ||
1169  processHealth(req, handoff);
1170 }
1171 
1174 {
1176  ret.reserve(size());
1177 
1178  for_each([&ret](std::shared_ptr<PeerImp>&& sp) {
1179  ret.emplace_back(std::move(sp));
1180  });
1181 
1182  return ret;
1183 }
1184 
1185 void
1187 {
1188  for_each(
1189  [index](std::shared_ptr<PeerImp>&& sp) { sp->checkTracking(index); });
1190 }
1191 
1194 {
1195  std::lock_guard lock(mutex_);
1196  auto const iter = ids_.find(id);
1197  if (iter != ids_.end())
1198  return iter->second.lock();
1199  return {};
1200 }
1201 
1202 // A public key hash map was not used due to the peer connect/disconnect
1203 // update overhead outweighing the performance of a small set linear search.
1206 {
1207  std::lock_guard lock(mutex_);
1208  for (auto const& e : ids_)
1209  {
1210  if (auto peer = e.second.lock())
1211  {
1212  if (peer->getNodePublic() == pubKey)
1213  return peer;
1214  }
1215  }
1216  return {};
1217 }
1218 
1219 void
1220 OverlayImpl::broadcast(protocol::TMProposeSet& m)
1221 {
1222  auto const sm = std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER);
1223  for_each([&](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1224 }
1225 
1228  protocol::TMProposeSet& m,
1229  uint256 const& uid,
1230  PublicKey const& validator)
1231 {
1232  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1233  {
1234  auto const sm =
1235  std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER, validator);
1237  if (toSkip->find(p->id()) == toSkip->end())
1238  p->send(sm);
1239  });
1240  return *toSkip;
1241  }
1242  return {};
1243 }
1244 
1245 void
1246 OverlayImpl::broadcast(protocol::TMValidation& m)
1247 {
1248  auto const sm = std::make_shared<Message>(m, protocol::mtVALIDATION);
1249  for_each([sm](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1250 }
1251 
1254  protocol::TMValidation& m,
1255  uint256 const& uid,
1256  PublicKey const& validator)
1257 {
1258  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1259  {
1260  auto const sm =
1261  std::make_shared<Message>(m, protocol::mtVALIDATION, validator);
1263  if (toSkip->find(p->id()) == toSkip->end())
1264  p->send(sm);
1265  });
1266  return *toSkip;
1267  }
1268  return {};
1269 }
1270 
1273 {
1275 
1276  if (auto seq = app_.validatorManifests().sequence();
1277  seq != manifestListSeq_)
1278  {
1279  protocol::TMManifests tm;
1280 
1282  [&tm](std::size_t s) { tm.mutable_list()->Reserve(s); },
1283  [&tm, &hr = app_.getHashRouter()](Manifest const& manifest) {
1284  tm.add_list()->set_stobject(
1285  manifest.serialized.data(), manifest.serialized.size());
1286  hr.addSuppression(manifest.hash());
1287  });
1288 
1290 
1291  if (tm.list_size() != 0)
1293  std::make_shared<Message>(tm, protocol::mtMANIFESTS);
1294 
1295  manifestListSeq_ = seq;
1296  }
1297 
1298  return manifestMessage_;
1299 }
1300 
1301 //------------------------------------------------------------------------------
1302 
1303 void
1305 {
1306  std::lock_guard lock(mutex_);
1307  list_.erase(&child);
1308  if (list_.empty())
1309  checkStopped();
1310 }
1311 
1312 void
1314 {
1315  // Calling list_[].second->stop() may cause list_ to be modified
1316  // (OverlayImpl::remove() may be called on this same thread). So
1317  // iterating directly over list_ to call child->stop() could lead to
1318  // undefined behavior.
1319  //
1320  // Therefore we copy all of the weak/shared ptrs out of list_ before we
1321  // start calling stop() on them. That guarantees OverlayImpl::remove()
1322  // won't be called until vector<> children leaves scope.
1324  {
1325  std::lock_guard lock(mutex_);
1326  if (!work_)
1327  return;
1328  work_ = boost::none;
1329 
1330  children.reserve(list_.size());
1331  for (auto const& element : list_)
1332  {
1333  children.emplace_back(element.second.lock());
1334  }
1335  } // lock released
1336 
1337  for (auto const& child : children)
1338  {
1339  if (child != nullptr)
1340  child->stop();
1341  }
1342 }
1343 
1344 void
1346 {
1347  auto const result = m_peerFinder->autoconnect();
1348  for (auto addr : result)
1349  connect(addr);
1350 }
1351 
1352 void
1354 {
1355  auto const result = m_peerFinder->buildEndpointsForPeers();
1356  for (auto const& e : result)
1357  {
1359  {
1360  std::lock_guard lock(mutex_);
1361  auto const iter = m_peers.find(e.first);
1362  if (iter != m_peers.end())
1363  peer = iter->second.lock();
1364  }
1365  if (peer)
1366  peer->sendEndpoints(e.second.begin(), e.second.end());
1367  }
1368 }
1369 
1372  PublicKey const& validator,
1373  bool squelch,
1374  uint32_t squelchDuration)
1375 {
1376  protocol::TMSquelch m;
1377  m.set_squelch(squelch);
1378  m.set_validatorpubkey(validator.data(), validator.size());
1379  if (squelch)
1380  m.set_squelchduration(squelchDuration);
1381  return std::make_shared<Message>(m, protocol::mtSQUELCH);
1382 }
1383 
1384 void
1385 OverlayImpl::unsquelch(PublicKey const& validator, Peer::id_t id) const
1386 {
1387  if (auto peer = findPeerByShortID(id);
1388  peer && app_.config().VP_REDUCE_RELAY_SQUELCH)
1389  {
1390  // optimize - multiple message with different
1391  // validator might be sent to the same peer
1392  peer->send(makeSquelchMessage(validator, false, 0));
1393  }
1394 }
1395 
1396 void
1398  PublicKey const& validator,
1399  Peer::id_t id,
1400  uint32_t squelchDuration) const
1401 {
1402  if (auto peer = findPeerByShortID(id);
1403  peer && app_.config().VP_REDUCE_RELAY_SQUELCH)
1404  {
1405  peer->send(makeSquelchMessage(validator, true, squelchDuration));
1406  }
1407 }
1408 
1409 void
1411  uint256 const& key,
1412  PublicKey const& validator,
1413  std::set<Peer::id_t>&& peers,
1414  protocol::MessageType type)
1415 {
1416  if (!strand_.running_in_this_thread())
1417  return post(
1418  strand_,
1419  [this, key, validator, peers = std::move(peers), type]() mutable {
1420  updateSlotAndSquelch(key, validator, std::move(peers), type);
1421  });
1422 
1423  for (auto id : peers)
1424  slots_.updateSlotAndSquelch(key, validator, id, type);
1425 }
1426 
1427 void
1429  uint256 const& key,
1430  PublicKey const& validator,
1431  Peer::id_t peer,
1432  protocol::MessageType type)
1433 {
1434  if (!strand_.running_in_this_thread())
1435  return post(strand_, [this, key, validator, peer, type]() {
1436  updateSlotAndSquelch(key, validator, peer, type);
1437  });
1438 
1439  slots_.updateSlotAndSquelch(key, validator, peer, type);
1440 }
1441 
1442 void
1444 {
1445  if (!strand_.running_in_this_thread())
1446  return post(strand_, std::bind(&OverlayImpl::deletePeer, this, id));
1447 
1448  slots_.deletePeer(id, true);
1449 }
1450 
1451 void
1453 {
1454  if (!strand_.running_in_this_thread())
1455  return post(strand_, std::bind(&OverlayImpl::deleteIdlePeers, this));
1456 
1457  slots_.deleteIdlePeers();
1458 }
1459 
1460 //------------------------------------------------------------------------------
1461 
1464 {
1466 
1467  {
1468  auto const& section = config.section("overlay");
1470 
1471  set(setup.ipLimit, "ip_limit", section);
1472  if (setup.ipLimit < 0)
1473  Throw<std::runtime_error>("Configured IP limit is invalid");
1474 
1475  std::string ip;
1476  set(ip, "public_ip", section);
1477  if (!ip.empty())
1478  {
1479  boost::system::error_code ec;
1480  setup.public_ip = beast::IP::Address::from_string(ip, ec);
1482  Throw<std::runtime_error>("Configured public IP is invalid");
1483  }
1484  }
1485 
1486  {
1487  auto const& section = config.section("crawl");
1488  auto const& values = section.values();
1489 
1490  if (values.size() > 1)
1491  {
1492  Throw<std::runtime_error>(
1493  "Configured [crawl] section is invalid, too many values");
1494  }
1495 
1496  bool crawlEnabled = true;
1497 
1498  // Only allow "0|1" as a value
1499  if (values.size() == 1)
1500  {
1501  try
1502  {
1503  crawlEnabled = boost::lexical_cast<bool>(values.front());
1504  }
1505  catch (boost::bad_lexical_cast const&)
1506  {
1507  Throw<std::runtime_error>(
1508  "Configured [crawl] section has invalid value: " +
1509  values.front());
1510  }
1511  }
1512 
1513  if (crawlEnabled)
1514  {
1515  if (get<bool>(section, "overlay", true))
1516  {
1518  }
1519  if (get<bool>(section, "server", true))
1520  {
1522  }
1523  if (get<bool>(section, "counts", false))
1524  {
1526  }
1527  if (get<bool>(section, "unl", true))
1528  {
1530  }
1531  }
1532  }
1533  {
1534  auto const& section = config.section("vl");
1535 
1536  set(setup.vlEnabled, "enabled", section);
1537  }
1538 
1539  try
1540  {
1541  auto id = config.legacy("network_id");
1542 
1543  if (!id.empty())
1544  {
1545  if (id == "main")
1546  id = "0";
1547 
1548  if (id == "testnet")
1549  id = "1";
1550 
1551  if (id == "devnet")
1552  id = "2";
1553 
1554  setup.networkID = beast::lexicalCastThrow<std::uint32_t>(id);
1555  }
1556  }
1557  catch (...)
1558  {
1559  Throw<std::runtime_error>(
1560  "Configured [network_id] section is invalid: must be a number "
1561  "or one of the strings 'main', 'testnet' or 'devnet'.");
1562  }
1563 
1564  return setup;
1565 }
1566 
1569  Application& app,
1570  Overlay::Setup const& setup,
1571  Stoppable& parent,
1574  Resolver& resolver,
1575  boost::asio::io_service& io_service,
1576  BasicConfig const& config,
1577  beast::insight::Collector::ptr const& collector)
1578 {
1579  return std::make_unique<OverlayImpl>(
1580  app,
1581  setup,
1582  parent,
1583  serverHandler,
1585  resolver,
1586  io_service,
1587  config,
1588  collector);
1589 }
1590 
1591 } // 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::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:101
ripple::OverlayImpl::getServerCounts
Json::Value getServerCounts()
Returns information about the local server's performance counters.
Definition: OverlayImpl.cpp:916
ripple::OverlayImpl::journal_
const beast::Journal journal_
Definition: OverlayImpl.h:106
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:80
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)
std::string
STL class.
std::shared_ptr< Collector >
ripple::OverlayImpl::work_
boost::optional< boost::asio::io_service::work > work_
Definition: OverlayImpl.h:99
ripple::makeSquelchMessage
std::shared_ptr< Message > makeSquelchMessage(PublicKey const &validator, bool squelch, uint32_t squelchDuration)
Definition: OverlayImpl.cpp:1371
ripple::Overlay::Setup::networkID
std::optional< std::uint32_t > networkID
Definition: Overlay.h:78
std::exception
STL class.
ripple::Stoppable::stopped
void stopped()
Called by derived classes to indicate that the stoppable has stopped.
Definition: Stoppable.cpp:72
ripple::CrawlOptions::Disabled
@ Disabled
Definition: OverlayImpl.cpp:46
beast::PropertyStream::Map
Definition: PropertyStream.h:236
ripple::OverlayImpl::collect_metrics
void collect_metrics()
Definition: OverlayImpl.h:590
std::string_view
STL class.
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:302
ripple::OverlayImpl::ids_
hash_map< Peer::id_t, std::weak_ptr< PeerImp > > ids_
Definition: OverlayImpl.h:112
ripple::Manifest
Definition: Manifest.h:78
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
std::vector::reserve
T reserve(T... args)
ripple::OverlayImpl::updateSlotAndSquelch
void updateSlotAndSquelch(uint256 const &key, PublicKey const &validator, std::set< Peer::id_t > &&peers, protocol::MessageType type)
Updates message count for validator/peer.
Definition: OverlayImpl.cpp:1410
ripple::OverlayImpl::autoConnect
void autoConnect()
Definition: OverlayImpl.cpp:1345
ripple::Application::validatorSites
virtual ValidatorSite & validatorSites()=0
ripple::HashPrefix::manifest
@ manifest
Manifest.
ripple::Overlay::Setup::crawlOptions
std::uint32_t crawlOptions
Definition: Overlay.h:77
ripple::convert
void convert(soci::blob &from, std::vector< std::uint8_t > &to)
Definition: SociDB.cpp:156
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:88
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:1568
ripple::OverlayImpl::makePrefix
static std::string makePrefix(std::uint32_t id)
Definition: OverlayImpl.cpp:347
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:175
std::chrono::seconds
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
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:888
std::lock_guard
STL class.
ripple::OverlayImpl::onStart
void onStart() override
Override called during start.
Definition: OverlayImpl.cpp:572
ripple::parseProtocolVersions
std::vector< ProtocolVersion > parseProtocolVersions(boost::beast::string_view const &value)
Parse a set of protocol versions.
Definition: ProtocolVersion.cpp:85
ripple::makeSharedValue
std::optional< uint256 > makeSharedValue(stream_type &ssl, beast::Journal journal)
Computes a shared value based on the SSL connection state.
Definition: Handshake.cpp:131
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)
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:45
ripple::OverlayImpl::broadcast
void broadcast(protocol::TMProposeSet &m) override
Broadcast a proposal.
Definition: OverlayImpl.cpp:1220
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:402
ripple::OverlayImpl::json
Json::Value json() override
Return diagnostics on the status of all peers.
Definition: OverlayImpl.cpp:953
ripple::OverlayImpl::setup
Setup const & setup() const
Definition: OverlayImpl.h:177
ripple::OverlayImpl::timer_count_
int timer_count_
Definition: OverlayImpl.h:115
ripple::OverlayImpl::processValidatorList
bool processValidatorList(http_request_type const &req, Handoff &handoff)
Handles validator list requests.
Definition: OverlayImpl.cpp:1001
beast::PropertyStream::Set
Definition: PropertyStream.h:308
std::shared_ptr::reset
T reset(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::processHealth
bool processHealth(http_request_type const &req, Handoff &handoff)
Handles health requests.
Definition: OverlayImpl.cpp:1069
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:588
ripple::PeerFinder::Config::makeConfig
static Config makeConfig(ripple::Config const &config, std::uint16_t port, bool validationPublicKey, int ipLimit)
Make PeerFinder::Config from configuration parameters.
Definition: PeerfinderConfig.cpp:78
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:138
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::Tuning::checkIdlePeers
@ checkIdlePeers
How often we check for idle peers (seconds)
Definition: overlay/impl/Tuning.h:56
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:159
ripple::base_uint< 256 >
ripple::OverlayImpl::size
std::size_t size() const override
The number of active peers on the network Active peers are only those peers that have completed the h...
Definition: OverlayImpl.cpp:827
ripple::OverlayImpl::checkTracking
void checkTracking(std::uint32_t) override
Calls the checkTracking function on each peer.
Definition: OverlayImpl.cpp:1186
beast::rfc2616::is_keep_alive
bool is_keep_alive(boost::beast::http::message< isRequest, Body, Fields > const &m)
Definition: rfc2616.h:386
ripple::ValidatorList::getAvailable
boost::optional< Json::Value > getAvailable(boost::beast::string_view const &pubKey, boost::optional< std::uint32_t > forceVersion={})
Returns the current valid list for the given publisher key, if available, as a Json object.
Definition: ValidatorList.cpp:1680
ripple::setup_Overlay
Overlay::Setup setup_Overlay(BasicConfig const &config)
Definition: OverlayImpl.cpp:1463
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::OverlayImpl::onManifests
void onManifests(std::shared_ptr< protocol::TMManifests > const &m, std::shared_ptr< PeerImp > const &from)
Definition: OverlayImpl.cpp:657
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:201
ripple::Overlay::Setup::public_ip
beast::IP::Address public_ip
Definition: Overlay.h:75
ripple::OverlayImpl::manifestMessage_
std::shared_ptr< Message > manifestMessage_
Definition: OverlayImpl.h:132
ripple::DatabaseCon::checkoutDb
LockedSociSession checkoutDb()
Definition: DatabaseCon.h:178
ripple::OverlayImpl::resourceManager
Resource::Manager & resourceManager()
Definition: OverlayImpl.h:165
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:840
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:644
ripple::Config::IPS_FIXED
std::vector< std::string > IPS_FIXED
Definition: Config.h:125
ripple::ServerHandlerImp
Definition: ServerHandlerImp.h:46
ripple::Config::standalone
bool standalone() const
Definition: Config.h:262
std::unique_lock
STL class.
ripple::Resolver
Definition: Resolver.h:30
ripple::OverlayImpl::slots_
reduce_relay::Slots< UptimeClock > slots_
Definition: OverlayImpl.h:129
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:585
ripple::OverlayImpl::serverHandler
ServerHandler & serverHandler()
Definition: OverlayImpl.h:171
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:922
ripple::OverlayImpl::checkStopped
void checkStopped()
Definition: OverlayImpl.cpp:490
ripple::ValidatorList::listed
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
Definition: ValidatorList.cpp:1351
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::ManifestCache::for_each_manifest
void for_each_manifest(Function &&f) const
Invokes the callback once for every populated manifest.
Definition: Manifest.h:378
ripple::OverlayImpl::app_
Application & app_
Definition: OverlayImpl.h:97
ripple::CrawlOptions::ServerCounts
@ ServerCounts
Definition: OverlayImpl.cpp:49
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:497
std::uint32_t
std::condition_variable_any::wait
T wait(T... args)
ripple::OverlayImpl::TrafficGauges
Definition: OverlayImpl.h:549
ripple::OverlayImpl::Child::Child
Child(OverlayImpl &overlay)
Definition: OverlayImpl.cpp:56
ripple::HashRouter::shouldRelay
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:118
ripple::OverlayImpl::getActivePeers
PeerSequence getActivePeers() const override
Returns a sequence representing the current list of peers.
Definition: OverlayImpl.cpp:1173
ripple::CrawlOptions::Unl
@ Unl
Definition: OverlayImpl.cpp:50
beast::rfc2616::split_commas
Result split_commas(FwdIt first, FwdIt last)
Definition: rfc2616.h:199
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:113
std::condition_variable::wait_for
T wait_for(T... args)
ripple::CrawlOptions::Overlay
@ Overlay
Definition: OverlayImpl.cpp:47
ripple::OverlayImpl::deleteIdlePeers
void deleteIdlePeers()
Check if peers stopped relaying messages and if slots stopped receiving messages from the validator.
Definition: OverlayImpl.cpp:1452
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:1165
ripple::OverlayImpl::manifestListSeq_
std::optional< std::uint32_t > manifestListSeq_
Definition: OverlayImpl.h:134
ripple::ManifestDisposition::accepted
@ accepted
Manifest is valid.
ripple::Resource::Manager
Tracks load and resource consumption.
Definition: ResourceManager.h:36
std::ostringstream
STL class.
ripple::BuildInfo::getFullVersionString
std::string const & getFullVersionString()
Full server version string.
Definition: BuildInfo.cpp:74
ripple::OverlayImpl::~OverlayImpl
~OverlayImpl()
Definition: OverlayImpl.cpp:161
ripple::OverlayImpl::deletePeer
void deletePeer(Peer::id_t id)
Called when the peer is deleted.
Definition: OverlayImpl.cpp:1443
ripple::getCountsJson
Json::Value getCountsJson(Application &app, int minObjectCount)
Definition: GetCounts.cpp:65
ripple::OverlayImpl::Child::~Child
virtual ~Child()
Definition: OverlayImpl.cpp:60
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::OverlayImpl::relay
std::set< Peer::id_t > relay(protocol::TMProposeSet &m, uint256 const &uid, PublicKey const &validator) override
Relay a proposal.
Definition: OverlayImpl.cpp:1227
ripple::deserializeManifest
boost::optional< Manifest > deserializeManifest(Slice s)
Constructs Manifest from serialized string.
Definition: app/misc/impl/Manifest.cpp:38
ripple::Overlay::Setup::ipLimit
int ipLimit
Definition: Overlay.h:76
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::Application::validatorManifests
virtual ManifestCache & validatorManifests()=0
ripple::OverlayImpl::getManifestsMessage
std::shared_ptr< Message > getManifestsMessage()
Definition: OverlayImpl.cpp:1272
Json::Value::removeMember
Value removeMember(const char *key)
Remove and return the named member.
Definition: json_value.cpp:907
ripple::Overlay::Setup::vlEnabled
bool vlEnabled
Definition: Overlay.h:79
ripple::OverlayImpl::remove
void remove(std::shared_ptr< PeerFinder::Slot > const &slot)
Definition: OverlayImpl.cpp:474
ripple::Overlay
Manages the set of connected peers.
Definition: Overlay.h:52
std
STL namespace.
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:626
ripple::OverlayImpl::onPeerDeactivate
void onPeerDeactivate(Peer::id_t id)
Definition: OverlayImpl.cpp:650
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:812
ripple::OverlayImpl::Timer::Timer
Timer(OverlayImpl &overlay)
Definition: OverlayImpl.cpp:67
ripple::OverlayImpl::squelch
void squelch(PublicKey const &validator, Peer::id_t const id, std::uint32_t squelchDuration) const override
Squelch handler.
Definition: OverlayImpl.cpp:1397
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:73
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:1205
ripple::ValidatorList::getJson
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
Definition: ValidatorList.cpp:1509
ripple::PeerReservationTable::contains
bool contains(PublicKey const &nodeId)
Definition: PeerReservationTable.h:92
std::stringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::Config::IPS
std::vector< std::string > IPS
Definition: Config.h:124
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:355
beast::IP::Endpoint
A version-independent IP address and port combination.
Definition: IPEndpoint.h:39
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
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
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
PeerFinder configuration settings.
Definition: PeerfinderManager.h:41
ripple::OverlayImpl::csLast_
std::atomic< std::chrono::seconds > csLast_
Definition: OverlayImpl.h:121
std::setw
T setw(T... args)
ripple::verifyHandshake
PublicKey verifyHandshake(boost::beast::http::fields const &headers, ripple::uint256 const &sharedValue, std::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:216
ripple::OverlayImpl
Definition: OverlayImpl.h:57
ripple::CrawlOptions::ServerInfo
@ ServerInfo
Definition: OverlayImpl.cpp:48
ripple::OverlayImpl::findPeerByShortID
std::shared_ptr< Peer > findPeerByShortID(Peer::id_t const &id) const override
Returns the peer with the matching short id, or null.
Definition: OverlayImpl.cpp:1193
ripple::OverlayImpl::reportTraffic
void reportTraffic(TrafficCount::category cat, bool isInbound, int bytes)
Definition: OverlayImpl.cpp:718
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:727
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::http_request_type
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition: Handshake.h:47
std::unique_ptr< stream_type >
ripple::ManifestCache::applyManifest
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
Definition: app/misc/impl/Manifest.cpp:340
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:382
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:338
ripple::OverlayImpl::add_active
void add_active(std::shared_ptr< PeerImp > const &peer)
Definition: OverlayImpl.cpp:440
ripple::OverlayImpl::error_code
boost::system::error_code error_code
Definition: OverlayImpl.h:79
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:601
std::set
STL class.
ripple::Application::getHashRouter
virtual HashRouter & getHashRouter()=0
ripple::BasicConfig
Holds unparsed configuration information.
Definition: BasicConfig.h:178
ripple::OverlayImpl::manifestLock_
std::mutex manifestLock_
Definition: OverlayImpl.h:136
ripple::OverlayImpl::sendEndpoints
void sendEndpoints()
Definition: OverlayImpl.cpp:1353
ripple::OverlayImpl::for_each
void for_each(UnaryFunc &&f) const
Definition: OverlayImpl.h:260
ripple::OverlayImpl::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: OverlayImpl.cpp:582
ripple::OverlayImpl::stop
void stop()
Definition: OverlayImpl.cpp:1313
std::exception::what
T what(T... args)
ripple::OverlayImpl::unsquelch
void unsquelch(PublicKey const &validator, Peer::id_t id) const override
Unsquelch handler.
Definition: OverlayImpl.cpp:1385
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::OverlayImpl::limit
int limit() override
Returns the maximum number of peers we are configured to allow.
Definition: OverlayImpl.cpp:834
ripple::OverlayImpl::processCrawl
bool processCrawl(http_request_type const &req, Handoff &handoff)
Handles crawl requests.
Definition: OverlayImpl.cpp:964
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
ripple::ManifestCache::sequence
std::uint32_t sequence() const
A monotonically increasing number used to detect new manifests.
Definition: Manifest.h:233
std::chrono
std::chrono::steady_clock::now
T now(T... args)