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