rippled
Loading...
Searching...
No Matches
PeerfinderConfig.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 <xrpld/peerfinder/PeerfinderManager.h>
21#include <xrpld/peerfinder/detail/Tuning.h>
22
23namespace ripple {
24namespace PeerFinder {
25
27 : maxPeers(Tuning::defaultMaxPeers)
28 , outPeers(calcOutPeers())
29 , inPeers(0)
30 , wantIncoming(true)
31 , autoConnect(true)
32 , listeningPort(0)
33 , ipLimit(0)
34{
35}
36
37bool
38operator==(Config const& lhs, Config const& rhs)
39{
40 return lhs.autoConnect == rhs.autoConnect &&
41 lhs.peerPrivate == rhs.peerPrivate &&
42 lhs.wantIncoming == rhs.wantIncoming && lhs.inPeers == rhs.inPeers &&
43 lhs.maxPeers == rhs.maxPeers && lhs.outPeers == rhs.outPeers &&
44 lhs.features == lhs.features && lhs.ipLimit == rhs.ipLimit &&
46}
47
50{
51 return std::max(
52 (maxPeers * Tuning::outPercent + 50) / 100,
54}
55
56void
58{
59 if (ipLimit == 0)
60 {
61 // Unless a limit is explicitly set, we allow between
62 // 2 and 5 connections from non RFC-1918 "private"
63 // IP addresses.
64 ipLimit = 2;
65
68 5, static_cast<int>(inPeers / Tuning::defaultMaxPeers));
69 }
70
71 // We don't allow a single IP to consume all incoming slots,
72 // unless we only have one incoming slot available.
73 ipLimit = std::max(1, std::min(ipLimit, static_cast<int>(inPeers / 2)));
74}
75
76void
78{
79 map["max_peers"] = maxPeers;
80 map["out_peers"] = outPeers;
81 map["want_incoming"] = wantIncoming;
82 map["auto_connect"] = autoConnect;
83 map["port"] = listeningPort;
84 map["features"] = features;
85 map["ip_limit"] = ipLimit;
86}
87
90 ripple::Config const& cfg,
91 std::uint16_t port,
92 bool validationPublicKey,
93 int ipLimit)
94{
95 PeerFinder::Config config;
96
97 config.peerPrivate = cfg.PEER_PRIVATE;
98
99 // Servers with peer privacy don't want to allow incoming connections
100 config.wantIncoming = (!config.peerPrivate) && (port != 0);
101
102 if (!cfg.PEERS_OUT_MAX && !cfg.PEERS_IN_MAX)
103 {
104 if (cfg.PEERS_MAX != 0)
105 config.maxPeers = cfg.PEERS_MAX;
106
107 if (config.maxPeers < Tuning::minOutCount)
109 config.outPeers = config.calcOutPeers();
110
111 // Calculate the number of outbound peers we want. If we dont want
112 // or can't accept incoming, this will simply be equal to maxPeers.
113 if (!config.wantIncoming)
114 config.outPeers = config.maxPeers;
115
116 // Calculate the largest number of inbound connections we could
117 // take.
118 if (config.maxPeers >= config.outPeers)
119 config.inPeers = config.maxPeers - config.outPeers;
120 else
121 config.inPeers = 0;
122 }
123 else
124 {
125 config.outPeers = cfg.PEERS_OUT_MAX;
126 config.inPeers = cfg.PEERS_IN_MAX;
127 config.maxPeers = 0;
128 }
129
130 // This will cause servers configured as validators to request that
131 // peers they connect to never report their IP address. We set this
132 // after we set the 'wantIncoming' because we want a "soft" version
133 // of peer privacy unless the operator explicitly asks for it.
134 if (validationPublicKey)
135 config.peerPrivate = true;
136
137 // if it's a private peer or we are running as standalone
138 // automatic connections would defeat the purpose.
139 config.autoConnect = !cfg.standalone() && !cfg.PEER_PRIVATE;
140 config.listeningPort = port;
141 config.features = "";
142 config.ipLimit = ipLimit;
143
144 // Enforce business rules
145 config.applyTuning();
146
147 return config;
148}
149
150} // namespace PeerFinder
151} // namespace ripple
std::size_t PEERS_IN_MAX
Definition Config.h:181
bool PEER_PRIVATE
Definition Config.h:173
bool standalone() const
Definition Config.h:336
std::size_t PEERS_OUT_MAX
Definition Config.h:180
std::size_t PEERS_MAX
Definition Config.h:179
T max(T... args)
T min(T... args)
bool operator==(Endpoint const &a, Endpoint const &b)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
PeerFinder configuration settings.
void onWrite(beast::PropertyStream::Map &map)
Write the configuration into a property stream.
Config()
Create a configuration with default values.
bool autoConnect
true if we want to establish connections automatically
int ipLimit
Limit how many incoming connections we allow per IP.
std::size_t inPeers
The number of automatic inbound connections to maintain.
void applyTuning()
Adjusts the values so they follow the business rules.
static Config makeConfig(ripple::Config const &config, std::uint16_t port, bool validationPublicKey, int ipLimit)
Make PeerFinder::Config from configuration parameters.
std::size_t maxPeers
The largest number of public peer slots to allow.
std::string features
The set of features we advertise.
bool wantIncoming
true if we want to accept incoming connections.
std::size_t outPeers
The number of automatic outbound connections to maintain.
std::size_t calcOutPeers() const
Returns a suitable value for outPeers according to the rules.
std::uint16_t listeningPort
The listening port number.
bool peerPrivate
true if we want our IP address kept private.