xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
peerfinder
detail
Handouts.h
1
#pragma once
2
3
#include <xrpl/beast/container/aged_set.h>
4
#include <xrpl/beast/net/IPAddress.h>
5
#include <xrpl/beast/utility/instrumentation.h>
6
#include <xrpl/peerfinder/Types.h>
7
#include <xrpl/peerfinder/detail/SlotImp.h>
8
#include <xrpl/peerfinder/detail/Tuning.h>
9
10
#include <
algorithm
>
11
#include <
cstddef
>
12
#include <
utility
>
13
#include <
vector
>
14
15
namespace
xrpl::peer_finder
{
16
17
namespace
detail
{
18
24
// VFALCO TODO specialization that handles std::list for SequenceContainer
25
// using splice for optimization over erase/push_back
26
//
27
template
<
class
Target,
class
HopContainer>
28
std::size_t
29
handoutOne
(Target& t, HopContainer& h)
30
{
31
XRPL_ASSERT(!t.full(),
"xrpl::peer_finder::detail::handoutOne : target is not full"
);
32
for
(
auto
it = h.begin(); it != h.end(); ++it)
33
{
34
auto
const
& e = *it;
35
if
(t.tryInsert(e))
36
{
37
h.moveBack(it);
38
return
1;
39
}
40
}
41
return
0;
42
}
43
44
}
// namespace detail
45
51
template
<
class
TargetFwdIter,
class
SeqFwdIter>
52
void
53
handout
(TargetFwdIter first, TargetFwdIter last, SeqFwdIter seqFirst, SeqFwdIter seqLast)
54
{
55
for
(;;)
56
{
57
std::size_t
n(0);
58
for
(
auto
si = seqFirst; si != seqLast; ++si)
59
{
60
auto
c = *si;
61
bool
allFull(
true
);
62
for
(
auto
ti = first; ti != last; ++ti)
63
{
64
auto
& t = *ti;
65
if
(!t.full())
66
{
67
n +=
detail::handoutOne
(t, c);
68
allFull =
false
;
69
}
70
}
71
if
(allFull)
72
return
;
73
}
74
if
(!n)
75
break
;
76
}
77
}
78
79
//------------------------------------------------------------------------------
80
85
class
RedirectHandouts
86
{
87
public
:
88
template
<
class
=
void
>
89
explicit
RedirectHandouts
(
SlotImp::Ptr
slot
);
90
91
template
<
class
=
void
>
92
bool
93
tryInsert
(
Endpoint
const
& ep);
94
95
[[nodiscard]]
bool
96
full
()
const
97
{
98
return
list_
.size() >=
tuning::kRedirectEndpointCount
;
99
}
100
101
[[nodiscard]]
SlotImp::Ptr
const
&
102
slot
()
const
103
{
104
return
slot_
;
105
}
106
107
std::vector<Endpoint>
&
108
list
()
109
{
110
return
list_
;
111
}
112
113
[[nodiscard]]
std::vector<Endpoint>
const
&
114
list
()
const
115
{
116
return
list_
;
117
}
118
119
private
:
120
SlotImp::Ptr
slot_
;
121
std::vector<Endpoint>
list_
;
122
};
123
124
template
<
class
>
125
RedirectHandouts::RedirectHandouts
(
SlotImp::Ptr
slot
) :
slot_
(
std
::move(
slot
))
126
{
127
list_
.reserve(
tuning::kRedirectEndpointCount
);
128
}
129
130
template
<
class
>
131
bool
132
RedirectHandouts::tryInsert
(
Endpoint
const
& ep)
133
{
134
if
(
full
())
135
return
false
;
136
137
// VFALCO NOTE This check can be removed when we provide the
138
// addresses in a peer HTTP handshake instead of
139
// the tmENDPOINTS message.
140
//
141
if
(ep.
hops
>
tuning::kMaxHops
)
142
return
false
;
143
144
// Don't send them our address
145
if
(ep.
hops
== 0)
146
return
false
;
147
148
// Don't send them their own address
149
if
(
slot_
->remoteEndpoint().address() == ep.
address
.
address
())
150
return
false
;
151
152
// Make sure the address isn't already in our list
153
if
(
std::ranges::any_of
(
list_
, [&ep](
Endpoint
const
& other) {
154
// Ignore port for security reasons
155
return
other.
address
.
address
() == ep.
address
.
address
();
156
}))
157
{
158
return
false
;
159
}
160
161
list_
.emplace_back(ep.
address
, ep.
hops
);
162
163
return
true
;
164
}
165
166
//------------------------------------------------------------------------------
167
171
class
SlotHandouts
172
{
173
public
:
174
template
<
class
=
void
>
175
explicit
SlotHandouts
(
SlotImp::Ptr
slot
);
176
177
template
<
class
=
void
>
178
bool
179
tryInsert
(
Endpoint
const
& ep);
180
181
[[nodiscard]]
bool
182
full
()
const
183
{
184
return
list_
.size() >=
tuning::kNumberOfEndpoints
;
185
}
186
187
void
188
insert
(
Endpoint
const
& ep)
189
{
190
list_
.push_back(ep);
191
}
192
193
[[nodiscard]]
SlotImp::Ptr
const
&
194
slot
()
const
195
{
196
return
slot_
;
197
}
198
199
[[nodiscard]]
std::vector<Endpoint>
const
&
200
list
()
const
201
{
202
return
list_
;
203
}
204
205
private
:
206
SlotImp::Ptr
slot_
;
207
std::vector<Endpoint>
list_
;
208
};
209
210
template
<
class
>
211
SlotHandouts::SlotHandouts
(
SlotImp::Ptr
slot
) :
slot_
(
std
::move(
slot
))
212
{
213
list_
.reserve(
tuning::kNumberOfEndpoints
);
214
}
215
216
template
<
class
>
217
bool
218
SlotHandouts::tryInsert
(
Endpoint
const
& ep)
219
{
220
if
(
full
())
221
return
false
;
222
223
if
(ep.
hops
>
tuning::kMaxHops
)
224
return
false
;
225
226
if
(
slot_
->recent.filter(ep.
address
, ep.
hops
))
227
return
false
;
228
229
// Don't send them their own address
230
if
(
slot_
->remoteEndpoint().address() == ep.
address
.
address
())
231
return
false
;
232
233
// Make sure the address isn't already in our list
234
if
(
std::ranges::any_of
(
list_
, [&ep](
Endpoint
const
& other) {
235
// Ignore port for security reasons
236
return
other.
address
.
address
() == ep.
address
.
address
();
237
}))
238
return
false
;
239
240
list_
.emplace_back(ep.
address
, ep.
hops
);
241
242
// Insert into this slot's recent table. Although the endpoint
243
// didn't come from the slot, adding it to the slot's table
244
// prevents us from sending it again until it has expired from
245
// the other end's cache.
246
//
247
slot_
->recent.insert(ep.
address
, ep.
hops
);
248
249
return
true
;
250
}
251
252
//------------------------------------------------------------------------------
253
257
class
ConnectHandouts
258
{
259
public
:
260
// Keeps track of addresses we have made outgoing connections
261
// to, for the purposes of not connecting to them too frequently.
262
using
Squelches
=
beast::AgedSet<beast::ip::Address>
;
263
264
using
ListType
=
std::vector<beast::ip::Endpoint>
;
265
266
private
:
267
std::size_t
needed_
;
268
Squelches
&
squelches_
;
269
ListType
list_
;
270
271
public
:
272
template
<
class
=
void
>
273
ConnectHandouts
(
std::size_t
needed,
Squelches
& squelches);
274
275
template
<
class
=
void
>
276
bool
277
tryInsert
(
beast::ip::Endpoint
const
& endpoint);
278
279
[[nodiscard]]
bool
280
empty
()
const
281
{
282
return
list_
.empty();
283
}
284
285
[[nodiscard]]
bool
286
full
()
const
287
{
288
return
list_
.size() >=
needed_
;
289
}
290
291
bool
292
tryInsert
(
Endpoint
const
& endpoint)
293
{
294
return
tryInsert
(endpoint.
address
);
295
}
296
297
ListType
&
298
list
()
299
{
300
return
list_
;
301
}
302
303
[[nodiscard]]
ListType
const
&
304
list
()
const
305
{
306
return
list_
;
307
}
308
};
309
310
template
<
class
>
311
ConnectHandouts::ConnectHandouts
(
std::size_t
needed,
Squelches
& squelches)
312
:
needed_
(needed),
squelches_
(squelches)
313
{
314
list_
.reserve(needed);
315
}
316
317
template
<
class
>
318
bool
319
ConnectHandouts::tryInsert
(
beast::ip::Endpoint
const
& endpoint)
320
{
321
if
(
full
())
322
return
false
;
323
324
// Make sure the address isn't already in our list
325
if
(
std::ranges::any_of
(
list_
, [&endpoint](
beast::ip::Endpoint
const
& other) {
326
// Ignore port for security reasons
327
return
other.
address
() == endpoint.
address
();
328
}))
329
{
330
return
false
;
331
}
332
333
// Add to squelch list so we don't try it too often.
334
// If its already there, then make try_insert fail.
335
auto
const
result(
squelches_
.insert(endpoint.
address
()));
336
if
(!result.second)
337
return
false
;
338
339
list_
.push_back(endpoint);
340
341
return
true
;
342
}
343
344
}
// namespace xrpl::peer_finder
algorithm
std::ranges::any_of
T any_of(T... args)
beast::ip::Endpoint
A version-independent IP address and port combination.
Definition
IPEndpoint.h:24
beast::ip::Endpoint::address
Address const & address() const
Returns the address portion of this endpoint.
Definition
IPEndpoint.h:74
xrpl::peer_finder::ConnectHandouts::ListType
std::vector< beast::ip::Endpoint > ListType
Definition
Handouts.h:264
xrpl::peer_finder::ConnectHandouts::list_
ListType list_
Definition
Handouts.h:269
xrpl::peer_finder::ConnectHandouts::squelches_
Squelches & squelches_
Definition
Handouts.h:268
xrpl::peer_finder::ConnectHandouts::full
bool full() const
Definition
Handouts.h:286
xrpl::peer_finder::ConnectHandouts::ConnectHandouts
ConnectHandouts(std::size_t needed, Squelches &squelches)
Definition
Handouts.h:311
xrpl::peer_finder::ConnectHandouts::tryInsert
bool tryInsert(beast::ip::Endpoint const &endpoint)
Definition
Handouts.h:319
xrpl::peer_finder::ConnectHandouts::Squelches
beast::AgedSet< beast::ip::Address > Squelches
Definition
Handouts.h:262
xrpl::peer_finder::ConnectHandouts::list
ListType const & list() const
Definition
Handouts.h:304
xrpl::peer_finder::ConnectHandouts::empty
bool empty() const
Definition
Handouts.h:280
xrpl::peer_finder::ConnectHandouts::needed_
std::size_t needed_
Definition
Handouts.h:267
xrpl::peer_finder::ConnectHandouts::tryInsert
bool tryInsert(Endpoint const &endpoint)
Definition
Handouts.h:292
xrpl::peer_finder::ConnectHandouts::list
ListType & list()
Definition
Handouts.h:298
xrpl::peer_finder::RedirectHandouts::list
std::vector< Endpoint > & list()
Definition
Handouts.h:108
xrpl::peer_finder::RedirectHandouts::RedirectHandouts
RedirectHandouts(SlotImp::Ptr slot)
Definition
Handouts.h:125
xrpl::peer_finder::RedirectHandouts::list_
std::vector< Endpoint > list_
Definition
Handouts.h:121
xrpl::peer_finder::RedirectHandouts::slot
SlotImp::Ptr const & slot() const
Definition
Handouts.h:102
xrpl::peer_finder::RedirectHandouts::slot_
SlotImp::Ptr slot_
Definition
Handouts.h:120
xrpl::peer_finder::RedirectHandouts::tryInsert
bool tryInsert(Endpoint const &ep)
Definition
Handouts.h:132
xrpl::peer_finder::RedirectHandouts::full
bool full() const
Definition
Handouts.h:96
xrpl::peer_finder::RedirectHandouts::list
std::vector< Endpoint > const & list() const
Definition
Handouts.h:114
xrpl::peer_finder::SlotHandouts::slot
SlotImp::Ptr const & slot() const
Definition
Handouts.h:194
xrpl::peer_finder::SlotHandouts::list_
std::vector< Endpoint > list_
Definition
Handouts.h:207
xrpl::peer_finder::SlotHandouts::full
bool full() const
Definition
Handouts.h:182
xrpl::peer_finder::SlotHandouts::list
std::vector< Endpoint > const & list() const
Definition
Handouts.h:200
xrpl::peer_finder::SlotHandouts::slot_
SlotImp::Ptr slot_
Definition
Handouts.h:206
xrpl::peer_finder::SlotHandouts::tryInsert
bool tryInsert(Endpoint const &ep)
Definition
Handouts.h:218
xrpl::peer_finder::SlotHandouts::SlotHandouts
SlotHandouts(SlotImp::Ptr slot)
Definition
Handouts.h:211
xrpl::peer_finder::SlotHandouts::insert
void insert(Endpoint const &ep)
Definition
Handouts.h:188
xrpl::peer_finder::SlotImp::Ptr
std::shared_ptr< SlotImp > Ptr
Definition
SlotImp.h:20
cstddef
beast::AgedSet
detail::AgedOrderedContainer< false, false, Key, void, Clock, Compare, Allocator > AgedSet
Definition
aged_set.h:16
std
STL namespace.
xrpl::peer_finder::detail
Definition
Handouts.h:17
xrpl::peer_finder::detail::handoutOne
std::size_t handoutOne(Target &t, HopContainer &h)
Try to insert one object in the target.
Definition
Handouts.h:29
xrpl::peer_finder::tuning::kRedirectEndpointCount
constexpr std::uint32_t kRedirectEndpointCount
Definition
include/xrpl/peerfinder/detail/Tuning.h:100
xrpl::peer_finder::tuning::kNumberOfEndpoints
constexpr std::uint32_t kNumberOfEndpoints
Definition
include/xrpl/peerfinder/detail/Tuning.h:93
xrpl::peer_finder::tuning::kMaxHops
constexpr std::uint32_t kMaxHops
Definition
include/xrpl/peerfinder/detail/Tuning.h:90
xrpl::peer_finder
Definition
include/xrpl/peerfinder/Config.h:12
xrpl::peer_finder::handout
void handout(TargetFwdIter first, TargetFwdIter last, SeqFwdIter seqFirst, SeqFwdIter seqLast)
Distributes objects to targets according to business rules.
Definition
Handouts.h:53
std::size_t
xrpl::peer_finder::Endpoint
Describes a connectable peer address along with some metadata.
Definition
peerfinder/Types.h:26
xrpl::peer_finder::Endpoint::hops
std::uint32_t hops
Definition
peerfinder/Types.h:31
xrpl::peer_finder::Endpoint::address
beast::ip::Endpoint address
Definition
peerfinder/Types.h:32
utility
vector
Generated by
1.17.0