TARAXA
Common.h
Go to the documentation of this file.
1 // Aleth: Ethereum C++ client, tools and libraries.
2 // Copyright 2014-2019 Aleth Authors.
3 // Licensed under the GNU General Public License, Version 3.
4 
5 //
6 // Miscellanea required for the Host/Session/NodeTable classes.
7 //
8 
9 #pragma once
10 
11 #include <atomic>
12 #include <set>
13 #include <shared_mutex>
14 #include <string>
15 #include <vector>
16 
17 // Make sure boost/asio.hpp is included before windows.h.
18 #include <libdevcore/Exceptions.h>
19 #include <libdevcore/Guards.h>
20 #include <libdevcore/Log.h>
21 #include <libdevcore/RLP.h>
22 #include <libdevcrypto/Common.h>
23 
24 #include <boost/asio.hpp>
25 #include <boost/asio/ip/tcp.hpp>
26 #include <boost/asio/steady_timer.hpp>
27 #include <chrono>
28 
29 namespace ba = boost::asio;
30 namespace bi = ba::ip;
31 
32 namespace dev {
33 
34 class RLP;
35 class RLPStream;
36 
37 namespace p2p {
38 
40 constexpr unsigned c_protocolVersion = 1029;
41 
42 class NodeIPEndpoint;
43 class Node;
45 extern const Node UnspecifiedNode;
46 
47 using NodeID = h512;
48 
49 bool isPrivateAddress(bi::address const& _addressToCheck);
50 bool isPrivateAddress(std::string const& _addressToCheck);
51 bool isLocalHostAddress(bi::address const& _addressToCheck);
52 bool isLocalHostAddress(std::string const& _addressToCheck);
53 bool isPublicAddress(bi::address const& _addressToCheck);
54 bool isPublicAddress(std::string const& _addressToCheck);
55 bool isAllowedAddress(bool _allowLocalDiscovery, bi::address const& _addressToCheck);
56 bool isAllowedEndpoint(bool _allowLocalDiscovery, NodeIPEndpoint const& _endpointToCheck);
57 
58 class UPnP;
59 struct Host;
60 struct Session;
61 
65 
67 struct ECDHEError : virtual Exception {};
68 
69 #define NET_GLOBAL_LOGGER(NAME, SEVERITY) \
70  BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS( \
71  g_##NAME##Logger, boost::log::sources::severity_channel_logger_mt<>, \
72  (boost::log::keywords::severity = SEVERITY)(boost::log::keywords::channel = "net"))
73 
75 #define cnetnote LOG(dev::p2p::g_netnoteLogger::get())
77 #define cnetlog LOG(dev::p2p::g_netlogLogger::get())
79 #define cnetdetails LOG(dev::p2p::g_netdetailsLogger::get())
80 
82 
83 char const* p2pPacketTypeToString(P2pPacketType _packetType);
84 
98  UserReason = 0x10,
99  NoDisconnect = 0xffff
100 };
101 
103 std::string reasonOf(DisconnectReason _r);
104 
106  NoFailure = 0,
108  Timeout,
109  TCPError,
114 };
115 
116 using CapDesc = std::pair<std::string, unsigned>;
117 using CapDescs = std::vector<CapDesc>;
118 
119 /*
120  * Used by Host to pass negotiated information about a connection to a
121  * new Peer Session; PeerSessionInfo is then maintained by Session and can
122  * be queried for point-in-time status information via Host.
123  */
126  std::string clientVersion;
127  std::string host;
128  unsigned short port;
129  std::chrono::steady_clock::duration lastPing;
130  std::set<CapDesc> caps;
131 };
132 
133 using PeerSessionInfos = std::vector<PeerSessionInfo>;
134 
135 enum class PeerType { Optional, Required };
136 
141  public:
143 
144  NodeIPEndpoint() = default;
145  NodeIPEndpoint(bi::address _addr, uint16_t _udp, uint16_t _tcp)
146  : m_address(std::move(_addr)), m_udpPort(_udp), m_tcpPort(_tcp) {}
147  explicit NodeIPEndpoint(RLP const& _r) { interpretRLP(_r); }
148 
149  operator bi::udp::endpoint() const { return {m_address, m_udpPort}; }
150  operator bi::tcp::endpoint() const { return {m_address, m_tcpPort}; }
151 
152  explicit operator bool() const { return !m_address.is_unspecified() && m_udpPort > 0 && m_tcpPort > 0; }
153 
154  bool operator==(NodeIPEndpoint const& _cmp) const {
155  return m_address == _cmp.m_address && m_udpPort == _cmp.m_udpPort && m_tcpPort == _cmp.m_tcpPort;
156  }
157  bool operator!=(NodeIPEndpoint const& _cmp) const { return !operator==(_cmp); }
158 
159  void streamRLP(RLPStream& _s, RLPAppend _append = StreamList) const;
160  void interpretRLP(RLP const& _r);
161 
162  bi::address address() const { return m_address; }
163 
164  void setAddress(bi::address _addr) { m_address = std::move(_addr); }
165 
166  uint16_t udpPort() const { return m_udpPort; }
167 
168  void setUdpPort(uint16_t _udp) { m_udpPort = _udp; }
169 
170  uint16_t tcpPort() const { return m_tcpPort; }
171 
172  void setTcpPort(uint16_t _tcp) { m_tcpPort = _tcp; }
173 
174  private:
175  bi::address m_address;
176  uint16_t m_udpPort = 0;
177  uint16_t m_tcpPort = 0;
178 };
179 
180 struct NodeSpec {
181  NodeSpec() {}
182 
185  NodeSpec(std::string const& _user);
186 
187  NodeSpec(std::string const& _addr, uint16_t _port, int _udpPort = -1)
188  : m_address(_addr), m_tcpPort(_port), m_udpPort(_udpPort == -1 ? _port : (uint16_t)_udpPort) {}
189 
190  NodeID id() const { return m_id; }
191 
193 
194  std::string enode() const;
195 
196  bool isValid() const;
197 
198  private:
199  std::string m_address;
200  uint16_t m_tcpPort = 0;
201  uint16_t m_udpPort = 0;
203 };
204 
205 class Node {
206  public:
207  virtual ~Node() = default;
208  Node(Node const&);
209  Node(Public _publicKey, NodeIPEndpoint const& _ip, PeerType _peerType = PeerType::Optional)
210  : id(_publicKey), endpoint_(_ip), peerType(_peerType) {}
211  Node(NodeSpec const& _s, PeerType _peerType = PeerType::Optional);
212 
213  NodeID const& address() const { return id; }
214 
216  void set_endpoint(NodeIPEndpoint endpoint);
217 
218  explicit operator bool() const { return static_cast<bool>(id); }
219 
220  // TODO: make private, give accessors and rename m_...
221  NodeID const id;
222 
223  private:
225  mutable std::shared_mutex endpoint_mu_;
226 
227  public:
228  // TODO: p2p implement
229  std::atomic<PeerType> peerType{PeerType::Optional};
230  std::atomic<uint16_t> external_udp_port;
231 };
232 
233 inline boost::log::formatting_ostream& operator<<(boost::log::formatting_ostream& _strm, Node const& _node) {
234  return _strm << _node.id << '@' << _node.get_endpoint();
235 }
236 
237 inline boost::log::formatting_ostream& operator<<(boost::log::formatting_ostream& _strm, Node& _node) {
238  auto const& constValue = _node;
239  _strm << constValue;
240  return _strm;
241 }
242 
243 inline std::ostream& operator<<(std::ostream& _strm, NodeID const& _id) {
244  _strm << "##" << _id.abridged();
245  return _strm;
246 }
247 
248 inline boost::log::formatting_ostream& operator<<(boost::log::formatting_ostream& _strm,
249  PeerSessionInfo const& _peerSessionInfo) {
250  _strm << _peerSessionInfo.id << "|" << _peerSessionInfo.clientVersion << "|" << _peerSessionInfo.host << "|"
251  << _peerSessionInfo.port << "|";
252  for (auto const& cap : _peerSessionInfo.caps) _strm << "(" << cap.first << "," << cap.second << ")";
253  return _strm;
254 }
255 
257 std::ostream& operator<<(std::ostream& _out, NodeIPEndpoint const& _ep);
258 } // namespace p2p
259 } // namespace dev
260 
262 #if !defined(BOOST_ASIO_HAS_STD_HASH)
263 namespace std {
264 template <>
265 struct hash<bi::address> {
266  size_t operator()(bi::address const& _a) const {
267  if (_a.is_v4()) return std::hash<unsigned long>()(_a.to_v4().to_ulong());
268  if (_a.is_v6()) {
269  auto const& range = _a.to_v6().to_bytes();
270  return boost::hash_range(range.begin(), range.end());
271  }
272  if (_a.is_unspecified())
273  return static_cast<size_t>(0x3487194039229152ull); // Chosen by fair dice roll, guaranteed to be
274  // random
275  return std::hash<std::string>()(_a.to_string());
276  }
277 };
278 } // namespace std
279 #endif // !defined(BOOST_ASIO_HAS_STD_HASH)
std::string abridged() const
Definition: FixedHash.h:167
Definition: RLP.h:56
Class for writing to an RLP bytestream.
Definition: RLP.h:484
Definition: Common.h:205
virtual ~Node()=default
Node(Node const &)
Definition: Common.cpp:148
std::atomic< PeerType > peerType
Definition: Common.h:229
std::atomic< uint16_t > external_udp_port
Definition: Common.h:230
Node(Public _publicKey, NodeIPEndpoint const &_ip, PeerType _peerType=PeerType::Optional)
Definition: Common.h:209
NodeID const id
Definition: Common.h:221
NodeID const & address() const
Definition: Common.h:213
std::shared_mutex endpoint_mu_
Definition: Common.h:225
void set_endpoint(NodeIPEndpoint endpoint)
Definition: Common.cpp:158
NodeIPEndpoint endpoint_
Definition: Common.h:224
NodeIPEndpoint get_endpoint() const
Definition: Common.cpp:153
IPv4,UDP/TCP endpoints.
Definition: Common.h:140
void setUdpPort(uint16_t _udp)
Definition: Common.h:168
void interpretRLP(RLP const &_r)
Definition: Common.cpp:137
uint16_t tcpPort() const
Definition: Common.h:170
void streamRLP(RLPStream &_s, RLPAppend _append=StreamList) const
Definition: Common.cpp:126
void setAddress(bi::address _addr)
Definition: Common.h:164
bool operator!=(NodeIPEndpoint const &_cmp) const
Definition: Common.h:157
uint16_t m_udpPort
Definition: Common.h:176
uint16_t udpPort() const
Definition: Common.h:166
NodeIPEndpoint(RLP const &_r)
Definition: Common.h:147
bi::address m_address
Definition: Common.h:175
void setTcpPort(uint16_t _tcp)
Definition: Common.h:172
RLPAppend
Definition: Common.h:142
@ StreamList
Definition: Common.h:142
@ StreamInline
Definition: Common.h:142
bi::address address() const
Definition: Common.h:162
NodeIPEndpoint(bi::address _addr, uint16_t _udp, uint16_t _tcp)
Definition: Common.h:145
bool operator==(NodeIPEndpoint const &_cmp) const
Definition: Common.h:154
uint16_t m_tcpPort
Definition: Common.h:177
Definition: UPnP.h:17
#define NET_GLOBAL_LOGGER(NAME, SEVERITY)
Definition: Common.h:69
std::vector< CapDesc > CapDescs
Definition: Common.h:117
std::string clientVersion
Definition: Common.h:126
ostream & operator<<(ostream &_out, NodeIPEndpoint const &_ep)
Definition: Common.cpp:205
HandshakeFailureReason
Definition: Common.h:105
std::set< CapDesc > caps
Definition: Common.h:130
std::string host
Definition: Common.h:127
NodeID id
Definition: Common.h:125
std::pair< std::string, unsigned > CapDesc
Definition: Common.h:116
std::chrono::steady_clock::duration lastPing
Definition: Common.h:129
std::vector< PeerSessionInfo > PeerSessionInfos
Definition: Common.h:133
bool isLocalHostAddress(bi::address const &_addressToCheck)
Definition: Common.cpp:77
const Node UnspecifiedNode
Definition: Common.cpp:17
bool isPublicAddress(string const &_addressToCheck)
Definition: Common.cpp:34
constexpr unsigned c_protocolVersion
Peer network protocol version.
Definition: Common.h:40
string reasonOf(DisconnectReason _r)
Definition: Common.cpp:93
char const * p2pPacketTypeToString(P2pPacketType _packetType)
Definition: Common.cpp:19
bool isPrivateAddress(bi::address const &_addressToCheck)
Definition: Common.cpp:52
unsigned short port
Definition: Common.h:128
bool isAllowedEndpoint(bool _allowLocalDiscovery, NodeIPEndpoint const &_endpointToCheck)
Definition: Common.cpp:46
DisconnectReason
Definition: Common.h:85
@ NoDisconnect
Definition: Common.h:99
@ UserReason
Definition: Common.h:98
@ LocalIdentity
Definition: Common.h:96
@ DisconnectRequested
Definition: Common.h:86
@ DuplicatePeer
Definition: Common.h:91
@ PingTimeout
Definition: Common.h:97
@ IncompatibleProtocol
Definition: Common.h:92
@ UnexpectedIdentity
Definition: Common.h:95
@ ClientQuit
Definition: Common.h:94
@ TCPError
Definition: Common.h:87
@ TooManyPeers
Definition: Common.h:90
@ NullIdentity
Definition: Common.h:93
@ UselessPeer
Definition: Common.h:89
@ BadProtocol
Definition: Common.h:88
P2pPacketType
Definition: Common.h:81
@ UserPacket
Definition: Common.h:81
@ PongPacket
Definition: Common.h:81
@ PingPacket
Definition: Common.h:81
@ DisconnectPacket
Definition: Common.h:81
@ HelloPacket
Definition: Common.h:81
bool isAllowedAddress(bool _allowLocalDiscovery, bi::address const &_addressToCheck)
Definition: Common.cpp:42
PeerType
Definition: Common.h:135
const NodeIPEndpoint UnspecifiedNodeIPEndpoint
Definition: Common.cpp:16
Definition: Common.h:124
Definition: Address.h:13
@ VerbosityInfo
Definition: Log.h:48
@ VerbosityDebug
Definition: Log.h:49
@ VerbosityTrace
Definition: Log.h:50
FixedHash< 64 > h512
Definition: FixedHash.h:452
std::hash for asio::adress
Definition: FixedHash.h:483
Base class for all exceptions.
Definition: Exceptions.h:21
The ECDHE agreement failed during RLPx handshake.
Definition: Common.h:67
The Host class Capabilities should be registered prior to startNetwork, since m_capabilities is not t...
Definition: Host.h:69
Definition: Common.h:63
Definition: Common.h:62
Definition: Common.h:180
bool isValid() const
Definition: Common.cpp:203
NodeID id() const
Definition: Common.h:190
NodeIPEndpoint nodeIPEndpoint() const
Definition: Common.cpp:185
NodeID m_id
Definition: Common.h:202
uint16_t m_tcpPort
Definition: Common.h:200
NodeSpec(std::string const &_user)
std::string enode() const
Definition: Common.cpp:189
NodeSpec()
Definition: Common.h:181
NodeSpec(std::string const &_addr, uint16_t _port, int _udpPort=-1)
Definition: Common.h:187
std::string m_address
Definition: Common.h:199
uint16_t m_udpPort
Definition: Common.h:201
The Session class.
Definition: Session.h:32
size_t operator()(bi::address const &_a) const
Definition: Common.h:266