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  // e is non-const so it may be moved from
813  for (auto& e : *psi)
814  {
815  auto it{peerShardInfo.find(e.first)};
816  if (it != peerShardInfo.end())
817  // The key exists so join the shard indexes.
818  it->second.shardIndexes += e.second.shardIndexes;
819  else
820  peerShardInfo.emplace(std::move(e));
821  }
822  }
823  });
824 
825  // Prepare json reply
826  auto& av = jv[jss::peers] = Json::Value(Json::arrayValue);
827  for (auto const& e : peerShardInfo)
828  {
829  auto& pv{av.append(Json::Value(Json::objectValue))};
830  if (pubKey)
831  pv[jss::public_key] = toBase58(TokenType::NodePublic, e.first);
832 
833  auto const& address{e.second.endpoint.address()};
834  if (!address.is_unspecified())
835  pv[jss::ip] = address.to_string();
836 
837  pv[jss::complete_shards] = to_string(e.second.shardIndexes);
838  }
839 
840  return jv;
841 }
842 
843 void
845 {
846  // Notify threads when every peer has received a last link.
847  // This doesn't account for every node that might reply but
848  // it is adequate.
850  if (csIDs_.erase(id) && csIDs_.empty())
851  csCV_.notify_all();
852 }
853 
860 {
861  std::lock_guard lock(mutex_);
862  return ids_.size();
863 }
864 
865 int
867 {
868  return m_peerFinder->config().maxPeers;
869 }
870 
873 {
874  using namespace std::chrono;
875  Json::Value jv;
876  auto& av = jv["active"] = Json::Value(Json::arrayValue);
877 
879  auto& pv = av.append(Json::Value(Json::objectValue));
880  pv[jss::public_key] = base64_encode(
881  sp->getNodePublic().data(), sp->getNodePublic().size());
882  pv[jss::type] = sp->slot()->inbound() ? "in" : "out";
883  pv[jss::uptime] = static_cast<std::uint32_t>(
884  duration_cast<seconds>(sp->uptime()).count());
885  if (sp->crawl())
886  {
887  pv[jss::ip] = sp->getRemoteAddress().address().to_string();
888  if (sp->slot()->inbound())
889  {
890  if (auto port = sp->slot()->listening_port())
891  pv[jss::port] = *port;
892  }
893  else
894  {
895  pv[jss::port] = std::to_string(sp->getRemoteAddress().port());
896  }
897  }
898 
899  {
900  auto version{sp->getVersion()};
901  if (!version.empty())
902  // Could move here if Json::value supported moving from strings
903  pv[jss::version] = version;
904  }
905 
906  std::uint32_t minSeq, maxSeq;
907  sp->ledgerRange(minSeq, maxSeq);
908  if (minSeq != 0 || maxSeq != 0)
909  pv[jss::complete_ledgers] =
910  std::to_string(minSeq) + "-" + std::to_string(maxSeq);
911 
912  if (auto shardIndexes = sp->getShardIndexes())
913  pv[jss::complete_shards] = to_string(*shardIndexes);
914  });
915 
916  return jv;
917 }
918 
921 {
922  bool const humanReadable = false;
923  bool const admin = false;
924  bool const counters = false;
925 
926  Json::Value server_info =
927  app_.getOPs().getServerInfo(humanReadable, admin, counters);
928 
929  // Filter out some information
930  server_info.removeMember(jss::hostid);
931  server_info.removeMember(jss::load_factor_fee_escalation);
932  server_info.removeMember(jss::load_factor_fee_queue);
933  server_info.removeMember(jss::validation_quorum);
934 
935  if (server_info.isMember(jss::validated_ledger))
936  {
937  Json::Value& validated_ledger = server_info[jss::validated_ledger];
938 
939  validated_ledger.removeMember(jss::base_fee);
940  validated_ledger.removeMember(jss::reserve_base_xrp);
941  validated_ledger.removeMember(jss::reserve_inc_xrp);
942  }
943 
944  return server_info;
945 }
946 
949 {
950  return getCountsJson(app_, 10);
951 }
952 
955 {
956  Json::Value validators = app_.validators().getJson();
957 
958  if (validators.isMember(jss::publisher_lists))
959  {
960  Json::Value& publisher_lists = validators[jss::publisher_lists];
961 
962  for (auto& publisher : publisher_lists)
963  {
964  publisher.removeMember(jss::list);
965  }
966  }
967 
968  validators.removeMember(jss::signing_keys);
969  validators.removeMember(jss::trusted_validator_keys);
970  validators.removeMember(jss::validation_quorum);
971 
972  Json::Value validatorSites = app_.validatorSites().getJson();
973 
974  if (validatorSites.isMember(jss::validator_sites))
975  {
976  validators[jss::validator_sites] =
977  std::move(validatorSites[jss::validator_sites]);
978  }
979 
980  return validators;
981 }
982 
983 // Returns information on verified peers.
986 {
988  for (auto const& peer : getActivePeers())
989  {
990  json.append(peer->json());
991  }
992  return json;
993 }
994 
995 bool
997 {
998  if (req.target() != "/crawl" ||
1000  return false;
1001 
1002  boost::beast::http::response<json_body> msg;
1003  msg.version(req.version());
1004  msg.result(boost::beast::http::status::ok);
1005  msg.insert("Server", BuildInfo::getFullVersionString());
1006  msg.insert("Content-Type", "application/json");
1007  msg.insert("Connection", "close");
1008  msg.body()["version"] = Json::Value(2u);
1009 
1011  {
1012  msg.body()["overlay"] = getOverlayInfo();
1013  }
1015  {
1016  msg.body()["server"] = getServerInfo();
1017  }
1019  {
1020  msg.body()["counts"] = getServerCounts();
1021  }
1023  {
1024  msg.body()["unl"] = getUnlInfo();
1025  }
1026 
1027  msg.prepare_payload();
1028  handoff.response = std::make_shared<SimpleWriter>(msg);
1029  return true;
1030 }
1031 
1032 bool
1034  http_request_type const& req,
1035  Handoff& handoff)
1036 {
1037  // If the target is in the form "/vl/<validator_list_public_key>",
1038  // return the most recent validator list for that key.
1039  constexpr std::string_view prefix("/vl/");
1040 
1041  if (!req.target().starts_with(prefix.data()) || !setup_.vlEnabled)
1042  return false;
1043 
1044  auto key = req.target().substr(prefix.size());
1045 
1046  if (key.empty())
1047  return false;
1048 
1049  // find the list
1050  auto vl = app_.validators().getAvailable(key);
1051 
1052  boost::beast::http::response<json_body> msg;
1053  msg.version(req.version());
1054  msg.insert("Server", BuildInfo::getFullVersionString());
1055  msg.insert("Content-Type", "application/json");
1056  msg.insert("Connection", "close");
1057 
1058  if (!vl)
1059  {
1060  // 404 not found
1061  msg.result(boost::beast::http::status::not_found);
1062  msg.insert("Content-Length", "0");
1063 
1064  msg.body() = Json::nullValue;
1065  }
1066  else
1067  {
1068  msg.result(boost::beast::http::status::ok);
1069 
1070  msg.body() = *vl;
1071  }
1072 
1073  msg.prepare_payload();
1074  handoff.response = std::make_shared<SimpleWriter>(msg);
1075  return true;
1076 }
1077 
1078 bool
1080 {
1081  // Take advantage of || short-circuiting
1082  return processCrawl(req, handoff) || processValidatorList(req, handoff);
1083 }
1084 
1087 {
1089  ret.reserve(size());
1090 
1091  for_each([&ret](std::shared_ptr<PeerImp>&& sp) {
1092  ret.emplace_back(std::move(sp));
1093  });
1094 
1095  return ret;
1096 }
1097 
1098 void
1100 {
1101  for_each(
1102  [index](std::shared_ptr<PeerImp>&& sp) { sp->checkSanity(index); });
1103 }
1104 
1105 void
1107 {
1108  for_each([](std::shared_ptr<PeerImp>&& sp) { sp->check(); });
1109 }
1110 
1113 {
1114  std::lock_guard lock(mutex_);
1115  auto const iter = ids_.find(id);
1116  if (iter != ids_.end())
1117  return iter->second.lock();
1118  return {};
1119 }
1120 
1121 // A public key hash map was not used due to the peer connect/disconnect
1122 // update overhead outweighing the performance of a small set linear search.
1125 {
1126  std::lock_guard lock(mutex_);
1127  for (auto const& e : ids_)
1128  {
1129  if (auto peer = e.second.lock())
1130  {
1131  if (peer->getNodePublic() == pubKey)
1132  return peer;
1133  }
1134  }
1135  return {};
1136 }
1137 
1138 void
1139 OverlayImpl::broadcast(protocol::TMProposeSet& m)
1140 {
1141  auto const sm = std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER);
1142  for_each([&](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1143 }
1144 
1145 void
1146 OverlayImpl::relay(protocol::TMProposeSet& m, uint256 const& uid)
1147 {
1148  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1149  {
1150  auto const sm =
1151  std::make_shared<Message>(m, protocol::mtPROPOSE_LEDGER);
1153  if (toSkip->find(p->id()) == toSkip->end())
1154  p->send(sm);
1155  });
1156  }
1157 }
1158 
1159 void
1160 OverlayImpl::broadcast(protocol::TMValidation& m)
1161 {
1162  auto const sm = std::make_shared<Message>(m, protocol::mtVALIDATION);
1163  for_each([sm](std::shared_ptr<PeerImp>&& p) { p->send(sm); });
1164 }
1165 
1166 void
1167 OverlayImpl::relay(protocol::TMValidation& m, uint256 const& uid)
1168 {
1169  if (auto const toSkip = app_.getHashRouter().shouldRelay(uid))
1170  {
1171  auto const sm = std::make_shared<Message>(m, protocol::mtVALIDATION);
1173  if (toSkip->find(p->id()) == toSkip->end())
1174  p->send(sm);
1175  });
1176  }
1177 }
1178 
1179 //------------------------------------------------------------------------------
1180 
1181 void
1183 {
1184  std::lock_guard lock(mutex_);
1185  list_.erase(&child);
1186  if (list_.empty())
1187  checkStopped();
1188 }
1189 
1190 void
1192 {
1193  // Calling list_[].second->stop() may cause list_ to be modified
1194  // (OverlayImpl::remove() may be called on this same thread). So
1195  // iterating directly over list_ to call child->stop() could lead to
1196  // undefined behavior.
1197  //
1198  // Therefore we copy all of the weak/shared ptrs out of list_ before we
1199  // start calling stop() on them. That guarantees OverlayImpl::remove()
1200  // won't be called until vector<> children leaves scope.
1202  {
1203  std::lock_guard lock(mutex_);
1204  if (!work_)
1205  return;
1206  work_ = boost::none;
1207 
1208  children.reserve(list_.size());
1209  for (auto const& element : list_)
1210  {
1211  children.emplace_back(element.second.lock());
1212  }
1213  } // lock released
1214 
1215  for (auto const& child : children)
1216  {
1217  if (child != nullptr)
1218  child->stop();
1219  }
1220 }
1221 
1222 void
1224 {
1225  auto const result = m_peerFinder->autoconnect();
1226  for (auto addr : result)
1227  connect(addr);
1228 }
1229 
1230 void
1232 {
1233  auto const result = m_peerFinder->buildEndpointsForPeers();
1234  for (auto const& e : result)
1235  {
1237  {
1238  std::lock_guard lock(mutex_);
1239  auto const iter = m_peers.find(e.first);
1240  if (iter != m_peers.end())
1241  peer = iter->second.lock();
1242  }
1243  if (peer)
1244  peer->sendEndpoints(e.second.begin(), e.second.end());
1245  }
1246 }
1247 
1250 {
1252 
1253  {
1254  auto const& section = config.section("overlay");
1256 
1257  set(setup.ipLimit, "ip_limit", section);
1258  if (setup.ipLimit < 0)
1259  Throw<std::runtime_error>("Configured IP limit is invalid");
1260 
1261  std::string ip;
1262  set(ip, "public_ip", section);
1263  if (!ip.empty())
1264  {
1265  boost::system::error_code ec;
1266  setup.public_ip = beast::IP::Address::from_string(ip, ec);
1268  Throw<std::runtime_error>("Configured public IP is invalid");
1269  }
1270  }
1271 
1272  {
1273  auto const& section = config.section("crawl");
1274  auto const& values = section.values();
1275 
1276  if (values.size() > 1)
1277  {
1278  Throw<std::runtime_error>(
1279  "Configured [crawl] section is invalid, too many values");
1280  }
1281 
1282  bool crawlEnabled = true;
1283 
1284  // Only allow "0|1" as a value
1285  if (values.size() == 1)
1286  {
1287  try
1288  {
1289  crawlEnabled = boost::lexical_cast<bool>(values.front());
1290  }
1291  catch (boost::bad_lexical_cast const&)
1292  {
1293  Throw<std::runtime_error>(
1294  "Configured [crawl] section has invalid value: " +
1295  values.front());
1296  }
1297  }
1298 
1299  if (crawlEnabled)
1300  {
1301  if (get<bool>(section, "overlay", true))
1302  {
1304  }
1305  if (get<bool>(section, "server", true))
1306  {
1308  }
1309  if (get<bool>(section, "counts", false))
1310  {
1312  }
1313  if (get<bool>(section, "unl", true))
1314  {
1316  }
1317  }
1318  }
1319  {
1320  auto const& section = config.section("vl");
1321 
1322  set(setup.vlEnabled, "enabled", section);
1323  }
1324 
1325  try
1326  {
1327  auto id = config.legacy("network_id");
1328 
1329  if (!id.empty())
1330  {
1331  if (id == "main")
1332  id = "0";
1333 
1334  if (id == "testnet")
1335  id = "1";
1336 
1337  if (id == "devnet")
1338  id = "2";
1339 
1340  setup.networkID = beast::lexicalCastThrow<std::uint32_t>(id);
1341  }
1342  }
1343  catch (...)
1344  {
1345  Throw<std::runtime_error>(
1346  "Configured [network_id] section is invalid: must be a number "
1347  "or one of the strings 'main', 'testnet' or 'devnet'.");
1348  }
1349 
1350  return setup;
1351 }
1352 
1355  Application& app,
1356  Overlay::Setup const& setup,
1357  Stoppable& parent,
1360  Resolver& resolver,
1361  boost::asio::io_service& io_service,
1362  BasicConfig const& config,
1363  beast::insight::Collector::ptr const& collector)
1364 {
1365  return std::make_unique<OverlayImpl>(
1366  app,
1367  setup,
1368  parent,
1369  serverHandler,
1371  resolver,
1372  io_service,
1373  config,
1374  collector);
1375 }
1376 
1377 } // 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:1112
ripple::OverlayImpl::relay
void relay(protocol::TMProposeSet &m, uint256 const &uid) override
Relay a proposal.
Definition: OverlayImpl.cpp:1146
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:948
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: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:1223
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:1354
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:143
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:920
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::OverlayImpl::broadcast
void broadcast(protocol::TMProposeSet &m) override
Broadcast a proposal.
Definition: OverlayImpl.cpp:1139
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:985
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:1033
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:859
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:1249
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:872
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:218
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: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:954
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::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:1086
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:1079
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:144
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:1099
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:844
ripple::OverlayImpl::check
void check() override
Calls the check function on each peer.
Definition: OverlayImpl.cpp:1106
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:1124
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:1231
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
ripple::OverlayImpl::stop
void stop()
Definition: OverlayImpl.cpp:1191
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:866
ripple::OverlayImpl::processCrawl
bool processCrawl(http_request_type const &req, Handoff &handoff)
Handles crawl requests.
Definition: OverlayImpl.cpp:996
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)