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/asio/basic_waitable_timer.hpp>
42#include <boost/asio/ip/tcp.hpp>
43#include <boost/asio/ssl/context.hpp>
44#include <boost/asio/strand.hpp>
45#include <boost/container/flat_map.hpp>
46
47#include <atomic>
48#include <chrono>
49#include <condition_variable>
50#include <cstdint>
51#include <memory>
52#include <mutex>
53#include <optional>
54#include <unordered_map>
55
56namespace ripple {
57
58class PeerImp;
59class BasicConfig;
60
62{
63public:
64 class Child
65 {
66 protected:
68
69 explicit Child(OverlayImpl& overlay);
70
71 virtual ~Child();
72
73 public:
74 virtual void
75 stop() = 0;
76 };
77
78private:
80 using socket_type = boost::asio::ip::tcp::socket;
81 using address_type = boost::asio::ip::address;
82 using endpoint_type = boost::asio::ip::tcp::endpoint;
83 using error_code = boost::system::error_code;
84
86 {
87 boost::asio::basic_waitable_timer<clock_type> timer_;
88 bool stopping_{false};
89
90 explicit Timer(OverlayImpl& overlay);
91
92 void
93 stop() override;
94
95 void
96 async_wait();
97
98 void
100 };
101
103 boost::asio::io_service& io_service_;
105 boost::asio::io_service::strand strand_;
106 mutable std::recursive_mutex mutex_; // VFALCO use std::mutex
109 boost::container::flat_map<Child*, std::weak_ptr<Child>> list_;
124
126
127 // Transaction reduce-relay metrics
129
130 // A message with the list of manifests we send to peers
132 // Used to track whether we need to update the cached list of manifests
134 // Protects the message and the sequence list of manifests
136
137 //--------------------------------------------------------------------------
138
139public:
141 Application& app,
142 Setup const& setup,
143 ServerHandler& serverHandler,
145 Resolver& resolver,
146 boost::asio::io_service& io_service,
147 BasicConfig const& config,
148 beast::insight::Collector::ptr const& collector);
149
150 OverlayImpl(OverlayImpl const&) = delete;
152 operator=(OverlayImpl const&) = delete;
153
154 void
155 start() override;
156
157 void
158 stop() override;
159
162 {
163 return *m_peerFinder;
164 }
165
168 {
169 return m_resourceManager;
170 }
171
172 Setup const&
173 setup() const
174 {
175 return setup_;
176 }
177
178 Handoff
179 onHandoff(
181 http_request_type&& request,
182 endpoint_type remote_endpoint) override;
183
184 void
185 connect(beast::IP::Endpoint const& remote_endpoint) override;
186
187 int
188 limit() override;
189
191 size() const override;
192
194 json() override;
195
197 getActivePeers() const override;
198
210 std::set<Peer::id_t> const& toSkip,
211 std::size_t& active,
212 std::size_t& disabled,
213 std::size_t& enabledInSkip) const;
214
215 void checkTracking(std::uint32_t) override;
216
218 findPeerByShortID(Peer::id_t const& id) const override;
219
221 findPeerByPublicKey(PublicKey const& pubKey) override;
222
223 void
224 broadcast(protocol::TMProposeSet& m) override;
225
226 void
227 broadcast(protocol::TMValidation& m) override;
228
230 relay(
231 protocol::TMProposeSet& m,
232 uint256 const& uid,
233 PublicKey const& validator) override;
234
236 relay(
237 protocol::TMValidation& m,
238 uint256 const& uid,
239 PublicKey const& validator) override;
240
241 void
242 relay(
243 uint256 const&,
245 std::set<Peer::id_t> const& skip) override;
246
249
250 //--------------------------------------------------------------------------
251 //
252 // OverlayImpl
253 //
254
255 void
257
258 void
260
266 void
268
269 // Called when an active peer is destroyed.
270 void
272
273 // UnaryFunc will be called as
274 // void(std::shared_ptr<PeerImp>&&)
275 //
276 template <class UnaryFunc>
277 void
278 for_each(UnaryFunc&& f) const
279 {
281 {
283
284 // Iterate over a copy of the peer list because peer
285 // destruction can invalidate iterators.
286 wp.reserve(ids_.size());
287
288 for (auto& x : ids_)
289 wp.push_back(x.second);
290 }
291
292 for (auto& w : wp)
293 {
294 if (auto p = w.lock())
295 f(std::move(p));
296 }
297 }
298
299 // Called when TMManifests is received from a peer
300 void
303 std::shared_ptr<PeerImp> const& from);
304
305 static bool
306 isPeerUpgrade(http_request_type const& request);
307
308 template <class Body>
309 static bool
310 isPeerUpgrade(boost::beast::http::response<Body> const& response)
311 {
312 if (!is_upgrade(response))
313 return false;
314 return response.result() ==
315 boost::beast::http::status::switching_protocols;
316 }
317
318 template <class Fields>
319 static bool
320 is_upgrade(boost::beast::http::header<true, Fields> const& req)
321 {
322 if (req.version() < 11)
323 return false;
324 if (req.method() != boost::beast::http::verb::get)
325 return false;
326 if (!boost::beast::http::token_list{req["Connection"]}.exists(
327 "upgrade"))
328 return false;
329 return true;
330 }
331
332 template <class Fields>
333 static bool
334 is_upgrade(boost::beast::http::header<false, Fields> const& req)
335 {
336 if (req.version() < 11)
337 return false;
338 if (!boost::beast::http::token_list{req["Connection"]}.exists(
339 "upgrade"))
340 return false;
341 return true;
342 }
343
344 static std::string
346
347 void
349
350 void
352
353 void
355 {
357 }
358
360 getJqTransOverflow() const override
361 {
362 return jqTransOverflow_;
363 }
364
365 void
367 {
369 }
370
372 getPeerDisconnect() const override
373 {
374 return peerDisconnects_;
375 }
376
377 void
382
385 {
387 }
388
390 networkID() const override
391 {
392 return setup_.networkID;
393 }
394
404 void
406 uint256 const& key,
407 PublicKey const& validator,
408 std::set<Peer::id_t>&& peers,
409 protocol::MessageType type);
410
413 void
415 uint256 const& key,
416 PublicKey const& validator,
417 Peer::id_t peer,
418 protocol::MessageType type);
419
425 void
427
429 txMetrics() const override
430 {
431 return txMetrics_.json();
432 }
433
435 template <typename... Args>
436 void
437 addTxMetrics(Args... args)
438 {
439 if (!strand_.running_in_this_thread())
440 return post(
441 strand_,
442 std::bind(&OverlayImpl::addTxMetrics<Args...>, this, args...));
443
444 txMetrics_.addMetrics(args...);
445 }
446
447private:
448 void
449 squelch(
450 PublicKey const& validator,
451 Peer::id_t const id,
452 std::uint32_t squelchDuration) const override;
453
454 void
455 unsquelch(PublicKey const& validator, Peer::id_t id) const override;
456
460 http_request_type const& request,
461 address_type remote_address);
462
466 http_request_type const& request,
467 address_type remote_address,
468 std::string msg);
469
475 bool
476 processCrawl(http_request_type const& req, Handoff& handoff);
477
485 bool
486 processValidatorList(http_request_type const& req, Handoff& handoff);
487
493 bool
494 processHealth(http_request_type const& req, Handoff& handoff);
495
500 bool
501 processRequest(http_request_type const& req, Handoff& handoff);
502
509
516
523
529 getUnlInfo();
530
531 //--------------------------------------------------------------------------
532
533 //
534 // PropertyStream
535 //
536
537 void
538 onWrite(beast::PropertyStream::Map& stream) override;
539
540 //--------------------------------------------------------------------------
541
542 void
543 remove(Child& child);
544
545 void
546 stopChildren();
547
548 void
549 autoConnect();
550
551 void
553
555 void
556 sendTxQueue();
557
560 void
562
563private:
565 {
567 std::string const& name,
568 beast::insight::Collector::ptr const& collector)
569 : name(name)
570 , bytesIn(collector->make_gauge(name, "Bytes_In"))
571 , bytesOut(collector->make_gauge(name, "Bytes_Out"))
572 , messagesIn(collector->make_gauge(name, "Messages_In"))
573 , messagesOut(collector->make_gauge(name, "Messages_Out"))
574 {
575 }
581 };
582
583 struct Stats
584 {
585 template <class Handler>
587 Handler const& handler,
588 beast::insight::Collector::ptr const& collector,
590 trafficGauges_)
592 collector->make_gauge("Overlay", "Peer_Disconnects"))
593 , trafficGauges(std::move(trafficGauges_))
594 , hook(collector->make_hook(handler))
595 {
596 }
597
601 };
602
605
606private:
607 void
609 {
610 auto counts = m_traffic.getCounts();
612 XRPL_ASSERT(
613 counts.size() == m_stats.trafficGauges.size(),
614 "ripple::OverlayImpl::collect_metrics : counts size do match");
615
616 for (auto const& [key, value] : counts)
617 {
618 auto it = m_stats.trafficGauges.find(key);
619 if (it == m_stats.trafficGauges.end())
620 continue;
621
622 auto& gauge = it->second;
623
624 XRPL_ASSERT(
625 gauge.name == value.name,
626 "ripple::OverlayImpl::collect_metrics : gauge and counter "
627 "match");
628
629 gauge.bytesIn = value.bytesIn;
630 gauge.bytesOut = value.bytesOut;
631 gauge.messagesIn = value.messagesIn;
632 gauge.messagesOut = value.messagesOut;
633 }
634
636 }
637};
638
639} // namespace ripple
640
641#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.
boost::system::error_code error_code
Definition OverlayImpl.h:83
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:82
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:81
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...
boost::asio::io_service & io_service_
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:80
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...
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)
std::optional< boost::asio::io_service::work > work_
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)
boost::asio::io_service::strand strand_
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:87
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.