Fabcoin Core  0.16.2
P2P Digital Currency
RLPXFrameReader.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16  */
22 #include "RLPXFrameReader.h"
23 
24 using namespace std;
25 using namespace dev;
26 using namespace dev::p2p;
27 
28 std::vector<RLPXPacket> RLPXFrameReader::demux(RLPXFrameCoder& _coder, RLPXFrameInfo const& _info, bytesRef _frame)
29 {
30  if (!_coder.authAndDecryptFrame(_frame))
31  BOOST_THROW_EXCEPTION(RLPXFrameDecryptFailed());
32 
33  std::vector<RLPXPacket> ret;
34  if (_frame.empty())
35  // drop: bad frame (empty)
36  return ret;
37  if (_info.multiFrame && _info.totalLength && (_frame.size() - (h128::size + _info.padding) > _info.totalLength))
38  // drop: bad frame (too large)
39  return ret;
40 
41  // trim mac
42  bytesConstRef buffer = _frame.cropped(0, _frame.size() - (h128::size + _info.padding));
43  // continue populating multiframe packets
44  if (_info.multiFrame && m_incomplete.count(_info.sequenceId))
45  {
46  uint32_t& remaining = m_incomplete.at(_info.sequenceId).second;
47  if (!_info.totalLength && buffer.size() > 0 && buffer.size() <= remaining)
48  {
49  remaining -= buffer.size();
50 
51  RLPXPacket& p = m_incomplete.at(_info.sequenceId).first;
52  if(p.append(buffer) && !remaining)
53  ret.push_back(std::move(p));
54 
55  if (remaining)
56  {
57  if (!ret.empty())
58  BOOST_THROW_EXCEPTION(RLPXInvalidPacket());
59  }
60  else
61  {
62  m_incomplete.erase(_info.sequenceId);
63  if (ret.empty())
64  BOOST_THROW_EXCEPTION(RLPXInvalidPacket());
65  }
66 
67  return ret;
68  }
69  else
70  m_incomplete.erase(_info.sequenceId);
71  }
72 
73  while (!buffer.empty())
74  {
75  auto type = nextRLP(buffer);
76  if (type.empty())
77  break;
78  buffer = buffer.cropped(type.size());
79  // consume entire buffer if packet has sequence
80  auto packet = _info.multiFrame ? buffer : nextRLP(buffer);
81  buffer = buffer.cropped(packet.size());
82  RLPXPacket p(m_protocolType, type);
83  if (!packet.empty())
84  p.append(packet);
85 
86  uint32_t remaining = _info.totalLength - type.size() - packet.size();
87  if (p.isValid())
88  ret.push_back(std::move(p));
89  else if (_info.multiFrame && remaining)
90  m_incomplete.insert(std::make_pair(_info.sequenceId, std::make_pair(std::move(p), remaining)));
91  else
92  BOOST_THROW_EXCEPTION(RLPXInvalidPacket());
93  }
94  return ret;
95 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
virtual bool isValid() const noexcept
Definition: RLPXPacket.h:62
A modifiable reference to an existing object or vector in memory.
Definition: vector_ref.h:20
bool append(bytesConstRef _in)
Appends byte data and returns if packet is valid.
Definition: RLPXPacket.h:60
bool authAndDecryptFrame(bytesRef io_cipherWithMac)
Authenticate and decrypt frame in-place.
std::hash for asio::adress
Definition: Common.h:323
vector_ref< _T > cropped(size_t _begin, size_t _count) const
Definition: vector_ref.h:62
bool empty() const
Definition: vector_ref.h:56
Encapsulation of Frame.
uint32_t const totalLength
Set to total length of packet in first frame of multiframe packet.
size_t size() const
Definition: vector_ref.h:55
bool const multiFrame
If this frame is part of a sequence.
PlatformStyle::TableColorType type
Definition: rpcconsole.cpp:61
RLPX Packet.
Definition: RLPXPacket.h:39
uint8_t const size_t const size
Definition: sha3.h:20
Encoder/decoder transport for RLPx connection established by RLPXHandshake.
uint8_t const padding
Length of padding which follows .
uint16_t const sequenceId
Sequence ID of frame.