35 Session::Session(
Host* _h, unique_ptr<RLPXFrameCoder>&& _io, std::shared_ptr<RLPXSocket>
const& _s, std::shared_ptr<Peer>
const& _n,
PeerSessionInfo _info):
55 m_peer->m_lastConnected =
m_peer->m_lastAttempted - chrono::seconds(1);
63 bi::tcp::socket& socket =
m_socket->ref();
66 boost::system::error_code ec;
67 socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
105 while (ret.size() > _n)
107 auto i = ret.begin();
108 advance(i, rand() % ret.size());
128 if (i.second->c_protocolID == _capId)
129 return i.second->m_enabled ? i.second->interpret(_t, _r) :
true;
134 if (_t >= (
int)i.second->m_idOffset && _t - i.second->m_idOffset < i.second->hostCapability()->messageCount())
135 return i.second->m_enabled ? i.second->interpret(_t - i.second->m_idOffset, _r) :
true;
140 catch (std::exception
const& _e)
142 clog(
NetWarn) <<
"Exception caught in p2p::Session::interpret(): " << _e.what() <<
". PacketType: " << _t <<
". RLP: " << _r;
155 string reason =
"Unspecified";
194 m_ping = std::chrono::steady_clock::now();
206 send(move(b), _protocolID);
211 if (_msg[0] > 0x7f || _msg.
size() < 2)
228 bool doWrite =
false;
260 bytes const* out =
nullptr;
266 auto self(shared_from_this());
267 ba::async_write(
m_socket->ref(), ba::buffer(*out), [
this,
self](boost::system::error_code ec, std::size_t )
274 clog(
NetWarn) <<
"Error sending: " << ec.message();
291 bytes const* out =
nullptr;
300 auto self(shared_from_this());
301 ba::async_write(
m_socket->ref(), ba::buffer(*out), [
this,
self](boost::system::error_code ec, std::size_t )
308 clog(
NetWarn) <<
"Error sending: " << ec.message();
331 bi::tcp::socket& socket =
m_socket->ref();
332 if (socket.is_open())
335 boost::system::error_code ec;
337 socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
342 m_peer->m_lastDisconnect = _reason;
380 auto self(shared_from_this());
382 ba::async_read(
m_socket->ref(), boost::asio::buffer(
m_data,
h256::size), [
this,
self](boost::system::error_code ec, std::size_t length)
395 uint16_t hProtocolId;
405 catch (std::exception
const& _e)
415 ba::async_read(
m_socket->ref(), boost::asio::buffer(
m_data, tlen), [
this,
self, hLength, hProtocolId, tlen](boost::system::error_code ec, std::size_t length)
431 cerr <<
"Received " << frame.
size() <<
": " <<
toHex(frame) << endl;
438 auto packetType = (
PacketType)
RLP(frame.cropped(0, 1)).toInt<unsigned>();
439 RLP r(frame.cropped(1));
440 bool ok =
readPacket(hProtocolId, packetType, r);
454 if (_ec && _ec.category() != boost::asio::error::get_misc_category() && _ec.value() != boost::asio::error::eof)
460 else if (_ec && _length < _expected)
462 clog(
NetWarn) <<
"Error reading - Abrupt peer disconnect: " << _ec.message();
467 else if (_length != _expected)
471 clog(
NetWarn) <<
"Error reading - TCP read buffer length differs from expected frame size.";
484 auto self(shared_from_this());
486 ba::async_read(
m_socket->ref(), boost::asio::buffer(
m_data,
h256::size), [
this,
self](boost::system::error_code ec, std::size_t length)
508 catch (std::exception
const& _e)
518 ba::async_read(
m_socket->ref(), boost::asio::buffer(
m_data, tlen), [
this,
self, tlen, header](boost::system::error_code ec, std::size_t length)
526 vector<RLPXPacket> px;
537 auto v =
f->reader.demux(*
m_io, header, frame);
bool readPacket(uint16_t _capId, PacketType _t, RLP const &_r)
Deliver RLPX packet to Session or Capability for interpretation.
std::unique_ptr< RLPXFrameCoder > m_io
Transport over which packets are sent.
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
unsigned maxFrameSize() const
bool isFramingEnabled() const
std::map< uint16_t, std::shared_ptr< Framing > > m_framing
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Mutex x_framing
Mutex for the write queue.
std::pair< std::string, u256 > CapDesc
RLPStream & append(unsigned _s)
Append given datum to the byte stream.
void registerCapability(CapDesc const &_desc, std::shared_ptr< Capability > _p) override
void noteRude(SessionFace const &_s, std::string const &_sub=std::string())
static RLPStream & prep(RLPStream &_s, PacketType _t, unsigned _args=0)
void write()
Perform a single round of the write operation. This could end up calling itself asynchronously.
bool interpret(PacketType _t, RLP const &_r)
Interpret an incoming Session packet.
The Host class Capabilities should be registered prior to startNetwork, since m_capabilities is not t...
ReputationManager & repMan() override
std::shared_ptr< RLPXSocket > m_socket
Socket of peer's connection.
std::hash for asio::adress
void drop(DisconnectReason _r)
Drop the connection for the reason _r.
void registerFraming(uint16_t _id) override
vector_ref< _T > cropped(size_t _begin, size_t _count) const
void doRead()
Perform a read on the socket.
vector< T > randomSelection(vector< T > const &_t, unsigned _n)
std::chrono::steady_clock::time_point m_lastReceived
Time point of last message.
std::chrono::steady_clock::duration lastPing
std::deque< bytes > m_encFrames
std::shared_ptr< Framing > getFraming(uint16_t _protocolID)
int rating() const override
#define DEV_GUARDED(MUTEX)
Simple block guard.
std::string reasonOf(DisconnectReason _r)
static bool checkPacket(bytesConstRef _msg)
std::vector< byte > bytes
vector_ref< byte const > bytesConstRef
RLPStream & appendList(size_t _items)
Appends a list.
bool m_dropped
If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to ...
bool checkRead(std::size_t _expected, boost::system::error_code _ec, std::size_t _length)
Check error code after reading and drop peer if error code.
PeerSessionInfo info() const override
void addRating(int _r) override
std::deque< bytes > m_writeQueue
The write queue.
std::map< CapDesc, std::shared_ptr< Capability > > m_capabilities
The peer's capability set.
std::vector< byte > m_data
Buffer for ingress packet data.
NodeID id() const override
std::chrono::steady_clock::time_point m_ping
Time point of last ping.
clock::time_point time_point
std::chrono::steady_clock::time_point m_connect
Time point of connection.
void disconnect(DisconnectReason _reason) override
void sealAndSend(RLPStream &_s, uint16_t _protocolID) override
PeerSessionInfo m_info
Dynamic information about this peer.
void swapOut(bytes &_dest)
Swap the contents of the output stream out for some other byte array.
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
Host * m_server
The host that owns us. Never null.
Class for writing to an RLP bytestream.
std::shared_ptr< Peer > m_peer
The Peer object.
uint8_t const padding
Length of padding which follows .
uint32_t const length
Size of frame (excludes padding). Max: 2**24.
Class for interpreting Recursive Linear-Prefix Data.
void send(bytes &&_msg, uint16_t _protocolID)
uint16_t const protocolId
Protocol ID as negotiated by handshake.
ReputationManager & repMan()