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