diff --git a/libp2p/RLPXFrameWriter.cpp b/libp2p/RLPXFrameWriter.cpp index c8c1e8ceb..a657afd70 100644 --- a/libp2p/RLPXFrameWriter.cpp +++ b/libp2p/RLPXFrameWriter.cpp @@ -25,6 +25,18 @@ using namespace std; using namespace dev; using namespace dev::p2p; +RLPXFrameInfo::RLPXFrameInfo(bytesConstRef _header) +{ + length = (_header[0] * 256 + _header[1]) * 256 + _header[2]; + padding = ((16 - (length % 16)) % 16); + RLP header(_header.cropped(3), RLP::ThrowOnFail | RLP::FailIfTooSmall); + auto itemCount = header.itemCount(); + protocolId = header[0].toInt(); + hasSequence = itemCount > 1; + sequenceId = hasSequence ? header[1].toInt() : 0; + totalLength = itemCount == 3 ? header[2].toInt() : 0; +} + void RLPXFrameWriter::enque(unsigned _packetType, RLPStream& _payload, PacketPriority _priority) { QueueState& qs = _priority ? m_q.first : m_q.second; diff --git a/libp2p/RLPXFrameWriter.h b/libp2p/RLPXFrameWriter.h index 957bb09a2..384bf0503 100644 --- a/libp2p/RLPXFrameWriter.h +++ b/libp2p/RLPXFrameWriter.h @@ -33,6 +33,22 @@ namespace dev namespace p2p { +struct RLPXFrameDecrytFailed: virtual dev::Exception {}; + +struct RLPXFrameInfo +{ + RLPXFrameInfo() = default; + /// Constructor. frame-size || protocol-type, [sequence-id[, total-packet-size]] + RLPXFrameInfo(bytesConstRef _frameHeader); + uint32_t length = 0; ///< Max: 2**24 + uint8_t padding = 0; + + uint16_t protocolId = 0; + bool hasSequence = false; + uint16_t sequenceId = 0; + uint32_t totalLength = 0; +}; + /** * RLPFrameReader * Reads and assembles RLPX frame byte buffers into RLPX packets. Additionally @@ -43,11 +59,15 @@ namespace p2p */ class RLPXFrameReader { +public: RLPXFrameReader(uint16_t _protocolType): m_protocolType(_protocolType) {} /// Processes a single frame returning complete packets. - std::vector demux(bytes& _frame, bool _sequence = false, uint16_t _seq = 0, uint32_t _totalSize = 0) + std::vector demux(RLPXFrameCoder& _coder, bytes& _frame, bool _sequence = false, uint16_t _seq = 0, uint32_t _totalSize = 0) { + if (!_coder.authAndDecryptFrame(&_frame)) + BOOST_THROW_EXCEPTION(RLPXFrameDecrytFailed()); + std::vector ret; if (!_frame.size() || _frame.size() > _totalSize) return ret; @@ -100,6 +120,11 @@ protected: std::map> m_incomplete; ///< Incomplete packets and bytes remaining. }; +/** + * RLPXFrameWriter + * Multiplex and encrypted packets into RLPX frames. + * @todo flag to disable multiple packets per frame + */ class RLPXFrameWriter { struct QueueState