Common.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file Common.h
  15. * @author Gav Wood <i@gavwood.com>
  16. * @author Alex Leverington <nessence@gmail.com>
  17. * @date 2014
  18. *
  19. * Miscellanea required for the Host/Session/NodeTable classes.
  20. */
  21. #pragma once
  22. #include <string>
  23. #include <set>
  24. #include <vector>
  25. // Make sure boost/asio.hpp is included before windows.h.
  26. #include <boost/asio.hpp>
  27. #include <boost/asio/ip/tcp.hpp>
  28. #include <chrono>
  29. #include <libdevcrypto/Common.h>
  30. #include <libdevcore/Log.h>
  31. #include <libdevcore/Exceptions.h>
  32. #include <libdevcore/RLP.h>
  33. #include <libdevcore/Guards.h>
  34. namespace ba = boost::asio;
  35. namespace bi = boost::asio::ip;
  36. namespace dev
  37. {
  38. class RLP;
  39. class RLPStream;
  40. namespace p2p
  41. {
  42. /// Peer network protocol version.
  43. extern const unsigned c_protocolVersion;
  44. extern const unsigned c_defaultIPPort;
  45. class NodeIPEndpoint;
  46. class Node;
  47. extern const NodeIPEndpoint UnspecifiedNodeIPEndpoint;
  48. extern const Node UnspecifiedNode;
  49. using NodeID = h512;
  50. bool isPrivateAddress(bi::address const& _addressToCheck);
  51. bool isPrivateAddress(std::string const& _addressToCheck);
  52. bool isLocalHostAddress(bi::address const& _addressToCheck);
  53. bool isLocalHostAddress(std::string const& _addressToCheck);
  54. bool isPublicAddress(bi::address const& _addressToCheck);
  55. bool isPublicAddress(std::string const& _addressToCheck);
  56. class UPnP;
  57. class Capability;
  58. class Host;
  59. class Session;
  60. struct NetworkStartRequired: virtual dev::Exception {};
  61. struct InvalidPublicIPAddress: virtual dev::Exception {};
  62. struct InvalidHostIPAddress: virtual dev::Exception {};
  63. struct NetWarn: public LogChannel { static const char* name(); static const int verbosity = 0; };
  64. struct NetNote: public LogChannel { static const char* name(); static const int verbosity = 2; };
  65. struct NetImpolite: public LogChannel { static const char* name(); static const int verbosity = 3; };
  66. struct NetMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 4; };
  67. struct NetConnect: public LogChannel { static const char* name(); static const int verbosity = 10; };
  68. struct NetMessageDetail: public LogChannel { static const char* name(); static const int verbosity = 5; };
  69. struct NetTriviaSummary: public LogChannel { static const char* name(); static const int verbosity = 10; };
  70. struct NetTriviaDetail: public LogChannel { static const char* name(); static const int verbosity = 11; };
  71. struct NetAllDetail: public LogChannel { static const char* name(); static const int verbosity = 13; };
  72. struct NetRight: public LogChannel { static const char* name(); static const int verbosity = 14; };
  73. struct NetLeft: public LogChannel { static const char* name(); static const int verbosity = 15; };
  74. struct NetP2PWarn: public LogChannel { static const char* name(); static const int verbosity = 2; };
  75. struct NetP2PNote: public LogChannel { static const char* name(); static const int verbosity = 6; };
  76. struct NetP2PConnect: public LogChannel { static const char* name(); static const int verbosity = 10; };
  77. enum PacketType
  78. {
  79. HelloPacket = 0,
  80. DisconnectPacket,
  81. PingPacket,
  82. PongPacket,
  83. GetPeersPacket,
  84. PeersPacket,
  85. UserPacket = 0x10
  86. };
  87. enum DisconnectReason
  88. {
  89. DisconnectRequested = 0,
  90. TCPError,
  91. BadProtocol,
  92. UselessPeer,
  93. TooManyPeers,
  94. DuplicatePeer,
  95. IncompatibleProtocol,
  96. NullIdentity,
  97. ClientQuit,
  98. UnexpectedIdentity,
  99. LocalIdentity,
  100. PingTimeout,
  101. UserReason = 0x10,
  102. NoDisconnect = 0xffff
  103. };
  104. inline bool isPermanentProblem(DisconnectReason _r)
  105. {
  106. switch (_r)
  107. {
  108. case DuplicatePeer:
  109. case IncompatibleProtocol:
  110. case NullIdentity:
  111. case UnexpectedIdentity:
  112. case LocalIdentity:
  113. return true;
  114. default:
  115. return false;
  116. }
  117. }
  118. /// @returns the string form of the given disconnection reason.
  119. std::string reasonOf(DisconnectReason _r);
  120. using CapDesc = std::pair<std::string, u256>;
  121. using CapDescSet = std::set<CapDesc>;
  122. using CapDescs = std::vector<CapDesc>;
  123. /*
  124. * Used by Host to pass negotiated information about a connection to a
  125. * new Peer Session; PeerSessionInfo is then maintained by Session and can
  126. * be queried for point-in-time status information via Host.
  127. */
  128. struct PeerSessionInfo
  129. {
  130. NodeID const id;
  131. std::string const clientVersion;
  132. std::string const host;
  133. unsigned short const port;
  134. std::chrono::steady_clock::duration lastPing;
  135. std::set<CapDesc> const caps;
  136. unsigned socketId;
  137. std::map<std::string, std::string> notes;
  138. unsigned const protocolVersion;
  139. };
  140. using PeerSessionInfos = std::vector<PeerSessionInfo>;
  141. enum class PeerType
  142. {
  143. Optional,
  144. Required
  145. };
  146. /**
  147. * @brief IPv4,UDP/TCP endpoints.
  148. */
  149. class NodeIPEndpoint
  150. {
  151. public:
  152. enum RLPAppend
  153. {
  154. StreamList,
  155. StreamInline
  156. };
  157. /// Setting true causes isAllowed to return true for all addresses. (Used by test fixtures)
  158. static bool test_allowLocal;
  159. NodeIPEndpoint() = default;
  160. NodeIPEndpoint(bi::address _addr, uint16_t _udp, uint16_t _tcp): address(_addr), udpPort(_udp), tcpPort(_tcp) {}
  161. NodeIPEndpoint(RLP const& _r) { interpretRLP(_r); }
  162. operator bi::udp::endpoint() const { return bi::udp::endpoint(address, udpPort); }
  163. operator bi::tcp::endpoint() const { return bi::tcp::endpoint(address, tcpPort); }
  164. operator bool() const { return !address.is_unspecified() && udpPort > 0 && tcpPort > 0; }
  165. bool isAllowed() const { return NodeIPEndpoint::test_allowLocal ? !address.is_unspecified() : isPublicAddress(address); }
  166. bool operator==(NodeIPEndpoint const& _cmp) const {
  167. return address == _cmp.address && udpPort == _cmp.udpPort && tcpPort == _cmp.tcpPort;
  168. }
  169. bool operator!=(NodeIPEndpoint const& _cmp) const {
  170. return !operator==(_cmp);
  171. }
  172. void streamRLP(RLPStream& _s, RLPAppend _append = StreamList) const;
  173. void interpretRLP(RLP const& _r);
  174. // TODO: make private, give accessors and rename m_...
  175. bi::address address;
  176. uint16_t udpPort = 0;
  177. uint16_t tcpPort = 0;
  178. };
  179. struct NodeSpec
  180. {
  181. NodeSpec() {}
  182. /// Accepts user-readable strings of the form (enode://pubkey@)host({:port,:tcpport.udpport})
  183. NodeSpec(std::string const& _user);
  184. NodeSpec(std::string const& _addr, uint16_t _port, int _udpPort = -1):
  185. m_address(_addr),
  186. m_tcpPort(_port),
  187. m_udpPort(_udpPort == -1 ? _port : (uint16_t)_udpPort)
  188. {}
  189. NodeID id() const { return m_id; }
  190. NodeIPEndpoint nodeIPEndpoint() const;
  191. std::string enode() const;
  192. private:
  193. std::string m_address;
  194. uint16_t m_tcpPort = 0;
  195. uint16_t m_udpPort = 0;
  196. NodeID m_id;
  197. };
  198. class Node
  199. {
  200. public:
  201. Node() = default;
  202. Node(Node const&) = default;
  203. Node(Public _publicKey, NodeIPEndpoint const& _ip, PeerType _peerType = PeerType::Optional): id(_publicKey), endpoint(_ip), peerType(_peerType) {}
  204. Node(NodeSpec const& _s, PeerType _peerType = PeerType::Optional);
  205. virtual NodeID const& address() const { return id; }
  206. virtual Public const& publicKey() const { return id; }
  207. virtual operator bool() const { return (bool)id; }
  208. // TODO: make private, give accessors and rename m_...
  209. NodeID id;
  210. /// Endpoints by which we expect to reach node.
  211. // TODO: make private, give accessors and rename m_...
  212. NodeIPEndpoint endpoint;
  213. // TODO: p2p implement
  214. PeerType peerType = PeerType::Optional;
  215. };
  216. class DeadlineOps
  217. {
  218. class DeadlineOp
  219. {
  220. public:
  221. DeadlineOp(ba::io_service& _io, unsigned _msInFuture, std::function<void(boost::system::error_code const&)> const& _f): m_timer(new ba::deadline_timer(_io)) { m_timer->expires_from_now(boost::posix_time::milliseconds(_msInFuture)); m_timer->async_wait(_f); }
  222. ~DeadlineOp() { if (m_timer) m_timer->cancel(); }
  223. DeadlineOp(DeadlineOp&& _s): m_timer(_s.m_timer.release()) {}
  224. DeadlineOp& operator=(DeadlineOp&& _s)
  225. {
  226. assert(&_s != this);
  227. m_timer.reset(_s.m_timer.release());
  228. return *this;
  229. }
  230. bool expired() { Guard l(x_timer); return m_timer->expires_from_now().total_nanoseconds() <= 0; }
  231. void wait() { Guard l(x_timer); m_timer->wait(); }
  232. private:
  233. std::unique_ptr<ba::deadline_timer> m_timer;
  234. Mutex x_timer;
  235. };
  236. public:
  237. DeadlineOps(ba::io_service& _io, unsigned _reapIntervalMs = 100): m_io(_io), m_reapIntervalMs(_reapIntervalMs), m_stopped(false) { reap(); }
  238. ~DeadlineOps() { stop(); }
  239. void schedule(unsigned _msInFuture, std::function<void(boost::system::error_code const&)> const& _f) { if (m_stopped) return; DEV_GUARDED(x_timers) m_timers.emplace_back(m_io, _msInFuture, _f); }
  240. void stop() { m_stopped = true; DEV_GUARDED(x_timers) m_timers.clear(); }
  241. bool isStopped() const { return m_stopped; }
  242. protected:
  243. void reap();
  244. private:
  245. ba::io_service& m_io;
  246. unsigned m_reapIntervalMs;
  247. std::vector<DeadlineOp> m_timers;
  248. Mutex x_timers;
  249. std::atomic<bool> m_stopped;
  250. };
  251. }
  252. /// Simple stream output for a NodeIPEndpoint.
  253. std::ostream& operator<<(std::ostream& _out, dev::p2p::NodeIPEndpoint const& _ep);
  254. }
  255. /// std::hash for asio::adress
  256. namespace std
  257. {
  258. template <> struct hash<bi::address>
  259. {
  260. size_t operator()(bi::address const& _a) const
  261. {
  262. if (_a.is_v4())
  263. return std::hash<unsigned long>()(_a.to_v4().to_ulong());
  264. if (_a.is_v6())
  265. {
  266. auto const& range = _a.to_v6().to_bytes();
  267. return boost::hash_range(range.begin(), range.end());
  268. }
  269. if (_a.is_unspecified())
  270. return static_cast<size_t>(0x3487194039229152ull); // Chosen by fair dice roll, guaranteed to be random
  271. return std::hash<std::string>()(_a.to_string());
  272. }
  273. };
  274. }