deprecate slow bdecode() function
This commit is contained in:
parent
0d8a5a8a44
commit
9ae4aedeb0
|
@ -5,6 +5,7 @@
|
|||
#include "boost_python.hpp"
|
||||
#include <libtorrent/identify_client.hpp>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
#include <libtorrent/bdecode.hpp>
|
||||
#include "bytes.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
|
@ -74,7 +75,7 @@ object client_fingerprint_(peer_id const& id)
|
|||
|
||||
entry bdecode_(bytes const& data)
|
||||
{
|
||||
return bdecode(data.arr.begin(), data.arr.end());
|
||||
return bdecode(data.arr);
|
||||
}
|
||||
|
||||
bytes bencode_(entry const& e)
|
||||
|
|
|
@ -38,35 +38,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
// Bencoding is a common representation in bittorrent used for for dictionary,
|
||||
// list, int and string hierarchies. It's used to encode .torrent files and
|
||||
// some messages in the network protocol. libtorrent also uses it to store
|
||||
// settings, resume data and other state between sessions.
|
||||
// settings, resume data and other session state.
|
||||
//
|
||||
// Strings in bencoded structures are not necessarily representing text.
|
||||
// Strings in bencoded structures do not necessarily represent text.
|
||||
// Strings are raw byte buffers of a certain length. If a string is meant to be
|
||||
// interpreted as text, it is required to be UTF-8 encoded. See `BEP 3`_.
|
||||
//
|
||||
// There are two mechanisms to *decode* bencoded buffers in libtorrent.
|
||||
// The function for decoding bencoded data bdecode(), returning a bdecode_node.
|
||||
// This function builds a tree that points back into the original buffer. The
|
||||
// returned bdecode_node will not be valid once the buffer it was parsed out of
|
||||
// is discarded.
|
||||
//
|
||||
// The most flexible one is `bdecode() bencode()`_, which returns a structure
|
||||
// represented by entry. Once a buffer has been decoded with this function, it
|
||||
// can be discarded. The entry does not contain any references back to it. This
|
||||
// means that bdecode() copies all the data out of the buffer and into its own
|
||||
// hierarchy. This makes this function expensive, which might matter if you're
|
||||
// parsing large amounts of data.
|
||||
//
|
||||
// Another consideration is that `bdecode() bencode()`_ is a recursive parser.
|
||||
// For this reason, in order to avoid DoS attacks by triggering a stack
|
||||
// overflow, there is a recursion limit. This limit is a sanity check to make
|
||||
// sure it doesn't run the risk of busting the stack.
|
||||
//
|
||||
// The second mechanism is the decode function for bdecode_node. This function
|
||||
// builds a tree that points back into the original buffer. The returned
|
||||
// bdecode_node will not be valid once the buffer it was parsed out of is
|
||||
// discarded.
|
||||
//
|
||||
// Not only is this function more efficient because of less memory allocation
|
||||
// and data copy, the parser is also not recursive, which means it probably
|
||||
// performs a little bit better and can have a higher recursion limit on the
|
||||
// structures it's parsing.
|
||||
// It's possible to construct an entry from a bdecode_node, if a structure needs
|
||||
// to be altered and re-encoded.
|
||||
|
||||
#include <string>
|
||||
#include <iterator> // for distance
|
||||
|
@ -206,7 +190,7 @@ namespace detail {
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
template<class InIt>
|
||||
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth)
|
||||
{
|
||||
|
@ -364,56 +348,36 @@ namespace detail {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
#endif // TORRENT_ABI_VERSION
|
||||
}
|
||||
|
||||
// These functions will encode data to bencoded or decode bencoded data.
|
||||
//
|
||||
// If possible, ``bdecode()`` producing a bdecode_node should be preferred
|
||||
// over this function.
|
||||
// This function will encode data to bencoded form.
|
||||
//
|
||||
// The entry_ class is the internal representation of the bencoded data
|
||||
// and it can be used to retrieve information, an entry_ can also be build by
|
||||
// the program and given to ``bencode()`` to encode it into the ``OutIt``
|
||||
// iterator.
|
||||
//
|
||||
// The ``OutIt`` and ``InIt`` are iterators
|
||||
// (InputIterator_ and OutputIterator_ respectively). They
|
||||
// are templates and are usually instantiated as ostream_iterator_,
|
||||
// back_insert_iterator_ or istream_iterator_. These
|
||||
// functions will assume that the iterator refers to a character
|
||||
// (``char``). So, if you want to encode entry ``e`` into a buffer
|
||||
// in memory, you can do it like this::
|
||||
// ``OutIt`` is an OutputIterator_. It's a template and usually
|
||||
// instantiated as ostream_iterator_ or back_insert_iterator_. This
|
||||
// function assumes the value_type of the iterator is a ``char``.
|
||||
// In order to encode entry ``e`` into a buffer, do::
|
||||
//
|
||||
// std::vector<char> buffer;
|
||||
// bencode(std::back_inserter(buf), e);
|
||||
//
|
||||
// .. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html
|
||||
// .. _OutputIterator: http://www.sgi.com/tech/stl/OutputIterator.html
|
||||
// .. _ostream_iterator: http://www.sgi.com/tech/stl/ostream_iterator.html
|
||||
// .. _back_insert_iterator: http://www.sgi.com/tech/stl/back_insert_iterator.html
|
||||
// .. _istream_iterator: http://www.sgi.com/tech/stl/istream_iterator.html
|
||||
//
|
||||
// If you want to decode a torrent file from a buffer in memory, you can do it like this::
|
||||
//
|
||||
// std::vector<char> buffer;
|
||||
// // ...
|
||||
// entry e = bdecode(buf.begin(), buf.end());
|
||||
//
|
||||
// Or, if you have a raw char buffer::
|
||||
//
|
||||
// const char* buf;
|
||||
// // ...
|
||||
// entry e = bdecode(buf, buf + data_size);
|
||||
//
|
||||
// Now we just need to know how to retrieve information from the entry.
|
||||
//
|
||||
// If ``bdecode()`` encounters invalid encoded data in the range given to it
|
||||
// it will return a default constructed ``entry`` object.
|
||||
// .. _OutputIterator: https://en.cppreference.com/w/cpp/named_req/OutputIterator
|
||||
// .. _ostream_iterator: https://en.cppreference.com/w/cpp/iterator/ostream_iterator
|
||||
// .. _back_insert_iterator: https://en.cppreference.com/w/cpp/iterator/back_insert_iterator
|
||||
template<class OutIt> int bencode(OutIt out, const entry& e)
|
||||
{
|
||||
return detail::bencode_recursive(out, e);
|
||||
}
|
||||
template<class InIt> entry bdecode(InIt start, InIt end)
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
template<class InIt>
|
||||
TORRENT_DEPRECATED
|
||||
entry bdecode(InIt start, InIt end)
|
||||
{
|
||||
entry e;
|
||||
bool err = false;
|
||||
|
@ -422,7 +386,9 @@ namespace detail {
|
|||
if (err) return entry();
|
||||
return e;
|
||||
}
|
||||
template<class InIt> entry bdecode(InIt start, InIt end
|
||||
template<class InIt>
|
||||
TORRENT_DEPRECATED
|
||||
entry bdecode(InIt start, InIt end
|
||||
, typename std::iterator_traits<InIt>::difference_type& len)
|
||||
{
|
||||
entry e;
|
||||
|
@ -434,6 +400,7 @@ namespace detail {
|
|||
if (err) return entry();
|
||||
return e;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // TORRENT_BENCODE_HPP_INCLUDED
|
||||
|
|
|
@ -162,10 +162,10 @@ void item::assign(entry v)
|
|||
void item::assign(entry v, span<char const> salt
|
||||
, sequence_number const seq, public_key const& pk, secret_key const& sk)
|
||||
{
|
||||
char buffer[1000];
|
||||
int bsize = bencode(buffer, v);
|
||||
std::array<char, 1000> buffer;
|
||||
int const bsize = bencode(buffer.begin(), v);
|
||||
TORRENT_ASSERT(bsize <= 1000);
|
||||
m_sig = sign_mutable_item({buffer, bsize}
|
||||
m_sig = sign_mutable_item(span<char const>(buffer).first(bsize)
|
||||
, salt, seq, pk, sk);
|
||||
m_salt.assign(salt.data(), static_cast<std::size_t>(salt.size()));
|
||||
m_pk = pk;
|
||||
|
|
|
@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/aux_/time.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "dht_server.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
|
@ -114,7 +115,7 @@ struct dht_server
|
|||
|
||||
void thread_fun()
|
||||
{
|
||||
char buffer[2000];
|
||||
std::array<char, 2000> buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -123,7 +124,7 @@ struct dht_server
|
|||
size_t bytes_transferred;
|
||||
bool done = false;
|
||||
m_socket.async_receive_from(
|
||||
boost::asio::buffer(buffer, sizeof(buffer)), from, 0
|
||||
boost::asio::buffer(buffer.data(), buffer.size()), from, 0
|
||||
, std::bind(&incoming_packet, _1, _2, &bytes_transferred, &ec, &done));
|
||||
while (!done)
|
||||
{
|
||||
|
@ -142,7 +143,7 @@ struct dht_server
|
|||
|
||||
try
|
||||
{
|
||||
entry msg = bdecode(buffer, buffer + bytes_transferred);
|
||||
entry msg = bdecode(span<char const>(buffer).first(int(bytes_transferred)));
|
||||
|
||||
#if TORRENT_USE_IOSTREAM
|
||||
std::cout << msg << std::endl;
|
||||
|
|
Loading…
Reference in New Issue