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  {
558  Throw<std::runtime_error>(
559  "Port not specified for "
560  "address:" +
561  addr.to_string());
562  }
563 
564  ips.push_back(to_string(addr));
565  }
566 
567  std::string const base("config: ");
568  if (!ips.empty())
569  m_peerFinder->addFallbackStrings(base + name, ips);
570  });
571 
572  // Add the ips_fixed from the rippled.cfg file
573  if (!app_.config().standalone() && !app_.config().IPS_FIXED.empty())
574  {
577  [this](
578  std::string const& name,
579  std::vector<beast::IP::Endpoint> const& addresses) {
580  if (!addresses.empty())
581  m_peerFinder->addFixedPeer(name, addresses);
582  });
583  }
584 }
585 
586 void
588 {
589  auto const timer = std::make_shared<Timer>(*this);
590  std::lock_guard lock(mutex_);
591  list_.emplace(timer.get(), timer);
592  timer_ = timer;
593  timer->run();
594 }
595 
596 void
598 {
599  strand_.dispatch(std::bind(&OverlayImpl::stop, this));
600 }
601 
602 void
604 {
605  std::lock_guard lock(mutex_);
606  checkStopped();
607 }
608 
609 //------------------------------------------------------------------------------
610 //
611 // PropertyStream
612 //
613 //------------------------------------------------------------------------------
614 
615 void
617 {
618  beast::PropertyStream::Set set("traffic", stream);
619  auto const stats = m_traffic.getCounts();
620  for (auto const& i : stats)
621  {
622  if (i)
623  {
625  item["category"] = i.name;
626  item["bytes_in"] = std::to_string(i.bytesIn.load());
627  item["messages_in"] = std::to_string(i.messagesIn.load());
628  item["bytes_out"] = std::to_string(i.bytesOut.load());
629  item["messages_out"] = std::to_string(i.messagesOut.load());
630  }
631  }
632 }
633 
634 //------------------------------------------------------------------------------
640 void
642 {
643  // Now track this peer
644  {
645  std::lock_guard lock(mutex_);
646  auto const result(ids_.emplace(
647  std::piecewise_construct,
648  std::make_tuple(peer->id()),
649  std::make_tuple(peer)));
650  assert(result.second);
651  (void)result.second;
652  }
653 
654  JLOG(journal_.debug()) << "activated " << peer->getRemoteAddress() << " ("
655  << peer->id() << ":"
656  << toBase58(
657  TokenType::NodePublic, peer->getNodePublic())
658  << ")";
659 
660  // We just accepted this peer so we have non-zero active peers
661  assert(size() != 0);
662 }
663 
664 void
666 {
667  std::lock_guard lock(mutex_);
668  ids_.erase(id);
669 }
670 
671 void
674  std::shared_ptr<PeerImp> const& from)
675 {
676  auto& hashRouter = app_.getHashRouter();
677  auto const n = m->list_size();
678  auto const& journal = from->pjournal();
679 
680  JLOG(journal.debug()) << "TMManifest, " << n
681  << (n == 1 ? " item" : " items");
682 
683  for (std::size_t i = 0; i < n; ++i)
684  {
685  auto& s = m->list().Get(i).stobject();
686 
687  if (auto mo = deserializeManifest(s))
688  {
689  uint256 const hash = mo->hash();
690  if (!hashRouter.addSuppressionPeer(hash, from->id()))
691  {
692  JLOG(journal.info()) << "Duplicate manifest #" << i + 1;
693  continue;
694  }
695 
696  if (!app_.validators().listed(mo->masterKey))
697  {
698  JLOG(journal.info()) << "Untrusted manifest #" << i + 1;
699  app_.getOPs().pubManifest(*mo);
700  continue;
701  }
702 
703  auto const serialized = mo->serialized;
704 
705  auto const result =
706  app_.validatorManifests().applyManifest(std::move(*mo));
707 
708  if (result == ManifestDisposition::accepted)
709  {
710  app_.getOPs().pubManifest(*deserializeManifest(serialized));
711  }
712 
713  if (result == ManifestDisposition::accepted)
714  {
715  auto db = app_.getWalletDB().checkoutDb();
716 
717  soci::transaction tr(*db);
718  static const char* const sql =
719  "INSERT INTO ValidatorManifests (RawData) VALUES "
720  "(:rawData);";
721  soci::blob rawData(*db);
722  convert(serialized, rawData);
723  *db << sql, soci::use(rawData);
724  tr.commit();
725 
726  protocol::TMManifests o;
727  o.add_list()->set_stobject(s);
728 
729  auto const toSkip = hashRouter.shouldRelay(hash);
730  if (toSkip)
731  foreach(send_if_not(
732  std::make_shared<Message>(o, protocol::mtMANIFESTS),
733  peer_in_set(*toSkip)));
734  }
735  else
736  {
737  JLOG(journal.info())
738  << "Bad manifest #" << i + 1 << ": " << to_string(result);
739  }
740  }
741  else
742  {
743  JLOG(journal.warn()) << "Malformed manifest #" << i + 1;
744  continue;
745  }
746  }
747 }
748 
749 void
752  bool isInbound,
753  int number)
754 {
755  m_traffic.addCount(cat, isInbound, number);
756 }
757 
760 {
761  using namespace std::chrono;
762  using namespace std::chrono_literals;
763 
765  auto const numPeers{size()};
766  if (numPeers == 0)
767  return jv;
768 
769  // If greater than a hop away, we may need to gather or freshen data
770  if (hops > 0)
771  {
772  // Prevent crawl spamming
773  clock_type::time_point const last(csLast_.load());
774  if ((clock_type::now() - last) > 60s)
775  {
776  auto const timeout(seconds((hops * hops) * 10));
778 
779  // Check if already requested
780  if (csIDs_.empty())
781  {
782  {
783  std::lock_guard lock{mutex_};
784  for (auto& id : ids_)
785  csIDs_.emplace(id.first);
786  }
787 
788  // Relay request to active peers
789  protocol::TMGetPeerShardInfo tmGPS;
790  tmGPS.set_hops(hops);
791  foreach(send_always(std::make_shared<Message>(
792  tmGPS, protocol::mtGET_PEER_SHARD_INFO)));
793 
794  if (csCV_.wait_for(l, timeout) == std::cv_status::timeout)
795  {
796  csIDs_.clear();
797  csCV_.notify_all();
798  }
799  csLast_ = duration_cast<seconds>(
800  clock_type::now().time_since_epoch());
801  }
802  else
803  csCV_.wait_for(l, timeout);
804  }
805  }
806 
807  // Combine the shard info from peers and their sub peers
809  for_each([&](std::shared_ptr<PeerImp> const& peer) {
810  if (auto psi = peer->getPeerShardInfo())
811  {
812  for (auto const& e : *psi)
813  {
814  auto it{peerShardInfo.find(e.first)};
815  if (it != peerShardInfo.end())
816  // The key exists so join the shard indexes.
817  it->second.shardIndexes += e.second.shardIndexes;
818  else
819  peerShardInfo.emplace(std::move(e));
820  }
821  }
822  });
823 
824  // Prepare json reply
825  auto& av = jv[jss::peers] = Json::Value(Json::arrayValue);
826  for (auto const& e : peerShardInfo)
827  {
828  auto& pv{av.append(Json::Value(Json::objectValue))};
829  if (pubKey)
830  pv[jss::public_key] = toBase58(TokenType::NodePublic, e.first);
831 
832  auto const& address{e.second.endpoint.address()};
833  if (!address.is_unspecified())
834  pv[jss::ip] = address.to_string();
835 
836  pv[jss::complete_shards] = to_string(e.second.shardIndexes);
837  }
838 
839  return jv;
840 }
841 
842 void
844 {
845  // Notify threads when every peer has received a last link.
846  // This doesn't account for every node that might reply but
847  // it is adequate.
849  if (csIDs_.erase(id) && csIDs_.empty())
850  csCV_.notify_all();
851 }
852 
859 {
860  std::lock_guard lock(mutex_);
861  return ids_.size();
862 }
863 
864 int
866 {
867  return m_peerFinder->config().maxPeers;
868 }
869 
872 {
873  using namespace std::chrono;
874  Json::Value jv;
875  auto& av = jv["active"] = Json::Value(Json::arrayValue);
876 
878  auto& pv = av.append(Json::Value(Json::objectValue));
879  pv[jss::public_key] = base64_encode(
880  sp->getNodePublic().data(), sp->getNodePublic().size());
881  pv[jss::type] = sp->slot()->inbound() ? "in" : "out";
882  pv[jss::uptime] = static_cast<std::uint32_t>(
883  duration_cast<seconds>(sp->uptime()).count());
884  if (sp->crawl())
885  {
886  pv[jss::ip] = sp->getRemoteAddress().address().to_string();
887  if (sp->slot()->inbound())
888  {
889  if (auto port = sp->slot()->listening_port())
890  pv[jss::port] = *port;
891  }
892  else
893  {
894  pv[jss::port] = std::to_string(sp->getRemoteAddress().port());
895  }
896  }
897 
898  {
899  auto version{sp->getVersion()};
900  if (!version.empty())
901  pv[jss::version] = std::move(version);
902  }
903 
904  std::uint32_t minSeq, maxSeq;
905  sp->ledgerRange(minSeq, maxSeq);
906  if (minSeq != 0 || maxSeq != 0)
907  pv[jss::complete_ledgers] =
908  std::to_string(minSeq) + "-" + std::to_string(maxSeq);
909 
910  if (auto shardIndexes = sp->getShardIndexes())
911  pv[jss::complete_shards] = to_string(*shardIndexes);
912  });
913 
914  return jv;
915 }
916 
919 {
920  bool const humanReadable = false;
921  bool const admin = false;
922  bool const counters = false;
923 
924  Json::Value server_info =
925  app_.getOPs().getServerInfo(humanReadable, admin, counters);
926 
927  // Filter out some information
928  server_info.removeMember(jss::hostid);
929  server_info.removeMember(jss::load_factor_fee_escalation);
930  server_info.removeMember(jss::load_factor_fee_queue);
931  server_info.removeMember(jss::validation_quorum);
932 
933  if (server_info.isMember(jss::validated_ledger))
934  {
935  Json::Value& validated_ledger = server_info[jss::validated_ledger];
936 
937  validated_ledger.removeMember(jss::base_fee);
938  validated_ledger.removeMember(jss::reserve_base_xrp);
939  validated_ledger.removeMember(jss::reserve_inc_xrp);
940  }
941 
942  return server_info;
943 }
944 
947 {
948  return getCountsJson(app_, 10);
949 }
950 
953 {
954  Json::Value validators = app_.validators().getJson();
955 
956  if (validators.isMember(jss::publisher_lists))
957  {
958  Json::Value& publisher_lists = validators[jss::publisher_lists];
959 
960  for (auto& publisher : publisher_lists)
961  {
962  publisher.removeMember(jss::list);
963  }
964  }
965 
966  validators.removeMember(jss::signing_keys);
967  validators.removeMember(jss::trusted_validator_keys);
968  validators.removeMember(jss::validation_quorum);
969 
970  Json::Value validatorSites = app_.validatorSites().getJson();
971 
972  if (validatorSites.isMember(jss::validator_sites))
973  {
974  validators[jss::validator_sites] =
975  std::move(validatorSites[jss::validator_sites]);
976  }
977 
978  return validators;
979 }
980 
981 // Returns information on verified peers.
984 {
986  for (auto const& peer : getActivePeers())
987  {
988  json.append(peer->json());
989  }
990  return json;
991 }
992 
993 bool
995 {
996  if (req.target() != "/crawl" ||
998  return false;
999 
1000  boost::beast::http::response<json_body> msg;
1001  msg.version(req.version());
1002  msg.result(boost::beast::http::status::ok);
1003  msg.insert("Server", BuildInfo::getFullVersionString());
1004  msg.insert("Content-Type", "application/json");
1005  msg.insert("Connection", "close");
1006  msg.body()["version"] = Json::Value(2u);
1007 
1009  {
1010  msg.body()["overlay"] = getOverlayInfo();
1011  }
1013  {
1014  msg.body()["server"] = getServerInfo();
1015  }
1017  {
1018  msg.body()["counts"] = getServerCounts();
1019  }
1021  {
1022  msg.body()["unl"] = getUnlInfo();
1023  }
1024 
1025  msg.prepare_payload();
1026  handoff.response = std::make_shared<SimpleWriter>(msg);
1027  return true;
1028 }
1029 
1030 bool
1032  http_request_type const& req,
1033  Handoff& handoff)
1034 {
1035  // If the target is in the form "/vl/<validator_list_public_key>",
1036  // return the most recent validator list for that key.
1037  constexpr std::string_view prefix("/vl/");
1038 
1039  if (!req.target().starts_with(prefix.data()) || !setup_.vlEnabled)
1040  return false;
1041 
1042  auto key = req.target().substr(prefix.size());
1043 
1044  if (key.empty())
1045  return false;
1046 
1047  // find the list
1048  auto vl = app_.validators().getAvailable(key);
1049 
1050  boost::beast::http::response<json_body> msg;
1051  msg.version(req.version());
1052  msg.insert("Server", BuildInfo::getFullVersionString());
1053  msg.insert("Content-Type", "application/json");
1054  msg.insert("Connection", "close");
1055 
1056  if (!vl)
1057  {
1058  // 404 not found
1059  msg.result(boost::beast::http::status::not_found);
1060  msg.insert("Content-Length", "0");
1061 
1062  msg.body() = Json::nullValue;
1063  }
1064  else
1065  {
1066  msg.result(boost::beast::http::status::ok);
1067 
1068  msg.body() = *vl;
1069  }
1070 
1071  msg.prepare_payload();
1072  handoff.response = std::make_shared<SimpleWriter>(msg);
1073  return true;
1074 }
1075 
1076 bool
1078 {
1079  // Take advantage of || short-circuiting
1080  return processCrawl(req, handoff) || processValidatorList(req, handoff);
1081 }
1082 
1085 {
1087  ret.reserve(size());
1088 
1089  for_each([&ret](std::shared_ptr<PeerImp>&& sp) {
1090  ret.emplace_back(std::move(sp));
1091  });
1092 
1093  return ret;
1094 }
1095 
1096 void
1098 {
1099  for_each(
1100  [index](std::shared_ptr<PeerImp>&& sp) { sp->checkSanity(index); });
1101 }
1102 
1103 void
1105 {
1106  for_each([](std::shared_ptr<PeerImp>&& sp) { sp->check(); });
1107 }
1108 
1111 {
1112  std::lock_guard lock(mutex_);
1113  auto const iter = ids_.find(id);
1114  if (iter != ids_.end())
1115  return iter->second.lock();
1116  return {};
1117 }
1118 
1119 // A public key hash map was not used due to the peer connect/disconnect
1120 // update overhead outweighing the performance of a small set linear search.
1123 {
1124  std::lock_guard lock(mutex_);
1125  for (auto const& e : ids_)
1126  {
1127  if (auto peer = e.second.lock())
1128  {
1129  if (peer->getNodePublic() == pubKey)
1130  return peer;
1131  }
1132  }
1133  return {};
1134 }
1135 
1136 void
1137 OverlayImpl::send(protocol::TMProposeSet& m)
1138 {
1139  auto const sm = std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER);
1140  for_each([&](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1141 }
1142 void
1143 OverlayImpl::send(protocol::TMValidation& m)
1144 {
1145  auto const sm = std::make_shared<Message>(m, protocol::mtVALIDATION);
1146  for_each([&](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1147 
1148  SerialIter sit(m.validation().data(), m.validation().size());
1149  auto val = std::make_shared<STValidation>(
1150  std::ref(sit),
1151  [this](PublicKey const& pk) {
1153  },
1154  false);
1155  app_.getOPs().pubValidation(val);
1156 }
1157 
1158 void
1159 OverlayImpl::relay(protocol::TMProposeSet& m, uint256 const& uid)
1160 {
1161  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1162  {
1163  auto const sm =
1164  std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER);
1166  if (toSkip->find(p->id()) == toSkip->end())
1167  p->send(sm);
1168  });
1169  }
1170 }
1171 
1172 void
1173 OverlayImpl::relay(protocol::TMValidation& m, uint256 const& uid)
1174 {
1175  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1176  {
1177  auto const sm = std::make_shared<Message>(m, protocol::mtVALIDATION);
1179  if (toSkip->find(p->id()) == toSkip->end())
1180  p->send(sm);
1181  });
1182  }
1183 }
1184 
1185 //------------------------------------------------------------------------------
1186 
1187 void
1189 {
1190  std::lock_guard lock(mutex_);
1191  list_.erase(&child);
1192  if (list_.empty())
1193  checkStopped();
1194 }
1195 
1196 void
1198 {
1199  // Calling list_[].second->stop() may cause list_ to be modified
1200  // (OverlayImpl::remove() may be called on this same thread). So
1201  // iterating directly over list_ to call child->stop() could lead to
1202  // undefined behavior.
1203  //
1204  // Therefore we copy all of the weak/shared ptrs out of list_ before we
1205  // start calling stop() on them. That guarantees OverlayImpl::remove()
1206  // won't be called until vector<> children leaves scope.
1208  {
1209  std::lock_guard lock(mutex_);
1210  if (!work_)
1211  return;
1212  work_ = boost::none;
1213 
1214  children.reserve(list_.size());
1215  for (auto const& element : list_)
1216  {
1217  children.emplace_back(element.second.lock());
1218  }
1219  } // lock released
1220 
1221  for (auto const& child : children)
1222  {
1223  if (child != nullptr)
1224  child->stop();
1225  }
1226 }
1227 
1228 void
1230 {
1231  auto const result = m_peerFinder->autoconnect();
1232  for (auto addr : result)
1233  connect(addr);
1234 }
1235 
1236 void
1238 {
1239  auto const result = m_peerFinder->buildEndpointsForPeers();
1240  for (auto const& e : result)
1241  {
1243  {
1244  std::lock_guard lock(mutex_);
1245  auto const iter = m_peers.find(e.first);
1246  if (iter != m_peers.end())
1247  peer = iter->second.lock();
1248  }
1249  if (peer)
1250  peer->sendEndpoints(e.second.begin(), e.second.end());
1251  }
1252 }
1253 
1256 {
1258 
1259  {
1260  auto const& section = config.section("overlay");
1262 
1263  set(setup.ipLimit, "ip_limit", section);
1264  if (setup.ipLimit < 0)
1265  Throw<std::runtime_error>("Configured IP limit is invalid");
1266 
1267  std::string ip;
1268  set(ip, "public_ip", section);
1269  if (!ip.empty())
1270  {
1271  boost::system::error_code ec;
1272  setup.public_ip = beast::IP::Address::from_string(ip, ec);
1274  Throw<std::runtime_error>("Configured public IP is invalid");
1275  }
1276  }
1277 
1278  {
1279  auto const& section = config.section("crawl");
1280  auto const& values = section.values();
1281 
1282  if (values.size() > 1)
1283  {
1284  Throw<std::runtime_error>(
1285  "Configured [crawl] section is invalid, too many values");
1286  }
1287 
1288  bool crawlEnabled = true;
1289 
1290  // Only allow "0|1" as a value
1291  if (values.size() == 1)
1292  {
1293  try
1294  {
1295  crawlEnabled = boost::lexical_cast<bool>(values.front());
1296  }
1297  catch (boost::bad_lexical_cast const&)
1298  {
1299  Throw<std::runtime_error>(
1300  "Configured [crawl] section has invalid value: " +
1301  values.front());
1302  }
1303  }
1304 
1305  if (crawlEnabled)
1306  {
1307  if (get<bool>(section, "overlay", true))
1308  {
1310  }
1311  if (get<bool>(section, "server", true))
1312  {
1314  }
1315  if (get<bool>(section, "counts", false))
1316  {
1318  }
1319  if (get<bool>(section, "unl", true))
1320  {
1322  }
1323  }
1324  }
1325  {
1326  auto const& section = config.section("vl");
1327 
1328  set(setup.vlEnabled, "enabled", section);
1329  }
1330 
1331  try
1332  {
1333  auto id = config.legacy("network_id");
1334 
1335  if (!id.empty())
1336  {
1337  if (id == "main")
1338  id = "0";
1339 
1340  if (id == "testnet")
1341  id = "1";
1342 
1343  if (id == "devnet")
1344  id = "2";
1345 
1346  setup.networkID = beast::lexicalCastThrow<std::uint32_t>(id);
1347  }
1348  }
1349  catch (...)
1350  {
1351  Throw<std::runtime_error>(
1352  "Configured [network_id] section is invalid: must be a number "
1353  "or one of the strings 'main', 'testnet' or 'devnet'.");
1354  }
1355 
1356  return setup;
1357 }
1358 
1361  Application& app,
1362  Overlay::Setup const& setup,
1363  Stoppable& parent,
1366  Resolver& resolver,
1367  boost::asio::io_service& io_service,
1368  BasicConfig const& config,
1369  beast::insight::Collector::ptr const& collector)
1370 {
1371  return std::make_unique<OverlayImpl>(
1372  app,
1373  setup,
1374  parent,
1375  serverHandler,
1377  resolver,
1378  io_service,
1379  config,
1380  collector);
1381 }
1382 
1383 } // 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:1110
ripple::OverlayImpl::relay
void relay(protocol::TMProposeSet &m, uint256 const &uid) override
Relay a proposal.
Definition: OverlayImpl.cpp:1159
ripple::Resource::Manager::newOutboundEndpoint
virtual Consumer newOutboundEndpoint(beast::IP::Endpoint const &address)=0
Create a new endpoint keyed by outbound IP address and port.
ripple::Application
Definition: Application.h:94
ripple::OverlayImpl::getServerCounts
Json::Value getServerCounts()
Returns information about the local server's performance counters.
Definition: OverlayImpl.cpp:946
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::ManifestCache::getMasterKey
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
Definition: app/misc/impl/Manifest.cpp:301
ripple::OverlayImpl::work_
boost::optional< boost::asio::io_service::work > work_
Definition: OverlayImpl.h:97
std::exception
STL class.
ripple::calcNodeID
NodeID calcNodeID(PublicKey const &pk)
Calculate the 160-bit node ID from a node public key.
Definition: PublicKey.cpp:299
ripple::Stoppable::stopped
void stopped()
Called by derived classes to indicate that the stoppable has stopped.
Definition: Stoppable.cpp:72
beast::PropertyStream::Map
Definition: PropertyStream.h:236
ripple::OverlayImpl::collect_metrics
void collect_metrics()
Definition: OverlayImpl.h:518
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:1229
ripple::ValidatorList::getAvailable
boost::optional< Json::Value > getAvailable(boost::beast::string_view const &pubKey)
Returns the current valid list for the given publisher key, if available, as a Json object.
Definition: ValidatorList.cpp:790
ripple::Application::validatorSites
virtual ValidatorSite & validatorSites()=0
ripple::Overlay::Setup::crawlOptions
std::uint32_t crawlOptions
Definition: Overlay.h: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:1360
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:141
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::CrawlOptions::ServerCounts
@ ServerCounts
Definition: OverlayImpl.cpp: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:918
std::lock_guard
STL class.
ripple::OverlayImpl::onStart
void onStart() override
Override called during start.
Definition: OverlayImpl.cpp:587
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:41
ripple::PeerFinder::Manager::new_outbound_slot
virtual std::shared_ptr< Slot > new_outbound_slot(beast::IP::Endpoint const &remote_endpoint)=0
Create a new outbound slot with the specified remote endpoint.
ripple::OverlayImpl::connect
void connect(beast::IP::Endpoint const &remote_endpoint) override
Establish a peer connection to the specified endpoint.
Definition: OverlayImpl.cpp:397
ripple::OverlayImpl::json
Json::Value json() override
Return diagnostics on the status of all peers.
Definition: OverlayImpl.cpp:983
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:1031
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::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:603
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:858
ripple::OverlayImpl::send
void send(protocol::TMProposeSet &m) override
Broadcast a proposal.
Definition: OverlayImpl.cpp:1137
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:1255
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:672
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:129
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:871
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:119
ripple::ServerHandlerImp
Definition: ServerHandlerImp.h:46
ripple::Config::standalone
bool standalone() const
Definition: Config.h:216
std::unique_lock
STL class.
ripple::Resolver
Definition: Resolver.h:30
ripple::NetworkOPs::pubValidation
virtual void pubValidation(std::shared_ptr< STValidation > const &val)=0
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:513
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:952
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:551
ripple::makeSharedValue
boost::optional< uint256 > makeSharedValue(stream_type &ssl, beast::Journal journal)
Computes a shared value based on the SSL connection state.
Definition: Handshake.cpp:70
ripple::PeerFinder::Config::outPeers
double outPeers
The number of automatic outbound connections to maintain.
Definition: PeerfinderManager.h:58
ripple::PeerFinder::Config::maxPeers
int maxPeers
The largest number of public peer slots to allow.
Definition: PeerfinderManager.h:46
beast::Journal::info
Stream info() const
Definition: Journal.h:321
std::set::erase
T erase(T... args)
ripple::BasicConfig::legacy
void legacy(std::string const &section, std::string value)
Set a value that is not a key/value pair.
Definition: BasicConfig.cpp:175
ripple::Application::logs
virtual Logs & logs()=0
ripple::OverlayImpl::app_
Application & app_
Definition: OverlayImpl.h:95
ripple::SerialIter
Definition: Serializer.h:308
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:477
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:1084
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:1077
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:142
ripple::OverlayImpl::~OverlayImpl
~OverlayImpl()
Definition: OverlayImpl.cpp:160
ripple::getCountsJson
Json::Value getCountsJson(Application &app, int minObjectCount)
Definition: GetCounts.cpp:64
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:1097
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:641
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:665
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:843
ripple::OverlayImpl::check
void check() override
Calls the check function on each peer.
Definition: OverlayImpl.cpp:1104
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:1122
ripple::ValidatorList::getJson
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
Definition: ValidatorList.cpp:658
ripple::PeerReservationTable::contains
bool contains(PublicKey const &nodeId)
Definition: PeerReservationTable.h:92
std::stringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::Config::IPS
std::vector< std::string > IPS
Definition: Config.h:118
std::size_t
ripple::OverlayImpl::makeRedirectResponse
std::shared_ptr< Writer > makeRedirectResponse(std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type const &request, address_type remote_address)
Definition: OverlayImpl.cpp: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:750
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:759
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:616
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:1237
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:597
std::ref
T ref(T... args)
ripple::OverlayImpl::stop
void stop()
Definition: OverlayImpl.cpp:1197
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:865
ripple::OverlayImpl::processCrawl
bool processCrawl(http_request_type const &req, Handoff &handoff)
Handles crawl requests.
Definition: OverlayImpl.cpp:994
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)