limit crypto messages to 1MB (#884)

limit crypto messages to 1MB
This commit is contained in:
Steven Siloti 2016-07-03 23:48:13 -07:00 committed by Arvid Norberg
parent 66416963eb
commit e0c0b14e6c
3 changed files with 35 additions and 18 deletions

View File

@ -2515,6 +2515,14 @@ namespace libtorrent
} }
received_bytes(0, consumed); received_bytes(0, consumed);
// don't accept packets larger than 1 MB with a 1KB allowance for headers
if (!m_recv_buffer.crypto_packet_finished()
&& m_recv_buffer.crypto_packet_size() > 1025 * 1024)
{
disconnect(errors::packet_too_large, op_encryption, 2);
return;
}
int sub_transferred = 0; int sub_transferred = 0;
while (bytes_transferred > 0 && while (bytes_transferred > 0 &&
((sub_transferred = int(m_recv_buffer.advance_pos(int(bytes_transferred)))) > 0)) ((sub_transferred = int(m_recv_buffer.advance_pos(int(bytes_transferred)))) > 0))

View File

@ -122,7 +122,7 @@ namespace libtorrent
bufs = TORRENT_ALLOCA(mutable_buffer, iovec.size()); bufs = TORRENT_ALLOCA(mutable_buffer, iovec.size());
need_destruct = true; need_destruct = true;
num_bufs = 0; num_bufs = 0;
for (int i = 0; to_process > 0; ++i) for (int i = 0; to_process > 0 && i < iovec.size(); ++i)
{ {
++num_bufs; ++num_bufs;
int const size = buffer_size(iovec[i]); int const size = buffer_size(iovec[i]);
@ -147,16 +147,19 @@ namespace libtorrent
int next_barrier = 0; int next_barrier = 0;
aux::array_view<const_buffer> out_iovec; aux::array_view<const_buffer> out_iovec;
bool process_barrier = num_bufs == 0; if (num_bufs != 0)
if (!process_barrier)
{ {
std::tie(next_barrier, out_iovec) std::tie(next_barrier, out_iovec)
= m_send_barriers.front().enc_handler->encrypt({bufs, num_bufs}); = m_send_barriers.front().enc_handler->encrypt({bufs, num_bufs});
process_barrier = (next_barrier != 0);
} }
if (process_barrier)
if (m_send_barriers.front().next != INT_MAX)
{ {
if (m_send_barriers.front().next != INT_MAX) // to_process holds the difference between the size of the buffers
// and the bytes left to the next barrier
// if it's zero then pop the barrier
// otherwise update the number of bytes remaining to the next barrier
if (to_process == 0)
{ {
if (m_send_barriers.size() == 1) if (m_send_barriers.size() == 1)
{ {
@ -165,21 +168,25 @@ namespace libtorrent
} }
m_send_barriers.pop_front(); m_send_barriers.pop_front();
} }
else
{
m_send_barriers.front().next = to_process;
}
}
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS
if (next_barrier != INT_MAX) if (next_barrier != INT_MAX && next_barrier != 0)
{ {
int payload = 0; int payload = 0;
for (int i = 0; i < num_bufs; ++i) for (int i = 0; i < num_bufs; ++i)
payload += int(buffer_size(bufs[i])); payload += int(buffer_size(bufs[i]));
int overhead = 0; int overhead = 0;
for (auto buf : out_iovec) for (auto buf : out_iovec)
overhead += int(buffer_size(buf)); overhead += int(buffer_size(buf));
TORRENT_ASSERT(overhead + payload == next_barrier); TORRENT_ASSERT(overhead + payload == next_barrier);
}
#endif
} }
#endif
if (need_destruct) if (need_destruct)
{ {
for (int i = 0; i < num_bufs; ++i) for (int i = 0; i < num_bufs; ++i)

View File

@ -5501,7 +5501,9 @@ namespace libtorrent
if (m_send_barrier == 0) if (m_send_barrier == 0)
{ {
std::vector<boost::asio::mutable_buffer> vec; std::vector<boost::asio::mutable_buffer> vec;
m_send_buffer.build_mutable_iovec(m_send_buffer.size(), vec); // limit outgoing crypto messages to 1MB
int const send_bytes = (std::min)(m_send_buffer.size(), 1024*1024);
m_send_buffer.build_mutable_iovec(send_bytes, vec);
int next_barrier; int next_barrier;
aux::array_view<boost::asio::const_buffer> inject_vec; aux::array_view<boost::asio::const_buffer> inject_vec;
std::tie(next_barrier, inject_vec) = hit_send_barrier(vec); std::tie(next_barrier, inject_vec) = hit_send_barrier(vec);