Session.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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 Session.h
  15. * @author Gav Wood <i@gavwood.com>
  16. * @author Alex Leverington <nessence@gmail.com>
  17. * @date 2014
  18. */
  19. #pragma once
  20. #include <mutex>
  21. #include <array>
  22. #include <deque>
  23. #include <set>
  24. #include <memory>
  25. #include <utility>
  26. #include <libdevcore/Common.h>
  27. #include <libdevcore/RLP.h>
  28. #include <libdevcore/Guards.h>
  29. #include "RLPXFrameCoder.h"
  30. #include "RLPXSocket.h"
  31. #include "Common.h"
  32. #include "RLPXFrameWriter.h"
  33. #include "RLPXFrameReader.h"
  34. namespace dev
  35. {
  36. namespace p2p
  37. {
  38. class Peer;
  39. class ReputationManager;
  40. /**
  41. * @brief The Session class
  42. * @todo Document fully.
  43. */
  44. class Session: public std::enable_shared_from_this<Session>
  45. {
  46. friend class Host;
  47. friend class HostCapabilityFace;
  48. public:
  49. Session(Host* _server, std::unique_ptr<RLPXFrameCoder>&& _io, std::shared_ptr<RLPXSocket> const& _s, std::shared_ptr<Peer> const& _n, PeerSessionInfo _info);
  50. virtual ~Session();
  51. void start();
  52. void disconnect(DisconnectReason _reason);
  53. void ping();
  54. bool isConnected() const { return m_socket->ref().is_open(); }
  55. NodeID id() const;
  56. unsigned socketId() const { Guard l(x_info); return m_info.socketId; }
  57. template <class PeerCap>
  58. std::shared_ptr<PeerCap> cap() const { try { return std::static_pointer_cast<PeerCap>(m_capabilities.at(std::make_pair(PeerCap::name(), PeerCap::version()))); } catch (...) { return nullptr; } }
  59. template <class PeerCap>
  60. std::shared_ptr<PeerCap> cap(u256 const& _version) const { try { return std::static_pointer_cast<PeerCap>(m_capabilities.at(std::make_pair(PeerCap::name(), _version))); } catch (...) { return nullptr; } }
  61. static RLPStream& prep(RLPStream& _s, PacketType _t, unsigned _args = 0);
  62. void sealAndSend(RLPStream& _s, uint16_t _protocolID);
  63. ReputationManager& repMan() const;
  64. int rating() const;
  65. void addRating(int _r);
  66. void addNote(std::string const& _k, std::string const& _v) { Guard l(x_info); m_info.notes[_k] = _v; }
  67. PeerSessionInfo info() const { Guard l(x_info); return m_info; }
  68. std::chrono::steady_clock::time_point connectionTime() { return m_connect; }
  69. void ensureNodesRequested();
  70. void serviceNodesRequest();
  71. void registerCapability(CapDesc const& _desc, std::shared_ptr<Capability> _p);
  72. void registerFraming(uint16_t _id);
  73. static bool isFramingAllowedForVersion(unsigned _version) { return _version > 4; }
  74. private:
  75. void send(bytes&& _msg, uint16_t _protocolID);
  76. /// Drop the connection for the reason @a _r.
  77. void drop(DisconnectReason _r);
  78. /// Perform a read on the socket.
  79. void doRead();
  80. void doReadFrames();
  81. /// Check error code after reading and drop peer if error code.
  82. bool checkRead(std::size_t _expected, boost::system::error_code _ec, std::size_t _length);
  83. /// Perform a single round of the write operation. This could end up calling itself asynchronously.
  84. void write();
  85. void writeFrames();
  86. /// Deliver RLPX packet to Session or Capability for interpretation.
  87. bool readPacket(uint16_t _capId, PacketType _t, RLP const& _r);
  88. /// Interpret an incoming Session packet.
  89. bool interpret(PacketType _t, RLP const& _r);
  90. /// @returns true iff the _msg forms a valid message for sending or receiving on the network.
  91. static bool checkPacket(bytesConstRef _msg);
  92. Host* m_server; ///< The host that owns us. Never null.
  93. std::unique_ptr<RLPXFrameCoder> m_io; ///< Transport over which packets are sent.
  94. std::shared_ptr<RLPXSocket> m_socket; ///< Socket of peer's connection.
  95. Mutex x_framing; ///< Mutex for the write queue.
  96. std::deque<bytes> m_writeQueue; ///< The write queue.
  97. std::vector<byte> m_data; ///< Buffer for ingress packet data.
  98. bytes m_incoming; ///< Read buffer for ingress bytes.
  99. unsigned m_protocolVersion = 0; ///< The protocol version of the peer.
  100. std::shared_ptr<Peer> m_peer; ///< The Peer object.
  101. bool m_dropped = false; ///< If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to fail before the shared_ptr goes OOS and the destructor kicks in.
  102. mutable Mutex x_info;
  103. PeerSessionInfo m_info; ///< Dynamic information about this peer.
  104. bool m_theyRequestedNodes = false; ///< Has the peer requested nodes from us without receiveing an answer from us?
  105. bool m_weRequestedNodes = false; ///< Have we requested nodes from the peer and not received an answer yet?
  106. std::chrono::steady_clock::time_point m_connect; ///< Time point of connection.
  107. std::chrono::steady_clock::time_point m_ping; ///< Time point of last ping.
  108. std::chrono::steady_clock::time_point m_lastReceived; ///< Time point of last message.
  109. std::map<CapDesc, std::shared_ptr<Capability>> m_capabilities; ///< The peer's capability set.
  110. // framing-related stuff (protected by x_writeQueue mutex)
  111. struct Framing
  112. {
  113. Framing() = delete;
  114. Framing(uint16_t _protocolID): writer(_protocolID), reader(_protocolID) {}
  115. RLPXFrameWriter writer;
  116. RLPXFrameReader reader;
  117. };
  118. std::map<uint16_t, std::shared_ptr<Framing> > m_framing;
  119. std::deque<bytes> m_encFrames;
  120. bool isFramingEnabled() const { return isFramingAllowedForVersion(m_info.protocolVersion); }
  121. unsigned maxFrameSize() const { return 1024; }
  122. std::shared_ptr<Framing> getFraming(uint16_t _protocolID);
  123. void multiplexAll();
  124. };
  125. }
  126. }