-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Dynamic predicting of external IP and UDP port #5602
Changes from all commits
5e8ac49
ca9bcda
92c7470
c56e891
0ece223
a2e5a62
74bcc39
50be004
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| // Aleth: Ethereum C++ client, tools and libraries. | ||
| // Copyright 2019 Aleth Authors. | ||
| // Licensed under the GNU General Public License, Version 3. | ||
|
|
||
| #include "EndpointTracker.h" | ||
|
|
||
| namespace dev | ||
| { | ||
| namespace p2p | ||
| { | ||
| /// Register the statement about endpoint from one othe peers. | ||
| /// @returns number of currently kept statements in favor of @a _externalEndpoint | ||
| size_t EndpointTracker::addEndpointStatement( | ||
| bi::udp::endpoint const& _sourceEndpoint, bi::udp::endpoint const& _externalEndpoint) | ||
| { | ||
| // remove previous statement by this peer | ||
| auto it = m_statementsMap.find(_sourceEndpoint); | ||
| if (it != m_statementsMap.end()) | ||
| removeStatement(it); | ||
|
|
||
| return addStatement(_sourceEndpoint, _externalEndpoint); | ||
| } | ||
|
|
||
| /// Find endpoint with max number of statemens | ||
| bi::udp::endpoint EndpointTracker::bestEndpoint() const | ||
| { | ||
| if (m_endpointStatementCountMap.empty()) | ||
| return {}; | ||
|
|
||
| // find endpoint with max count | ||
| auto itMax = | ||
| std::max_element(m_endpointStatementCountMap.begin(), m_endpointStatementCountMap.end(), | ||
| [](std::pair<bi::udp::endpoint const, size_t> const& _endpointAndCount1, | ||
| std::pair<bi::udp::endpoint const, size_t> const& _endpointAndCount2) { | ||
| return _endpointAndCount1.second < _endpointAndCount2.second; | ||
| }); | ||
|
|
||
| return itMax->first; | ||
| } | ||
|
|
||
| /// Remove old statements | ||
| void EndpointTracker::garbageCollectStatements(std::chrono::seconds const& _timeToLive) | ||
| { | ||
| auto const expiration = std::chrono::steady_clock::now() - _timeToLive; | ||
| for (auto it = m_statementsMap.begin(); it != m_statementsMap.end();) | ||
| { | ||
| if (it->second.second < expiration) | ||
| it = removeStatement(it); | ||
| else | ||
| ++it; | ||
| } | ||
| } | ||
|
|
||
| size_t EndpointTracker::addStatement( | ||
| bi::udp::endpoint const& _sourceEndpoint, bi::udp::endpoint const& _externalEndpoint) | ||
| { | ||
| EndpointAndTimePoint endpointAndTime{_externalEndpoint, std::chrono::steady_clock::now()}; | ||
| m_statementsMap.insert({_sourceEndpoint, endpointAndTime}); | ||
| return ++m_endpointStatementCountMap[_externalEndpoint]; | ||
| } | ||
|
|
||
| EndpointTracker::SourceToStatementMap::iterator EndpointTracker::removeStatement( | ||
| SourceToStatementMap::iterator _it) | ||
| { | ||
| // first decrement statement counter | ||
| auto itCount = m_endpointStatementCountMap.find(_it->second.first); | ||
| assert(itCount != m_endpointStatementCountMap.end() && itCount->second > 0); | ||
| if (--itCount->second == 0) | ||
| m_endpointStatementCountMap.erase(itCount); | ||
|
|
||
| return m_statementsMap.erase(_it); | ||
| } | ||
|
|
||
| } // namespace p2p | ||
| } // namespace dev |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // Aleth: Ethereum C++ client, tools and libraries. | ||
| // Copyright 2019 Aleth Authors. | ||
| // Licensed under the GNU General Public License, Version 3. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "Common.h" | ||
|
|
||
| namespace dev | ||
| { | ||
| namespace p2p | ||
| { | ||
| /// Class for keeping track of our external endpoint as seen by our peers. | ||
| /// Keeps track of what external endpoint is seen by every peer | ||
| /// and finds which endpoint is reported most often | ||
| class EndpointTracker | ||
| { | ||
| public: | ||
| /// Register the statement about endpoint from one of the peers. | ||
| /// @returns number of currently kept statements in favor of @a _externalEndpoint | ||
| size_t addEndpointStatement( | ||
| bi::udp::endpoint const& _sourceEndpoint, bi::udp::endpoint const& _externalEndpoint); | ||
|
|
||
| /// Find endpoint with max number of statements | ||
| bi::udp::endpoint bestEndpoint() const; | ||
|
|
||
| /// Remove statements older than _timeToLive | ||
| void garbageCollectStatements(std::chrono::seconds const& _timeToLive); | ||
|
|
||
| private: | ||
| using EndpointAndTimePoint = | ||
| std::pair<bi::udp::endpoint, std::chrono::steady_clock::time_point>; | ||
| using SourceToStatementMap = std::map<bi::udp::endpoint, EndpointAndTimePoint>; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be unsorted map.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Boost doesn't have a hashing function defined for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you check in the latest boost version? If not there we should report a bug.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if it's a bug, maybe not every type should define hashing function?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like good candidate for being a key in a hash map.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reported boostorg/asio#245 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resurrecting this from the dead, just to say that I'm surprised that boostorg/asio#245 got no responses so far. We have been carrying custom hashing support for these types in I'm happy to have Ripple sponsor a bounty to get support coded up, or I can have someone from my team do it if nobody else is interested. |
||
|
|
||
| size_t addStatement( | ||
| bi::udp::endpoint const& _sourceEndpoint, bi::udp::endpoint const& _externalEndpoint); | ||
|
|
||
| SourceToStatementMap::iterator removeStatement(SourceToStatementMap::iterator _it); | ||
|
|
||
| /// Statements about our external endpoint, maps statement source peer => endpoint, timestamp | ||
| SourceToStatementMap m_statementsMap; | ||
| /// map external endpoint => how many sources reported it | ||
| std::map<bi::udp::endpoint, size_t> m_endpointStatementCountMap; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be unsorted map. |
||
| }; | ||
|
|
||
| } // namespace p2p | ||
| } // namespace dev | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(nit) typo (statemens)