rippled
Loading...
Searching...
No Matches
OverlayImpl.h
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#ifndef RIPPLE_OVERLAY_OVERLAYIMPL_H_INCLUDED
21#define RIPPLE_OVERLAY_OVERLAYIMPL_H_INCLUDED
22
23#include <xrpld/app/main/Application.h>
24#include <xrpld/core/Job.h>
25#include <xrpld/overlay/Message.h>
26#include <xrpld/overlay/Overlay.h>
27#include <xrpld/overlay/Slot.h>
28#include <xrpld/overlay/detail/Handshake.h>
29#include <xrpld/overlay/detail/TrafficCount.h>
30#include <xrpld/overlay/detail/TxMetrics.h>
31#include <xrpld/peerfinder/PeerfinderManager.h>
32#include <xrpld/rpc/ServerHandler.h>
33
34#include <xrpl/basics/Resolver.h>
35#include <xrpl/basics/UnorderedContainers.h>
36#include <xrpl/basics/chrono.h>
37#include <xrpl/beast/utility/instrumentation.h>
38#include <xrpl/resource/ResourceManager.h>
39#include <xrpl/server/Handoff.h>
40
41#include <boost/algorithm/string/predicate.hpp>
42#include <boost/asio/basic_waitable_timer.hpp>
43#include <boost/asio/ip/tcp.hpp>
44#include <boost/asio/ssl/context.hpp>
45#include <boost/asio/strand.hpp>
46#include <boost/container/flat_map.hpp>
47
48#include <atomic>
49#include <chrono>
50#include <condition_variable>
51#include <cstdint>
52#include <memory>
53#include <mutex>
54#include <optional>
55#include <unordered_map>
56
57namespace ripple {
58
59class PeerImp;
60class BasicConfig;
61
63{
64public:
65 class Child
66 {
67 protected:
69
70 explicit Child(OverlayImpl& overlay);
71
72 virtual ~Child();
73
74 public:
75 virtual void
76 stop() = 0;
77 };
78
79private:
81 using socket_type = boost::asio::ip::tcp::socket;
82 using address_type = boost::asio::ip::address;
83 using endpoint_type = boost::asio::ip::tcp::endpoint;
84 using error_code = boost::system::error_code;
85
87 {
88 boost::asio::basic_waitable_timer<clock_type> timer_;
89 bool stopping_{false};
90
91 explicit Timer(OverlayImpl& overlay);
92
93 void
94 stop() override;
95
96 void
97 async_wait();
98
99 void
101 };
102
104 boost::asio::io_context& io_context_;
105 std::optional<boost::asio::executor_work_guard<
106 boost::asio::io_context::executor_type>>
108 boost::asio::strand<boost::asio::io_context::executor_type> strand_;
109 mutable std::recursive_mutex mutex_; // VFALCO use std::mutex
112 boost::container::flat_map<Child*, std::weak_ptr<Child>> list_;
127
129
130 // Transaction reduce-relay metrics
132
133 // A message with the list of manifests we send to peers
135 // Used to track whether we need to update the cached list of manifests
137 // Protects the message and the sequence list of manifests
139
140 //--------------------------------------------------------------------------
141
142public:
144 Application& app,
145 Setup const& setup,
146 ServerHandler& serverHandler,
148 Resolver& resolver,
149 boost::asio::io_context& io_context,
150 BasicConfig const& config,
151 beast::insight::Collector::ptr const& collector);
152
153 OverlayImpl(OverlayImpl const&) = delete;
155 operator=(OverlayImpl const&) = delete;
156
157 void
158 start() override;
159
160 void
161 stop() override;
162
165 {
166 return *m_peerFinder;
167 }
168
171 {
172 return m_resourceManager;
173 }
174
175 Setup const&
176 setup() const
177 {
178 return setup_;
179 }
180
181 Handoff
182 onHandoff(
184 http_request_type&& request,
185 endpoint_type remote_endpoint) override;
186
187 void
188 connect(beast::IP::Endpoint const& remote_endpoint) override;
189
190 int
191 limit() override;
192
194 size() const override;
195
197 json() override;
198
200 getActivePeers() const override;
201
213 std::set<Peer::id_t> const& toSkip,
214 std::size_t& active,
215 std::size_t& disabled,
216 std::size_t& enabledInSkip) const;
217
218 void checkTracking(std::uint32_t) override;
219
221 findPeerByShortID(Peer::id_t const& id) const override;
222
224 findPeerByPublicKey(PublicKey const& pubKey) override;
225
226 void
227 broadcast(protocol::TMProposeSet& m) override;
228
229 void
230 broadcast(protocol::TMValidation& m) override;
231
233 relay(
234 protocol::TMProposeSet& m,
235 uint256 const& uid,
236 PublicKey const& validator) override;
237
239 relay(
240 protocol::TMValidation& m,
241 uint256 const& uid,
242 PublicKey const& validator) override;
243
244 void
245 relay(
246 uint256 const&,
248 std::set<Peer::id_t> const& skip) override;
249
252
253 //--------------------------------------------------------------------------
254 //
255 // OverlayImpl
256 //
257
258 void
260
261 void
263
269 void
271
272 // Called when an active peer is destroyed.
273 void
275
276 // UnaryFunc will be called as
277 // void(std::shared_ptr<PeerImp>&&)
278 //
279 template <class UnaryFunc>
280 void
281 for_each(UnaryFunc&& f) const
282 {
284 {
286
287 // Iterate over a copy of the peer list because peer
288 // destruction can invalidate iterators.
289 wp.reserve(ids_.size());
290
291 for (auto& x : ids_)
292 wp.push_back(x.second);
293 }
294
295 for (auto& w : wp)
296 {
297 if (auto p = w.lock())
298 f(std::move(p));
299 }
300 }
301
302 // Called when TMManifests is received from a peer
303 void
306 std::shared_ptr<PeerImp> const& from);
307
308 static bool
309 isPeerUpgrade(http_request_type const& request);
310
311 template <class Body>
312 static bool
313 isPeerUpgrade(boost::beast::http::response<Body> const& response)
314 {
315 if (!is_upgrade(response))
316 return false;
317 return response.result() ==
318 boost::beast::http::status::switching_protocols;
319 }
320
321 template <class Fields>
322 static bool
323 is_upgrade(boost::beast::http::header<true, Fields> const& req)
324 {
325 if (req.version() < 11)
326 return false;
327 if (req.method() != boost::beast::http::verb::get)
328 return false;
329 if (!boost::beast::http::token_list{req["Connection"]}.exists(
330 "upgrade"))
331 return false;
332 return true;
333 }
334
335 template <class Fields>
336 static bool
337 is_upgrade(boost::beast::http::header<false, Fields> const& req)
338 {
339 if (req.version() < 11)
340 return false;
341 if (!boost::beast::http::token_list{req["Connection"]}.exists(
342 "upgrade"))
343 return false;
344 return true;
345 }
346
347 static std::string
349
350 void
352
353 void
355
356 void
358 {
360 }
361
363 getJqTransOverflow() const override
364 {
365 return jqTransOverflow_;
366 }
367
368 void
370 {
372 }
373
375 getPeerDisconnect() const override
376 {
377 return peerDisconnects_;
378 }
379
380 void
385
388 {
390 }
391
393 networkID() const override
394 {
395 return setup_.networkID;
396 }
397
407 void
409 uint256 const& key,
410 PublicKey const& validator,
411 std::set<Peer::id_t>&& peers,
412 protocol::MessageType type);
413
416 void
418 uint256 const& key,
419 PublicKey const& validator,
420 Peer::id_t peer,
421 protocol::MessageType type);
422
428 void
430
432 txMetrics() const override
433 {
434 return txMetrics_.json();
435 }
436
438 template <typename... Args>
439 void
440 addTxMetrics(Args... args)
441 {
442 if (!strand_.running_in_this_thread())
443 return post(
444 strand_,
445 std::bind(&OverlayImpl::addTxMetrics<Args...>, this, args...));
446
447 txMetrics_.addMetrics(args...);
448 }
449
450private:
451 void
452 squelch(
453 PublicKey const& validator,
454 Peer::id_t const id,
455 std::uint32_t squelchDuration) const override;
456
457 void
458 unsquelch(PublicKey const& validator, Peer::id_t id) const override;
459
463 http_request_type const& request,
464 address_type remote_address);
465
469 http_request_type const& request,
470 address_type remote_address,
471 std::string msg);
472
478 bool
479 processCrawl(http_request_type const& req, Handoff& handoff);
480
488 bool
489 processValidatorList(http_request_type const& req, Handoff& handoff);
490
496 bool
497 processHealth(http_request_type const& req, Handoff& handoff);
498
503 bool
504 processRequest(http_request_type const& req, Handoff& handoff);
505
512
519
526
532 getUnlInfo();
533
534 //--------------------------------------------------------------------------
535
536 //
537 // PropertyStream
538 //
539
540 void
541 onWrite(beast::PropertyStream::Map& stream) override;
542
543 //--------------------------------------------------------------------------
544
545 void
546 remove(Child& child);
547
548 void
549 stopChildren();
550
551 void
552 autoConnect();
553
554 void
556
558 void
559 sendTxQueue();
560
563 void
565
566private:
568 {
570 std::string const& name,
571 beast::insight::Collector::ptr const& collector)
572 : name(name)
573 , bytesIn(collector->make_gauge(name, "Bytes_In"))
574 , bytesOut(collector->make_gauge(name, "Bytes_Out"))
575 , messagesIn(collector->make_gauge(name, "Messages_In"))
576 , messagesOut(collector->make_gauge(name, "Messages_Out"))
577 {
578 }
584 };
585
586 struct Stats
587 {
588 template <class Handler>
590 Handler const& handler,
591 beast::insight::Collector::ptr const& collector,
593 trafficGauges_)
595 collector->make_gauge("Overlay", "Peer_Disconnects"))
596 , trafficGauges(std::move(trafficGauges_))
597 , hook(collector->make_hook(handler))
598 {
599 }
600
604 };
605
608
609private:
610 void
612 {
613 auto counts = m_traffic.getCounts();
615 XRPL_ASSERT(
616 counts.size() == m_stats.trafficGauges.size(),
617 "ripple::OverlayImpl::collect_metrics : counts size do match");
618
619 for (auto const& [key, value] : counts)
620 {
621 auto it = m_stats.trafficGauges.find(key);
622 if (it == m_stats.trafficGauges.end())
623 continue;
624
625 auto& gauge = it->second;
626
627 XRPL_ASSERT(
628 gauge.name == value.name,
629 "ripple::OverlayImpl::collect_metrics : gauge and counter "
630 "match");
631
632 gauge.bytesIn = value.bytesIn;
633 gauge.bytesOut = value.bytesOut;
634 gauge.messagesIn = value.messagesIn;
635 gauge.messagesOut = value.messagesOut;
636 }
637
639 }
640};
641
642} // namespace ripple
643
644#endif
T bind(T... args)
Represents a JSON value.
Definition json_value.h:149
A version-independent IP address and port combination.
Definition IPEndpoint.h:38
A generic endpoint for log messages.
Definition Journal.h:60
A metric for measuring an integral value.
Definition Gauge.h:40
A reference to a handler for performing polled collection.
Definition Hook.h:32
Holds unparsed configuration information.
std::optional< boost::asio::executor_work_guard< boost::asio::io_context::executor_type > > work_
boost::system::error_code error_code
Definition OverlayImpl.h:84
Json::Value getUnlInfo()
Returns information about the local server's UNL.
void stop() override
static std::string makePrefix(std::uint32_t id)
PeerFinder::Manager & peerFinder()
boost::asio::ip::tcp::endpoint endpoint_type
Definition OverlayImpl.h:83
std::atomic< uint64_t > peerDisconnects_
bool processHealth(http_request_type const &req, Handoff &handoff)
Handles health requests.
boost::asio::ip::address address_type
Definition OverlayImpl.h:82
boost::asio::io_context & io_context_
static bool is_upgrade(boost::beast::http::header< true, Fields > const &req)
std::condition_variable_any cond_
void onWrite(beast::PropertyStream::Map &stream) override
Subclass override.
Json::Value txMetrics() const override
Returns tx reduce-relay metrics.
void deleteIdlePeers()
Check if peers stopped relaying messages and if slots stopped receiving messages from the validator.
Resolver & m_resolver
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...
PeerSequence getActivePeers() const override
Returns a sequence representing the current list of peers.
void start() override
hash_map< std::shared_ptr< PeerFinder::Slot >, std::weak_ptr< PeerImp > > m_peers
void add_active(std::shared_ptr< PeerImp > const &peer)
std::shared_ptr< Peer > findPeerByPublicKey(PublicKey const &pubKey) override
Returns the peer with the matching public key, or null.
Resource::Manager & m_resourceManager
std::shared_ptr< Message > manifestMessage_
std::optional< std::uint32_t > manifestListSeq_
OverlayImpl & operator=(OverlayImpl const &)=delete
TrafficCount m_traffic
void squelch(PublicKey const &validator, Peer::id_t const id, std::uint32_t squelchDuration) const override
Squelch handler.
std::shared_ptr< Writer > makeErrorResponse(std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type const &request, address_type remote_address, std::string msg)
reduce_relay::Slots< UptimeClock > slots_
void deletePeer(Peer::id_t id)
Called when the peer is deleted.
std::shared_ptr< Peer > findPeerByShortID(Peer::id_t const &id) const override
Returns the peer with the matching short id, or null.
std::atomic< Peer::id_t > next_id_
void incPeerDisconnect() override
Increment and retrieve counters for total peer disconnects, and disconnects we initiate for excessive...
void addTxMetrics(Args... args)
Add tx reduce-relay metrics.
Application & app_
std::optional< std::uint32_t > networkID() const override
Returns the ID of the network this server is configured for, if any.
std::weak_ptr< Timer > timer_
std::atomic< uint64_t > jqTransOverflow_
metrics::TxMetrics txMetrics_
void broadcast(protocol::TMProposeSet &m) override
Broadcast a proposal.
void onPeerDeactivate(Peer::id_t id)
std::mutex manifestLock_
bool processRequest(http_request_type const &req, Handoff &handoff)
Handles non-peer protocol requests.
std::recursive_mutex mutex_
std::uint64_t getPeerDisconnectCharges() const override
boost::asio::ip::tcp::socket socket_type
Definition OverlayImpl.h:81
void remove(std::shared_ptr< PeerFinder::Slot > const &slot)
void sendTxQueue()
Send once a second transactions' hashes aggregated by peers.
void reportOutboundTraffic(TrafficCount::category cat, int bytes)
std::set< Peer::id_t > relay(protocol::TMProposeSet &m, uint256 const &uid, PublicKey const &validator) override
Relay a proposal.
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...
boost::asio::strand< boost::asio::io_context::executor_type > strand_
void unsquelch(PublicKey const &validator, Peer::id_t id) const override
Unsquelch handler.
std::shared_ptr< Writer > makeRedirectResponse(std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type const &request, address_type remote_address)
void for_each(UnaryFunc &&f) const
static bool isPeerUpgrade(boost::beast::http::response< Body > const &response)
OverlayImpl(OverlayImpl const &)=delete
Json::Value getOverlayInfo()
Returns information about peers on the overlay network.
Resource::Manager & resourceManager()
static bool isPeerUpgrade(http_request_type const &request)
Json::Value getServerCounts()
Returns information about the local server's performance counters.
void reportInboundTraffic(TrafficCount::category cat, int bytes)
void onManifests(std::shared_ptr< protocol::TMManifests > const &m, std::shared_ptr< PeerImp > const &from)
std::unique_ptr< PeerFinder::Manager > m_peerFinder
std::uint64_t getJqTransOverflow() const override
void connect(beast::IP::Endpoint const &remote_endpoint) override
Establish a peer connection to the specified endpoint.
Handoff onHandoff(std::unique_ptr< stream_type > &&bundle, http_request_type &&request, endpoint_type remote_endpoint) override
Conditionally accept an incoming HTTP request.
Setup const & setup() const
std::atomic< uint64_t > peerDisconnectsCharges_
std::shared_ptr< Message > getManifestsMessage()
hash_map< Peer::id_t, std::weak_ptr< PeerImp > > ids_
Json::Value getServerInfo()
Returns information about the local server.
bool processValidatorList(http_request_type const &req, Handoff &handoff)
Handles validator list requests.
Json::Value json() override
Return diagnostics on the status of all peers.
std::mutex m_statsMutex
void checkTracking(std::uint32_t) override
Calls the checkTracking function on each peer.
void incPeerDisconnectCharges() override
ServerHandler & serverHandler_
bool processCrawl(http_request_type const &req, Handoff &handoff)
Handles crawl requests.
static bool is_upgrade(boost::beast::http::header< false, Fields > const &req)
int limit() override
Returns the maximum number of peers we are configured to allow.
void updateSlotAndSquelch(uint256 const &key, PublicKey const &validator, std::set< Peer::id_t > &&peers, protocol::MessageType type)
Updates message count for validator/peer.
void incJqTransOverflow() override
Increment and retrieve counter for transaction job queue overflows.
beast::Journal const journal_
boost::container::flat_map< Child *, std::weak_ptr< Child > > list_
std::uint64_t getPeerDisconnect() const override
Manages the set of connected peers.
Definition Overlay.h:49
std::vector< std::shared_ptr< Peer > > PeerSequence
Definition Overlay.h:76
Maintains a set of IP addresses used for getting into the network.
A public key.
Definition PublicKey.h:61
Tracks load and resource consumption.
TrafficCount is used to count ingress and egress wire bytes and number of messages.
auto const & getCounts() const
An up-to-date copy of all the counters.
Slots is a container for validator's Slot and handles Slot update when a message is received from a v...
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition Handoff.h:33
STL namespace.
T push_back(T... args)
T reserve(T... args)
Used to indicate the result of a server connection handoff.
Definition Handoff.h:40
beast::insight::Gauge peerDisconnects
std::unordered_map< TrafficCount::category, TrafficGauges > trafficGauges
Stats(Handler const &handler, beast::insight::Collector::ptr const &collector, std::unordered_map< TrafficCount::category, TrafficGauges > &&trafficGauges_)
beast::insight::Hook hook
void on_timer(error_code ec)
boost::asio::basic_waitable_timer< clock_type > timer_
Definition OverlayImpl.h:88
beast::insight::Gauge messagesIn
beast::insight::Gauge bytesIn
beast::insight::Gauge messagesOut
beast::insight::Gauge bytesOut
TrafficGauges(std::string const &name, beast::insight::Collector::ptr const &collector)
std::optional< std::uint32_t > networkID
Definition Overlay.h:72
Run transaction reduce-relay feature related metrics.
Definition TxMetrics.h:89
void addMetrics(protocol::MessageType type, std::uint32_t val)
Add protocol message metrics.
Definition TxMetrics.cpp:31
Json::Value json() const
Get json representation of the metrics.