forked from premiere/premiere-libtorrent
landed the bdecode branch in master. lazy_bdecode/lazy_entry is now being replaced by bdecode/bdecode_node
This commit is contained in:
parent
c1dc982f4f
commit
6c1df7eb55
|
@ -13,6 +13,7 @@ set(sources
|
|||
bandwidth_limit
|
||||
bandwidth_manager
|
||||
bandwidth_queue_entry
|
||||
bdecode
|
||||
block_cache
|
||||
bloom_filter
|
||||
chained_buffer
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
* replaced lazy_bdecode with a new bdecoder that's a lot more efficient
|
||||
* deprecate time functions, expose typedefs of boost::chrono in the libtorrent
|
||||
namespace instead
|
||||
* deprecate file_base feature in file_storage/torrent_info
|
||||
|
|
1
Jamfile
1
Jamfile
|
@ -529,6 +529,7 @@ SOURCES =
|
|||
bandwidth_limit
|
||||
bandwidth_manager
|
||||
bandwidth_queue_entry
|
||||
bdecode
|
||||
block_cache
|
||||
bloom_filter
|
||||
chained_buffer
|
||||
|
|
|
@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/error_code.hpp>
|
||||
#include <libtorrent/lazy_entry.hpp>
|
||||
#include <libtorrent/bdecode.hpp>
|
||||
#include <libtorrent/upnp.hpp>
|
||||
#include <libtorrent/socks5_stream.hpp>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <libtorrent/disk_io_thread.hpp>
|
||||
#include <libtorrent/aux_/session_settings.hpp>
|
||||
#include <libtorrent/extensions.hpp>
|
||||
#include <libtorrent/lazy_entry.hpp>
|
||||
#include <libtorrent/bdecode.hpp>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
#include <libtorrent/aux_/session_impl.hpp> // for settings_map()
|
||||
|
||||
|
@ -486,9 +486,9 @@ namespace
|
|||
|
||||
std::vector<char> buf;
|
||||
bencode(std::back_inserter(buf), st);
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
|
||||
bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
|
||||
TORRENT_ASSERT(!ec);
|
||||
ses.load_state(e);
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ category_mapping = {
|
|||
'alert_types.hpp': 'Alerts',
|
||||
'bencode.hpp': 'Bencoding',
|
||||
'lazy_entry.hpp': 'Bencoding',
|
||||
'bdecode.hpp': 'Bdecoding',
|
||||
'entry.hpp': 'Bencoding',
|
||||
'time.hpp': 'Time',
|
||||
'escape_string.hpp': 'String',
|
||||
|
|
|
@ -85,8 +85,8 @@ $(REFERENCE_TARGETS:=.rst):gen_reference_doc.py ../include/libtorrent/*.hpp ../i
|
|||
rst2pdf $? -o $@ --stylesheets stylesheet
|
||||
|
||||
%.html:%.rst
|
||||
rst2html-2.6.py --template=template.txt --stylesheet-path=style.css --link-stylesheet --no-toc-backlinks $? > $@
|
||||
rst2html-2.6.py --template=template2.txt --stylesheet-path=style.css --link-stylesheet --no-toc-backlinks $? > $(WEB_PATH)/$@
|
||||
rst2html-3.4.py --template=template.txt --stylesheet-path=style.css --link-stylesheet --no-toc-backlinks $? > $@
|
||||
rst2html-3.4.py --template=template2.txt --stylesheet-path=style.css --link-stylesheet --no-toc-backlinks $? > $(WEB_PATH)/$@
|
||||
|
||||
%.png:%.dot
|
||||
dot -Tpng $? >$@
|
||||
|
|
|
@ -64,7 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/magnet_uri.hpp"
|
||||
#include "libtorrent/bitfield.hpp"
|
||||
#include "libtorrent/peer_info.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/add_torrent_params.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/create_torrent.hpp"
|
||||
|
@ -697,7 +697,6 @@ void add_torrent(libtorrent::session& ses
|
|||
if (seed_mode) p.flags |= add_torrent_params::flag_seed_mode;
|
||||
if (disable_storage) p.storage = disabled_storage_constructor;
|
||||
if (share_mode) p.flags |= add_torrent_params::flag_share_mode;
|
||||
lazy_entry resume_data;
|
||||
|
||||
std::string filename = path_append(save_path, path_append(".resume"
|
||||
, leaf_path(torrent) + ".resume"));
|
||||
|
@ -1324,8 +1323,8 @@ int main(int argc, char* argv[])
|
|||
error_code ec;
|
||||
if (load_file(".ses_state", in, ec) == 0)
|
||||
{
|
||||
lazy_entry e;
|
||||
if (lazy_bdecode(&in[0], &in[0] + in.size(), e, ec) == 0)
|
||||
bdecode_node e;
|
||||
if (bdecode(&in[0], &in[0] + in.size(), e, ec) == 0)
|
||||
ses.load_state(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,10 +33,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/magnet_uri.hpp"
|
||||
|
||||
int load_file(std::string const& filename, std::vector<char>& v, libtorrent::error_code& ec, int limit = 8000000)
|
||||
int load_file(std::string const& filename, std::vector<char>& v
|
||||
, libtorrent::error_code& ec, int limit = 8000000)
|
||||
{
|
||||
ec.clear();
|
||||
FILE* f = fopen(filename.c_str(), "rb");
|
||||
|
@ -127,11 +128,11 @@ int main(int argc, char* argv[])
|
|||
fprintf(stderr, "failed to load file: %s\n", ec.message().c_str());
|
||||
return 1;
|
||||
}
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
int pos = -1;
|
||||
printf("decoding. recursion limit: %d total item count limit: %d\n"
|
||||
, depth_limit, item_limit);
|
||||
ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec, &pos
|
||||
ret = bdecode(&buf[0], &buf[0] + buf.size(), e, ec, &pos
|
||||
, depth_limit, item_limit);
|
||||
|
||||
printf("\n\n----- raw info -----\n\n%s\n", print_entry(e).c_str());
|
||||
|
|
|
@ -179,8 +179,8 @@ int main(int argc, char* argv[])
|
|||
error_code ec;
|
||||
if (load_file(".ses_state", in, ec) == 0)
|
||||
{
|
||||
lazy_entry e;
|
||||
if (lazy_bdecode(&in[0], &in[0] + in.size(), e, ec) == 0)
|
||||
bdecode_node e;
|
||||
if (bdecode(&in[0], &in[0] + in.size(), e, ec) == 0)
|
||||
ses.load_state(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ nobase_include_HEADERS = \
|
|||
bandwidth_socket.hpp \
|
||||
bandwidth_queue_entry.hpp \
|
||||
bencode.hpp \
|
||||
bdecode.hpp \
|
||||
bitfield.hpp \
|
||||
block_cache.hpp \
|
||||
bloom_filter.hpp \
|
||||
|
|
|
@ -492,7 +492,7 @@ namespace libtorrent
|
|||
void announce_lsd(sha1_hash const& ih, int port, bool broadcast = false);
|
||||
|
||||
void save_state(entry* e, boost::uint32_t flags) const;
|
||||
void load_state(lazy_entry const* e);
|
||||
void load_state(bdecode_node const* e);
|
||||
|
||||
bool has_connection(peer_connection* p) const;
|
||||
void insert_peer(boost::shared_ptr<peer_connection> const& c);
|
||||
|
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2015, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#ifndef TORRENT_BDECODE_HPP
|
||||
#define TORRENT_BDECODE_HPP
|
||||
|
||||
/*
|
||||
|
||||
This is an efficient bdecoder. It decodes into a flat memory buffer of tokens.
|
||||
|
||||
Each token has an offset into the bencoded buffer where the token came from
|
||||
and a next pointer, which is a relative number of tokens to skip forward to
|
||||
get to the logical next item in a container.
|
||||
|
||||
strings and ints offset pointers point to the first character of the length
|
||||
prefix or the 'i' character. This is to maintain uniformity with other types
|
||||
and to allow easily calculating the span of a node by subtracting its offset
|
||||
by the offset of the next node.
|
||||
|
||||
example layout:
|
||||
|
||||
{
|
||||
"a": { "b": 1, "c": "abcd" },
|
||||
"d": 3
|
||||
}
|
||||
|
||||
/---------------------------------------------------------------------------------------\
|
||||
| |
|
||||
| |
|
||||
| /--------------------------------------------\ |
|
||||
| | | |
|
||||
| | | |
|
||||
| /-----\ | /----\ /----\ /----\ /----\ | /----\ /----\ |
|
||||
| next | | | | | | | | | | | | | | | | |
|
||||
| pointers | v | | v | v | v | v v | v | v v
|
||||
+-+-----+----+--+----+--+----+--+----+--+----+--+----+--+-------+----+--+----+--+------+ X
|
||||
| dict | str | dict | str | int | str | str | end | str | int | end |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
+-+-----+-+-----+-+-----+-+-----+-+-----+-+-----+-+-----+-+-----+-+-----+-+-----+-+----+
|
||||
| offset| | | | | | | | | |
|
||||
| | | | | | | | | | |
|
||||
|/------/ | | | | | | | | |
|
||||
|| /-----------/ | | | | | | | |
|
||||
|| |/------------------/ | | | | | | |
|
||||
|| || /-----------------------/ | | | | | |
|
||||
|| || | /----------------------------/ | | | | |
|
||||
|| || | | /---------------------------------/ | | | |
|
||||
|| || | | | /-----------------------------------/ | | |
|
||||
|| || | | | |/------------------------------------------/ | |
|
||||
|| || | | | || /-----------------------------------------------/ |
|
||||
|| || | | | || | /----------------------------------------------------/
|
||||
|| || | | | || | |
|
||||
vv vv v v v vv v v
|
||||
``d1:ad1:bi1e1:c4:abcde1:di3ee``
|
||||
|
||||
*/
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
TORRENT_EXPORT boost::system::error_category& get_bdecode_category();
|
||||
|
||||
namespace bdecode_errors
|
||||
{
|
||||
// libtorrent uses boost.system's ``error_code`` class to represent
|
||||
// errors. libtorrent has its own error category get_bdecode_category()
|
||||
// whith the error codes defined by error_code_enum.
|
||||
enum error_code_enum
|
||||
{
|
||||
// Not an error
|
||||
no_error = 0,
|
||||
// expected string in bencoded string
|
||||
expected_digit,
|
||||
// expected colon in bencoded string
|
||||
expected_colon,
|
||||
// unexpected end of file in bencoded string
|
||||
unexpected_eof,
|
||||
// expected value (list, dict, int or string) in bencoded string
|
||||
expected_value,
|
||||
// bencoded recursion depth limit exceeded
|
||||
depth_exceeded,
|
||||
// bencoded item count limit exceeded
|
||||
limit_exceeded,
|
||||
// integer overflow
|
||||
overflow,
|
||||
|
||||
// the number of error codes
|
||||
error_code_max
|
||||
};
|
||||
|
||||
// hidden
|
||||
TORRENT_EXPORT boost::system::error_code make_error_code(error_code_enum e);
|
||||
}
|
||||
} // namespace libtorrent
|
||||
|
||||
namespace boost { namespace system {
|
||||
|
||||
template<> struct is_error_code_enum<libtorrent::bdecode_errors::error_code_enum>
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<> struct is_error_condition_enum<libtorrent::bdecode_errors::error_code_enum>
|
||||
{ static const bool value = true; };
|
||||
} }
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
TORRENT_EXTRA_EXPORT char const* parse_int(char const* start
|
||||
, char const* end, char delimiter, boost::int64_t& val
|
||||
, bdecode_errors::error_code_enum& ec);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// internal
|
||||
struct bdecode_token
|
||||
{
|
||||
// the node with type 'end' is a logical node, pointing to the end
|
||||
// of the bencoded buffer.
|
||||
enum type_t
|
||||
{ none, dict, list, string, integer, end };
|
||||
|
||||
enum limits_t
|
||||
{
|
||||
max_offset = (1 << 29) - 1,
|
||||
max_next_item = (1 << 29) - 1,
|
||||
max_header = (1 << 3) - 1,
|
||||
};
|
||||
|
||||
bdecode_token(boost::uint32_t off, bdecode_token::type_t t)
|
||||
: offset(off)
|
||||
, type(t)
|
||||
, next_item(0)
|
||||
, header(0)
|
||||
{
|
||||
TORRENT_ASSERT(off <= max_offset);
|
||||
TORRENT_ASSERT(t >= 0 && t <= end);
|
||||
}
|
||||
|
||||
bdecode_token(boost::uint32_t off, boost::uint32_t next
|
||||
, bdecode_token::type_t t, boost::uint8_t header_size = 0)
|
||||
: offset(off)
|
||||
, type(t)
|
||||
, next_item(next)
|
||||
, header(type == string ? header_size - 2 : 0)
|
||||
{
|
||||
TORRENT_ASSERT(type != string || header_size >= 2);
|
||||
TORRENT_ASSERT(off <= max_offset);
|
||||
TORRENT_ASSERT(next <= max_next_item);
|
||||
TORRENT_ASSERT(header_size < 8);
|
||||
TORRENT_ASSERT(t >= 0 && t <= end);
|
||||
}
|
||||
|
||||
int start_offset() const { TORRENT_ASSERT(type == string); return header + 2; }
|
||||
|
||||
// offset into the bdecoded buffer where this node is
|
||||
boost::uint32_t offset:29;
|
||||
|
||||
// one of type_t enums
|
||||
boost::uint32_t type:3;
|
||||
|
||||
// if this node is a member of a list, 'next_item' is the number of nodes
|
||||
// to jump forward in th node array to get to the next item in the list.
|
||||
// if it's a key in a dictionary, it's the number of step forwards to get
|
||||
// to its corresponding value. If it's a value in a dictionary, it's the
|
||||
// number of steps to the next key, or to the end node.
|
||||
// this is the _relative_ offset to the next node
|
||||
boost::uint32_t next_item:29;
|
||||
|
||||
// this is the number of bytes to skip forward from the offset to get to the
|
||||
// first character of the string, if this is a string. This field is not
|
||||
// used for other types. Essentially this is the length of the length prefix
|
||||
// and the colon. Since a string always has at least one character of length
|
||||
// prefix and always a colon, those 2 characters are implied.
|
||||
boost::uint32_t header:3;
|
||||
};
|
||||
}
|
||||
|
||||
// a ``bdecode_node`` is used to traverse and hold the tree structure defined
|
||||
// by bencoded data after it has been parse by bdecode().
|
||||
//
|
||||
// There are primarily two kinds of bdecode_nodes. The ones that own the tree
|
||||
// structure, and defines its lifetime, and nodes that are child nodes in the
|
||||
// tree, pointing back into the root's tree.
|
||||
//
|
||||
// The ``bdecode_node`` passed in to ``bdecode()`` becomes the one owning the
|
||||
// tree structure. Make sure not to destruct that object for as long as you
|
||||
// use any of its child nodes. Also, keep in mind that the buffer originally
|
||||
// parsed also must remain valid while using it. (see switch_underlying_buffer()).
|
||||
//
|
||||
// Copying an owning node will create a copy of the whole tree, but will still
|
||||
// point into the same parsed bencoded buffer as the first one.
|
||||
|
||||
// Sometimes it's important to get a non-owning reference to the root node (
|
||||
// to be able to copy it as a reference for instance). For that, use the
|
||||
// non_owninig() member function.
|
||||
//
|
||||
// There are 5 different types of nodes, see type_t.
|
||||
struct TORRENT_EXPORT bdecode_node
|
||||
{
|
||||
friend int bdecode(char const* start, char const* end, bdecode_node& ret
|
||||
, error_code& ec, int* error_pos, int depth_limit, int token_limit);
|
||||
|
||||
// creates a default constructed node, it will have the type ``none_t``.
|
||||
bdecode_node();
|
||||
|
||||
// For owning nodes, the copy will create a copy of the tree, but the
|
||||
// underlying buffer remains the same.
|
||||
bdecode_node(bdecode_node const&);
|
||||
bdecode_node& operator=(bdecode_node const&);
|
||||
|
||||
// the dypes of bdecoded nodes
|
||||
enum type_t
|
||||
{
|
||||
// uninitialized or default constructed. This is also used
|
||||
// to indicate that a node was not found in some cases.
|
||||
none_t,
|
||||
// a dictionary node. The ``dict_find_`` functions are valid.
|
||||
dict_t,
|
||||
// a list node. The ``list_`` functions are valid.
|
||||
list_t,
|
||||
// a string node, the ``string_`` functions are valid.
|
||||
string_t,
|
||||
// an integer node. The ``int_`` functions are valid.
|
||||
int_t
|
||||
};
|
||||
|
||||
// the type of this node. See type_t.
|
||||
type_t type() const;
|
||||
|
||||
// returns true if type() != none_t.
|
||||
operator bool() const;
|
||||
|
||||
// return a non-owning reference to this node. This is useful to refer to
|
||||
// the root node without copying it in assignments.
|
||||
bdecode_node non_owning() const;
|
||||
|
||||
// returns the buffer and length of the section in the original bencoded
|
||||
// buffer where this node is defined. For a dictionary for instance, this
|
||||
// starts with ``d`` and ends with ``e``, and has all the content of the
|
||||
// dictionary in between.
|
||||
std::pair<char const*, int> data_section() const;
|
||||
|
||||
// functions with the ``list_`` prefix operate on lists. These functions are
|
||||
// only valid if ``type()`` == ``list_t``. ``list_at()`` returns the item
|
||||
// in the list at index ``i``. ``i`` may not be greater than or equal to the
|
||||
// size of the list. ``size()`` returns the size of the list.
|
||||
bdecode_node list_at(int i) const;
|
||||
std::string list_string_value_at(int i
|
||||
, char const* default_val = "");
|
||||
boost::int64_t list_int_value_at(int i
|
||||
, boost::int64_t default_val = 0);
|
||||
int list_size() const;
|
||||
|
||||
// functions with the ``dict_`` prefix operates on dictionaries. Theu are
|
||||
// only valid if ``type()`` == ``dict_t``. In case a key you're looking up
|
||||
// contains a 0 byte, you cannot use the null-terminated string overloads,
|
||||
// but have to use ``std::string`` instead. ``dict_find_list`` will return
|
||||
// a valid ``bdecode_node`` if the key is found _and_ it is a list. Otherwise
|
||||
// it will return a default-constructed bdecode_node.
|
||||
bdecode_node dict_find(std::string key) const;
|
||||
bdecode_node dict_find(char const* key) const;
|
||||
std::pair<std::string, bdecode_node> dict_at(int i) const;
|
||||
bdecode_node dict_find_dict(std::string key) const;
|
||||
bdecode_node dict_find_dict(char const* key) const;
|
||||
bdecode_node dict_find_list(char const* key) const;
|
||||
bdecode_node dict_find_string(char const* key) const;
|
||||
bdecode_node dict_find_int(char const* key) const;
|
||||
std::string dict_find_string_value(char const* key
|
||||
, char const* default_value = "") const;
|
||||
boost::int64_t dict_find_int_value(char const* key
|
||||
, boost::int64_t default_val = 0) const;
|
||||
int dict_size() const;
|
||||
|
||||
// this function is only valid if ``type()`` == ``int_t``. It returns the
|
||||
// value of the integer.
|
||||
boost::int64_t int_value() const;
|
||||
|
||||
// these functions are only valid if ``type()`` == ``string_t``. They return
|
||||
// the string values. Note that ``string_ptr()`` is _not_ null-terminated.
|
||||
// ``string_length()`` returns the number of bytes in the string.
|
||||
std::string string_value() const;
|
||||
char const* string_ptr() const;
|
||||
int string_length() const;
|
||||
|
||||
// resets the ``bdecoded_node`` to a default constructed state. If this is
|
||||
// an owning node, the tree is freed and all child nodes are invalidated.
|
||||
void clear();
|
||||
|
||||
// Swap contents.
|
||||
void swap(bdecode_node& n);
|
||||
|
||||
// pre-allocate memory for the specified numbers of tokens. This is
|
||||
// useful if you know approximately how many tokens are in the file
|
||||
// you are about to parse. Doing so will save realloc operations
|
||||
// while parsing. You should only call this on the root node, before
|
||||
// passing it in to bdecode().
|
||||
void reserve(int tokens);
|
||||
|
||||
// this buffer MUST be identical to the one originally parsed.
|
||||
// This operation is only defined on owning root nodes, i.e. the one
|
||||
// passed in to decode().
|
||||
void switch_underlying_buffer(char const* buf);
|
||||
|
||||
private:
|
||||
bdecode_node(detail::bdecode_token const* tokens, char const* buf
|
||||
, int len, int idx);
|
||||
|
||||
// if this is the root node, that owns all the tokens, they live in this
|
||||
// vector. If this is a sub-node, this field is not used, instead the
|
||||
// m_root_tokens pointer points to the root node's token.
|
||||
std::vector<detail::bdecode_token> m_tokens;
|
||||
|
||||
// this points to the root nodes token vector
|
||||
// for the root node, this points to its own m_tokens member
|
||||
detail::bdecode_token const* m_root_tokens;
|
||||
|
||||
// this points to the original buffer that was parsed
|
||||
char const* m_buffer;
|
||||
int m_buffer_size;
|
||||
|
||||
// this is the index into m_root_tokens that this node refers to
|
||||
// for the root node, it's 0. -1 means uninitialized.
|
||||
int m_token_idx;
|
||||
|
||||
// this is a cache of the last element index looked up. This only applies
|
||||
// to lists and dictionaries. If the next lookup is at m_last_index or
|
||||
// greater, we can start iterating the tokens at m_last_token.
|
||||
mutable int m_last_index;
|
||||
mutable int m_last_token;
|
||||
|
||||
// the number of elements in this list or dict (computed on the first
|
||||
// call to dict_size() or list_size())
|
||||
mutable int m_size;
|
||||
};
|
||||
|
||||
// print the bencoded structure in a human-readable format to a string
|
||||
// that's returned.
|
||||
TORRENT_EXPORT std::string print_entry(bdecode_node const& e
|
||||
, bool single_line = false, int indent = 0);
|
||||
|
||||
// This function decodes/parses bdecoded data (for example a .torrent file).
|
||||
// The data structure is returned in the ``ret`` argument.
|
||||
// the buffer to parse is specified by the ``start`` of the buffer as well as
|
||||
// the ``end``, i.e. one byte past the end. If the buffer fails to parse, the
|
||||
// function returns a non-zero value and fills in ``ec`` with the error code.
|
||||
// The optional argument ``error_pos``, if set to non-null, will be set to the byte
|
||||
// offset into the buffer where the parse failure occurred.
|
||||
//
|
||||
// ``depth_limit`` specifies the max number of nested lists or dictionaries are
|
||||
// allowed in the data structure. (This affects the stack usage of the
|
||||
// function, be careful not to set it too high).
|
||||
//
|
||||
// ``token_limit`` is the max number of tokens allowed to be parsed from the
|
||||
// buffer. This is simply a sanity check to not have unbounded memory usage.
|
||||
//
|
||||
// The resulting ``bdecode_node`` is an *owning* node. That means it will
|
||||
// be holding the whole parsed tree. When iterating lists and dictionaries,
|
||||
// those ``bdecode_node``s will simply have references to the root or owning
|
||||
// ``bdecode_node``. If the root node is destructed, all other nodes that
|
||||
// refer to anything in that tree become invalid.
|
||||
//
|
||||
// However, the underlying buffer passed in to this function (``start``, ``end``)
|
||||
// must also remain valid while the bdecoded tree is used. The parsed tree
|
||||
// produced by this function does not copy any data out of the buffer, but
|
||||
// simply produces references back into it.
|
||||
TORRENT_EXPORT int bdecode(char const* start, char const* end, bdecode_node& ret
|
||||
, error_code& ec, int* error_pos = 0, int depth_limit = 100
|
||||
, int token_limit = 1000000);
|
||||
|
||||
}
|
||||
|
||||
#endif // TORRENT_BDECODE_HPP
|
||||
|
|
@ -51,7 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
||||
// There are two mechanims to *decode* bencoded buffers in libtorrent.
|
||||
//
|
||||
// The most flexible one is bdecode(), which returns a structure
|
||||
// The most flexible one is `bdecode() bencode()`_, which returns a structure
|
||||
// represented by entry. When a buffer is decoded with this function,
|
||||
// it can be discarded. The entry does not contain any references back
|
||||
// to it. This means that bdecode() actually copies all the data out
|
||||
|
@ -59,16 +59,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
// function potentially expensive, if you're parsing large amounts
|
||||
// of data.
|
||||
//
|
||||
// Another consideration is that bdecode() is a recursive parser.
|
||||
// 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 lazy_bdecode(), which returns a
|
||||
// bencoded structure represented by lazy_entry. This function
|
||||
// The second mechanism is bdecode(), which returns a
|
||||
// bencoded structure represented by bdecode_node. This function
|
||||
// builds a tree that points back into the original buffer.
|
||||
// The returned lazy_entry will not be valid once the 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
|
||||
|
@ -391,9 +391,10 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
// These functions will encode data to bencoded_ or decode bencoded_ data.
|
||||
// These functions will encode data to bencoded or decode bencoded data.
|
||||
//
|
||||
// If possible, lazy_bdecode() should be preferred over ``bdecode()``.
|
||||
// If possible, bdecode() and bdecode_node should be preferred over this
|
||||
// function.
|
||||
//
|
||||
// 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
|
||||
|
|
|
@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
// internal
|
||||
inline void cpuid(unsigned int info[4], int type)
|
||||
{
|
||||
#if TORRENT_HAS_SSE && defined _MSC_VER
|
||||
|
|
|
@ -36,7 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/function/function1.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace libtorrent
|
|||
, boost::function<void(disk_io_job const*)> const& handler
|
||||
= boost::function<void(disk_io_job const*)>()) = 0;
|
||||
virtual void async_check_fastresume(piece_manager* storage
|
||||
, lazy_entry const* resume_data
|
||||
, bdecode_node const* resume_data
|
||||
, boost::function<void(disk_io_job const*)> const& handler) = 0;
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
virtual void async_finalize_file(piece_manager*, int file
|
||||
|
|
|
@ -307,7 +307,7 @@ namespace libtorrent
|
|||
void async_delete_files(piece_manager* storage
|
||||
, boost::function<void(disk_io_job const*)> const& handler);
|
||||
void async_check_fastresume(piece_manager* storage
|
||||
, lazy_entry const* resume_data
|
||||
, bdecode_node const* resume_data
|
||||
, boost::function<void(disk_io_job const*)> const& handler);
|
||||
void async_save_resume_data(piece_manager* storage
|
||||
, boost::function<void(disk_io_job const*)> const& handler);
|
||||
|
|
|
@ -76,7 +76,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
struct lazy_entry;
|
||||
#endif
|
||||
struct bdecode_node;
|
||||
|
||||
// thrown by any accessor function of entry if the accessor
|
||||
// function requires a type different than the actual type
|
||||
|
@ -142,7 +145,10 @@ namespace libtorrent
|
|||
|
||||
// copies the structure of the right hand side into this
|
||||
// entry.
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
void operator=(lazy_entry const&);
|
||||
#endif
|
||||
void operator=(bdecode_node const&);
|
||||
void operator=(entry const&);
|
||||
void operator=(dictionary_type const&);
|
||||
void operator=(string_type const&);
|
||||
|
|
|
@ -191,7 +191,7 @@ namespace libtorrent
|
|||
struct peer_request;
|
||||
class peer_connection;
|
||||
class entry;
|
||||
struct lazy_entry;
|
||||
struct bdecode_node;
|
||||
struct disk_buffer_holder;
|
||||
struct bitfield;
|
||||
class alert;
|
||||
|
@ -248,7 +248,7 @@ namespace libtorrent
|
|||
virtual void save_state(entry&) const {}
|
||||
|
||||
// called when loading settings state
|
||||
virtual void load_state(lazy_entry const&) {}
|
||||
virtual void load_state(bdecode_node const&) {}
|
||||
};
|
||||
|
||||
// Torrent plugins are associated with a single torrent and have a number
|
||||
|
@ -387,7 +387,7 @@ namespace libtorrent
|
|||
// supported by this peer. It will result in this peer_plugin
|
||||
// being removed from the peer_connection and destructed.
|
||||
// this is not called for web seeds
|
||||
virtual bool on_extension_handshake(lazy_entry const&) { return true; }
|
||||
virtual bool on_extension_handshake(bdecode_node const&) { return true; }
|
||||
|
||||
// returning true from any of the message handlers
|
||||
// indicates that the plugin has handeled the message.
|
||||
|
|
|
@ -56,7 +56,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent
|
||||
{
|
||||
namespace aux { struct session_impl; }
|
||||
struct lazy_entry;
|
||||
struct counters;
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
struct session_status;
|
||||
|
@ -139,6 +138,11 @@ namespace libtorrent { namespace dht
|
|||
virtual bool send_packet(libtorrent::entry& e, udp::endpoint const& addr
|
||||
, int send_flags);
|
||||
|
||||
// this is the bdecode_node DHT messages are parsed into. It's a member
|
||||
// in order to avoid having to deallocate and re-allocate it for every
|
||||
// message.
|
||||
bdecode_node m_msg;
|
||||
|
||||
counters& m_counters;
|
||||
node_impl m_dht;
|
||||
rate_limited_udp_socket& m_sock;
|
||||
|
|
|
@ -45,7 +45,7 @@ class get_item : public find_data
|
|||
public:
|
||||
typedef boost::function<bool(item&)> data_callback;
|
||||
|
||||
void got_data(lazy_entry const* v,
|
||||
void got_data(bdecode_node const& v,
|
||||
char const* pk,
|
||||
boost::uint64_t seq,
|
||||
char const* sig);
|
||||
|
|
|
@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define LIBTORRENT_ITEM_HPP
|
||||
|
||||
#include <libtorrent/sha1_hash.hpp>
|
||||
#include <libtorrent/lazy_entry.hpp>
|
||||
#include <libtorrent/bdecode.hpp>
|
||||
#include <libtorrent/entry.hpp>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
|
@ -91,7 +91,7 @@ public:
|
|||
item(entry const& v
|
||||
, std::pair<char const*, int> salt
|
||||
, boost::uint64_t seq, char const* pk, char const* sk);
|
||||
item(lazy_entry const* v) { assign(v); }
|
||||
item(bdecode_node const& v) { assign(v); }
|
||||
|
||||
void assign(entry const& v)
|
||||
{
|
||||
|
@ -100,12 +100,12 @@ public:
|
|||
}
|
||||
void assign(entry const& v, std::pair<char const*, int> salt
|
||||
, boost::uint64_t seq, char const* pk, char const* sk);
|
||||
void assign(lazy_entry const* v)
|
||||
void assign(bdecode_node const& v)
|
||||
{
|
||||
assign(v, std::pair<char const*, int>(static_cast<char const*>(NULL)
|
||||
, 0), 0, NULL, NULL);
|
||||
}
|
||||
bool assign(lazy_entry const* v, std::pair<char const*, int> salt
|
||||
bool assign(bdecode_node const& v, std::pair<char const*, int> salt
|
||||
, boost::uint64_t seq, char const* pk, char const* sig);
|
||||
void assign(entry const& v, std::string salt, boost::uint64_t seq
|
||||
, char const* pk, char const* sig);
|
||||
|
|
|
@ -51,9 +51,9 @@ typedef std::vector<tcp::endpoint> peers_t;
|
|||
|
||||
struct msg
|
||||
{
|
||||
msg(lazy_entry const& m, udp::endpoint const& ep): message(m), addr(ep) {}
|
||||
msg(bdecode_node const& m, udp::endpoint const& ep): message(m), addr(ep) {}
|
||||
// the message
|
||||
lazy_entry const& message;
|
||||
bdecode_node const& message;
|
||||
|
||||
// the address of the process sending or receiving
|
||||
// the message.
|
||||
|
|
|
@ -99,8 +99,8 @@ struct key_desc_t
|
|||
};
|
||||
};
|
||||
|
||||
bool TORRENT_EXTRA_EXPORT verify_message(lazy_entry const* msg, key_desc_t const desc[]
|
||||
, lazy_entry const* ret[], int size , char* error, int error_size);
|
||||
bool TORRENT_EXTRA_EXPORT verify_message(bdecode_node const& msg, key_desc_t const desc[]
|
||||
, bdecode_node ret[], int size , char* error, int error_size);
|
||||
|
||||
// this is the entry for every peer
|
||||
// the timestamp is there to make it possible
|
||||
|
|
|
@ -33,6 +33,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_LAZY_ENTRY_HPP_INCLUDED
|
||||
#define TORRENT_LAZY_ENTRY_HPP_INCLUDED
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
@ -41,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/bdecode.hpp" // for error codes
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -50,9 +53,8 @@ namespace libtorrent
|
|||
//
|
||||
// .. _bencoded: http://wiki.theory.org/index.php/BitTorrentSpecification
|
||||
//
|
||||
// Whenever possible, ``lazy_bdecode()`` should be preferred over ``bdecode()``.
|
||||
// It is more efficient and more secure. It supports having constraints on the
|
||||
// amount of memory is consumed by the parser.
|
||||
// The lazy bdecoder and lazy_entry has been deprecated in favour of
|
||||
// bdecode_node and its corresponding bdecode() function.
|
||||
//
|
||||
// *lazy* refers to the fact that it doesn't copy any actual data out of the
|
||||
// bencoded buffer. It builds a tree of ``lazy_entry`` which has pointers into
|
||||
|
@ -79,9 +81,10 @@ namespace libtorrent
|
|||
// in case the function fails. ``error_pos`` is an optional pointer to an int,
|
||||
// which will be set to the byte offset into the buffer where an error occurred,
|
||||
// in case the function fails.
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end
|
||||
, lazy_entry& ret, error_code& ec, int* error_pos = 0
|
||||
, int depth_limit = 1000, int item_limit = 1000000);
|
||||
, int depth_limit = 1000, int item_limit = 1000000) TORRENT_DEPRECATED;
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
// for backwards compatibility, does not report error code
|
||||
|
@ -392,63 +395,21 @@ namespace libtorrent
|
|||
lazy_entry val;
|
||||
};
|
||||
|
||||
// print the bencoded structure in a human-readable format to a stting
|
||||
// print the bencoded structure in a human-readable format to a string
|
||||
// that's returned.
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
TORRENT_EXPORT std::string print_entry(lazy_entry const& e
|
||||
, bool single_line = false, int indent = 0);
|
||||
|
||||
// get the ``error_category`` for bdecode errors
|
||||
TORRENT_EXPORT boost::system::error_category& get_bdecode_category();
|
||||
|
||||
namespace bdecode_errors
|
||||
{
|
||||
// libtorrent uses boost.system's ``error_code`` class to represent errors. libtorrent has
|
||||
// its own error category get_bdecode_category() whith the error codes defined by error_code_enum.
|
||||
enum error_code_enum
|
||||
{
|
||||
// Not an error
|
||||
no_error = 0,
|
||||
// expected string in bencoded string
|
||||
expected_string,
|
||||
// expected colon in bencoded string
|
||||
expected_colon,
|
||||
// unexpected end of file in bencoded string
|
||||
unexpected_eof,
|
||||
// expected value (list, dict, int or string) in bencoded string
|
||||
expected_value,
|
||||
// bencoded recursion depth limit exceeded
|
||||
depth_exceeded,
|
||||
// bencoded item count limit exceeded
|
||||
limit_exceeded,
|
||||
// integer overflow
|
||||
overflow,
|
||||
|
||||
// the number of error codes
|
||||
error_code_max
|
||||
};
|
||||
|
||||
// hidden
|
||||
TORRENT_EXPORT boost::system::error_code make_error_code(error_code_enum e);
|
||||
}
|
||||
, bool single_line = false, int indent = 0) TORRENT_DEPRECATED;
|
||||
|
||||
// defined in bdecode.cpp
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
TORRENT_EXTRA_EXPORT char const* parse_int(char const* start
|
||||
, char const* end, char delimiter, boost::int64_t& val
|
||||
, bdecode_errors::error_code_enum& ec);
|
||||
, bdecode_errors::error_code_enum& ec) TORRENT_DEPRECATED;
|
||||
|
||||
}
|
||||
|
||||
#if BOOST_VERSION >= 103500
|
||||
|
||||
namespace boost { namespace system {
|
||||
|
||||
template<> struct is_error_code_enum<libtorrent::bdecode_errors::error_code_enum>
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<> struct is_error_condition_enum<libtorrent::bdecode_errors::error_code_enum>
|
||||
{ static const bool value = true; };
|
||||
} }
|
||||
|
||||
#endif
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ namespace libtorrent
|
|||
|
||||
int next_update(time_t now) const;
|
||||
|
||||
void load_state(lazy_entry const& rd);
|
||||
void load_state(bdecode_node const& rd);
|
||||
void save_state(entry& rd) const;
|
||||
|
||||
// private:
|
||||
|
|
|
@ -311,14 +311,14 @@ namespace libtorrent
|
|||
// to the ``entry`` that's passed in, which needs to either not be
|
||||
// initialized, or initialized as a dictionary.
|
||||
//
|
||||
// ``load_state`` expects a lazy_entry which can be built from a bencoded
|
||||
// buffer with lazy_bdecode().
|
||||
// ``load_state`` expects a bdecode_node which can be built from a bencoded
|
||||
// buffer with bdecode().
|
||||
//
|
||||
// The ``flags`` arguments passed in to ``save_state`` can be used to
|
||||
// filter which parts of the session state to save. By default, all state
|
||||
// is saved (except for the individual torrents). see save_state_flags_t
|
||||
void save_state(entry& e, boost::uint32_t flags = 0xffffffff) const;
|
||||
void load_state(lazy_entry const& e);
|
||||
void load_state(bdecode_node const& e);
|
||||
|
||||
// .. note::
|
||||
// these calls are potentially expensive and won't scale well with
|
||||
|
@ -735,6 +735,9 @@ namespace libtorrent
|
|||
void load_state(entry const& ses_state) TORRENT_DEPRECATED;
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
entry state() const TORRENT_DEPRECATED;
|
||||
// deprecated in 1.1
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
void load_state(lazy_entry const& ses_state) TORRENT_DEPRECATED;
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
|
||||
// Sets a filter that will be used to reject and accept incoming as well
|
||||
|
|
|
@ -51,9 +51,9 @@ namespace libtorrent
|
|||
namespace aux { struct session_impl; struct session_settings; }
|
||||
|
||||
struct settings_pack;
|
||||
struct lazy_entry;
|
||||
struct bdecode_node;
|
||||
|
||||
TORRENT_EXTRA_EXPORT settings_pack* load_pack_from_dict(lazy_entry const* settings);
|
||||
TORRENT_EXTRA_EXPORT settings_pack* load_pack_from_dict(bdecode_node const& settings);
|
||||
TORRENT_EXTRA_EXPORT void save_settings_to_dict(aux::session_settings const& s, entry::dictionary_type& sett);
|
||||
TORRENT_EXTRA_EXPORT void apply_pack(settings_pack const* pack, aux::session_settings& sett, aux::session_impl* ses = 0);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/address.hpp"
|
||||
#include "libtorrent/io.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/peer_id.hpp" // for sha1_hash
|
||||
#include <string>
|
||||
|
@ -123,20 +123,21 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
template <class EndpointType>
|
||||
void read_endpoint_list(libtorrent::lazy_entry const* n, std::vector<EndpointType>& epl)
|
||||
void read_endpoint_list(libtorrent::bdecode_node const& n
|
||||
, std::vector<EndpointType>& epl)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
if (n->type() != lazy_entry::list_t) return;
|
||||
for (int i = 0; i < n->list_size(); ++i)
|
||||
if (n.type() != bdecode_node::list_t) return;
|
||||
for (int i = 0; i < n.list_size(); ++i)
|
||||
{
|
||||
lazy_entry const* e = n->list_at(i);
|
||||
if (e->type() != lazy_entry::string_t) return;
|
||||
if (e->string_length() < 6) continue;
|
||||
char const* in = e->string_ptr();
|
||||
if (e->string_length() == 6)
|
||||
bdecode_node e = n.list_at(i);
|
||||
if (e.type() != bdecode_node::string_t) return;
|
||||
if (e.string_length() < 6) continue;
|
||||
char const* in = e.string_ptr();
|
||||
if (e.string_length() == 6)
|
||||
epl.push_back(read_v4_endpoint<EndpointType>(in));
|
||||
#if TORRENT_USE_IPV6
|
||||
else if (e->string_length() == 18)
|
||||
else if (e.string_length() == 18)
|
||||
epl.push_back(read_v6_endpoint<EndpointType>(in));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/file_pool.hpp" // pool_file_status
|
||||
#include "libtorrent/part_file.hpp"
|
||||
#include "libtorrent/stat_cache.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/bitfield.hpp"
|
||||
#include "libtorrent/performance_counters.hpp"
|
||||
|
||||
|
@ -115,7 +115,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
// virtual bool rename_file(int file, std::string const& new_name)
|
||||
// { assert(false); return false; }
|
||||
// virtual bool move_storage(std::string const& save_path) { return false; }
|
||||
// virtual bool verify_resume_data(lazy_entry const& rd, storage_error& error) { return false; }
|
||||
// virtual bool verify_resume_data(bdecode_node const& rd, storage_error& error) { return false; }
|
||||
// virtual bool write_resume_data(entry& rd) const { return false; }
|
||||
// virtual boost::int64_t physical_offset(int slot, int offset)
|
||||
// { return slot * m_files.piece_length() + offset; };
|
||||
|
@ -307,7 +307,7 @@ namespace libtorrent
|
|||
// This function should verify the resume data ``rd`` with the files
|
||||
// on disk. If the resume data seems to be up-to-date, return true. If
|
||||
// not, set ``error`` to a description of what mismatched and return false.
|
||||
virtual bool verify_resume_data(lazy_entry const& rd, storage_error& ec) = 0;
|
||||
virtual bool verify_resume_data(bdecode_node const& rd, storage_error& ec) = 0;
|
||||
|
||||
// This function should fill in resume data, the current state of the
|
||||
// storage, in ``rd``. The default storage adds file timestamps and
|
||||
|
@ -423,7 +423,7 @@ namespace libtorrent
|
|||
void initialize(storage_error& ec);
|
||||
int move_storage(std::string const& save_path, int flags, storage_error& ec);
|
||||
int sparse_end(int start) const;
|
||||
bool verify_resume_data(lazy_entry const& rd, storage_error& error);
|
||||
bool verify_resume_data(bdecode_node const& rd, storage_error& error);
|
||||
void write_resume_data(entry& rd, storage_error& ec) const;
|
||||
bool tick();
|
||||
|
||||
|
@ -519,7 +519,7 @@ namespace libtorrent
|
|||
int writev(file::iovec_t const* bufs, int num_bufs, int piece
|
||||
, int offset, int flags, storage_error& ec);
|
||||
|
||||
bool verify_resume_data(lazy_entry const&, storage_error&) { return false; }
|
||||
bool verify_resume_data(bdecode_node const&, storage_error&) { return false; }
|
||||
void write_resume_data(entry&, storage_error&) const {}
|
||||
|
||||
int m_piece_size;
|
||||
|
@ -541,7 +541,7 @@ namespace libtorrent
|
|||
, storage_error&) {}
|
||||
virtual int move_storage(std::string const& /* save_path */
|
||||
, int /* flags */, storage_error&) { return 0; }
|
||||
virtual bool verify_resume_data(lazy_entry const& /* rd */, storage_error&)
|
||||
virtual bool verify_resume_data(bdecode_node const& /* rd */, storage_error&)
|
||||
{ return false; }
|
||||
virtual void write_resume_data(entry&, storage_error&) const {}
|
||||
virtual void release_files(storage_error&) {}
|
||||
|
@ -674,7 +674,7 @@ namespace libtorrent
|
|||
// the error message indicates that the fast resume data was rejected
|
||||
// if 'fatal_disk_error' is returned, the error message indicates what
|
||||
// when wrong in the disk access
|
||||
int check_fastresume(lazy_entry const& rd, storage_error& error);
|
||||
int check_fastresume(bdecode_node const& rd, storage_error& error);
|
||||
|
||||
// helper functions for check_fastresume
|
||||
int check_no_fastresume(storage_error& error);
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace libtorrent
|
|||
struct resume_data_t
|
||||
{
|
||||
std::vector<char> buf;
|
||||
lazy_entry entry;
|
||||
bdecode_node node;
|
||||
};
|
||||
|
||||
struct time_critical_piece
|
||||
|
@ -1019,7 +1019,7 @@ namespace libtorrent
|
|||
torrent_handle get_handle();
|
||||
|
||||
void write_resume_data(entry& rd) const;
|
||||
void read_resume_data(lazy_entry const& rd);
|
||||
void read_resume_data(bdecode_node const& rd);
|
||||
|
||||
void seen_complete() { m_last_seen_complete = time(0); }
|
||||
int time_since_complete() const { return int(time(0) - m_last_seen_complete); }
|
||||
|
|
|
@ -49,7 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
@ -280,10 +280,10 @@ namespace libtorrent
|
|||
// metadata will be created by libtorrent as soon as it has been
|
||||
// downloaded from the swarm.
|
||||
//
|
||||
// The constructor that takes a lazy_entry will create a torrent_info
|
||||
// The constructor that takes a bdecode_node will create a torrent_info
|
||||
// object from the information found in the given torrent_file. The
|
||||
// lazy_entry represents a tree node in an bencoded file. To load an
|
||||
// ordinary .torrent file into a lazy_entry, use lazy_bdecode().
|
||||
// bdecode_node represents a tree node in an bencoded file. To load an
|
||||
// ordinary .torrent file into a bdecode_node, use bdecode().
|
||||
//
|
||||
// The version that takes a buffer pointer and a size will decode it as a
|
||||
// .torrent file and initialize the torrent_info object for you.
|
||||
|
@ -306,7 +306,7 @@ namespace libtorrent
|
|||
//
|
||||
// The ``flags`` argument is currently unused.
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
torrent_info(lazy_entry const& torrent_file, int flags = 0);
|
||||
torrent_info(bdecode_node const& torrent_file, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, int flags = 0);
|
||||
torrent_info(std::string const& filename, int flags = 0);
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
|
@ -317,18 +317,24 @@ namespace libtorrent
|
|||
torrent_info(std::wstring const& filename, int flags = 0) TORRENT_DEPRECATED;
|
||||
#endif // TORRENT_USE_WSTRING
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
#endif
|
||||
#endif // BOOST_NO_EXCEPTIONS
|
||||
torrent_info(torrent_info const& t);
|
||||
torrent_info(sha1_hash const& info_hash, int flags = 0);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags = 0);
|
||||
torrent_info(bdecode_node const& torrent_file, error_code& ec, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, error_code& ec, int flags = 0);
|
||||
torrent_info(std::string const& filename, error_code& ec, int flags = 0);
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
torrent_info(lazy_entry const& torrent_file, int flags = 0) TORRENT_DEPRECATED;
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec
|
||||
, int flags = 0) TORRENT_DEPRECATED;
|
||||
#if TORRENT_USE_WSTRING
|
||||
// all wstring APIs are deprecated since 0.16.11 instead, use the wchar
|
||||
// -> utf8 conversion functions and pass in utf8 strings
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
torrent_info(std::wstring const& filename, error_code& ec, int flags = 0) TORRENT_DEPRECATED;
|
||||
torrent_info(std::wstring const& filename, error_code& ec
|
||||
, int flags = 0) TORRENT_DEPRECATED;
|
||||
#endif // TORRENT_USE_WSTRING
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
|
||||
|
@ -413,6 +419,11 @@ namespace libtorrent
|
|||
std::vector<std::string> url_seeds() const TORRENT_DEPRECATED;
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
std::vector<std::string> http_seeds() const TORRENT_DEPRECATED;
|
||||
|
||||
// deprecated in 1.1
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
bool parse_info_section(lazy_entry const& e, error_code& ec
|
||||
, int flags) TORRENT_DEPRECATED;
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
|
||||
// ``web_seeds()`` returns all url seeds and http seeds in the torrent.
|
||||
|
@ -629,23 +640,23 @@ namespace libtorrent
|
|||
|
||||
// populates the torrent_info by providing just the info-dict buffer.
|
||||
// This is used when loading a torrent from a magnet link for instance,
|
||||
// where we only have the info-dict. The lazy_entry ``e`` points to a
|
||||
// where we only have the info-dict. The bdecode_node ``e`` points to a
|
||||
// parsed info-dictionary. ``ec`` returns an error code if something
|
||||
// fails (typically if the info dictionary is malformed). ``flags`` are
|
||||
// currently unused.
|
||||
bool parse_info_section(lazy_entry const& e, error_code& ec, int flags);
|
||||
bool parse_info_section(bdecode_node const& e, error_code& ec, int flags);
|
||||
|
||||
// This function looks up keys from the info-dictionary of the loaded
|
||||
// torrent file. It can be used to access extension values put in the
|
||||
// .torrent file. If the specified key cannot be found, it returns NULL.
|
||||
lazy_entry const* info(char const* key) const
|
||||
bdecode_node info(char const* key) const
|
||||
{
|
||||
if (m_info_dict.type() == lazy_entry::none_t)
|
||||
if (m_info_dict.type() == bdecode_node::none_t)
|
||||
{
|
||||
error_code ec;
|
||||
lazy_bdecode(m_info_section.get(), m_info_section.get()
|
||||
bdecode(m_info_section.get(), m_info_section.get()
|
||||
+ m_info_section_size, m_info_dict, ec);
|
||||
if (ec) return NULL;
|
||||
if (ec) return bdecode_node();
|
||||
}
|
||||
return m_info_dict.dict_find(key);
|
||||
}
|
||||
|
@ -670,7 +681,7 @@ namespace libtorrent
|
|||
// __ http://bittorrent.org/beps/bep_0030.html
|
||||
bool is_merkle_torrent() const { return !m_merkle_tree.empty(); }
|
||||
|
||||
bool parse_torrent_file(lazy_entry const& libtorrent, error_code& ec, int flags);
|
||||
bool parse_torrent_file(bdecode_node const& libtorrent, error_code& ec, int flags);
|
||||
|
||||
// if we're logging member offsets, we need access to them
|
||||
private:
|
||||
|
@ -726,7 +737,7 @@ namespace libtorrent
|
|||
|
||||
// the info section parsed. points into m_info_section
|
||||
// parsed lazily
|
||||
mutable lazy_entry m_info_dict;
|
||||
mutable bdecode_node m_info_dict;
|
||||
|
||||
// if a creation date is found in the torrent file
|
||||
// this will be set to that, otherwise it'll be
|
||||
|
|
|
@ -43,6 +43,7 @@ libtorrent_rasterbar_la_SOURCES = \
|
|||
bandwidth_limit.cpp \
|
||||
bandwidth_manager.cpp \
|
||||
bandwidth_queue_entry.cpp \
|
||||
bdecode.cpp \
|
||||
bloom_filter.cpp \
|
||||
broadcast_socket.cpp \
|
||||
block_cache.cpp \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1263,9 +1263,9 @@ namespace libtorrent
|
|||
#ifdef TORRENT_LOGGING
|
||||
peer_log("<== HASHPIECE [ piece: %d list: %d ]", p.piece, list_size);
|
||||
#endif
|
||||
lazy_entry hash_list;
|
||||
bdecode_node hash_list;
|
||||
error_code ec;
|
||||
if (lazy_bdecode(recv_buffer.begin + 13, recv_buffer.begin+ 13 + list_size
|
||||
if (bdecode(recv_buffer.begin + 13, recv_buffer.begin+ 13 + list_size
|
||||
, hash_list, ec) != 0)
|
||||
{
|
||||
disconnect(errors::invalid_hash_piece, op_bittorrent, 2);
|
||||
|
@ -1274,7 +1274,7 @@ namespace libtorrent
|
|||
|
||||
// the list has this format:
|
||||
// [ [node-index, hash], [node-index, hash], ... ]
|
||||
if (hash_list.type() != lazy_entry::list_t)
|
||||
if (hash_list.type() != bdecode_node::list_t)
|
||||
{
|
||||
disconnect(errors::invalid_hash_list, op_bittorrent, 2);
|
||||
return;
|
||||
|
@ -1283,15 +1283,15 @@ namespace libtorrent
|
|||
std::map<int, sha1_hash> nodes;
|
||||
for (int i = 0; i < hash_list.list_size(); ++i)
|
||||
{
|
||||
lazy_entry const* e = hash_list.list_at(i);
|
||||
if (e->type() != lazy_entry::list_t
|
||||
|| e->list_size() != 2
|
||||
|| e->list_at(0)->type() != lazy_entry::int_t
|
||||
|| e->list_at(1)->type() != lazy_entry::string_t
|
||||
|| e->list_at(1)->string_length() != 20) continue;
|
||||
bdecode_node e = hash_list.list_at(i);
|
||||
if (e.type() != bdecode_node::list_t
|
||||
|| e.list_size() != 2
|
||||
|| e.list_at(0).type() != bdecode_node::int_t
|
||||
|| e.list_at(1).type() != bdecode_node::string_t
|
||||
|| e.list_at(1).string_length() != 20) continue;
|
||||
|
||||
nodes.insert(std::make_pair(int(e->list_int_value_at(0))
|
||||
, sha1_hash(e->list_at(1)->string_ptr())));
|
||||
nodes.insert(std::make_pair(int(e.list_int_value_at(0))
|
||||
, sha1_hash(e.list_at(1).string_ptr())));
|
||||
}
|
||||
if (!nodes.empty() && !t->add_merkle_nodes(nodes, p.piece))
|
||||
{
|
||||
|
@ -1783,11 +1783,11 @@ namespace libtorrent
|
|||
|
||||
buffer::const_interval recv_buffer = m_recv_buffer.get();
|
||||
|
||||
lazy_entry root;
|
||||
bdecode_node root;
|
||||
error_code ec;
|
||||
int pos;
|
||||
int ret = lazy_bdecode(recv_buffer.begin + 2, recv_buffer.end, root, ec, &pos);
|
||||
if (ret != 0 || ec || root.type() != lazy_entry::dict_t)
|
||||
int ret = bdecode(recv_buffer.begin + 2, recv_buffer.end, root, ec, &pos);
|
||||
if (ret != 0 || ec || root.type() != bdecode_node::dict_t)
|
||||
{
|
||||
#ifdef TORRENT_LOGGING
|
||||
peer_log("*** invalid extended handshake: %s pos: %d"
|
||||
|
@ -1813,11 +1813,11 @@ namespace libtorrent
|
|||
if (is_disconnecting()) return;
|
||||
|
||||
// upload_only
|
||||
if (lazy_entry const* m = root.dict_find_dict("m"))
|
||||
if (bdecode_node m = root.dict_find_dict("m"))
|
||||
{
|
||||
m_upload_only_id = boost::uint8_t(m->dict_find_int_value("upload_only", 0));
|
||||
m_holepunch_id = boost::uint8_t(m->dict_find_int_value("ut_holepunch", 0));
|
||||
m_dont_have_id = boost::uint8_t(m->dict_find_int_value("lt_donthave", 0));
|
||||
m_upload_only_id = boost::uint8_t(m.dict_find_int_value("upload_only", 0));
|
||||
m_holepunch_id = boost::uint8_t(m.dict_find_int_value("ut_holepunch", 0));
|
||||
m_dont_have_id = boost::uint8_t(m.dict_find_int_value("lt_donthave", 0));
|
||||
}
|
||||
|
||||
// there is supposed to be a remote listen port
|
||||
|
|
|
@ -1902,7 +1902,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
void disk_io_thread::async_check_fastresume(piece_manager* storage
|
||||
, lazy_entry const* resume_data
|
||||
, bdecode_node const* resume_data
|
||||
, boost::function<void(disk_io_job const*)> const& handler)
|
||||
{
|
||||
#ifdef TORRENT_DEBUG
|
||||
|
@ -2603,8 +2603,8 @@ namespace libtorrent
|
|||
// if this assert fails, something's wrong with the fence logic
|
||||
TORRENT_ASSERT(j->storage->num_outstanding_jobs() == 1);
|
||||
|
||||
lazy_entry const* rd = (lazy_entry const*)j->buffer;
|
||||
lazy_entry tmp;
|
||||
bdecode_node const* rd = (bdecode_node const*)j->buffer;
|
||||
bdecode_node tmp;
|
||||
if (rd == NULL) rd = &tmp;
|
||||
|
||||
return j->storage->check_fastresume(*rd, j->error);
|
||||
|
|
|
@ -38,7 +38,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/escape_string.hpp"
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#endif
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/escape_string.hpp"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
@ -314,6 +317,44 @@ namespace libtorrent
|
|||
m_type = int_t;
|
||||
}
|
||||
|
||||
// convert a bdecode_node into an old skool entry
|
||||
void entry::operator=(bdecode_node const& e)
|
||||
{
|
||||
switch (e.type())
|
||||
{
|
||||
case bdecode_node::string_t:
|
||||
this->string() = e.string_value();
|
||||
break;
|
||||
case bdecode_node::int_t:
|
||||
this->integer() = e.int_value();
|
||||
break;
|
||||
case bdecode_node::dict_t:
|
||||
{
|
||||
dictionary_type& d = this->dict();
|
||||
for (int i = 0; i < e.dict_size(); ++i)
|
||||
{
|
||||
std::pair<std::string, bdecode_node> elem = e.dict_at(i);
|
||||
d[elem.first] = elem.second;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case bdecode_node::list_t:
|
||||
{
|
||||
list_type& l = this->list();
|
||||
for (int i = 0; i < e.list_size(); ++i)
|
||||
{
|
||||
l.push_back(entry());
|
||||
l.back() = e.list_at(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case bdecode_node::none_t:
|
||||
destruct();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
// convert a lazy_entry into an old skool entry
|
||||
void entry::operator=(lazy_entry const& e)
|
||||
{
|
||||
|
@ -350,6 +391,7 @@ namespace libtorrent
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void entry::operator=(dictionary_type const& v)
|
||||
{
|
||||
|
|
|
@ -377,18 +377,18 @@ namespace libtorrent
|
|||
close();
|
||||
}
|
||||
|
||||
bool extract_peer_info(lazy_entry const& info, peer_entry& ret, error_code& ec)
|
||||
bool extract_peer_info(bdecode_node const& info, peer_entry& ret, error_code& ec)
|
||||
{
|
||||
// extract peer id (if any)
|
||||
if (info.type() != lazy_entry::dict_t)
|
||||
if (info.type() != bdecode_node::dict_t)
|
||||
{
|
||||
ec.assign(errors::invalid_peer_dict, get_libtorrent_category());
|
||||
return false;
|
||||
}
|
||||
lazy_entry const* i = info.dict_find_string("peer id");
|
||||
if (i != 0 && i->string_length() == 20)
|
||||
bdecode_node i = info.dict_find_string("peer id");
|
||||
if (i && i.string_length() == 20)
|
||||
{
|
||||
std::copy(i->string_ptr(), i->string_ptr()+20, ret.pid.begin());
|
||||
std::copy(i.string_ptr(), i.string_ptr()+20, ret.pid.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -403,7 +403,7 @@ namespace libtorrent
|
|||
ec.assign(errors::invalid_tracker_response, get_libtorrent_category());
|
||||
return false;
|
||||
}
|
||||
ret.hostname = i->string_value();
|
||||
ret.hostname = i.string_value();
|
||||
|
||||
// extract port
|
||||
i = info.dict_find_int("port");
|
||||
|
@ -412,7 +412,7 @@ namespace libtorrent
|
|||
ec.assign(errors::invalid_tracker_response, get_libtorrent_category());
|
||||
return false;
|
||||
}
|
||||
ret.port = (unsigned short)i->int_value();
|
||||
ret.port = (unsigned short)i.int_value();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -422,12 +422,12 @@ namespace libtorrent
|
|||
{
|
||||
tracker_response resp;
|
||||
|
||||
lazy_entry e;
|
||||
int res = lazy_bdecode(data, data + size, e, ec);
|
||||
bdecode_node e;
|
||||
int res = bdecode(data, data + size, e, ec);
|
||||
|
||||
if (ec) return resp;
|
||||
|
||||
if (res != 0 || e.type() != lazy_entry::dict_t)
|
||||
if (res != 0 || e.type() != bdecode_node::dict_t)
|
||||
{
|
||||
ec.assign(errors::invalid_tracker_response, get_libtorrent_category());
|
||||
return resp;
|
||||
|
@ -441,45 +441,45 @@ namespace libtorrent
|
|||
resp.interval = interval;
|
||||
resp.min_interval = min_interval;
|
||||
|
||||
lazy_entry const* tracker_id = e.dict_find_string("tracker id");
|
||||
bdecode_node tracker_id = e.dict_find_string("tracker id");
|
||||
if (tracker_id)
|
||||
resp.trackerid = tracker_id->string_value();
|
||||
resp.trackerid = tracker_id.string_value();
|
||||
|
||||
// parse the response
|
||||
lazy_entry const* failure = e.dict_find_string("failure reason");
|
||||
bdecode_node failure = e.dict_find_string("failure reason");
|
||||
if (failure)
|
||||
{
|
||||
resp.failure_reason = failure->string_value();
|
||||
resp.failure_reason = failure.string_value();
|
||||
ec.assign(errors::tracker_failure, get_libtorrent_category());
|
||||
return resp;
|
||||
}
|
||||
|
||||
lazy_entry const* warning = e.dict_find_string("warning message");
|
||||
bdecode_node warning = e.dict_find_string("warning message");
|
||||
if (warning)
|
||||
resp.warning_message = warning->string_value();
|
||||
resp.warning_message = warning.string_value();
|
||||
|
||||
if (scrape_request)
|
||||
{
|
||||
lazy_entry const* files = e.dict_find_dict("files");
|
||||
if (files == 0)
|
||||
bdecode_node files = e.dict_find_dict("files");
|
||||
if (!files)
|
||||
{
|
||||
ec.assign(errors::invalid_files_entry, get_libtorrent_category());
|
||||
return resp;
|
||||
}
|
||||
|
||||
lazy_entry const* scrape_data = files->dict_find_dict(
|
||||
bdecode_node scrape_data = files.dict_find_dict(
|
||||
scrape_ih.to_string());
|
||||
|
||||
if (scrape_data == 0)
|
||||
if (!scrape_data)
|
||||
{
|
||||
ec.assign(errors::invalid_hash_entry, get_libtorrent_category());
|
||||
return resp;
|
||||
}
|
||||
|
||||
resp.complete = int(scrape_data->dict_find_int_value("complete", -1));
|
||||
resp.incomplete = int(scrape_data->dict_find_int_value("incomplete", -1));
|
||||
resp.downloaded = int(scrape_data->dict_find_int_value("downloaded", -1));
|
||||
resp.downloaders = int(scrape_data->dict_find_int_value("downloaders", -1));
|
||||
resp.complete = int(scrape_data.dict_find_int_value("complete", -1));
|
||||
resp.incomplete = int(scrape_data.dict_find_int_value("incomplete", -1));
|
||||
resp.downloaded = int(scrape_data.dict_find_int_value("downloaded", -1));
|
||||
resp.downloaders = int(scrape_data.dict_find_int_value("downloaders", -1));
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
@ -489,11 +489,11 @@ namespace libtorrent
|
|||
resp.incomplete = int(e.dict_find_int_value("incomplete", -1));
|
||||
resp.downloaded = int(e.dict_find_int_value("downloaded", -1));
|
||||
|
||||
lazy_entry const* peers_ent = e.dict_find("peers");
|
||||
if (peers_ent && peers_ent->type() == lazy_entry::string_t)
|
||||
bdecode_node peers_ent = e.dict_find("peers");
|
||||
if (peers_ent && peers_ent.type() == bdecode_node::string_t)
|
||||
{
|
||||
char const* peers = peers_ent->string_ptr();
|
||||
int len = peers_ent->string_length();
|
||||
char const* peers = peers_ent.string_ptr();
|
||||
int len = peers_ent.string_length();
|
||||
resp.peers4.reserve(len / 6);
|
||||
for (int i = 0; i < len; i += 6)
|
||||
{
|
||||
|
@ -506,15 +506,15 @@ namespace libtorrent
|
|||
resp.peers4.push_back(p);
|
||||
}
|
||||
}
|
||||
else if (peers_ent && peers_ent->type() == lazy_entry::list_t)
|
||||
else if (peers_ent && peers_ent.type() == bdecode_node::list_t)
|
||||
{
|
||||
int len = peers_ent->list_size();
|
||||
int len = peers_ent.list_size();
|
||||
resp.peers.reserve(len);
|
||||
error_code parse_error;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
peer_entry p;
|
||||
if (!extract_peer_info(*peers_ent->list_at(i), p, parse_error))
|
||||
if (!extract_peer_info(peers_ent.list_at(i), p, parse_error))
|
||||
continue;
|
||||
resp.peers.push_back(p);
|
||||
}
|
||||
|
@ -528,15 +528,15 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
peers_ent = 0;
|
||||
peers_ent.clear();
|
||||
}
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
lazy_entry const* ipv6_peers = e.dict_find_string("peers6");
|
||||
bdecode_node ipv6_peers = e.dict_find_string("peers6");
|
||||
if (ipv6_peers)
|
||||
{
|
||||
char const* peers = ipv6_peers->string_ptr();
|
||||
int len = ipv6_peers->string_length();
|
||||
char const* peers = ipv6_peers.string_ptr();
|
||||
int len = ipv6_peers.string_length();
|
||||
resp.peers6.reserve(len / 18);
|
||||
for (int i = 0; i < len; i += 18)
|
||||
{
|
||||
|
@ -550,10 +550,10 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
ipv6_peers = 0;
|
||||
ipv6_peers.clear();
|
||||
}
|
||||
#else
|
||||
lazy_entry const* ipv6_peers = 0;
|
||||
bdecode_node ipv6_peers = 0;
|
||||
#endif
|
||||
/*
|
||||
// if we didn't receive any peers. We don't care if we're stopping anyway
|
||||
|
@ -564,14 +564,14 @@ namespace libtorrent
|
|||
return resp;
|
||||
}
|
||||
*/
|
||||
lazy_entry const* ip_ent = e.dict_find_string("external ip");
|
||||
bdecode_node ip_ent = e.dict_find_string("external ip");
|
||||
if (ip_ent)
|
||||
{
|
||||
char const* p = ip_ent->string_ptr();
|
||||
if (ip_ent->string_length() == int(address_v4::bytes_type().size()))
|
||||
char const* p = ip_ent.string_ptr();
|
||||
if (ip_ent.string_length() == int(address_v4::bytes_type().size()))
|
||||
resp.external_ip = detail::read_v4_address(p);
|
||||
#if TORRENT_USE_IPV6
|
||||
else if (ip_ent->string_length() == int(address_v6::bytes_type().size()))
|
||||
else if (ip_ent.string_length() == int(address_v6::bytes_type().size()))
|
||||
resp.external_ip = detail::read_v6_address(p);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -72,9 +72,9 @@ namespace libtorrent { namespace dht
|
|||
void incoming_error(entry& e, char const* msg);
|
||||
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
std::string parse_dht_client(lazy_entry const& e)
|
||||
std::string parse_dht_client(bdecode_node const& e)
|
||||
{
|
||||
lazy_entry const* ver = e.dict_find_string("v");
|
||||
bdecode_node ver = e.dict_find_string("v");
|
||||
if (!ver) return "generic";
|
||||
std::string const& client = ver->string_value();
|
||||
if (client.size() < 2)
|
||||
|
@ -116,12 +116,12 @@ namespace libtorrent { namespace dht
|
|||
TORRENT_DEFINE_LOG(dht_tracker)
|
||||
#endif
|
||||
|
||||
node_id extract_node_id(lazy_entry const* e)
|
||||
node_id extract_node_id(bdecode_node e)
|
||||
{
|
||||
if (e == 0 || e->type() != lazy_entry::dict_t) return (node_id::min)();
|
||||
lazy_entry const* nid = e->dict_find_string("node-id");
|
||||
if (nid == 0 || nid->string_length() != 20) return (node_id::min)();
|
||||
return node_id(node_id(nid->string_ptr()));
|
||||
if (!e || e.type() != bdecode_node::dict_t) return (node_id::min)();
|
||||
bdecode_node nid = e.dict_find_string("node-id");
|
||||
if (!nid || nid.string_length() != 20) return (node_id::min)();
|
||||
return node_id(node_id(nid.string_ptr()));
|
||||
}
|
||||
|
||||
node_id extract_node_id(entry const* e)
|
||||
|
@ -135,7 +135,8 @@ namespace libtorrent { namespace dht
|
|||
|
||||
// class that puts the networking and the kademlia node in a single
|
||||
// unit and connecting them together.
|
||||
dht_tracker::dht_tracker(libtorrent::aux::session_impl& ses, rate_limited_udp_socket& sock
|
||||
dht_tracker::dht_tracker(libtorrent::aux::session_impl& ses
|
||||
, rate_limited_udp_socket& sock
|
||||
, dht_settings const& settings, counters& cnt, entry const* state)
|
||||
: m_counters(cnt)
|
||||
, m_dht(&ses, this, settings, extract_node_id(state)
|
||||
|
@ -391,10 +392,9 @@ namespace libtorrent { namespace dht
|
|||
|
||||
TORRENT_ASSERT(size > 0);
|
||||
|
||||
lazy_entry e;
|
||||
int pos;
|
||||
error_code err;
|
||||
int ret = lazy_bdecode(buf, buf + size, e, err, &pos, 10, 500);
|
||||
int ret = bdecode(buf, buf + size, m_msg, err, &pos, 10, 500);
|
||||
if (ret != 0)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
|
@ -404,9 +404,7 @@ namespace libtorrent { namespace dht
|
|||
return false;
|
||||
}
|
||||
|
||||
libtorrent::dht::msg m(e, ep);
|
||||
|
||||
if (e.type() != lazy_entry::dict_t)
|
||||
if (m_msg.type() != bdecode_node::dict_t)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(dht_tracker) << "<== " << ep << " ERROR: not a dictionary: "
|
||||
|
@ -420,6 +418,7 @@ namespace libtorrent { namespace dht
|
|||
return false;
|
||||
}
|
||||
|
||||
libtorrent::dht::msg m(m_msg, ep);
|
||||
m_dht.incoming(m);
|
||||
return true;
|
||||
}
|
||||
|
@ -503,8 +502,8 @@ namespace libtorrent { namespace dht
|
|||
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
std::stringstream log_line;
|
||||
lazy_entry print;
|
||||
int ret = lazy_bdecode(&m_send_buf[0], &m_send_buf[0] + m_send_buf.size(), print, ec);
|
||||
bdecode_node print;
|
||||
int ret = bdecode(&m_send_buf[0], &m_send_buf[0] + m_send_buf.size(), print, ec);
|
||||
TORRENT_ASSERT(ret == 0);
|
||||
log_line << print_entry(print, true);
|
||||
#endif
|
||||
|
|
|
@ -54,7 +54,7 @@ using detail::read_v6_endpoint;
|
|||
|
||||
void find_data_observer::reply(msg const& m)
|
||||
{
|
||||
lazy_entry const* r = m.message.dict_find_dict("r");
|
||||
bdecode_node r = m.message.dict_find_dict("r");
|
||||
if (!r)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
|
@ -63,19 +63,19 @@ void find_data_observer::reply(msg const& m)
|
|||
return;
|
||||
}
|
||||
|
||||
lazy_entry const* id = r->dict_find_string("id");
|
||||
if (!id || id->string_length() != 20)
|
||||
bdecode_node id = r.dict_find_string("id");
|
||||
if (!id || id.string_length() != 20)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(traversal) << "[" << m_algorithm.get() << "] invalid id in response";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
lazy_entry const* token = r->dict_find_string("token");
|
||||
bdecode_node token = r.dict_find_string("token");
|
||||
if (token)
|
||||
{
|
||||
static_cast<find_data*>(m_algorithm.get())->got_write_token(
|
||||
node_id(id->string_ptr()), token->string_value());
|
||||
node_id(id.string_ptr()), token.string_value());
|
||||
}
|
||||
|
||||
traversal_observer::reply(m);
|
||||
|
|
|
@ -42,7 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent { namespace dht
|
||||
{
|
||||
|
||||
void get_item::got_data(lazy_entry const* v,
|
||||
void get_item::got_data(bdecode_node const& v,
|
||||
char const* pk,
|
||||
boost::uint64_t seq,
|
||||
char const* sig)
|
||||
|
@ -55,7 +55,7 @@ void get_item::got_data(lazy_entry const* v,
|
|||
if (pk)
|
||||
incoming_target = item_target_id(salt, pk);
|
||||
else
|
||||
incoming_target = item_target_id(v->data_section());
|
||||
incoming_target = item_target_id(v.data_section());
|
||||
|
||||
if (incoming_target != m_target) return;
|
||||
|
||||
|
@ -248,7 +248,7 @@ void get_item_observer::reply(msg const& m)
|
|||
char const* sig = NULL;
|
||||
boost::uint64_t seq = 0;
|
||||
|
||||
lazy_entry const* r = m.message.dict_find_dict("r");
|
||||
bdecode_node r = m.message.dict_find_dict("r");
|
||||
if (!r)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
|
@ -257,21 +257,21 @@ void get_item_observer::reply(msg const& m)
|
|||
return;
|
||||
}
|
||||
|
||||
lazy_entry const* k = r->dict_find_string("k");
|
||||
if (k && k->string_length() == item_pk_len)
|
||||
pk = k->string_ptr();
|
||||
bdecode_node k = r.dict_find_string("k");
|
||||
if (k && k.string_length() == item_pk_len)
|
||||
pk = k.string_ptr();
|
||||
|
||||
lazy_entry const* s = r->dict_find_string("sig");
|
||||
if (s && s->string_length() == item_sig_len)
|
||||
sig = s->string_ptr();
|
||||
bdecode_node s = r.dict_find_string("sig");
|
||||
if (s && s.string_length() == item_sig_len)
|
||||
sig = s.string_ptr();
|
||||
|
||||
lazy_entry const* q = r->dict_find_int("seq");
|
||||
bdecode_node q = r.dict_find_int("seq");
|
||||
if (q)
|
||||
seq = q->int_value();
|
||||
seq = q.int_value();
|
||||
else if (pk && sig)
|
||||
return;
|
||||
|
||||
lazy_entry const* v = r->dict_find("v");
|
||||
bdecode_node v = r.dict_find("v");
|
||||
if (v)
|
||||
{
|
||||
static_cast<get_item*>(m_algorithm.get())->got_data(v, pk, seq, sig);
|
||||
|
|
|
@ -47,7 +47,7 @@ using detail::read_v6_endpoint;
|
|||
|
||||
void get_peers_observer::reply(msg const& m)
|
||||
{
|
||||
lazy_entry const* r = m.message.dict_find_dict("r");
|
||||
bdecode_node r = m.message.dict_find_dict("r");
|
||||
if (!r)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
|
@ -57,27 +57,27 @@ void get_peers_observer::reply(msg const& m)
|
|||
}
|
||||
|
||||
// look for peers
|
||||
lazy_entry const* n = r->dict_find_list("values");
|
||||
bdecode_node n = r.dict_find_list("values");
|
||||
if (n)
|
||||
{
|
||||
std::vector<tcp::endpoint> peer_list;
|
||||
if (n->list_size() == 1 && n->list_at(0)->type() == lazy_entry::string_t)
|
||||
if (n.list_size() == 1 && n.list_at(0).type() == bdecode_node::string_t)
|
||||
{
|
||||
// assume it's mainline format
|
||||
char const* peers = n->list_at(0)->string_ptr();
|
||||
char const* end = peers + n->list_at(0)->string_length();
|
||||
char const* peers = n.list_at(0).string_ptr();
|
||||
char const* end = peers + n.list_at(0).string_length();
|
||||
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
lazy_entry const* id = r->dict_find_string("id");
|
||||
if (id && id->string_length() == 20)
|
||||
bdecode_node id = r.dict_find_string("id");
|
||||
if (id && id.string_length() == 20)
|
||||
{
|
||||
TORRENT_LOG(traversal)
|
||||
<< "[" << m_algorithm.get() << "] PEERS"
|
||||
<< " invoke-count: " << m_algorithm->invoke_count()
|
||||
<< " branch-factor: " << m_algorithm->branch_factor()
|
||||
<< " invoke-count: " << m_algorithm.invoke_count()
|
||||
<< " branch-factor: " << m_algorithm.branch_factor()
|
||||
<< " addr: " << m.addr
|
||||
<< " id: " << node_id(id->string_ptr())
|
||||
<< " distance: " << distance_exp(m_algorithm->target(), node_id(id->string_ptr()))
|
||||
<< " id: " << node_id(id.string_ptr())
|
||||
<< " distance: " << distance_exp(m_algorithm.target(), node_id(id.string_ptr()))
|
||||
<< " p: " << ((end - peers) / 6);
|
||||
}
|
||||
#endif
|
||||
|
@ -89,17 +89,17 @@ void get_peers_observer::reply(msg const& m)
|
|||
// assume it's uTorrent/libtorrent format
|
||||
read_endpoint_list<tcp::endpoint>(n, peer_list);
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
lazy_entry const* id = r->dict_find_string("id");
|
||||
if (id && id->string_length() == 20)
|
||||
bdecode_node id = r.dict_find_string("id");
|
||||
if (id && id.string_length() == 20)
|
||||
{
|
||||
TORRENT_LOG(traversal)
|
||||
<< "[" << m_algorithm.get() << "] PEERS"
|
||||
<< " invoke-count: " << m_algorithm->invoke_count()
|
||||
<< " branch-factor: " << m_algorithm->branch_factor()
|
||||
<< " addr: " << m.addr
|
||||
<< " id: " << node_id(id->string_ptr())
|
||||
<< " id: " << node_id(id.string_ptr())
|
||||
<< " distance: " << distance_exp(m_algorithm->target(), node_id(id->string_ptr()))
|
||||
<< " p: " << n->list_size();
|
||||
<< " p: " << n.list_size();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ void obfuscated_get_peers::done()
|
|||
|
||||
void obfuscated_get_peers_observer::reply(msg const& m)
|
||||
{
|
||||
lazy_entry const* r = m.message.dict_find_dict("r");
|
||||
bdecode_node r = m.message.dict_find_dict("r");
|
||||
if (!r)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
|
@ -305,8 +305,8 @@ void obfuscated_get_peers_observer::reply(msg const& m)
|
|||
return;
|
||||
}
|
||||
|
||||
lazy_entry const* id = r->dict_find_string("id");
|
||||
if (!id || id->string_length() != 20)
|
||||
bdecode_node id = r.dict_find_string("id");
|
||||
if (!id || id.string_length() != 20)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(traversal) << "[" << m_algorithm.get()
|
||||
|
|
|
@ -36,7 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <libtorrent/ed25519.hpp>
|
||||
|
||||
#ifdef TORRENT_DEBUG
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_USE_VALGRIND
|
||||
|
@ -54,9 +54,9 @@ namespace
|
|||
{
|
||||
// v must be valid bencoding!
|
||||
#ifdef TORRENT_DEBUG
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
TORRENT_ASSERT(lazy_bdecode(v.first, v.first + v.second, e, ec) == 0);
|
||||
TORRENT_ASSERT(bdecode(v.first, v.first + v.second, e, ec) == 0);
|
||||
#endif
|
||||
char* ptr = out;
|
||||
|
||||
|
@ -185,14 +185,14 @@ void item::assign(entry const& v, std::pair<char const*, int> salt
|
|||
m_mutable = false;
|
||||
}
|
||||
|
||||
bool item::assign(lazy_entry const* v
|
||||
bool item::assign(bdecode_node const& v
|
||||
, std::pair<char const*, int> salt
|
||||
, boost::uint64_t seq, char const* pk, char const* sig)
|
||||
{
|
||||
TORRENT_ASSERT(v->data_section().second <= 1000);
|
||||
TORRENT_ASSERT(v.data_section().second <= 1000);
|
||||
if (pk && sig)
|
||||
{
|
||||
if (!verify_mutable_item(v->data_section(), salt, seq, pk, sig))
|
||||
if (!verify_mutable_item(v.data_section(), salt, seq, pk, sig))
|
||||
return false;
|
||||
memcpy(m_pk.c_array(), pk, item_pk_len);
|
||||
memcpy(m_sig.c_array(), sig, item_sig_len);
|
||||
|
@ -206,7 +206,7 @@ bool item::assign(lazy_entry const* v
|
|||
else
|
||||
m_mutable = false;
|
||||
|
||||
m_value = *v;
|
||||
m_value = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -221,44 +221,44 @@ void node_impl::unreachable(udp::endpoint const& ep)
|
|||
void node_impl::incoming(msg const& m)
|
||||
{
|
||||
// is this a reply?
|
||||
lazy_entry const* y_ent = m.message.dict_find_string("y");
|
||||
if (!y_ent || y_ent->string_length() == 0)
|
||||
bdecode_node y_ent = m.message.dict_find_string("y");
|
||||
if (!y_ent || y_ent.string_length() == 0)
|
||||
{
|
||||
// don't respond to this obviously broken messages. We don't
|
||||
// want to open up a magnification opportunity
|
||||
// entry e;
|
||||
// incoming_error(e, "missing 'y' entry");
|
||||
// m_sock->send_packet(e, m.addr, 0);
|
||||
// m_sock.send_packet(e, m.addr, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
char y = *(y_ent->string_ptr());
|
||||
char y = *(y_ent.string_ptr());
|
||||
|
||||
lazy_entry const* ext_ip = m.message.dict_find_string("ip");
|
||||
bdecode_node ext_ip = m.message.dict_find_string("ip");
|
||||
|
||||
// backwards compatibility
|
||||
if (ext_ip == NULL)
|
||||
if (!ext_ip)
|
||||
{
|
||||
lazy_entry const* r = m.message.dict_find_dict("r");
|
||||
bdecode_node r = m.message.dict_find_dict("r");
|
||||
if (r)
|
||||
ext_ip = r->dict_find_string("ip");
|
||||
ext_ip = r.dict_find_string("ip");
|
||||
}
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
if (ext_ip && ext_ip->string_length() >= 16)
|
||||
if (ext_ip && ext_ip.string_length() >= 16)
|
||||
{
|
||||
// this node claims we use the wrong node-ID!
|
||||
address_v6::bytes_type b;
|
||||
memcpy(&b[0], ext_ip->string_ptr(), 16);
|
||||
memcpy(&b[0], ext_ip.string_ptr(), 16);
|
||||
if (m_observer)
|
||||
m_observer->set_external_address(address_v6(b)
|
||||
, m.addr.address());
|
||||
} else
|
||||
#endif
|
||||
if (ext_ip && ext_ip->string_length() >= 4)
|
||||
if (ext_ip && ext_ip.string_length() >= 4)
|
||||
{
|
||||
address_v4::bytes_type b;
|
||||
memcpy(&b[0], ext_ip->string_ptr(), 4);
|
||||
memcpy(&b[0], ext_ip.string_ptr(), 4);
|
||||
if (m_observer)
|
||||
m_observer->set_external_address(address_v4(b)
|
||||
, m.addr.address());
|
||||
|
@ -283,10 +283,10 @@ void node_impl::incoming(msg const& m)
|
|||
case 'e':
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
lazy_entry const* err = m.message.dict_find_list("e");
|
||||
if (err && err->list_size() >= 2)
|
||||
bdecode_node err = m.message.dict_find_list("e");
|
||||
if (err && err.list_size() >= 2)
|
||||
{
|
||||
TORRENT_LOG(node) << "INCOMING ERROR: " << err->list_string_value_at(1);
|
||||
TORRENT_LOG(node) << "INCOMING ERROR: " << err.list_string_value_at(1);
|
||||
}
|
||||
#endif
|
||||
node_id id;
|
||||
|
@ -419,7 +419,7 @@ struct ping_observer : observer
|
|||
{
|
||||
flags |= flag_done;
|
||||
|
||||
lazy_entry const* r = m.message.dict_find_dict("r");
|
||||
bdecode_node r = m.message.dict_find_dict("r");
|
||||
if (!r)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
|
@ -430,11 +430,11 @@ struct ping_observer : observer
|
|||
}
|
||||
|
||||
// look for nodes
|
||||
lazy_entry const* n = r->dict_find_string("nodes");
|
||||
bdecode_node n = r.dict_find_string("nodes");
|
||||
if (n)
|
||||
{
|
||||
char const* nodes = n->string_ptr();
|
||||
char const* end = nodes + n->string_length();
|
||||
char const* nodes = n.string_ptr();
|
||||
char const* end = nodes + n.string_length();
|
||||
|
||||
while (end - nodes >= 26)
|
||||
{
|
||||
|
@ -674,18 +674,23 @@ using detail::write_nodes_entry;
|
|||
|
||||
// verifies that a message has all the required
|
||||
// entries and returns them in ret
|
||||
bool verify_message(lazy_entry const* msg, key_desc_t const desc[], lazy_entry const* ret[]
|
||||
, int size , char* error, int error_size)
|
||||
bool verify_message(bdecode_node const& message, key_desc_t const desc[]
|
||||
, bdecode_node ret[], int size , char* error, int error_size)
|
||||
{
|
||||
// get a non-root bdecode_node that still
|
||||
// points to the root. message should not be copied
|
||||
bdecode_node msg = message.non_owning();
|
||||
|
||||
// clear the return buffer
|
||||
memset(ret, 0, sizeof(ret[0]) * size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
ret[i].clear();
|
||||
|
||||
// when parsing child nodes, this is the stack
|
||||
// of lazy_entry pointers to return to
|
||||
lazy_entry const* stack[5];
|
||||
// of bdecode_nodes to return to
|
||||
bdecode_node stack[5];
|
||||
int stack_ptr = -1;
|
||||
|
||||
if (msg->type() != lazy_entry::dict_t)
|
||||
if (msg.type() != bdecode_node::dict_t)
|
||||
{
|
||||
snprintf(error, error_size, "not a dictionary");
|
||||
return false;
|
||||
|
@ -698,9 +703,10 @@ bool verify_message(lazy_entry const* msg, key_desc_t const desc[], lazy_entry c
|
|||
|
||||
// fprintf(stderr, "looking for %s in %s\n", k.name, print_entry(*msg).c_str());
|
||||
|
||||
ret[i] = msg->dict_find(k.name);
|
||||
ret[i] = msg.dict_find(k.name);
|
||||
// none_t means any type
|
||||
if (ret[i] && ret[i]->type() != k.type && k.type != lazy_entry::none_t) ret[i] = 0;
|
||||
if (ret[i] && ret[i].type() != k.type && k.type != bdecode_node::none_t)
|
||||
ret[i].clear();
|
||||
if (ret[i] == 0 && (k.flags & key_desc_t::optional) == 0)
|
||||
{
|
||||
// the key was not found, and it's not an optional key
|
||||
|
@ -710,18 +716,18 @@ bool verify_message(lazy_entry const* msg, key_desc_t const desc[], lazy_entry c
|
|||
|
||||
if (k.size > 0
|
||||
&& ret[i]
|
||||
&& k.type == lazy_entry::string_t)
|
||||
&& k.type == bdecode_node::string_t)
|
||||
{
|
||||
bool invalid = false;
|
||||
if (k.flags & key_desc_t::size_divisible)
|
||||
invalid = (ret[i]->string_length() % k.size) != 0;
|
||||
invalid = (ret[i].string_length() % k.size) != 0;
|
||||
else
|
||||
invalid = ret[i]->string_length() != k.size;
|
||||
invalid = ret[i].string_length() != k.size;
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
// the string was not of the required size
|
||||
ret[i] = 0;
|
||||
ret[i].clear();
|
||||
if ((k.flags & key_desc_t::optional) == 0)
|
||||
{
|
||||
snprintf(error, error_size, "invalid value for '%s'", k.name);
|
||||
|
@ -731,7 +737,7 @@ bool verify_message(lazy_entry const* msg, key_desc_t const desc[], lazy_entry c
|
|||
}
|
||||
if (k.flags & key_desc_t::parse_children)
|
||||
{
|
||||
TORRENT_ASSERT(k.type == lazy_entry::dict_t);
|
||||
TORRENT_ASSERT(k.type == bdecode_node::dict_t);
|
||||
|
||||
if (ret[i])
|
||||
{
|
||||
|
@ -805,15 +811,16 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
e["t"] = m.message.dict_find_string_value("t");
|
||||
|
||||
key_desc_t top_desc[] = {
|
||||
{"q", lazy_entry::string_t, 0, 0},
|
||||
{"ro", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"a", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"q", bdecode_node::string_t, 0, 0},
|
||||
{"ro", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
{"a", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
lazy_entry const* top_level[4];
|
||||
bdecode_node top_level[4];
|
||||
char error_string[200];
|
||||
if (!verify_message(&m.message, top_desc, top_level, 4, error_string, sizeof(error_string)))
|
||||
if (!verify_message(m.message, top_desc, top_level, 4, error_string
|
||||
, sizeof(error_string)))
|
||||
{
|
||||
incoming_error(e, error_string);
|
||||
return;
|
||||
|
@ -821,11 +828,12 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
|
||||
e["ip"] = endpoint_to_bytes(m.addr);
|
||||
|
||||
char const* query = top_level[0]->string_cstr();
|
||||
char const* query = top_level[0].string_ptr();
|
||||
int query_len = top_level[0].string_length();
|
||||
|
||||
lazy_entry const* arg_ent = top_level[2];
|
||||
bool read_only = top_level[1] && top_level[1]->int_value() != 0;
|
||||
node_id id(top_level[3]->string_ptr());
|
||||
bdecode_node arg_ent = top_level[2];
|
||||
bool read_only = top_level[1] && top_level[1].int_value() != 0;
|
||||
node_id id(top_level[3].string_ptr());
|
||||
|
||||
// if this nodes ID doesn't match its IP, tell it what
|
||||
// its IP is with an error
|
||||
|
@ -845,21 +853,21 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
// mirror back the other node's external port
|
||||
reply["p"] = m.addr.port();
|
||||
|
||||
if (strcmp(query, "ping") == 0)
|
||||
if (query_len == 4 && memcmp(query, "ping", 4) == 0)
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_ping_in);
|
||||
// we already have 't' and 'id' in the response
|
||||
// no more left to add
|
||||
}
|
||||
else if (strcmp(query, "get_peers") == 0)
|
||||
else if (query_len == 9 && memcmp(query, "get_peers", 9) == 0)
|
||||
{
|
||||
key_desc_t msg_desc[] = {
|
||||
{"info_hash", lazy_entry::string_t, 20, 0},
|
||||
{"noseed", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"scrape", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"info_hash", bdecode_node::string_t, 20, 0},
|
||||
{"noseed", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
{"scrape", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
};
|
||||
|
||||
lazy_entry const* msg_keys[3];
|
||||
bdecode_node msg_keys[3];
|
||||
if (!verify_message(arg_ent, msg_desc, msg_keys, 3, error_string
|
||||
, sizeof(error_string)))
|
||||
{
|
||||
|
@ -868,11 +876,11 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
return;
|
||||
}
|
||||
|
||||
reply["token"] = generate_token(m.addr, msg_keys[0]->string_ptr());
|
||||
reply["token"] = generate_token(m.addr, msg_keys[0].string_ptr());
|
||||
|
||||
m_counters.inc_stats_counter(counters::dht_get_peers_in);
|
||||
|
||||
sha1_hash info_hash(msg_keys[0]->string_ptr());
|
||||
sha1_hash info_hash(msg_keys[0].string_ptr());
|
||||
nodes_t n;
|
||||
// always return nodes as well as peers
|
||||
m_table.find_node(info_hash, n, 0);
|
||||
|
@ -880,8 +888,8 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
|
||||
bool noseed = false;
|
||||
bool scrape = false;
|
||||
if (msg_keys[1] && msg_keys[1]->int_value() != 0) noseed = true;
|
||||
if (msg_keys[2] && msg_keys[2]->int_value() != 0) scrape = true;
|
||||
if (msg_keys[1] && msg_keys[1].int_value() != 0) noseed = true;
|
||||
if (msg_keys[2] && msg_keys[2].int_value() != 0) scrape = true;
|
||||
lookup_peers(info_hash, reply, noseed, scrape);
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
if (reply.find_key("values"))
|
||||
|
@ -890,13 +898,13 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(query, "find_node") == 0)
|
||||
else if (query_len == 9 && memcmp(query, "find_node", 9) == 0)
|
||||
{
|
||||
key_desc_t msg_desc[] = {
|
||||
{"target", lazy_entry::string_t, 20, 0},
|
||||
{"target", bdecode_node::string_t, 20, 0},
|
||||
};
|
||||
|
||||
lazy_entry const* msg_keys[1];
|
||||
bdecode_node msg_keys[1];
|
||||
if (!verify_message(arg_ent, msg_desc, msg_keys, 1, error_string, sizeof(error_string)))
|
||||
{
|
||||
incoming_error(e, error_string);
|
||||
|
@ -904,25 +912,25 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
}
|
||||
|
||||
m_counters.inc_stats_counter(counters::dht_find_node_in);
|
||||
sha1_hash target(msg_keys[0]->string_ptr());
|
||||
sha1_hash target(msg_keys[0].string_ptr());
|
||||
|
||||
// TODO: 2 find_node should write directly to the response entry
|
||||
nodes_t n;
|
||||
m_table.find_node(target, n, 0);
|
||||
write_nodes_entry(reply, n);
|
||||
}
|
||||
else if (strcmp(query, "announce_peer") == 0)
|
||||
else if (query_len == 13 && memcmp(query, "announce_peer", 13) == 0)
|
||||
{
|
||||
key_desc_t msg_desc[] = {
|
||||
{"info_hash", lazy_entry::string_t, 20, 0},
|
||||
{"port", lazy_entry::int_t, 0, 0},
|
||||
{"token", lazy_entry::string_t, 0, 0},
|
||||
{"n", lazy_entry::string_t, 0, key_desc_t::optional},
|
||||
{"seed", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"implied_port", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"info_hash", bdecode_node::string_t, 20, 0},
|
||||
{"port", bdecode_node::int_t, 0, 0},
|
||||
{"token", bdecode_node::string_t, 0, 0},
|
||||
{"n", bdecode_node::string_t, 0, key_desc_t::optional},
|
||||
{"seed", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
{"implied_port", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
};
|
||||
|
||||
lazy_entry const* msg_keys[6];
|
||||
bdecode_node msg_keys[6];
|
||||
if (!verify_message(arg_ent, msg_desc, msg_keys, 6, error_string, sizeof(error_string)))
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_announce);
|
||||
|
@ -930,11 +938,11 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
return;
|
||||
}
|
||||
|
||||
int port = int(msg_keys[1]->int_value());
|
||||
int port = int(msg_keys[1].int_value());
|
||||
|
||||
// is the announcer asking to ignore the explicit
|
||||
// listen port and instead use the source port of the packet?
|
||||
if (msg_keys[5] && msg_keys[5]->int_value() != 0)
|
||||
if (msg_keys[5] && msg_keys[5].int_value() != 0)
|
||||
port = m.addr.port();
|
||||
|
||||
if (port < 0 || port >= 65536)
|
||||
|
@ -944,7 +952,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
return;
|
||||
}
|
||||
|
||||
sha1_hash info_hash(msg_keys[0]->string_ptr());
|
||||
sha1_hash info_hash(msg_keys[0].string_ptr());
|
||||
|
||||
if (m_post_alert)
|
||||
{
|
||||
|
@ -952,7 +960,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
if (!m_post_alert->post_alert(a)) delete a;
|
||||
}
|
||||
|
||||
if (!verify_token(msg_keys[2]->string_value(), msg_keys[0]->string_ptr(), m.addr))
|
||||
if (!verify_token(msg_keys[2].string_value(), msg_keys[0].string_ptr(), m.addr))
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_announce);
|
||||
incoming_error(e, "invalid token");
|
||||
|
@ -1001,7 +1009,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
// for this torrent. Store it.
|
||||
if (msg_keys[3] && v->name.empty())
|
||||
{
|
||||
std::string name = msg_keys[3]->string_value();
|
||||
std::string name = msg_keys[3].string_value();
|
||||
if (name.size() > 50) name.resize(50);
|
||||
v->name = name;
|
||||
}
|
||||
|
@ -1009,28 +1017,28 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
peer_entry peer;
|
||||
peer.addr = tcp::endpoint(m.addr.address(), port);
|
||||
peer.added = aux::time_now();
|
||||
peer.seed = msg_keys[4] && msg_keys[4]->int_value();
|
||||
peer.seed = msg_keys[4] && msg_keys[4].int_value();
|
||||
std::set<peer_entry>::iterator i = v->peers.find(peer);
|
||||
if (i != v->peers.end()) v->peers.erase(i++);
|
||||
v->peers.insert(i, peer);
|
||||
}
|
||||
else if (strcmp(query, "put") == 0)
|
||||
else if (query_len == 3 && memcmp(query, "put", 3) == 0)
|
||||
{
|
||||
// the first 2 entries are for both mutable and
|
||||
// immutable puts
|
||||
const static key_desc_t msg_desc[] = {
|
||||
{"token", lazy_entry::string_t, 0, 0},
|
||||
{"v", lazy_entry::none_t, 0, 0},
|
||||
{"seq", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"token", bdecode_node::string_t, 0, 0},
|
||||
{"v", bdecode_node::none_t, 0, 0},
|
||||
{"seq", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
// public key
|
||||
{"k", lazy_entry::string_t, item_pk_len, key_desc_t::optional},
|
||||
{"sig", lazy_entry::string_t, item_sig_len, key_desc_t::optional},
|
||||
{"cas", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"salt", lazy_entry::string_t, 0, key_desc_t::optional},
|
||||
{"k", bdecode_node::string_t, item_pk_len, key_desc_t::optional},
|
||||
{"sig", bdecode_node::string_t, item_sig_len, key_desc_t::optional},
|
||||
{"cas", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
{"salt", bdecode_node::string_t, 0, key_desc_t::optional},
|
||||
};
|
||||
|
||||
// attempt to parse the message
|
||||
lazy_entry const* msg_keys[7];
|
||||
bdecode_node msg_keys[7];
|
||||
if (!verify_message(arg_ent, msg_desc, msg_keys, 7, error_string, sizeof(error_string)))
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_put);
|
||||
|
@ -1045,14 +1053,14 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
|
||||
// public key (only set if it's a mutable put)
|
||||
char const* pk = NULL;
|
||||
if (msg_keys[3]) pk = msg_keys[3]->string_ptr();
|
||||
if (msg_keys[3]) pk = msg_keys[3].string_ptr();
|
||||
|
||||
// signature (only set if it's a mutable put)
|
||||
char const* sig = NULL;
|
||||
if (msg_keys[4]) sig = msg_keys[4]->string_ptr();
|
||||
if (msg_keys[4]) sig = msg_keys[4].string_ptr();
|
||||
|
||||
// pointer and length to the whole entry
|
||||
std::pair<char const*, int> buf = msg_keys[1]->data_section();
|
||||
std::pair<char const*, int> buf = msg_keys[1].data_section();
|
||||
if (buf.second > 1000 || buf.second <= 0)
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_put);
|
||||
|
@ -1063,7 +1071,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
std::pair<char const*, int> salt(static_cast<char const*>(NULL), 0);
|
||||
if (msg_keys[6])
|
||||
salt = std::pair<char const*, int>(
|
||||
msg_keys[6]->string_ptr(), msg_keys[6]->string_length());
|
||||
msg_keys[6].string_ptr(), msg_keys[6].string_length());
|
||||
if (salt.second > 64)
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_put);
|
||||
|
@ -1085,7 +1093,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
|
||||
// verify the write-token. tokens are only valid to write to
|
||||
// specific target hashes. it must match the one we got a "get" for
|
||||
if (!verify_token(msg_keys[0]->string_value(), (char const*)&target[0], m.addr))
|
||||
if (!verify_token(msg_keys[0].string_value(), (char const*)&target[0], m.addr))
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_put);
|
||||
incoming_error(e, "invalid token");
|
||||
|
@ -1133,12 +1141,12 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
// mutable put, we must verify the signature
|
||||
|
||||
#ifdef TORRENT_USE_VALGRIND
|
||||
VALGRIND_CHECK_MEM_IS_DEFINED(msg_keys[4]->string_ptr(), item_sig_len);
|
||||
VALGRIND_CHECK_MEM_IS_DEFINED(msg_keys[4].string_ptr(), item_sig_len);
|
||||
VALGRIND_CHECK_MEM_IS_DEFINED(pk, item_pk_len);
|
||||
#endif
|
||||
// msg_keys[4] is the signature, msg_keys[3] is the public key
|
||||
if (!verify_mutable_item(buf, salt
|
||||
, msg_keys[2]->int_value(), pk, sig))
|
||||
, msg_keys[2].int_value(), pk, sig))
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_put);
|
||||
incoming_error(e, "invalid signature", 206);
|
||||
|
@ -1167,7 +1175,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
dht_mutable_item to_add;
|
||||
to_add.value = (char*)malloc(buf.second);
|
||||
to_add.size = buf.second;
|
||||
to_add.seq = msg_keys[2]->int_value();
|
||||
to_add.seq = msg_keys[2].int_value();
|
||||
to_add.salt = NULL;
|
||||
to_add.salt_size = 0;
|
||||
if (salt.second > 0)
|
||||
|
@ -1177,7 +1185,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
memcpy(to_add.salt, salt.first, salt.second);
|
||||
}
|
||||
memcpy(to_add.sig, sig, sizeof(to_add.sig));
|
||||
TORRENT_ASSERT(sizeof(to_add.sig) == msg_keys[4]->string_length());
|
||||
TORRENT_ASSERT(sizeof(to_add.sig) == msg_keys[4].string_length());
|
||||
memcpy(to_add.value, buf.first, buf.second);
|
||||
memcpy(&to_add.key, pk, sizeof(to_add.key));
|
||||
|
||||
|
@ -1197,21 +1205,21 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
// number matches the expected value before replacing it
|
||||
// this is critical for avoiding race conditions when multiple
|
||||
// writers are accessing the same slot
|
||||
if (msg_keys[5] && item->seq != msg_keys[5]->int_value())
|
||||
if (msg_keys[5] && item->seq != msg_keys[5].int_value())
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_put);
|
||||
incoming_error(e, "CAS mismatch", 301);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->seq > boost::uint64_t(msg_keys[2]->int_value()))
|
||||
if (item->seq > boost::uint64_t(msg_keys[2].int_value()))
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_invalid_put);
|
||||
incoming_error(e, "old sequence number", 302);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->seq < boost::uint64_t(msg_keys[2]->int_value()))
|
||||
if (item->seq < boost::uint64_t(msg_keys[2].int_value()))
|
||||
{
|
||||
if (item->size != buf.second)
|
||||
{
|
||||
|
@ -1219,9 +1227,9 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
item->value = (char*)malloc(buf.second);
|
||||
item->size = buf.second;
|
||||
}
|
||||
item->seq = msg_keys[2]->int_value();
|
||||
memcpy(item->sig, msg_keys[4]->string_ptr(), sizeof(item->sig));
|
||||
TORRENT_ASSERT(sizeof(item->sig) == msg_keys[4]->string_length());
|
||||
item->seq = msg_keys[2].int_value();
|
||||
memcpy(item->sig, msg_keys[4].string_ptr(), sizeof(item->sig));
|
||||
TORRENT_ASSERT(sizeof(item->sig) == msg_keys[4].string_length());
|
||||
memcpy(item->value, buf.first, buf.second);
|
||||
}
|
||||
}
|
||||
|
@ -1242,17 +1250,17 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
++f->num_announcers;
|
||||
}
|
||||
}
|
||||
else if (strcmp(query, "get") == 0)
|
||||
else if (query_len == 3 && memcmp(query, "get", 3) == 0)
|
||||
{
|
||||
key_desc_t msg_desc[] = {
|
||||
{"seq", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"target", lazy_entry::string_t, 20, 0},
|
||||
{"seq", bdecode_node::int_t, 0, key_desc_t::optional},
|
||||
{"target", bdecode_node::string_t, 20, 0},
|
||||
};
|
||||
|
||||
// k is not used for now
|
||||
|
||||
// attempt to parse the message
|
||||
lazy_entry const* msg_keys[2];
|
||||
bdecode_node msg_keys[2];
|
||||
if (!verify_message(arg_ent, msg_desc, msg_keys, 2, error_string
|
||||
, sizeof(error_string)))
|
||||
{
|
||||
|
@ -1262,13 +1270,13 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
}
|
||||
|
||||
m_counters.inc_stats_counter(counters::dht_get_in);
|
||||
sha1_hash target(msg_keys[1]->string_ptr());
|
||||
sha1_hash target(msg_keys[1].string_ptr());
|
||||
|
||||
// fprintf(stderr, "%s GET target: %s\n"
|
||||
// , msg_keys[1] ? "mutable":"immutable"
|
||||
// , to_hex(target.to_string()).c_str());
|
||||
|
||||
reply["token"] = generate_token(m.addr, msg_keys[1]->string_ptr());
|
||||
reply["token"] = generate_token(m.addr, msg_keys[1].string_ptr());
|
||||
|
||||
nodes_t n;
|
||||
// always return nodes as well as peers
|
||||
|
@ -1294,7 +1302,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
{
|
||||
dht_mutable_item const& f = i->second;
|
||||
reply["seq"] = f.seq;
|
||||
if (!msg_keys[0] || boost::uint64_t(msg_keys[0]->int_value()) < f.seq)
|
||||
if (!msg_keys[0] || boost::uint64_t(msg_keys[0].int_value()) < f.seq)
|
||||
{
|
||||
reply["v"] = bdecode(f.value, f.value + f.size);
|
||||
reply["sig"] = std::string(f.sig, f.sig + sizeof(f.sig));
|
||||
|
@ -1308,18 +1316,18 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||
// if we don't recognize the message but there's a
|
||||
// 'target' or 'info_hash' in the arguments, treat it
|
||||
// as find_node to be future compatible
|
||||
lazy_entry const* target_ent = arg_ent->dict_find_string("target");
|
||||
if (target_ent == 0 || target_ent->string_length() != 20)
|
||||
bdecode_node target_ent = arg_ent.dict_find_string("target");
|
||||
if (!target_ent || target_ent.string_length() != 20)
|
||||
{
|
||||
target_ent = arg_ent->dict_find_string("info_hash");
|
||||
if (target_ent == 0 || target_ent->string_length() != 20)
|
||||
target_ent = arg_ent.dict_find_string("info_hash");
|
||||
if (!target_ent || target_ent.string_length() != 20)
|
||||
{
|
||||
incoming_error(e, "unknown message");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sha1_hash target(target_ent->string_ptr());
|
||||
sha1_hash target(target_ent.string_ptr());
|
||||
nodes_t n;
|
||||
// always return nodes as well as peers
|
||||
m_table.find_node(target, n, 0);
|
||||
|
|
|
@ -324,13 +324,13 @@ bool rpc_manager::incoming(msg const& m, node_id* id, libtorrent::dht_settings c
|
|||
<< std::endl;
|
||||
#endif
|
||||
|
||||
lazy_entry const* ret_ent = m.message.dict_find_dict("r");
|
||||
if (ret_ent == 0)
|
||||
bdecode_node ret_ent = m.message.dict_find_dict("r");
|
||||
if (!ret_ent)
|
||||
{
|
||||
// it may be an error
|
||||
ret_ent = m.message.dict_find("e");
|
||||
o->timeout();
|
||||
if (ret_ent == NULL)
|
||||
if (!ret_ent)
|
||||
{
|
||||
entry e;
|
||||
incoming_error(e, "missing 'r' key");
|
||||
|
@ -339,8 +339,8 @@ bool rpc_manager::incoming(msg const& m, node_id* id, libtorrent::dht_settings c
|
|||
return false;
|
||||
}
|
||||
|
||||
lazy_entry const* node_id_ent = ret_ent->dict_find_string("id");
|
||||
if (node_id_ent == 0 || node_id_ent->string_length() != 20)
|
||||
bdecode_node node_id_ent = ret_ent.dict_find_string("id");
|
||||
if (!node_id_ent || node_id_ent.string_length() != 20)
|
||||
{
|
||||
o->timeout();
|
||||
entry e;
|
||||
|
@ -349,7 +349,7 @@ bool rpc_manager::incoming(msg const& m, node_id* id, libtorrent::dht_settings c
|
|||
return false;
|
||||
}
|
||||
|
||||
node_id nid = node_id(node_id_ent->string_ptr());
|
||||
node_id nid = node_id(node_id_ent.string_ptr());
|
||||
if (settings.enforce_node_id && !verify_id(nid, m.addr.address()))
|
||||
{
|
||||
o->timeout();
|
||||
|
|
|
@ -521,7 +521,7 @@ void traversal_algorithm::status(dht_lookup& l)
|
|||
|
||||
void traversal_observer::reply(msg const& m)
|
||||
{
|
||||
lazy_entry const* r = m.message.dict_find_dict("r");
|
||||
bdecode_node r = m.message.dict_find_dict("r");
|
||||
if (!r)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
|
@ -532,20 +532,20 @@ void traversal_observer::reply(msg const& m)
|
|||
}
|
||||
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
lazy_entry const* nid = r->dict_find_string("id");
|
||||
bdecode_node nid = r.dict_find_string("id");
|
||||
TORRENT_LOG(traversal) << "[" << m_algorithm.get() << "] "
|
||||
"RESPONSE id: " << to_hex(nid->string_value())
|
||||
<< " invoke-count: " << m_algorithm->invoke_count()
|
||||
"RESPONSE id: " << to_hex(nid.string_value())
|
||||
<< " invoke-count: " << m_algorithm.invoke_count()
|
||||
<< " addr: " << m.addr
|
||||
<< " type: " << m_algorithm->name()
|
||||
<< " type: " << m_algorithm.name()
|
||||
;
|
||||
#endif
|
||||
// look for nodes
|
||||
lazy_entry const* n = r->dict_find_string("nodes");
|
||||
bdecode_node n = r.dict_find_string("nodes");
|
||||
if (n)
|
||||
{
|
||||
char const* nodes = n->string_ptr();
|
||||
char const* end = nodes + n->string_length();
|
||||
char const* nodes = n.string_ptr();
|
||||
char const* end = nodes + n.string_length();
|
||||
|
||||
while (end - nodes >= 26)
|
||||
{
|
||||
|
@ -556,8 +556,8 @@ void traversal_observer::reply(msg const& m)
|
|||
}
|
||||
}
|
||||
|
||||
lazy_entry const* id = r->dict_find_string("id");
|
||||
if (!id || id->string_length() != 20)
|
||||
bdecode_node id = r.dict_find_string("id");
|
||||
if (!id || id.string_length() != 20)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(traversal) << "[" << m_algorithm.get() << "] invalid id in response";
|
||||
|
@ -567,7 +567,7 @@ void traversal_observer::reply(msg const& m)
|
|||
|
||||
// in case we didn't know the id of this peer when we sent the message to
|
||||
// it. For instance if it's a bootstrap node.
|
||||
set_id(node_id(id->string_ptr()));
|
||||
set_id(node_id(id.string_ptr()));
|
||||
}
|
||||
|
||||
void traversal_algorithm::abort()
|
||||
|
|
|
@ -30,8 +30,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp" // for error codes
|
||||
#include <cstring>
|
||||
#include <limits> // for numeric_limits
|
||||
|
||||
|
@ -70,40 +73,6 @@ namespace libtorrent
|
|||
|
||||
namespace { bool numeric(char c) { return c >= '0' && c <= '9'; } }
|
||||
|
||||
// fills in 'val' with what the string between start and the
|
||||
// first occurance of the delimiter is interpreted as an int.
|
||||
// return the pointer to the delimiter, or 0 if there is a
|
||||
// parse error. val should be initialized to zero
|
||||
char const* parse_int(char const* start, char const* end, char delimiter
|
||||
, boost::int64_t& val, bdecode_errors::error_code_enum& ec)
|
||||
{
|
||||
while (start < end && *start != delimiter)
|
||||
{
|
||||
if (!numeric(*start))
|
||||
{
|
||||
ec = bdecode_errors::expected_string;
|
||||
return start;
|
||||
}
|
||||
if (val > (std::numeric_limits<boost::int64_t>::max)() / 10)
|
||||
{
|
||||
ec = bdecode_errors::overflow;
|
||||
return start;
|
||||
}
|
||||
val *= 10;
|
||||
int digit = *start - '0';
|
||||
if (val > (std::numeric_limits<boost::int64_t>::max)() - digit)
|
||||
{
|
||||
ec = bdecode_errors::overflow;
|
||||
return start;
|
||||
}
|
||||
val += digit;
|
||||
++start;
|
||||
}
|
||||
if (*start != delimiter)
|
||||
ec = bdecode_errors::expected_colon;
|
||||
return start;
|
||||
}
|
||||
|
||||
char const* find_char(char const* start, char const* end, char delimiter)
|
||||
{
|
||||
while (start < end && *start != delimiter) ++start;
|
||||
|
@ -153,7 +122,7 @@ namespace libtorrent
|
|||
stack.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (!numeric(t)) TORRENT_FAIL_BDECODE(bdecode_errors::expected_string);
|
||||
if (!numeric(t)) TORRENT_FAIL_BDECODE(bdecode_errors::expected_digit);
|
||||
boost::int64_t len = t - '0';
|
||||
bdecode_errors::error_code_enum e = bdecode_errors::no_error;
|
||||
start = parse_int(start, end, ':', len, e);
|
||||
|
@ -382,7 +351,8 @@ namespace libtorrent
|
|||
return e;
|
||||
}
|
||||
|
||||
boost::int64_t lazy_entry::dict_find_int_value(char const* name, boost::int64_t default_val) const
|
||||
boost::int64_t lazy_entry::dict_find_int_value(char const* name
|
||||
, boost::int64_t default_val) const
|
||||
{
|
||||
lazy_entry const* e = dict_find(name);
|
||||
if (e == 0 || e->type() != lazy_entry::int_t) return default_val;
|
||||
|
@ -672,50 +642,7 @@ namespace libtorrent
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct bdecode_error_category : boost::system::error_category
|
||||
{
|
||||
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT;
|
||||
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT;
|
||||
virtual boost::system::error_condition default_error_condition(int ev) const BOOST_SYSTEM_NOEXCEPT
|
||||
{ return boost::system::error_condition(ev, *this); }
|
||||
};
|
||||
|
||||
const char* bdecode_error_category::name() const BOOST_SYSTEM_NOEXCEPT
|
||||
{
|
||||
return "bdecode error";
|
||||
}
|
||||
|
||||
std::string bdecode_error_category::message(int ev) const BOOST_SYSTEM_NOEXCEPT
|
||||
{
|
||||
static char const* msgs[] =
|
||||
{
|
||||
"no error",
|
||||
"expected string in bencoded string",
|
||||
"expected colon in bencoded string",
|
||||
"unexpected end of file in bencoded string",
|
||||
"expected value (list, dict, int or string) in bencoded string",
|
||||
"bencoded nesting depth exceeded",
|
||||
"bencoded item count limit exceeded",
|
||||
"integer overflow",
|
||||
};
|
||||
if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0])))
|
||||
return "Unknown error";
|
||||
return msgs[ev];
|
||||
}
|
||||
|
||||
boost::system::error_category& get_bdecode_category()
|
||||
{
|
||||
static bdecode_error_category bdecode_category;
|
||||
return bdecode_category;
|
||||
}
|
||||
|
||||
namespace bdecode_errors
|
||||
{
|
||||
boost::system::error_code make_error_code(error_code_enum e)
|
||||
{
|
||||
return boost::system::error_code(e, get_bdecode_category());
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
|
||||
|
|
|
@ -167,14 +167,14 @@ namespace libtorrent { namespace
|
|||
}
|
||||
|
||||
// called when the extension handshake from the other end is received
|
||||
virtual bool on_extension_handshake(lazy_entry const& h)
|
||||
virtual bool on_extension_handshake(bdecode_node const& h)
|
||||
{
|
||||
m_message_index = 0;
|
||||
if (h.type() != lazy_entry::dict_t) return false;
|
||||
lazy_entry const* messages = h.dict_find("m");
|
||||
if (!messages || messages->type() != lazy_entry::dict_t) return false;
|
||||
if (h.type() != bdecode_node::dict_t) return false;
|
||||
bdecode_node messages = h.dict_find("m");
|
||||
if (!messages || messages.type() != bdecode_node::dict_t) return false;
|
||||
|
||||
int index = int(messages->dict_find_int_value("lt_tex", -1));
|
||||
int index = int(messages.dict_find_int_value("lt_tex", -1));
|
||||
if (index == -1) return false;
|
||||
m_message_index = index;
|
||||
|
||||
|
@ -196,16 +196,16 @@ namespace libtorrent { namespace
|
|||
if (m_message_index == 0) return false;
|
||||
if (!m_pc.packet_finished()) return true;
|
||||
|
||||
lazy_entry msg;
|
||||
bdecode_node msg;
|
||||
error_code ec;
|
||||
int ret = lazy_bdecode(body.begin, body.end, msg, ec);
|
||||
if (ret != 0 || msg.type() != lazy_entry::dict_t)
|
||||
int ret = bdecode(body.begin, body.end, msg, ec);
|
||||
if (ret != 0 || msg.type() != bdecode_node::dict_t)
|
||||
{
|
||||
m_pc.disconnect(errors::invalid_lt_tracker_message, op_bittorrent, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
lazy_entry const* added = msg.dict_find_list("added");
|
||||
bdecode_node added = msg.dict_find_list("added");
|
||||
|
||||
// invalid tex message
|
||||
if (added == 0)
|
||||
|
@ -231,9 +231,9 @@ namespace libtorrent { namespace
|
|||
"added: ";
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < added->list_size(); ++i)
|
||||
for (int i = 0; i < added.list_size(); ++i)
|
||||
{
|
||||
announce_entry e(added->list_string_value_at(i));
|
||||
announce_entry e(added.list_string_value_at(i));
|
||||
if (e.url.empty()) continue;
|
||||
|
||||
// ignore urls with binary data in them
|
||||
|
|
|
@ -277,14 +277,14 @@ namespace libtorrent { namespace
|
|||
}
|
||||
|
||||
// called when the extension handshake from the other end is received
|
||||
virtual bool on_extension_handshake(lazy_entry const& h)
|
||||
virtual bool on_extension_handshake(bdecode_node const& h)
|
||||
{
|
||||
m_message_index = 0;
|
||||
if (h.type() != lazy_entry::dict_t) return false;
|
||||
lazy_entry const* messages = h.dict_find("m");
|
||||
if (!messages || messages->type() != lazy_entry::dict_t) return false;
|
||||
if (h.type() != bdecode_node::dict_t) return false;
|
||||
bdecode_node messages = h.dict_find("m");
|
||||
if (!messages || messages.type() != bdecode_node::dict_t) return false;
|
||||
|
||||
int index = int(messages->dict_find_int_value("LT_metadata", -1));
|
||||
int index = int(messages.dict_find_int_value("LT_metadata", -1));
|
||||
if (index == -1) return false;
|
||||
m_message_index = index;
|
||||
return true;
|
||||
|
|
46
src/rss.cpp
46
src/rss.cpp
|
@ -398,31 +398,31 @@ void feed::on_feed(error_code const& ec
|
|||
m_ses.update_rss_feeds();
|
||||
}
|
||||
|
||||
void feed::load_state(lazy_entry const& rd)
|
||||
void feed::load_state(bdecode_node const& rd)
|
||||
{
|
||||
m_title = rd.dict_find_string_value("m_title");
|
||||
m_description = rd.dict_find_string_value("m_description");
|
||||
m_last_attempt = rd.dict_find_int_value("m_last_attempt");
|
||||
m_last_update = rd.dict_find_int_value("m_last_update");
|
||||
|
||||
lazy_entry const* e = rd.dict_find_list("items");
|
||||
bdecode_node e = rd.dict_find_list("items");
|
||||
if (e)
|
||||
{
|
||||
m_items.reserve(e->list_size());
|
||||
for (int i = 0; i < e->list_size(); ++i)
|
||||
m_items.reserve(e.list_size());
|
||||
for (int i = 0; i < e.list_size(); ++i)
|
||||
{
|
||||
lazy_entry const* entry = e->list_at(i);
|
||||
if (entry->type() != lazy_entry::dict_t) continue;
|
||||
bdecode_node entry = e.list_at(i);
|
||||
if (entry.type() != bdecode_node::dict_t) continue;
|
||||
|
||||
m_items.push_back(feed_item());
|
||||
feed_item& item = m_items.back();
|
||||
item.url = entry->dict_find_string_value("url");
|
||||
item.uuid = entry->dict_find_string_value("uuid");
|
||||
item.title = entry->dict_find_string_value("title");
|
||||
item.description = entry->dict_find_string_value("description");
|
||||
item.comment = entry->dict_find_string_value("comment");
|
||||
item.category = entry->dict_find_string_value("category");
|
||||
item.size = entry->dict_find_int_value("size");
|
||||
item.url = entry.dict_find_string_value("url");
|
||||
item.uuid = entry.dict_find_string_value("uuid");
|
||||
item.title = entry.dict_find_string_value("title");
|
||||
item.description = entry.dict_find_string_value("description");
|
||||
item.comment = entry.dict_find_string_value("comment");
|
||||
item.category = entry.dict_find_string_value("category");
|
||||
item.size = entry.dict_find_int_value("size");
|
||||
|
||||
// don't load duplicates
|
||||
if (m_urls.find(item.url) != m_urls.end())
|
||||
|
@ -442,27 +442,27 @@ void feed::load_state(lazy_entry const& rd)
|
|||
e = rd.dict_find_dict("add_params");
|
||||
if (e)
|
||||
{
|
||||
m_settings.add_args.save_path = e->dict_find_string_value("save_path");
|
||||
m_settings.add_args.flags = e->dict_find_int_value("flags");
|
||||
m_settings.add_args.save_path = e.dict_find_string_value("save_path");
|
||||
m_settings.add_args.flags = e.dict_find_int_value("flags");
|
||||
}
|
||||
|
||||
e = rd.dict_find_list("history");
|
||||
if (e)
|
||||
{
|
||||
for (int i = 0; i < e->list_size(); ++i)
|
||||
for (int i = 0; i < e.list_size(); ++i)
|
||||
{
|
||||
if (e->list_at(i)->type() != lazy_entry::list_t) continue;
|
||||
if (e.list_at(i).type() != bdecode_node::list_t) continue;
|
||||
|
||||
lazy_entry const* item = e->list_at(i);
|
||||
bdecode_node item = e.list_at(i);
|
||||
|
||||
if (item->list_size() != 2
|
||||
|| item->list_at(0)->type() != lazy_entry::string_t
|
||||
|| item->list_at(1)->type() != lazy_entry::int_t)
|
||||
if (item.list_size() != 2
|
||||
|| item.list_at(0).type() != bdecode_node::string_t
|
||||
|| item.list_at(1).type() != bdecode_node::int_t)
|
||||
continue;
|
||||
|
||||
m_added.insert(std::pair<std::string, time_t>(
|
||||
item->list_at(0)->string_value()
|
||||
, item->list_at(1)->int_value()));
|
||||
item.list_at(0).string_value()
|
||||
, item.list_at(1).int_value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -433,7 +433,7 @@ namespace libtorrent
|
|||
TORRENT_SYNC_CALL2(save_state, &e, flags);
|
||||
}
|
||||
|
||||
void session::load_state(lazy_entry const& e)
|
||||
void session::load_state(bdecode_node const& e)
|
||||
{
|
||||
// this needs to be synchronized since the lifespan
|
||||
// of e is tied to the caller
|
||||
|
@ -494,12 +494,30 @@ namespace libtorrent
|
|||
if (ses_state.type() == entry::undefined_t) return;
|
||||
std::vector<char> buf;
|
||||
bencode(std::back_inserter(buf), ses_state);
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || !defined BOOST_NO_EXCEPTIONS
|
||||
int ret =
|
||||
#endif
|
||||
lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
|
||||
bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
|
||||
|
||||
TORRENT_ASSERT(ret == 0);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
if (ret != 0) throw libtorrent_exception(ec);
|
||||
#endif
|
||||
TORRENT_SYNC_CALL1(load_state, &e);
|
||||
}
|
||||
|
||||
void session::load_state(lazy_entry const& ses_state)
|
||||
{
|
||||
if (ses_state.type() == lazy_entry::none_t) return;
|
||||
std::pair<char const*, int> buf = ses_state.data_section();
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || !defined BOOST_NO_EXCEPTIONS
|
||||
int ret =
|
||||
#endif
|
||||
bdecode(buf.first, buf.first + buf.second, e, ec);
|
||||
|
||||
TORRENT_ASSERT(ret == 0);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
|
|
@ -740,35 +740,35 @@ namespace aux {
|
|||
return proxy_settings(m_settings);
|
||||
}
|
||||
|
||||
void session_impl::load_state(lazy_entry const* e)
|
||||
void session_impl::load_state(bdecode_node const* e)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
lazy_entry const* settings;
|
||||
if (e->type() != lazy_entry::dict_t) return;
|
||||
bdecode_node settings;
|
||||
if (e->type() != bdecode_node::dict_t) return;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// load from the old settings names
|
||||
settings = e->dict_find_dict("dht");
|
||||
if (settings)
|
||||
{
|
||||
lazy_entry const* val;
|
||||
val = settings->dict_find_int("max_peers_reply");
|
||||
if (val) m_dht_settings.max_peers_reply = val->int_value();
|
||||
val = settings->dict_find_int("search_branching");
|
||||
if (val) m_dht_settings.search_branching = val->int_value();
|
||||
val = settings->dict_find_int("max_fail_count");
|
||||
if (val) m_dht_settings.max_fail_count = val->int_value();
|
||||
val = settings->dict_find_int("max_torrents");
|
||||
if (val) m_dht_settings.max_torrents = val->int_value();
|
||||
val = settings->dict_find_int("max_dht_items");
|
||||
if (val) m_dht_settings.max_dht_items = val->int_value();
|
||||
val = settings->dict_find_int("max_torrent_search_reply");
|
||||
if (val) m_dht_settings.max_torrent_search_reply = val->int_value();
|
||||
val = settings->dict_find_int("restrict_routing_ips");
|
||||
if (val) m_dht_settings.restrict_routing_ips = val->int_value();
|
||||
val = settings->dict_find_int("extended_routing_table");
|
||||
if (val) m_dht_settings.extended_routing_table = val->int_value();
|
||||
bdecode_node val;
|
||||
val = settings.dict_find_int("max_peers_reply");
|
||||
if (val) m_dht_settings.max_peers_reply = val.int_value();
|
||||
val = settings.dict_find_int("search_branching");
|
||||
if (val) m_dht_settings.search_branching = val.int_value();
|
||||
val = settings.dict_find_int("max_fail_count");
|
||||
if (val) m_dht_settings.max_fail_count = val.int_value();
|
||||
val = settings.dict_find_int("max_torrents");
|
||||
if (val) m_dht_settings.max_torrents = val.int_value();
|
||||
val = settings.dict_find_int("max_dht_items");
|
||||
if (val) m_dht_settings.max_dht_items = val.int_value();
|
||||
val = settings.dict_find_int("max_torrent_search_reply");
|
||||
if (val) m_dht_settings.max_torrent_search_reply = val.int_value();
|
||||
val = settings.dict_find_int("restrict_routing_ips");
|
||||
if (val) m_dht_settings.restrict_routing_ips = val.int_value();
|
||||
val = settings.dict_find_int("extended_routing_table");
|
||||
if (val) m_dht_settings.extended_routing_table = val.int_value();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -776,35 +776,35 @@ namespace aux {
|
|||
settings = e->dict_find_dict("proxy");
|
||||
if (settings)
|
||||
{
|
||||
lazy_entry const* val;
|
||||
val = settings->dict_find_int("port");
|
||||
if (val) m_settings.set_int(settings_pack::proxy_port, val->int_value());
|
||||
val = settings->dict_find_int("type");
|
||||
if (val) m_settings.set_int(settings_pack::proxy_type, val->int_value());
|
||||
val = settings->dict_find_int("proxy_hostnames");
|
||||
if (val) m_settings.set_bool(settings_pack::proxy_hostnames, val->int_value());
|
||||
val = settings->dict_find_int("proxy_peer_connections");
|
||||
if (val) m_settings.set_bool(settings_pack::proxy_peer_connections, val->int_value());
|
||||
val = settings->dict_find_string("hostname");
|
||||
if (val) m_settings.set_str(settings_pack::proxy_hostname, val->string_value());
|
||||
val = settings->dict_find_string("password");
|
||||
if (val) m_settings.set_str(settings_pack::proxy_password, val->string_value());
|
||||
val = settings->dict_find_string("username");
|
||||
if (val) m_settings.set_str(settings_pack::proxy_username, val->string_value());
|
||||
bdecode_node val;
|
||||
val = settings.dict_find_int("port");
|
||||
if (val) m_settings.set_int(settings_pack::proxy_port, val.int_value());
|
||||
val = settings.dict_find_int("type");
|
||||
if (val) m_settings.set_int(settings_pack::proxy_type, val.int_value());
|
||||
val = settings.dict_find_int("proxy_hostnames");
|
||||
if (val) m_settings.set_bool(settings_pack::proxy_hostnames, val.int_value());
|
||||
val = settings.dict_find_int("proxy_peer_connections");
|
||||
if (val) m_settings.set_bool(settings_pack::proxy_peer_connections, val.int_value());
|
||||
val = settings.dict_find_string("hostname");
|
||||
if (val) m_settings.set_str(settings_pack::proxy_hostname, val.string_value());
|
||||
val = settings.dict_find_string("password");
|
||||
if (val) m_settings.set_str(settings_pack::proxy_password, val.string_value());
|
||||
val = settings.dict_find_string("username");
|
||||
if (val) m_settings.set_str(settings_pack::proxy_username, val.string_value());
|
||||
}
|
||||
|
||||
settings = e->dict_find_dict("encryption");
|
||||
if (settings)
|
||||
{
|
||||
lazy_entry const* val;
|
||||
val = settings->dict_find_int("prefer_rc4");
|
||||
if (val) m_settings.set_bool(settings_pack::prefer_rc4, val->int_value());
|
||||
val = settings->dict_find_int("out_enc_policy");
|
||||
if (val) m_settings.set_int(settings_pack::out_enc_policy, val->int_value());
|
||||
val = settings->dict_find_int("in_enc_policy");
|
||||
if (val) m_settings.set_int(settings_pack::in_enc_policy, val->int_value());
|
||||
val = settings->dict_find_int("allowed_enc_level");
|
||||
if (val) m_settings.set_int(settings_pack::allowed_enc_level, val->int_value());
|
||||
bdecode_node val;
|
||||
val = settings.dict_find_int("prefer_rc4");
|
||||
if (val) m_settings.set_bool(settings_pack::prefer_rc4, val.int_value());
|
||||
val = settings.dict_find_int("out_enc_policy");
|
||||
if (val) m_settings.set_int(settings_pack::out_enc_policy, val.int_value());
|
||||
val = settings.dict_find_int("in_enc_policy");
|
||||
if (val) m_settings.set_int(settings_pack::in_enc_policy, val.int_value());
|
||||
val = settings.dict_find_int("allowed_enc_level");
|
||||
if (val) m_settings.set_int(settings_pack::allowed_enc_level, val.int_value());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -824,19 +824,19 @@ namespace aux {
|
|||
settings = e->dict_find_dict("dht state");
|
||||
if (settings)
|
||||
{
|
||||
m_dht_state = *settings;
|
||||
m_dht_state = settings;
|
||||
}
|
||||
#endif
|
||||
|
||||
settings = e->dict_find_list("feeds");
|
||||
if (settings)
|
||||
{
|
||||
m_feeds.reserve(settings->list_size());
|
||||
for (int i = 0; i < settings->list_size(); ++i)
|
||||
m_feeds.reserve(settings.list_size());
|
||||
for (int i = 0; i < settings.list_size(); ++i)
|
||||
{
|
||||
if (settings->list_at(i)->type() != lazy_entry::dict_t) continue;
|
||||
if (settings.list_at(i).type() != bdecode_node::dict_t) continue;
|
||||
boost::shared_ptr<feed> f(new_feed(*this, feed_settings()));
|
||||
f->load_state(*settings->list_at(i));
|
||||
f->load_state(settings.list_at(i));
|
||||
f->update_feed();
|
||||
m_feeds.push_back(f);
|
||||
}
|
||||
|
@ -4542,14 +4542,14 @@ retry:
|
|||
{
|
||||
int pos;
|
||||
error_code ec;
|
||||
lazy_entry tmp;
|
||||
lazy_entry const* info = 0;
|
||||
bdecode_node tmp;
|
||||
bdecode_node info;
|
||||
#if defined TORRENT_LOGGING
|
||||
session_log("adding magnet link with resume data");
|
||||
#endif
|
||||
if (lazy_bdecode(¶ms.resume_data[0], ¶ms.resume_data[0]
|
||||
if (bdecode(¶ms.resume_data[0], ¶ms.resume_data[0]
|
||||
+ params.resume_data.size(), tmp, ec, &pos) == 0
|
||||
&& tmp.type() == lazy_entry::dict_t
|
||||
&& tmp.type() == bdecode_node::dict_t
|
||||
&& (info = tmp.dict_find_dict("info")))
|
||||
{
|
||||
#if defined TORRENT_LOGGING
|
||||
|
@ -4558,7 +4558,7 @@ retry:
|
|||
// verify the info-hash of the metadata stored in the resume file matches
|
||||
// the torrent we're loading
|
||||
|
||||
std::pair<char const*, int> buf = info->data_section();
|
||||
std::pair<char const*, int> buf = info.data_section();
|
||||
sha1_hash resume_ih = hasher(buf.first, buf.second).final();
|
||||
|
||||
// if url is set, the info_hash is not actually the info-hash of the
|
||||
|
@ -4573,7 +4573,7 @@ retry:
|
|||
#endif
|
||||
params.ti = boost::make_shared<torrent_info>(resume_ih);
|
||||
|
||||
if (params.ti->parse_info_section(*info, ec, 0))
|
||||
if (params.ti->parse_info_section(info, ec, 0))
|
||||
{
|
||||
#if defined TORRENT_LOGGING
|
||||
session_log("successfully loaded metadata from resume file");
|
||||
|
|
|
@ -386,27 +386,27 @@ namespace libtorrent
|
|||
return "";
|
||||
}
|
||||
|
||||
settings_pack* load_pack_from_dict(lazy_entry const* settings)
|
||||
settings_pack* load_pack_from_dict(bdecode_node const& settings)
|
||||
{
|
||||
settings_pack* pack = new settings_pack;
|
||||
|
||||
for (int i = 0; i < settings->dict_size(); ++i)
|
||||
for (int i = 0; i < settings.dict_size(); ++i)
|
||||
{
|
||||
std::string key;
|
||||
lazy_entry const* val;
|
||||
boost::tie(key, val) = settings->dict_at(i);
|
||||
switch (val->type())
|
||||
bdecode_node val;
|
||||
boost::tie(key, val) = settings.dict_at(i);
|
||||
switch (val.type())
|
||||
{
|
||||
case lazy_entry::dict_t:
|
||||
case lazy_entry::list_t:
|
||||
case bdecode_node::dict_t:
|
||||
case bdecode_node::list_t:
|
||||
continue;
|
||||
case lazy_entry::int_t:
|
||||
case bdecode_node::int_t:
|
||||
{
|
||||
bool found = false;
|
||||
for (int k = 0; k < sizeof(int_settings)/sizeof(int_settings[0]); ++k)
|
||||
{
|
||||
if (key != int_settings[k].name) continue;
|
||||
pack->set_int(settings_pack::int_type_base + k, val->int_value());
|
||||
pack->set_int(settings_pack::int_type_base + k, val.int_value());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -414,20 +414,20 @@ namespace libtorrent
|
|||
for (int k = 0; k < sizeof(bool_settings)/sizeof(bool_settings[0]); ++k)
|
||||
{
|
||||
if (key != bool_settings[k].name) continue;
|
||||
pack->set_bool(settings_pack::bool_type_base + k, val->int_value());
|
||||
pack->set_bool(settings_pack::bool_type_base + k, val.int_value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case lazy_entry::string_t:
|
||||
case bdecode_node::string_t:
|
||||
for (int k = 0; k < sizeof(str_settings)/sizeof(str_settings[0]); ++k)
|
||||
{
|
||||
if (key != str_settings[k].name) continue;
|
||||
pack->set_str(settings_pack::string_type_base + k, val->string_value());
|
||||
pack->set_str(settings_pack::string_type_base + k, val.string_value());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case lazy_entry::none_t:
|
||||
case bdecode_node::none_t:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -712,47 +712,47 @@ namespace libtorrent
|
|||
return int((data_start + files().piece_length() - 1) / files().piece_length());
|
||||
}
|
||||
|
||||
bool default_storage::verify_resume_data(lazy_entry const& rd, storage_error& ec)
|
||||
bool default_storage::verify_resume_data(bdecode_node const& rd, storage_error& ec)
|
||||
{
|
||||
// TODO: make this more generic to not just work if files have been
|
||||
// renamed, but also if they have been merged into a single file for instance
|
||||
// maybe use the same format as .torrent files and reuse some code from torrent_info
|
||||
lazy_entry const* mapped_files = rd.dict_find_list("mapped_files");
|
||||
if (mapped_files && mapped_files->list_size() == m_files.num_files())
|
||||
bdecode_node mapped_files = rd.dict_find_list("mapped_files");
|
||||
if (mapped_files && mapped_files.list_size() == m_files.num_files())
|
||||
{
|
||||
m_mapped_files.reset(new file_storage(m_files));
|
||||
for (int i = 0; i < m_files.num_files(); ++i)
|
||||
{
|
||||
std::string new_filename = mapped_files->list_string_value_at(i);
|
||||
std::string new_filename = mapped_files.list_string_value_at(i);
|
||||
if (new_filename.empty()) continue;
|
||||
m_mapped_files->rename_file(i, new_filename);
|
||||
}
|
||||
}
|
||||
|
||||
lazy_entry const* file_priority = rd.dict_find_list("file_priority");
|
||||
if (file_priority && file_priority->list_size()
|
||||
bdecode_node file_priority = rd.dict_find_list("file_priority");
|
||||
if (file_priority && file_priority.list_size()
|
||||
== files().num_files())
|
||||
{
|
||||
m_file_priority.resize(file_priority->list_size());
|
||||
for (int i = 0; i < file_priority->list_size(); ++i)
|
||||
m_file_priority[i] = boost::uint8_t(file_priority->list_int_value_at(i, 1));
|
||||
m_file_priority.resize(file_priority.list_size());
|
||||
for (int i = 0; i < file_priority.list_size(); ++i)
|
||||
m_file_priority[i] = boost::uint8_t(file_priority.list_int_value_at(i, 1));
|
||||
}
|
||||
|
||||
lazy_entry const* file_sizes_ent = rd.dict_find_list("file sizes");
|
||||
bdecode_node file_sizes_ent = rd.dict_find_list("file sizes");
|
||||
if (file_sizes_ent == 0)
|
||||
{
|
||||
ec.ec = errors::missing_file_sizes;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file_sizes_ent->list_size() == 0)
|
||||
if (file_sizes_ent.list_size() == 0)
|
||||
{
|
||||
ec.ec = errors::no_files_in_resume_data;
|
||||
return false;
|
||||
}
|
||||
|
||||
file_storage const& fs = files();
|
||||
if (file_sizes_ent->list_size() != fs.num_files())
|
||||
if (file_sizes_ent.list_size() != fs.num_files())
|
||||
{
|
||||
ec.ec = errors::mismatching_number_of_files;
|
||||
ec.file = -1;
|
||||
|
@ -761,27 +761,27 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
bool seed = false;
|
||||
lazy_entry const* slots = rd.dict_find_list("slots");
|
||||
bdecode_node slots = rd.dict_find_list("slots");
|
||||
if (slots)
|
||||
{
|
||||
if (int(slots->list_size()) == m_files.num_pieces())
|
||||
if (int(slots.list_size()) == m_files.num_pieces())
|
||||
{
|
||||
seed = true;
|
||||
for (int i = 0; i < slots->list_size(); ++i)
|
||||
for (int i = 0; i < slots.list_size(); ++i)
|
||||
{
|
||||
if (slots->list_int_value_at(i, -1) >= 0) continue;
|
||||
if (slots.list_int_value_at(i, -1) >= 0) continue;
|
||||
seed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lazy_entry const* pieces = rd.dict_find_string("pieces"))
|
||||
else if (bdecode_node pieces = rd.dict_find_string("pieces"))
|
||||
{
|
||||
if (int(pieces->string_length()) == m_files.num_pieces())
|
||||
if (int(pieces.string_length()) == m_files.num_pieces())
|
||||
{
|
||||
seed = true;
|
||||
char const* p = pieces->string_ptr();
|
||||
for (int i = 0; i < pieces->string_length(); ++i)
|
||||
char const* p = pieces.string_ptr();
|
||||
for (int i = 0; i < pieces.string_length(); ++i)
|
||||
{
|
||||
if ((p[i] & 1) == 1) continue;
|
||||
seed = false;
|
||||
|
@ -795,14 +795,14 @@ namespace libtorrent
|
|||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < file_sizes_ent->list_size(); ++i)
|
||||
for (int i = 0; i < file_sizes_ent.list_size(); ++i)
|
||||
{
|
||||
if (fs.pad_file_at(i)) continue;
|
||||
lazy_entry const* e = file_sizes_ent->list_at(i);
|
||||
if (e->type() != lazy_entry::list_t
|
||||
|| e->list_size() < 2
|
||||
|| e->list_at(0)->type() != lazy_entry::int_t
|
||||
|| e->list_at(1)->type() != lazy_entry::int_t)
|
||||
bdecode_node e = file_sizes_ent.list_at(i);
|
||||
if (e.type() != bdecode_node::list_t
|
||||
|| e.list_size() < 2
|
||||
|| e.list_at(0).type() != bdecode_node::int_t
|
||||
|| e.list_at(1).type() != bdecode_node::int_t)
|
||||
{
|
||||
ec.ec = errors::missing_file_sizes;
|
||||
ec.file = i;
|
||||
|
@ -810,8 +810,8 @@ namespace libtorrent
|
|||
return false;
|
||||
}
|
||||
|
||||
boost::int64_t expected_size = e->list_int_value_at(0);
|
||||
time_t expected_time = e->list_int_value_at(1);
|
||||
boost::int64_t expected_size = e.list_int_value_at(0);
|
||||
time_t expected_time = e.list_int_value_at(1);
|
||||
|
||||
// if we're a seed, the expected size should match
|
||||
// the actual full size according to the torrent
|
||||
|
@ -1472,14 +1472,14 @@ namespace libtorrent
|
|||
// isn't return false and the full check
|
||||
// will be run
|
||||
int piece_manager::check_fastresume(
|
||||
lazy_entry const& rd, storage_error& ec)
|
||||
bdecode_node const& rd, storage_error& ec)
|
||||
{
|
||||
TORRENT_ASSERT(m_files.piece_length() > 0);
|
||||
|
||||
// if we don't have any resume data, return
|
||||
if (rd.type() == lazy_entry::none_t) return check_no_fastresume(ec);
|
||||
if (rd.type() == bdecode_node::none_t) return check_no_fastresume(ec);
|
||||
|
||||
if (rd.type() != lazy_entry::dict_t)
|
||||
if (rd.type() != bdecode_node::dict_t)
|
||||
{
|
||||
ec.ec = errors::not_a_dictionary;
|
||||
return check_no_fastresume(ec);
|
||||
|
|
169
src/torrent.cpp
169
src/torrent.cpp
|
@ -763,8 +763,8 @@ namespace libtorrent
|
|||
{
|
||||
int pos;
|
||||
error_code ec;
|
||||
if (lazy_bdecode(&m_resume_data->buf[0], &m_resume_data->buf[0]
|
||||
+ m_resume_data->buf.size(), m_resume_data->entry, ec, &pos) != 0)
|
||||
if (bdecode(&m_resume_data->buf[0], &m_resume_data->buf[0]
|
||||
+ m_resume_data->buf.size(), m_resume_data->node, ec, &pos) != 0)
|
||||
{
|
||||
m_resume_data.reset();
|
||||
#if defined TORRENT_LOGGING
|
||||
|
@ -1745,13 +1745,16 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_resume_data && m_resume_data->entry.type() == lazy_entry::dict_t)
|
||||
if (m_resume_data && m_resume_data->node.type() == bdecode_node::dict_t)
|
||||
{
|
||||
int ev = 0;
|
||||
if (m_resume_data->entry.dict_find_string_value("file-format") != "libtorrent resume file")
|
||||
if (m_resume_data->node.dict_find_string_value("file-format")
|
||||
!= "libtorrent resume file")
|
||||
{
|
||||
ev = errors::invalid_file_tag;
|
||||
}
|
||||
|
||||
std::string info_hash = m_resume_data->entry.dict_find_string_value("info-hash");
|
||||
std::string info_hash = m_resume_data->node.dict_find_string_value("info-hash");
|
||||
if (!ev && info_hash.empty())
|
||||
ev = errors::missing_info_hash;
|
||||
|
||||
|
@ -1774,7 +1777,7 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
read_resume_data(m_resume_data->entry);
|
||||
read_resume_data(m_resume_data->node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1786,12 +1789,14 @@ namespace libtorrent
|
|||
|
||||
if (!m_seed_mode && m_resume_data)
|
||||
{
|
||||
lazy_entry const* piece_priority = m_resume_data->entry.dict_find_string("piece_priority");
|
||||
if (piece_priority && piece_priority->string_length()
|
||||
bdecode_node piece_priority = m_resume_data->node
|
||||
.dict_find_string("piece_priority");
|
||||
|
||||
if (piece_priority && piece_priority.string_length()
|
||||
== m_torrent_file->num_pieces())
|
||||
{
|
||||
char const* p = piece_priority->string_ptr();
|
||||
for (int i = 0; i < piece_priority->string_length(); ++i)
|
||||
char const* p = piece_priority.string_ptr();
|
||||
for (int i = 0; i < piece_priority.string_length(); ++i)
|
||||
{
|
||||
int prio = p[i];
|
||||
if (!has_picker() && prio == 1) continue;
|
||||
|
@ -1924,7 +1929,7 @@ namespace libtorrent
|
|||
|
||||
inc_refcount("check_fastresume");
|
||||
m_ses.disk_thread().async_check_fastresume(
|
||||
m_storage.get(), m_resume_data ? &m_resume_data->entry : NULL
|
||||
m_storage.get(), m_resume_data ? &m_resume_data->node : NULL
|
||||
, boost::bind(&torrent::on_resume_data_checked
|
||||
, shared_from_this(), _1));
|
||||
#if defined TORRENT_LOGGING
|
||||
|
@ -2146,14 +2151,14 @@ namespace libtorrent
|
|||
|
||||
state_updated();
|
||||
|
||||
if (m_resume_data && m_resume_data->entry.type() == lazy_entry::dict_t)
|
||||
if (m_resume_data && m_resume_data->node.type() == bdecode_node::dict_t)
|
||||
{
|
||||
using namespace libtorrent::detail; // for read_*_endpoint()
|
||||
|
||||
if (lazy_entry const* peers_entry = m_resume_data->entry.dict_find_string("peers"))
|
||||
if (bdecode_node peers_entry = m_resume_data->node.dict_find_string("peers"))
|
||||
{
|
||||
int num_peers = peers_entry->string_length() / (sizeof(address_v4::bytes_type) + 2);
|
||||
char const* ptr = peers_entry->string_ptr();
|
||||
int num_peers = peers_entry.string_length() / (sizeof(address_v4::bytes_type) + 2);
|
||||
char const* ptr = peers_entry.string_ptr();
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
add_peer(read_v4_endpoint<tcp::endpoint>(ptr)
|
||||
|
@ -2162,10 +2167,11 @@ namespace libtorrent
|
|||
update_want_peers();
|
||||
}
|
||||
|
||||
if (lazy_entry const* banned_peers_entry = m_resume_data->entry.dict_find_string("banned_peers"))
|
||||
if (bdecode_node banned_peers_entry
|
||||
= m_resume_data->node.dict_find_string("banned_peers"))
|
||||
{
|
||||
int num_peers = banned_peers_entry->string_length() / (sizeof(address_v4::bytes_type) + 2);
|
||||
char const* ptr = banned_peers_entry->string_ptr();
|
||||
int num_peers = banned_peers_entry.string_length() / (sizeof(address_v4::bytes_type) + 2);
|
||||
char const* ptr = banned_peers_entry.string_ptr();
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
std::vector<torrent_peer*> peers;
|
||||
|
@ -2178,10 +2184,10 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
if (lazy_entry const* peers6_entry = m_resume_data->entry.dict_find_string("peers6"))
|
||||
if (bdecode_node peers6_entry = m_resume_data->node.dict_find_string("peers6"))
|
||||
{
|
||||
int num_peers = peers6_entry->string_length() / (sizeof(address_v6::bytes_type) + 2);
|
||||
char const* ptr = peers6_entry->string_ptr();
|
||||
int num_peers = peers6_entry.string_length() / (sizeof(address_v6::bytes_type) + 2);
|
||||
char const* ptr = peers6_entry.string_ptr();
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
add_peer(read_v6_endpoint<tcp::endpoint>(ptr)
|
||||
|
@ -2190,10 +2196,10 @@ namespace libtorrent
|
|||
update_want_peers();
|
||||
}
|
||||
|
||||
if (lazy_entry const* banned_peers6_entry = m_resume_data->entry.dict_find_string("banned_peers6"))
|
||||
if (bdecode_node banned_peers6_entry = m_resume_data->node.dict_find_string("banned_peers6"))
|
||||
{
|
||||
int num_peers = banned_peers6_entry->string_length() / (sizeof(address_v6::bytes_type) + 2);
|
||||
char const* ptr = banned_peers6_entry->string_ptr();
|
||||
int num_peers = banned_peers6_entry.string_length() / (sizeof(address_v6::bytes_type) + 2);
|
||||
char const* ptr = banned_peers6_entry.string_ptr();
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
torrent_peer* p = add_peer(read_v6_endpoint<tcp::endpoint>(ptr)
|
||||
|
@ -2205,14 +2211,14 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
// parse out "peers" from the resume data and add them to the peer list
|
||||
if (lazy_entry const* peers_entry = m_resume_data->entry.dict_find_list("peers"))
|
||||
if (bdecode_node peers_entry = m_resume_data->node.dict_find_list("peers"))
|
||||
{
|
||||
for (int i = 0; i < peers_entry->list_size(); ++i)
|
||||
for (int i = 0; i < peers_entry.list_size(); ++i)
|
||||
{
|
||||
lazy_entry const* e = peers_entry->list_at(i);
|
||||
if (e->type() != lazy_entry::dict_t) continue;
|
||||
std::string ip = e->dict_find_string_value("ip");
|
||||
int port = e->dict_find_int_value("port");
|
||||
bdecode_node e = peers_entry.list_at(i);
|
||||
if (e.type() != bdecode_node::dict_t) continue;
|
||||
std::string ip = e.dict_find_string_value("ip");
|
||||
int port = e.dict_find_int_value("port");
|
||||
if (ip.empty() || port == 0) continue;
|
||||
error_code ec;
|
||||
tcp::endpoint a(address::from_string(ip, ec), (unsigned short)port);
|
||||
|
@ -2223,14 +2229,14 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
// parse out "banned_peers" and add them as banned
|
||||
if (lazy_entry const* banned_peers_entry = m_resume_data->entry.dict_find_list("banned_peers"))
|
||||
if (bdecode_node banned_peers_entry = m_resume_data->node.dict_find_list("banned_peers"))
|
||||
{
|
||||
for (int i = 0; i < banned_peers_entry->list_size(); ++i)
|
||||
for (int i = 0; i < banned_peers_entry.list_size(); ++i)
|
||||
{
|
||||
lazy_entry const* e = banned_peers_entry->list_at(i);
|
||||
if (e->type() != lazy_entry::dict_t) continue;
|
||||
std::string ip = e->dict_find_string_value("ip");
|
||||
int port = e->dict_find_int_value("port");
|
||||
bdecode_node e = banned_peers_entry.list_at(i);
|
||||
if (e.type() != bdecode_node::dict_t) continue;
|
||||
std::string ip = e.dict_find_string_value("ip");
|
||||
int port = e.dict_find_int_value("port");
|
||||
if (ip.empty() || port == 0) continue;
|
||||
error_code ec;
|
||||
tcp::endpoint a(address::from_string(ip, ec), (unsigned short)port);
|
||||
|
@ -2276,15 +2282,15 @@ namespace libtorrent
|
|||
// there are either no files for this torrent
|
||||
// or the resume_data was accepted
|
||||
|
||||
if (!j->error && m_resume_data && m_resume_data->entry.type() == lazy_entry::dict_t)
|
||||
if (!j->error && m_resume_data && m_resume_data->node.type() == bdecode_node::dict_t)
|
||||
{
|
||||
// parse have bitmask
|
||||
lazy_entry const* pieces = m_resume_data->entry.dict_find("pieces");
|
||||
if (pieces && pieces->type() == lazy_entry::string_t
|
||||
&& int(pieces->string_length()) == m_torrent_file->num_pieces())
|
||||
bdecode_node pieces = m_resume_data->node.dict_find("pieces");
|
||||
if (pieces && pieces.type() == bdecode_node::string_t
|
||||
&& int(pieces.string_length()) == m_torrent_file->num_pieces())
|
||||
{
|
||||
char const* pieces_str = pieces->string_ptr();
|
||||
for (int i = 0, end(pieces->string_length()); i < end; ++i)
|
||||
char const* pieces_str = pieces.string_ptr();
|
||||
for (int i = 0, end(pieces.string_length()); i < end; ++i)
|
||||
{
|
||||
if (pieces_str[i] & 1)
|
||||
{
|
||||
|
@ -2299,12 +2305,12 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
lazy_entry const* slots = m_resume_data->entry.dict_find("slots");
|
||||
if (slots && slots->type() == lazy_entry::list_t)
|
||||
bdecode_node slots = m_resume_data->node.dict_find("slots");
|
||||
if (slots && slots.type() == bdecode_node::list_t)
|
||||
{
|
||||
for (int i = 0; i < slots->list_size(); ++i)
|
||||
for (int i = 0; i < slots.list_size(); ++i)
|
||||
{
|
||||
int piece = slots->list_int_value_at(i, -1);
|
||||
int piece = slots.list_int_value_at(i, -1);
|
||||
if (piece >= 0)
|
||||
{
|
||||
need_picker();
|
||||
|
@ -2321,13 +2327,14 @@ namespace libtorrent
|
|||
int num_blocks_per_piece =
|
||||
static_cast<int>(torrent_file().piece_length()) / block_size();
|
||||
|
||||
if (lazy_entry const* unfinished_ent = m_resume_data->entry.dict_find_list("unfinished"))
|
||||
if (bdecode_node unfinished_ent
|
||||
= m_resume_data->node.dict_find_list("unfinished"))
|
||||
{
|
||||
for (int i = 0; i < unfinished_ent->list_size(); ++i)
|
||||
for (int i = 0; i < unfinished_ent.list_size(); ++i)
|
||||
{
|
||||
lazy_entry const* e = unfinished_ent->list_at(i);
|
||||
if (e->type() != lazy_entry::dict_t) continue;
|
||||
int piece = e->dict_find_int_value("piece", -1);
|
||||
bdecode_node e = unfinished_ent.list_at(i);
|
||||
if (e.type() != bdecode_node::dict_t) continue;
|
||||
int piece = e.dict_find_int_value("piece", -1);
|
||||
if (piece < 0 || piece > torrent_file().num_pieces()) continue;
|
||||
|
||||
if (has_picker() && m_picker->have_piece(piece))
|
||||
|
@ -2336,7 +2343,7 @@ namespace libtorrent
|
|||
update_gauge();
|
||||
}
|
||||
|
||||
std::string bitmask = e->dict_find_string_value("bitmask");
|
||||
std::string bitmask = e.dict_find_string_value("bitmask");
|
||||
if (bitmask.empty()) continue;
|
||||
|
||||
need_picker();
|
||||
|
@ -6534,7 +6541,7 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
void torrent::read_resume_data(lazy_entry const& rd)
|
||||
void torrent::read_resume_data(bdecode_node const& rd)
|
||||
{
|
||||
m_total_uploaded = rd.dict_find_int_value("total_uploaded");
|
||||
m_total_downloaded = rd.dict_find_int_value("total_downloaded");
|
||||
|
@ -6627,12 +6634,12 @@ namespace libtorrent
|
|||
// The mapped_files needs to be read both in the network thread
|
||||
// and in the disk thread, since they both have their own mapped files structures
|
||||
// which are kept in sync
|
||||
lazy_entry const* mapped_files = rd.dict_find_list("mapped_files");
|
||||
if (mapped_files && mapped_files->list_size() == m_torrent_file->num_files())
|
||||
bdecode_node mapped_files = rd.dict_find_list("mapped_files");
|
||||
if (mapped_files && mapped_files.list_size() == m_torrent_file->num_files())
|
||||
{
|
||||
for (int i = 0; i < m_torrent_file->num_files(); ++i)
|
||||
{
|
||||
std::string new_filename = mapped_files->list_string_value_at(i);
|
||||
std::string new_filename = mapped_files.list_string_value_at(i);
|
||||
if (new_filename.empty()) continue;
|
||||
m_torrent_file->rename_file(i, new_filename);
|
||||
}
|
||||
|
@ -6645,14 +6652,14 @@ namespace libtorrent
|
|||
|
||||
if (!m_seed_mode && !m_override_resume_data)
|
||||
{
|
||||
lazy_entry const* file_priority = rd.dict_find_list("file_priority");
|
||||
if (file_priority && file_priority->list_size()
|
||||
bdecode_node file_priority = rd.dict_find_list("file_priority");
|
||||
if (file_priority && file_priority.list_size()
|
||||
== m_torrent_file->num_files())
|
||||
{
|
||||
int num_files = m_torrent_file->num_files();
|
||||
m_file_priority.resize(num_files);
|
||||
for (int i = 0; i < num_files; ++i)
|
||||
m_file_priority[i] = file_priority->list_int_value_at(i, 1);
|
||||
m_file_priority[i] = file_priority.list_int_value_at(i, 1);
|
||||
// unallocated slots are assumed to be priority 1, so cut off any
|
||||
// trailing ones
|
||||
int end_range = num_files - 1;
|
||||
|
@ -6671,19 +6678,19 @@ namespace libtorrent
|
|||
update_piece_priorities();
|
||||
}
|
||||
|
||||
lazy_entry const* trackers = rd.dict_find_list("trackers");
|
||||
bdecode_node trackers = rd.dict_find_list("trackers");
|
||||
if (trackers)
|
||||
{
|
||||
if (!m_merge_resume_trackers) m_trackers.clear();
|
||||
int tier = 0;
|
||||
for (int i = 0; i < trackers->list_size(); ++i)
|
||||
for (int i = 0; i < trackers.list_size(); ++i)
|
||||
{
|
||||
lazy_entry const* tier_list = trackers->list_at(i);
|
||||
if (tier_list == 0 || tier_list->type() != lazy_entry::list_t)
|
||||
bdecode_node tier_list = trackers.list_at(i);
|
||||
if (!tier_list || tier_list.type() != bdecode_node::list_t)
|
||||
continue;
|
||||
for (int j = 0; j < tier_list->list_size(); ++j)
|
||||
for (int j = 0; j < tier_list.list_size(); ++j)
|
||||
{
|
||||
announce_entry e(tier_list->list_string_value_at(j));
|
||||
announce_entry e(tier_list.list_string_value_at(j));
|
||||
if (std::find_if(m_trackers.begin(), m_trackers.end()
|
||||
, boost::bind(&announce_entry::url, _1) == e.url) != m_trackers.end())
|
||||
continue;
|
||||
|
@ -6700,24 +6707,24 @@ namespace libtorrent
|
|||
prioritize_udp_trackers();
|
||||
}
|
||||
|
||||
lazy_entry const* url_list = rd.dict_find_list("url-list");
|
||||
bdecode_node url_list = rd.dict_find_list("url-list");
|
||||
if (url_list)
|
||||
{
|
||||
for (int i = 0; i < url_list->list_size(); ++i)
|
||||
for (int i = 0; i < url_list.list_size(); ++i)
|
||||
{
|
||||
std::string url = url_list->list_string_value_at(i);
|
||||
std::string url = url_list.list_string_value_at(i);
|
||||
if (url.empty()) continue;
|
||||
if (m_torrent_file->num_files() > 1 && url[url.size()-1] != '/') url += '/';
|
||||
add_web_seed(url, web_seed_entry::url_seed);
|
||||
}
|
||||
}
|
||||
|
||||
lazy_entry const* httpseeds = rd.dict_find_list("httpseeds");
|
||||
bdecode_node httpseeds = rd.dict_find_list("httpseeds");
|
||||
if (httpseeds)
|
||||
{
|
||||
for (int i = 0; i < httpseeds->list_size(); ++i)
|
||||
for (int i = 0; i < httpseeds.list_size(); ++i)
|
||||
{
|
||||
std::string url = httpseeds->list_string_value_at(i);
|
||||
std::string url = httpseeds.list_string_value_at(i);
|
||||
if (url.empty()) continue;
|
||||
add_web_seed(url, web_seed_entry::http_seed);
|
||||
}
|
||||
|
@ -6725,16 +6732,16 @@ namespace libtorrent
|
|||
|
||||
if (m_torrent_file->is_merkle_torrent())
|
||||
{
|
||||
lazy_entry const* mt = rd.dict_find_string("merkle tree");
|
||||
bdecode_node mt = rd.dict_find_string("merkle tree");
|
||||
if (mt)
|
||||
{
|
||||
std::vector<sha1_hash> tree;
|
||||
tree.resize(m_torrent_file->merkle_tree().size());
|
||||
std::memcpy(&tree[0], mt->string_ptr()
|
||||
, (std::min)(mt->string_length(), int(tree.size()) * 20));
|
||||
if (mt->string_length() < int(tree.size()) * 20)
|
||||
std::memset(&tree[0] + mt->string_length() / 20, 0
|
||||
, tree.size() - mt->string_length() / 20);
|
||||
std::memcpy(&tree[0], mt.string_ptr()
|
||||
, (std::min)(mt.string_length(), int(tree.size()) * 20));
|
||||
if (mt.string_length() < int(tree.size()) * 20)
|
||||
std::memset(&tree[0] + mt.string_length() / 20, 0
|
||||
, tree.size() - mt.string_length() / 20);
|
||||
m_torrent_file->set_merkle_tree(tree);
|
||||
}
|
||||
else
|
||||
|
@ -7425,9 +7432,9 @@ namespace libtorrent
|
|||
return false;
|
||||
}
|
||||
|
||||
lazy_entry metadata;
|
||||
bdecode_node metadata;
|
||||
error_code ec;
|
||||
int ret = lazy_bdecode(metadata_buf, metadata_buf + metadata_size, metadata, ec);
|
||||
int ret = bdecode(metadata_buf, metadata_buf + metadata_size, metadata, ec);
|
||||
if (ret != 0 || !m_torrent_file->parse_info_section(metadata, ec, 0))
|
||||
{
|
||||
update_gauge();
|
||||
|
@ -8416,8 +8423,8 @@ namespace libtorrent
|
|||
// this fires during disconnecting peers
|
||||
// if (is_paused()) TORRENT_ASSERT(num_peers() == 0 || m_graceful_pause_mode);
|
||||
|
||||
TORRENT_ASSERT(!m_resume_data || m_resume_data->entry.type() == lazy_entry::dict_t
|
||||
|| m_resume_data->entry.type() == lazy_entry::none_t);
|
||||
TORRENT_ASSERT(!m_resume_data || m_resume_data->node.type() == bdecode_node::dict_t
|
||||
|| m_resume_data->node.type() == bdecode_node::none_t);
|
||||
|
||||
int seeds = 0;
|
||||
int num_uploads = 0;
|
||||
|
|
|
@ -54,6 +54,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/add_torrent_params.hpp"
|
||||
#include "libtorrent/magnet_uri.hpp"
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
@ -362,11 +366,11 @@ namespace libtorrent
|
|||
// "path"
|
||||
// root_dir is the name of the torrent, unless this is a single file
|
||||
// torrent, in which case it's empty.
|
||||
bool extract_single_file(lazy_entry const& dict, file_storage& files
|
||||
bool extract_single_file(bdecode_node const& dict, file_storage& files
|
||||
, std::string const& root_dir, ptrdiff_t info_ptr_diff, bool top_level
|
||||
, error_code& ec)
|
||||
{
|
||||
if (dict.type() != lazy_entry::dict_t) return false;
|
||||
if (dict.type() != bdecode_node::dict_t) return false;
|
||||
boost::int64_t file_size = dict.dict_find_int_value("length", -1);
|
||||
if (file_size < 0)
|
||||
{
|
||||
|
@ -385,52 +389,52 @@ namespace libtorrent
|
|||
{
|
||||
// prefer the name.utf-8 because if it exists, it is more likely to be
|
||||
// correctly encoded
|
||||
lazy_entry const* p = dict.dict_find_string("name.utf-8");
|
||||
if (p == 0) p = dict.dict_find_string("name");
|
||||
if (p == 0 || p->string_length() == 0)
|
||||
bdecode_node p = dict.dict_find_string("name.utf-8");
|
||||
if (!p) p = dict.dict_find_string("name");
|
||||
if (!p || p.string_length() == 0)
|
||||
{
|
||||
ec = errors::torrent_missing_name;
|
||||
return false;
|
||||
}
|
||||
|
||||
filename = p->string_ptr() + info_ptr_diff;
|
||||
filename_len = p->string_length();
|
||||
sanitize_append_path_element(path, p->string_ptr(), p->string_length());
|
||||
filename = p.string_ptr() + info_ptr_diff;
|
||||
filename_len = p.string_length();
|
||||
sanitize_append_path_element(path, p.string_ptr(), p.string_length());
|
||||
|
||||
// if (path.empty()) path = to_hex(files.info_hash().to_string());
|
||||
}
|
||||
else
|
||||
{
|
||||
lazy_entry const* p = dict.dict_find_list("path.utf-8");
|
||||
if (p == 0) p = dict.dict_find_list("path");
|
||||
if (p == 0 || p->list_size() == 0)
|
||||
bdecode_node p = dict.dict_find_list("path.utf-8");
|
||||
if (!p) p = dict.dict_find_list("path");
|
||||
if (!p || p.list_size() == 0)
|
||||
{
|
||||
ec = errors::torrent_missing_name;
|
||||
return false;
|
||||
}
|
||||
|
||||
int preallocate = path.size();
|
||||
for (int i = 0, end(p->list_size()); i < end; ++i)
|
||||
for (int i = 0, end(p.list_size()); i < end; ++i)
|
||||
{
|
||||
lazy_entry const* e = p->list_at(i);
|
||||
if (e->type() != lazy_entry::string_t)
|
||||
bdecode_node e = p.list_at(i);
|
||||
if (e.type() != bdecode_node::string_t)
|
||||
{
|
||||
ec = errors::torrent_missing_name;
|
||||
return false;
|
||||
}
|
||||
preallocate += e->string_length() + 1;
|
||||
preallocate += e.string_length() + 1;
|
||||
}
|
||||
path.reserve(preallocate);
|
||||
|
||||
for (int i = 0, end(p->list_size()); i < end; ++i)
|
||||
for (int i = 0, end(p.list_size()); i < end; ++i)
|
||||
{
|
||||
lazy_entry const* e = p->list_at(i);
|
||||
bdecode_node e = p.list_at(i);
|
||||
if (i == end - 1)
|
||||
{
|
||||
filename = e->string_ptr() + info_ptr_diff;
|
||||
filename_len = e->string_length();
|
||||
filename = e.string_ptr() + info_ptr_diff;
|
||||
filename_len = e.string_length();
|
||||
}
|
||||
sanitize_append_path_element(path, e->string_ptr(), e->string_length());
|
||||
sanitize_append_path_element(path, e.string_ptr(), e.string_length());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,12 +443,12 @@ namespace libtorrent
|
|||
if (path.find("_____padding_file_") != std::string::npos)
|
||||
file_flags = file_storage::flag_pad_file;
|
||||
|
||||
lazy_entry const* attr = dict.dict_find_string("attr");
|
||||
bdecode_node attr = dict.dict_find_string("attr");
|
||||
if (attr)
|
||||
{
|
||||
for (int i = 0; i < attr->string_length(); ++i)
|
||||
for (int i = 0; i < attr.string_length(); ++i)
|
||||
{
|
||||
switch (attr->string_ptr()[i])
|
||||
switch (attr.string_ptr()[i])
|
||||
{
|
||||
case 'l': file_flags |= file_storage::flag_symlink; file_size = 0; break;
|
||||
case 'x': file_flags |= file_storage::flag_executable; break;
|
||||
|
@ -454,19 +458,19 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
lazy_entry const* fh = dict.dict_find_string("sha1");
|
||||
bdecode_node fh = dict.dict_find_string("sha1");
|
||||
char const* filehash = NULL;
|
||||
if (fh && fh->string_length() == 20)
|
||||
filehash = fh->string_ptr() + info_ptr_diff;
|
||||
if (fh && fh.string_length() == 20)
|
||||
filehash = fh.string_ptr() + info_ptr_diff;
|
||||
|
||||
std::string symlink_path;
|
||||
lazy_entry const* s_p = dict.dict_find("symlink path");
|
||||
if (s_p != 0 && s_p->type() == lazy_entry::list_t
|
||||
bdecode_node s_p = dict.dict_find("symlink path");
|
||||
if (s_p && s_p.type() == bdecode_node::list_t
|
||||
&& (file_flags & file_storage::flag_symlink))
|
||||
{
|
||||
for (int i = 0, end(s_p->list_size()); i < end; ++i)
|
||||
for (int i = 0, end(s_p.list_size()); i < end; ++i)
|
||||
{
|
||||
std::string path_element = s_p->list_at(i)->string_value();
|
||||
std::string path_element = s_p.list_at(i).string_value();
|
||||
symlink_path = combine_path(symlink_path, path_element);
|
||||
}
|
||||
}
|
||||
|
@ -550,10 +554,10 @@ namespace libtorrent
|
|||
|
||||
// root_dir is the name of the torrent, unless this is a single file
|
||||
// torrent, in which case it's empty.
|
||||
bool extract_files(lazy_entry const& list, file_storage& target
|
||||
bool extract_files(bdecode_node const& list, file_storage& target
|
||||
, std::string const& root_dir, ptrdiff_t info_ptr_diff, error_code& ec)
|
||||
{
|
||||
if (list.type() != lazy_entry::list_t)
|
||||
if (list.type() != bdecode_node::list_t)
|
||||
{
|
||||
ec = errors::torrent_file_parse_failed;
|
||||
return false;
|
||||
|
@ -562,7 +566,7 @@ namespace libtorrent
|
|||
|
||||
for (int i = 0, end(list.list_size()); i < end; ++i)
|
||||
{
|
||||
if (!extract_single_file(*list.list_at(i), target, root_dir
|
||||
if (!extract_single_file(list.list_at(i), target, root_dir
|
||||
, info_ptr_diff, false, ec))
|
||||
return false;
|
||||
}
|
||||
|
@ -691,7 +695,7 @@ namespace libtorrent
|
|||
// event, we need to let this announce through
|
||||
bool need_send_complete = is_seed && !complete_sent;
|
||||
|
||||
return now >= next_announce
|
||||
return now > next_announce
|
||||
&& (now >= min_announce || need_send_complete)
|
||||
&& (fails < fail_limit || fail_limit == 0)
|
||||
&& !updating;
|
||||
|
@ -735,6 +739,7 @@ namespace libtorrent
|
|||
t.check_invariant();
|
||||
#endif
|
||||
if (m_info_section_size == 0) return;
|
||||
TORRENT_ASSERT(m_piece_hashes);
|
||||
|
||||
error_code ec;
|
||||
m_info_section.reset(new char[m_info_section_size]);
|
||||
|
@ -746,15 +751,12 @@ namespace libtorrent
|
|||
if (m_orig_files)
|
||||
const_cast<file_storage&>(*m_orig_files).apply_pointer_offset(offset);
|
||||
|
||||
#if TORRENT_USE_ASSERTS || !defined BOOST_NO_EXCEPTIONS
|
||||
int ret =
|
||||
#endif
|
||||
lazy_bdecode(m_info_section.get(), m_info_section.get()
|
||||
+ m_info_section_size, m_info_dict, ec);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
if (ret != 0) throw libtorrent_exception(ec);
|
||||
#endif
|
||||
TORRENT_ASSERT(ret == 0);
|
||||
if (m_info_dict)
|
||||
{
|
||||
// make this decoded object point to our copy of the info section
|
||||
// buffer
|
||||
m_info_dict.switch_underlying_buffer(m_info_section.get());
|
||||
}
|
||||
|
||||
m_piece_hashes += offset;
|
||||
TORRENT_ASSERT(m_piece_hashes >= m_info_section.get());
|
||||
|
@ -861,6 +863,50 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file, error_code& ec
|
||||
, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
, m_info_section_size(0)
|
||||
, m_multifile(false)
|
||||
, m_private(false)
|
||||
, m_i2p(false)
|
||||
{
|
||||
std::pair<char const*, int> buf = torrent_file.data_section();
|
||||
bdecode_node e;
|
||||
if (bdecode(buf.first, buf.first + buf.second, e, ec) != 0)
|
||||
return;
|
||||
parse_torrent_file(e, ec, 0);
|
||||
}
|
||||
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
, m_info_section_size(0)
|
||||
, m_multifile(false)
|
||||
, m_private(false)
|
||||
, m_i2p(false)
|
||||
{
|
||||
std::pair<char const*, int> buf = torrent_file.data_section();
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
if (bdecode(buf.first, buf.first + buf.second, e, ec) != 0)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw invalid_torrent_file(ec);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
if (!parse_torrent_file(e, ec, 0))
|
||||
throw invalid_torrent_file(ec);
|
||||
#else
|
||||
parse_torrent_file(e, ec, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// standard constructor that parses a torrent file
|
||||
torrent_info::torrent_info(entry const& torrent_file)
|
||||
: m_piece_hashes(0)
|
||||
|
@ -875,9 +921,9 @@ namespace libtorrent
|
|||
std::back_insert_iterator<std::vector<char> > out(tmp);
|
||||
bencode(out, torrent_file);
|
||||
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
if (tmp.size() == 0 || lazy_bdecode(&tmp[0], &tmp[0] + tmp.size(), e, ec) != 0)
|
||||
if (tmp.size() == 0 || bdecode(&tmp[0], &tmp[0] + tmp.size(), e, ec) != 0)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw invalid_torrent_file(ec);
|
||||
|
@ -895,7 +941,7 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file, int flags)
|
||||
torrent_info::torrent_info(bdecode_node const& torrent_file, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
|
@ -921,8 +967,8 @@ namespace libtorrent
|
|||
, m_i2p(false)
|
||||
{
|
||||
error_code ec;
|
||||
lazy_entry e;
|
||||
if (lazy_bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
throw invalid_torrent_file(ec);
|
||||
|
||||
if (!parse_torrent_file(e, ec, flags))
|
||||
|
@ -945,8 +991,8 @@ namespace libtorrent
|
|||
int ret = load_file(filename, buf, ec);
|
||||
if (ret < 0) throw invalid_torrent_file(ec);
|
||||
|
||||
lazy_entry e;
|
||||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (buf.size() == 0 || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
throw invalid_torrent_file(ec);
|
||||
|
||||
if (!parse_torrent_file(e, ec, flags))
|
||||
|
@ -973,8 +1019,8 @@ namespace libtorrent
|
|||
int ret = load_file(utf8, buf, ec);
|
||||
if (ret < 0) throw invalid_torrent_file(ec);
|
||||
|
||||
lazy_entry e;
|
||||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (buf.size() == 0 || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
throw invalid_torrent_file(ec);
|
||||
|
||||
if (!parse_torrent_file(e, ec, flags))
|
||||
|
@ -993,7 +1039,7 @@ namespace libtorrent
|
|||
#endif // TORRENT_USE_WSTRING
|
||||
#endif
|
||||
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags)
|
||||
torrent_info::torrent_info(bdecode_node const& torrent_file, error_code& ec, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
|
@ -1016,8 +1062,8 @@ namespace libtorrent
|
|||
, m_private(false)
|
||||
, m_i2p(false)
|
||||
{
|
||||
lazy_entry e;
|
||||
if (lazy_bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
return;
|
||||
parse_torrent_file(e, ec, flags);
|
||||
|
||||
|
@ -1037,8 +1083,8 @@ namespace libtorrent
|
|||
int ret = load_file(filename, buf, ec);
|
||||
if (ret < 0) return;
|
||||
|
||||
lazy_entry e;
|
||||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (buf.size() == 0 || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
return;
|
||||
parse_torrent_file(e, ec, flags);
|
||||
|
||||
|
@ -1062,8 +1108,8 @@ namespace libtorrent
|
|||
int ret = load_file(utf8, buf, ec);
|
||||
if (ret < 0) return;
|
||||
|
||||
lazy_entry e;
|
||||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (buf.size() == 0 || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
return;
|
||||
parse_torrent_file(e, ec, flags);
|
||||
|
||||
|
@ -1092,8 +1138,8 @@ namespace libtorrent
|
|||
|
||||
void torrent_info::load(char const* buffer, int size, error_code& ec)
|
||||
{
|
||||
lazy_entry e;
|
||||
if (lazy_bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
return;
|
||||
|
||||
if (!parse_torrent_file(e, ec, 0))
|
||||
|
@ -1166,20 +1212,21 @@ namespace libtorrent
|
|||
std::string torrent_info::ssl_cert() const
|
||||
{
|
||||
// this is parsed lazily
|
||||
if (m_info_dict.type() == lazy_entry::none_t)
|
||||
if (!m_info_dict)
|
||||
{
|
||||
error_code ec;
|
||||
lazy_bdecode(m_info_section.get(), m_info_section.get()
|
||||
bdecode(m_info_section.get(), m_info_section.get()
|
||||
+ m_info_section_size, m_info_dict, ec);
|
||||
if (ec) return "";
|
||||
}
|
||||
if (m_info_dict.type() != lazy_entry::dict_t) return "";
|
||||
if (m_info_dict.type() != bdecode_node::dict_t) return "";
|
||||
return m_info_dict.dict_find_string_value("ssl-cert");
|
||||
}
|
||||
|
||||
bool torrent_info::parse_info_section(lazy_entry const& info, error_code& ec, int flags)
|
||||
bool torrent_info::parse_info_section(bdecode_node const& info
|
||||
, error_code& ec, int flags)
|
||||
{
|
||||
if (info.type() != lazy_entry::dict_t)
|
||||
if (info.type() != bdecode_node::dict_t)
|
||||
{
|
||||
ec = errors::torrent_info_no_dict;
|
||||
return false;
|
||||
|
@ -1214,22 +1261,23 @@ namespace libtorrent
|
|||
files.set_piece_length(piece_length);
|
||||
|
||||
// extract file name (or the directory name if it's a multifile libtorrent)
|
||||
lazy_entry const* name_ent = info.dict_find_string("name.utf-8");
|
||||
if (name_ent == 0) name_ent = info.dict_find_string("name");
|
||||
if (name_ent == 0)
|
||||
bdecode_node name_ent = info.dict_find_string("name.utf-8");
|
||||
if (!name_ent) name_ent = info.dict_find_string("name");
|
||||
if (!name_ent)
|
||||
{
|
||||
ec = errors::torrent_missing_name;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
sanitize_append_path_element(name, name_ent->string_ptr(), name_ent->string_length());
|
||||
sanitize_append_path_element(name, name_ent.string_ptr()
|
||||
, name_ent.string_length());
|
||||
|
||||
if (name.empty()) name = to_hex(m_info_hash.to_string());
|
||||
|
||||
// extract file list
|
||||
lazy_entry const* i = info.dict_find_list("files");
|
||||
if (i == 0)
|
||||
bdecode_node i = info.dict_find_list("files");
|
||||
if (!i)
|
||||
{
|
||||
// if there's no list of files, there has to be a length
|
||||
// field.
|
||||
|
@ -1240,7 +1288,7 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!extract_files(*i, files, name, info_ptr_diff, ec))
|
||||
if (!extract_files(i, files, name, info_ptr_diff, ec))
|
||||
return false;
|
||||
m_multifile = true;
|
||||
}
|
||||
|
@ -1253,9 +1301,9 @@ namespace libtorrent
|
|||
files.set_num_pieces(int((files.total_size() + files.piece_length() - 1)
|
||||
/ files.piece_length()));
|
||||
|
||||
lazy_entry const* pieces = info.dict_find_string("pieces");
|
||||
lazy_entry const* root_hash = info.dict_find_string("root hash");
|
||||
if (pieces == 0 && root_hash == 0)
|
||||
bdecode_node pieces = info.dict_find_string("pieces");
|
||||
bdecode_node root_hash = info.dict_find_string("root hash");
|
||||
if (!pieces && !root_hash)
|
||||
{
|
||||
ec = errors::torrent_missing_pieces;
|
||||
return false;
|
||||
|
@ -1263,20 +1311,20 @@ namespace libtorrent
|
|||
|
||||
if (pieces)
|
||||
{
|
||||
if (pieces->string_length() != files.num_pieces() * 20)
|
||||
if (pieces.string_length() != files.num_pieces() * 20)
|
||||
{
|
||||
ec = errors::torrent_invalid_hashes;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_piece_hashes = pieces->string_ptr() + info_ptr_diff;
|
||||
m_piece_hashes = pieces.string_ptr() + info_ptr_diff;
|
||||
TORRENT_ASSERT(m_piece_hashes >= m_info_section.get());
|
||||
TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
TORRENT_ASSERT(root_hash);
|
||||
if (root_hash->string_length() != 20)
|
||||
if (root_hash.string_length() != 20)
|
||||
{
|
||||
ec = errors::torrent_invalid_hashes;
|
||||
return false;
|
||||
|
@ -1286,7 +1334,7 @@ namespace libtorrent
|
|||
m_merkle_first_leaf = num_nodes - num_leafs;
|
||||
m_merkle_tree.resize(num_nodes);
|
||||
std::memset(&m_merkle_tree[0], 0, num_nodes * 20);
|
||||
m_merkle_tree[0].assign(root_hash->string_ptr());
|
||||
m_merkle_tree[0].assign(root_hash.string_ptr());
|
||||
}
|
||||
|
||||
m_private = info.dict_find_int_value("private", 0);
|
||||
|
@ -1396,21 +1444,22 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
bool torrent_info::parse_torrent_file(lazy_entry const& torrent_file, error_code& ec, int flags)
|
||||
bool torrent_info::parse_torrent_file(bdecode_node const& torrent_file
|
||||
, error_code& ec, int flags)
|
||||
{
|
||||
if (torrent_file.type() != lazy_entry::dict_t)
|
||||
if (torrent_file.type() != bdecode_node::dict_t)
|
||||
{
|
||||
ec = errors::torrent_is_no_dict;
|
||||
return false;
|
||||
}
|
||||
|
||||
lazy_entry const* info = torrent_file.dict_find_dict("info");
|
||||
bdecode_node info = torrent_file.dict_find_dict("info");
|
||||
if (info == 0)
|
||||
{
|
||||
lazy_entry const* link = torrent_file.dict_find_string("magnet-uri");
|
||||
bdecode_node link = torrent_file.dict_find_string("magnet-uri");
|
||||
if (link)
|
||||
{
|
||||
std::string uri = link->string_value();
|
||||
std::string uri = link.string_value();
|
||||
|
||||
add_torrent_params p;
|
||||
parse_magnet_uri(uri, p, ec);
|
||||
|
@ -1427,21 +1476,21 @@ namespace libtorrent
|
|||
ec = errors::torrent_missing_info;
|
||||
return false;
|
||||
}
|
||||
if (!parse_info_section(*info, ec, flags)) return false;
|
||||
if (!parse_info_section(info, ec, flags)) return false;
|
||||
resolve_duplicate_filenames();
|
||||
|
||||
// extract the url of the tracker
|
||||
lazy_entry const* i = torrent_file.dict_find_list("announce-list");
|
||||
bdecode_node i = torrent_file.dict_find_list("announce-list");
|
||||
if (i)
|
||||
{
|
||||
m_urls.reserve(i->list_size());
|
||||
for (int j = 0, end(i->list_size()); j < end; ++j)
|
||||
m_urls.reserve(i.list_size());
|
||||
for (int j = 0, end(i.list_size()); j < end; ++j)
|
||||
{
|
||||
lazy_entry const* tier = i->list_at(j);
|
||||
if (tier->type() != lazy_entry::list_t) continue;
|
||||
for (int k = 0, end(tier->list_size()); k < end; ++k)
|
||||
bdecode_node tier = i.list_at(j);
|
||||
if (tier.type() != bdecode_node::list_t) continue;
|
||||
for (int k = 0, end(tier.list_size()); k < end; ++k)
|
||||
{
|
||||
announce_entry e(tier->list_string_value_at(k));
|
||||
announce_entry e(tier.list_string_value_at(k));
|
||||
e.trim();
|
||||
if (e.url.empty()) continue;
|
||||
e.tier = j;
|
||||
|
@ -1486,20 +1535,20 @@ namespace libtorrent
|
|||
if (!e.url.empty()) m_urls.push_back(e);
|
||||
}
|
||||
|
||||
lazy_entry const* nodes = torrent_file.dict_find_list("nodes");
|
||||
bdecode_node nodes = torrent_file.dict_find_list("nodes");
|
||||
if (nodes)
|
||||
{
|
||||
for (int i = 0, end(nodes->list_size()); i < end; ++i)
|
||||
for (int i = 0, end(nodes.list_size()); i < end; ++i)
|
||||
{
|
||||
lazy_entry const* n = nodes->list_at(i);
|
||||
if (n->type() != lazy_entry::list_t
|
||||
|| n->list_size() < 2
|
||||
|| n->list_at(0)->type() != lazy_entry::string_t
|
||||
|| n->list_at(1)->type() != lazy_entry::int_t)
|
||||
bdecode_node n = nodes.list_at(i);
|
||||
if (n.type() != bdecode_node::list_t
|
||||
|| n.list_size() < 2
|
||||
|| n.list_at(0).type() != bdecode_node::string_t
|
||||
|| n.list_at(1).type() != bdecode_node::int_t)
|
||||
continue;
|
||||
m_nodes.push_back(std::make_pair(
|
||||
n->list_at(0)->string_value()
|
||||
, int(n->list_at(1)->int_value())));
|
||||
n.list_at(0).string_value()
|
||||
, int(n.list_at(1).int_value())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1511,24 +1560,25 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
// if there are any url-seeds, extract them
|
||||
lazy_entry const* url_seeds = torrent_file.dict_find("url-list");
|
||||
if (url_seeds && url_seeds->type() == lazy_entry::string_t && url_seeds->string_length() > 0)
|
||||
bdecode_node url_seeds = torrent_file.dict_find("url-list");
|
||||
if (url_seeds && url_seeds.type() == bdecode_node::string_t
|
||||
&& url_seeds.string_length() > 0)
|
||||
{
|
||||
web_seed_entry ent(maybe_url_encode(url_seeds->string_value())
|
||||
web_seed_entry ent(maybe_url_encode(url_seeds.string_value())
|
||||
, web_seed_entry::url_seed);
|
||||
if (m_multifile && ent.url[ent.url.size()-1] != '/') ent.url += '/';
|
||||
m_web_seeds.push_back(ent);
|
||||
}
|
||||
else if (url_seeds && url_seeds->type() == lazy_entry::list_t)
|
||||
else if (url_seeds && url_seeds.type() == bdecode_node::list_t)
|
||||
{
|
||||
// only add a URL once
|
||||
std::set<std::string> unique;
|
||||
for (int i = 0, end(url_seeds->list_size()); i < end; ++i)
|
||||
for (int i = 0, end(url_seeds.list_size()); i < end; ++i)
|
||||
{
|
||||
lazy_entry const* url = url_seeds->list_at(i);
|
||||
if (url->type() != lazy_entry::string_t) continue;
|
||||
if (url->string_length() == 0) continue;
|
||||
web_seed_entry ent(maybe_url_encode(url->string_value())
|
||||
bdecode_node url = url_seeds.list_at(i);
|
||||
if (url.type() != bdecode_node::string_t) continue;
|
||||
if (url.string_length() == 0) continue;
|
||||
web_seed_entry ent(maybe_url_encode(url.string_value())
|
||||
, web_seed_entry::url_seed);
|
||||
if (m_multifile && ent.url[ent.url.size()-1] != '/') ent.url += '/';
|
||||
if (unique.count(ent.url)) continue;
|
||||
|
@ -1538,21 +1588,22 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
// if there are any http-seeds, extract them
|
||||
lazy_entry const* http_seeds = torrent_file.dict_find("httpseeds");
|
||||
if (http_seeds && http_seeds->type() == lazy_entry::string_t && http_seeds->string_length() > 0)
|
||||
bdecode_node http_seeds = torrent_file.dict_find("httpseeds");
|
||||
if (http_seeds && http_seeds.type() == bdecode_node::string_t
|
||||
&& http_seeds.string_length() > 0)
|
||||
{
|
||||
m_web_seeds.push_back(web_seed_entry(maybe_url_encode(http_seeds->string_value())
|
||||
m_web_seeds.push_back(web_seed_entry(maybe_url_encode(http_seeds.string_value())
|
||||
, web_seed_entry::http_seed));
|
||||
}
|
||||
else if (http_seeds && http_seeds->type() == lazy_entry::list_t)
|
||||
else if (http_seeds && http_seeds.type() == bdecode_node::list_t)
|
||||
{
|
||||
// only add a URL once
|
||||
std::set<std::string> unique;
|
||||
for (int i = 0, end(http_seeds->list_size()); i < end; ++i)
|
||||
for (int i = 0, end(http_seeds.list_size()); i < end; ++i)
|
||||
{
|
||||
lazy_entry const* url = http_seeds->list_at(i);
|
||||
if (url->type() != lazy_entry::string_t || url->string_length() == 0) continue;
|
||||
std::string u = maybe_url_encode(url->string_value());
|
||||
bdecode_node url = http_seeds.list_at(i);
|
||||
if (url.type() != bdecode_node::string_t || url.string_length() == 0) continue;
|
||||
std::string u = maybe_url_encode(url.string_value());
|
||||
if (unique.count(u)) continue;
|
||||
unique.insert(u);
|
||||
m_web_seeds.push_back(web_seed_entry(u, web_seed_entry::http_seed));
|
||||
|
@ -1616,6 +1667,18 @@ namespace libtorrent
|
|||
, filter_web_seed_type(web_seed_entry::http_seed)).urls;
|
||||
}
|
||||
|
||||
bool torrent_info::parse_info_section(lazy_entry const& le, error_code& ec
|
||||
, int flags)
|
||||
{
|
||||
if (le.type() == lazy_entry::none_t) return false;
|
||||
std::pair<char const*, int> buf = le.data_section();
|
||||
bdecode_node e;
|
||||
if (bdecode(buf.first, buf.first + buf.second, e, ec) != 0)
|
||||
return false;
|
||||
|
||||
return parse_info_section(e, ec, flags);
|
||||
}
|
||||
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
|
||||
void torrent_info::add_url_seed(std::string const& url
|
||||
|
|
|
@ -234,14 +234,14 @@ namespace libtorrent { namespace
|
|||
}
|
||||
|
||||
// called when the extension handshake from the other end is received
|
||||
virtual bool on_extension_handshake(lazy_entry const& h)
|
||||
virtual bool on_extension_handshake(bdecode_node const& h)
|
||||
{
|
||||
m_message_index = 0;
|
||||
if (h.type() != lazy_entry::dict_t) return false;
|
||||
lazy_entry const* messages = h.dict_find_dict("m");
|
||||
if (h.type() != bdecode_node::dict_t) return false;
|
||||
bdecode_node messages = h.dict_find_dict("m");
|
||||
if (!messages) return false;
|
||||
|
||||
int index = messages->dict_find_int_value("ut_metadata", -1);
|
||||
int index = messages.dict_find_int_value("ut_metadata", -1);
|
||||
if (index == -1) return false;
|
||||
m_message_index = index;
|
||||
|
||||
|
|
|
@ -260,14 +260,14 @@ namespace libtorrent { namespace
|
|||
messages[extension_name] = extension_index;
|
||||
}
|
||||
|
||||
virtual bool on_extension_handshake(lazy_entry const& h)
|
||||
virtual bool on_extension_handshake(bdecode_node const& h)
|
||||
{
|
||||
m_message_index = 0;
|
||||
if (h.type() != lazy_entry::dict_t) return false;
|
||||
lazy_entry const* messages = h.dict_find("m");
|
||||
if (!messages || messages->type() != lazy_entry::dict_t) return false;
|
||||
if (h.type() != bdecode_node::dict_t) return false;
|
||||
bdecode_node messages = h.dict_find_dict("m");
|
||||
if (!messages) return false;
|
||||
|
||||
int index = int(messages->dict_find_int_value(extension_name, -1));
|
||||
int index = int(messages.dict_find_int_value(extension_name, -1));
|
||||
if (index == -1) return false;
|
||||
m_message_index = index;
|
||||
return true;
|
||||
|
@ -300,26 +300,26 @@ namespace libtorrent { namespace
|
|||
m_last_pex[i] = m_last_pex[i+1];
|
||||
m_last_pex[num_pex_timers-1] = now;
|
||||
|
||||
lazy_entry pex_msg;
|
||||
bdecode_node pex_msg;
|
||||
error_code ec;
|
||||
int ret = lazy_bdecode(body.begin, body.end, pex_msg, ec);
|
||||
if (ret != 0 || pex_msg.type() != lazy_entry::dict_t)
|
||||
int ret = bdecode(body.begin, body.end, pex_msg, ec);
|
||||
if (ret != 0 || pex_msg.type() != bdecode_node::dict_t)
|
||||
{
|
||||
m_pc.disconnect(errors::invalid_pex_message, op_bittorrent, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
lazy_entry const* p = pex_msg.dict_find_string("dropped");
|
||||
bdecode_node p = pex_msg.dict_find_string("dropped");
|
||||
|
||||
#ifdef TORRENT_LOGGING
|
||||
int num_dropped = 0;
|
||||
int num_added = 0;
|
||||
if (p) num_dropped += p->string_length()/6;
|
||||
if (p) num_dropped += p.string_length()/6;
|
||||
#endif
|
||||
if (p)
|
||||
{
|
||||
int num_peers = p->string_length() / 6;
|
||||
char const* in = p->string_ptr();
|
||||
int num_peers = p.string_length() / 6;
|
||||
char const* in = p.string_ptr();
|
||||
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
|
@ -331,18 +331,16 @@ namespace libtorrent { namespace
|
|||
}
|
||||
|
||||
p = pex_msg.dict_find_string("added");
|
||||
lazy_entry const* pf = pex_msg.dict_find_string("added.f");
|
||||
bdecode_node pf = pex_msg.dict_find_string("added.f");
|
||||
|
||||
#ifdef TORRENT_LOGGING
|
||||
if (p) num_added += p->string_length() / 6;
|
||||
if (p) num_added += p.string_length() / 6;
|
||||
#endif
|
||||
if (p != 0
|
||||
&& pf != 0
|
||||
&& pf->string_length() == p->string_length() / 6)
|
||||
if (p && pf && pf.string_length() == p.string_length() / 6)
|
||||
{
|
||||
int num_peers = pf->string_length();
|
||||
char const* in = p->string_ptr();
|
||||
char const* fin = pf->string_ptr();
|
||||
int num_peers = pf.string_length();
|
||||
char const* in = p.string_ptr();
|
||||
char const* fin = pf.string_ptr();
|
||||
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
|
@ -366,14 +364,14 @@ namespace libtorrent { namespace
|
|||
|
||||
#if TORRENT_USE_IPV6
|
||||
|
||||
lazy_entry const* p6 = pex_msg.dict_find("dropped6");
|
||||
bdecode_node p6 = pex_msg.dict_find("dropped6");
|
||||
#ifdef TORRENT_LOGGING
|
||||
if (p6) num_dropped += p6->string_length() / 18;
|
||||
if (p6) num_dropped += p6.string_length() / 18;
|
||||
#endif
|
||||
if (p6 != 0 && p6->type() == lazy_entry::string_t)
|
||||
if (p6 != 0 && p6.type() == bdecode_node::string_t)
|
||||
{
|
||||
int num_peers = p6->string_length() / 18;
|
||||
char const* in = p6->string_ptr();
|
||||
int num_peers = p6.string_length() / 18;
|
||||
char const* in = p6.string_ptr();
|
||||
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
|
@ -386,18 +384,18 @@ namespace libtorrent { namespace
|
|||
|
||||
p6 = pex_msg.dict_find("added6");
|
||||
#ifdef TORRENT_LOGGING
|
||||
if (p6) num_added += p6->string_length() / 18;
|
||||
if (p6) num_added += p6.string_length() / 18;
|
||||
#endif
|
||||
lazy_entry const* p6f = pex_msg.dict_find("added6.f");
|
||||
bdecode_node p6f = pex_msg.dict_find("added6.f");
|
||||
if (p6 != 0
|
||||
&& p6f != 0
|
||||
&& p6->type() == lazy_entry::string_t
|
||||
&& p6f->type() == lazy_entry::string_t
|
||||
&& p6f->string_length() == p6->string_length() / 18)
|
||||
&& p6.type() == bdecode_node::string_t
|
||||
&& p6f.type() == bdecode_node::string_t
|
||||
&& p6f.string_length() == p6.string_length() / 18)
|
||||
{
|
||||
int num_peers = p6f->string_length();
|
||||
char const* in = p6->string_ptr();
|
||||
char const* fin = p6f->string_ptr();
|
||||
int num_peers = p6f.string_length();
|
||||
char const* in = p6.string_ptr();
|
||||
char const* fin = p6f.string_ptr();
|
||||
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
|
@ -500,21 +498,21 @@ namespace libtorrent { namespace
|
|||
m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_pex);
|
||||
|
||||
#ifdef TORRENT_LOGGING
|
||||
lazy_entry m;
|
||||
bdecode_node m;
|
||||
error_code ec;
|
||||
int ret = lazy_bdecode(&pex_msg[0], &pex_msg[0] + pex_msg.size(), m, ec);
|
||||
int ret = bdecode(&pex_msg[0], &pex_msg[0] + pex_msg.size(), m, ec);
|
||||
TORRENT_ASSERT(ret == 0);
|
||||
TORRENT_ASSERT(!ec);
|
||||
int num_dropped = 0;
|
||||
int num_added = 0;
|
||||
lazy_entry const* e = m.dict_find_string("added");
|
||||
if (e) num_added += e->string_length() / 6;
|
||||
bdecode_node e = m.dict_find_string("added");
|
||||
if (e) num_added += e.string_length() / 6;
|
||||
e = m.dict_find_string("dropped");
|
||||
if (e) num_dropped += e->string_length() / 6;
|
||||
if (e) num_dropped += e.string_length() / 6;
|
||||
e = m.dict_find_string("added6");
|
||||
if (e) num_added += e->string_length() / 18;
|
||||
if (e) num_added += e.string_length() / 18;
|
||||
e = m.dict_find_string("dropped6");
|
||||
if (e) num_dropped += e->string_length() / 18;
|
||||
if (e) num_dropped += e.string_length() / 18;
|
||||
m_pc.peer_log("==> PEX_DIFF [ dropped: %d added: %d msg_size: %d ]"
|
||||
, num_dropped, num_added, int(pex_msg.size()));
|
||||
#endif
|
||||
|
|
|
@ -9,8 +9,12 @@ exe test_natpmp : test_natpmp.cpp /torrent//torrent
|
|||
exe enum_if : enum_if.cpp /torrent//torrent
|
||||
: <threading>multi <debug-iterators>on <invariant-checks>full ;
|
||||
|
||||
exe bdecode_benchmark : test_bdecode_performance.cpp /torrent//torrent
|
||||
: <variant>release ;
|
||||
|
||||
explicit test_natpmp ;
|
||||
explicit enum_if ;
|
||||
explicit bdecode_benchmark ;
|
||||
|
||||
rule link_test ( properties * )
|
||||
{
|
||||
|
@ -117,6 +121,7 @@ test-suite libtorrent :
|
|||
[ run test_buffer.cpp ]
|
||||
[ run test_piece_picker.cpp ]
|
||||
[ run test_bencoding.cpp ]
|
||||
[ run test_bdecode.cpp ]
|
||||
[ run test_fast_extension.cpp ]
|
||||
[ run test_primitives.cpp ]
|
||||
[ run test_http_parser.cpp ]
|
||||
|
@ -149,7 +154,6 @@ test-suite libtorrent :
|
|||
[ run test_web_seed_http_pw.cpp ]
|
||||
[ run test_web_seed_chunked.cpp ]
|
||||
[ run test_web_seed_ban.cpp ]
|
||||
[ run test_bdecode_performance.cpp ]
|
||||
[ run test_pe_crypto.cpp ]
|
||||
[ run test_dos_blocker.cpp ]
|
||||
|
||||
|
|
|
@ -602,7 +602,6 @@ void create_random_files(std::string const& path, const int file_sizes[], int nu
|
|||
boost::shared_ptr<torrent_info> create_torrent(std::ostream* file, int piece_size
|
||||
, int num_pieces, bool add_tracker, std::string ssl_certificate)
|
||||
{
|
||||
char const* tracker_url = "http://non-existent-name.com/announce";
|
||||
// excercise the path when encountering invalid urls
|
||||
char const* invalid_tracker_url = "http:";
|
||||
char const* invalid_tracker_protocol = "foo://non/existent-name.com/announce";
|
||||
|
@ -613,7 +612,6 @@ boost::shared_ptr<torrent_info> create_torrent(std::ostream* file, int piece_siz
|
|||
libtorrent::create_torrent t(fs, piece_size);
|
||||
if (add_tracker)
|
||||
{
|
||||
t.add_tracker(tracker_url);
|
||||
t.add_tracker(invalid_tracker_url);
|
||||
t.add_tracker(invalid_tracker_protocol);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,6 +31,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/sha1_hash.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -39,22 +42,143 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace libtorrent;
|
||||
|
||||
int test_main()
|
||||
int load_file(std::string const& filename, std::vector<char>& v
|
||||
, libtorrent::error_code& ec, int limit = 8000000)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
time_point start(clock_type::now());
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
ec.clear();
|
||||
FILE* f = fopen(filename.c_str(), "rb");
|
||||
if (f == NULL)
|
||||
{
|
||||
char b[] = "d1:ai12453e1:b3:aaa1:c3:bbbe";
|
||||
lazy_entry e;
|
||||
error_code ec;
|
||||
lazy_bdecode(b, b + sizeof(b)-1, e, ec);
|
||||
ec.assign(errno, boost::system::generic_category());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int r = fseek(f, 0, SEEK_END);
|
||||
if (r != 0)
|
||||
{
|
||||
ec.assign(errno, boost::system::generic_category());
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
long s = ftell(f);
|
||||
if (s < 0)
|
||||
{
|
||||
ec.assign(errno, boost::system::generic_category());
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s > limit)
|
||||
{
|
||||
fclose(f);
|
||||
return -2;
|
||||
}
|
||||
|
||||
r = fseek(f, 0, SEEK_SET);
|
||||
if (r != 0)
|
||||
{
|
||||
ec.assign(errno, boost::system::generic_category());
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
v.resize(s);
|
||||
if (s == 0)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = fread(&v[0], 1, v.size(), f);
|
||||
if (r < 0)
|
||||
{
|
||||
ec.assign(errno, boost::system::generic_category());
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (r != s) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
fputs("usage: bdecode_benchmark torrent-file\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<char> buf;
|
||||
error_code ec;
|
||||
int ret = load_file(argv[1], buf, ec, 40 * 1000000);
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, "file too big, aborting\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
fprintf(stderr, "failed to load file: %s\n", ec.message().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
time_point start(clock_type::now());
|
||||
entry e;
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
{
|
||||
int len;
|
||||
e = bdecode(&buf[0], &buf[0] + buf.size(), len);
|
||||
// entry& info = e["info"];
|
||||
}
|
||||
ptime stop(time_now_hires());
|
||||
|
||||
fprintf(stderr, "(slow) bdecode done in %5d ns per message\n"
|
||||
, int(total_microseconds(stop - start) / 1000));
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
|
||||
{
|
||||
ptime start(time_now_hires());
|
||||
lazy_entry e;
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
{
|
||||
error_code ec;
|
||||
lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
|
||||
// lazy_entry* info = e.dict_find("info");
|
||||
}
|
||||
time_point stop(clock_type::now());
|
||||
|
||||
fprintf(stderr, "lazy_bdecode done in %5d ns per message\n"
|
||||
, int(total_microseconds(stop - start) / 1000));
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
|
||||
{
|
||||
ptime start(time_now_hires());
|
||||
bdecode_node e;
|
||||
e.reserve(100);
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
{
|
||||
error_code ec;
|
||||
bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
|
||||
// bdecode_node info = e.dict_find("info");
|
||||
}
|
||||
ptime stop(time_now_hires());
|
||||
|
||||
fprintf(stderr, "bdecode done in %5d ns per message\n"
|
||||
, int(total_microseconds(stop - start) / 1000));
|
||||
}
|
||||
time_point stop(clock_type::now());
|
||||
|
||||
std::cout << "done in " << total_milliseconds(stop - start) / 100. << " seconds per million message" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#endif
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
@ -57,8 +60,6 @@ entry decode(std::string const& str)
|
|||
|
||||
int test_main()
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
// ** strings **
|
||||
{
|
||||
entry e("spam");
|
||||
|
@ -104,6 +105,7 @@ int test_main()
|
|||
TEST_CHECK(decode(encode(e)) == e);
|
||||
}
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
{
|
||||
char b[] = "i12453e";
|
||||
lazy_entry e;
|
||||
|
@ -347,7 +349,7 @@ int test_main()
|
|||
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
|
||||
TEST_CHECK(ret != 0);
|
||||
printf("%s\n", print_entry(e).c_str());
|
||||
TEST_EQUAL(ec, error_code(bdecode_errors::expected_string
|
||||
TEST_EQUAL(ec, error_code(bdecode_errors::expected_digit
|
||||
, get_bdecode_category()));
|
||||
}
|
||||
|
||||
|
@ -386,7 +388,7 @@ int test_main()
|
|||
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
|
||||
TEST_CHECK(ret != 0);
|
||||
printf("%s\n", print_entry(e).c_str());
|
||||
TEST_EQUAL(ec, error_code(bdecode_errors::expected_string
|
||||
TEST_EQUAL(ec, error_code(bdecode_errors::expected_digit
|
||||
, get_bdecode_category()));
|
||||
}
|
||||
|
||||
|
@ -564,7 +566,7 @@ int test_main()
|
|||
boost::int64_t val = 0;
|
||||
bdecode_errors::error_code_enum ec;
|
||||
char const* e = parse_int(b, b + sizeof(b)-1, 'e', val, ec);
|
||||
TEST_EQUAL(ec, bdecode_errors::expected_string);
|
||||
TEST_EQUAL(ec, bdecode_errors::expected_digit);
|
||||
TEST_EQUAL(e, b + 1);
|
||||
}
|
||||
|
||||
|
@ -583,6 +585,7 @@ int test_main()
|
|||
char const* e = parse_int(b, b + sizeof(b)-1, ':', val, ec);
|
||||
TEST_CHECK(ec == bdecode_errors::expected_colon);
|
||||
}
|
||||
#endif // TORRENT_NO_DEPRECATE
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -72,12 +72,16 @@ struct test_storage_impl : storage_interface
|
|||
}
|
||||
|
||||
virtual bool has_any_file(storage_error& ec) { return false; }
|
||||
virtual void set_file_priority(std::vector<boost::uint8_t> const& prio, storage_error& ec) {}
|
||||
virtual int move_storage(std::string const& save_path, int flags, storage_error& ec) { return 0; }
|
||||
virtual bool verify_resume_data(lazy_entry const& rd, storage_error& ec) { return true; }
|
||||
virtual void set_file_priority(std::vector<boost::uint8_t> const& prio
|
||||
, storage_error& ec) {}
|
||||
virtual int move_storage(std::string const& save_path, int flags, storage_error& ec)
|
||||
{ return 0; }
|
||||
virtual bool verify_resume_data(bdecode_node const& rd, storage_error& ec)
|
||||
{ return true; }
|
||||
virtual void write_resume_data(entry& rd, storage_error& ec) const {}
|
||||
virtual void release_files(storage_error& ec) {}
|
||||
virtual void rename_file(int index, std::string const& new_filenamem, storage_error& ec) {}
|
||||
virtual void rename_file(int index, std::string const& new_filenamem
|
||||
, storage_error& ec) {}
|
||||
virtual void delete_files(storage_error& ec) {}
|
||||
virtual void finalize_file(int, storage_error&) {}
|
||||
};
|
||||
|
|
|
@ -127,17 +127,17 @@ find_packet(udp::endpoint ep)
|
|||
, boost::bind(&std::pair<udp::endpoint, entry>::first, _1) == ep);
|
||||
}
|
||||
|
||||
void lazy_from_entry(entry const& e, lazy_entry& l)
|
||||
void lazy_from_entry(entry const& e, bdecode_node& l)
|
||||
{
|
||||
error_code ec;
|
||||
static char inbuf[1500];
|
||||
int len = bencode(inbuf, e);
|
||||
int ret = lazy_bdecode(inbuf, inbuf + len, l, ec);
|
||||
int ret = bdecode(inbuf, inbuf + len, l, ec);
|
||||
TEST_CHECK(ret == 0);
|
||||
}
|
||||
|
||||
void send_dht_request(node_impl& node, char const* msg, udp::endpoint const& ep
|
||||
, lazy_entry* reply, char const* t = "10", char const* info_hash = 0
|
||||
, bdecode_node* reply, char const* t = "10", char const* info_hash = 0
|
||||
, char const* name = 0, std::string const token = std::string(), int port = 0
|
||||
, char const* target = 0, entry const* value = 0
|
||||
, bool scrape = false, bool seed = false
|
||||
|
@ -179,10 +179,10 @@ void send_dht_request(node_impl& node, char const* msg, udp::endpoint const& ep
|
|||
VALGRIND_CHECK_MEM_IS_DEFINED(msg_buf, size);
|
||||
#endif
|
||||
|
||||
lazy_entry decoded;
|
||||
bdecode_node decoded;
|
||||
error_code ec;
|
||||
lazy_bdecode(msg_buf, msg_buf + size, decoded, ec);
|
||||
if (ec) fprintf(stderr, "lazy_bdecode failed: %s\n", ec.message().c_str());
|
||||
bdecode(msg_buf, msg_buf + size, decoded, ec);
|
||||
if (ec) fprintf(stderr, "bdecode failed: %s\n", ec.message().c_str());
|
||||
|
||||
dht::msg m(decoded, ep);
|
||||
node.incoming(m);
|
||||
|
@ -222,7 +222,7 @@ void write_peers(entry::dictionary_type& r, std::set<tcp::endpoint> const& peers
|
|||
}
|
||||
}
|
||||
|
||||
void send_dht_response(node_impl& node, lazy_entry const& request, udp::endpoint const& ep
|
||||
void send_dht_response(node_impl& node, bdecode_node const& request, udp::endpoint const& ep
|
||||
, nodes_t const& nodes = nodes_t()
|
||||
, std::string const token = std::string(), int port = 0
|
||||
, std::set<tcp::endpoint> const& peers = std::set<tcp::endpoint>()
|
||||
|
@ -256,10 +256,10 @@ void send_dht_response(node_impl& node, lazy_entry const& request, udp::endpoint
|
|||
VALGRIND_CHECK_MEM_IS_DEFINED(msg_buf, size);
|
||||
#endif
|
||||
|
||||
lazy_entry decoded;
|
||||
bdecode_node decoded;
|
||||
error_code ec;
|
||||
lazy_bdecode(msg_buf, msg_buf + size, decoded, ec);
|
||||
if (ec) fprintf(stderr, "lazy_bdecode failed: %s\n", ec.message().c_str());
|
||||
bdecode(msg_buf, msg_buf + size, decoded, ec);
|
||||
if (ec) fprintf(stderr, "bdecode failed: %s\n", ec.message().c_str());
|
||||
|
||||
dht::msg m(decoded, ep);
|
||||
node.incoming(m);
|
||||
|
@ -295,28 +295,29 @@ void announce_immutable_items(node_impl& node, udp::endpoint const* eps
|
|||
for (int j = 0; j < num_items; ++j)
|
||||
{
|
||||
if ((i % items[j].num_peers) == 0) continue;
|
||||
lazy_entry response;
|
||||
bdecode_node response;
|
||||
send_dht_request(node, "get", eps[i], &response, "10", 0
|
||||
, 0, no, 0, (char const*)&items[j].target[0]);
|
||||
|
||||
key_desc_t desc[] =
|
||||
{
|
||||
{ "r", lazy_entry::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "id", lazy_entry::string_t, 20, 0},
|
||||
{ "token", lazy_entry::string_t, 0, 0},
|
||||
{ "ip", lazy_entry::string_t, 0, key_desc_t::optional | key_desc_t::last_child},
|
||||
{ "y", lazy_entry::string_t, 1, 0},
|
||||
{ "r", bdecode_node::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "id", bdecode_node::string_t, 20, 0},
|
||||
{ "token", bdecode_node::string_t, 0, 0},
|
||||
{ "ip", bdecode_node::string_t, 0, key_desc_t::optional | key_desc_t::last_child},
|
||||
{ "y", bdecode_node::string_t, 1, 0},
|
||||
};
|
||||
|
||||
lazy_entry const* parsed[6];
|
||||
bdecode_node parsed[6];
|
||||
char error_string[200];
|
||||
|
||||
// fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
int ret = verify_message(&response, desc, parsed, 5, error_string, sizeof(error_string));
|
||||
int ret = verify_message(response, desc, parsed, 5, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[4]->string_value(), "r");
|
||||
token = parsed[2]->string_value();
|
||||
TEST_EQUAL(parsed[4].string_value(), "r");
|
||||
token = parsed[2].string_value();
|
||||
// fprintf(stderr, "got token: %s\n", token.c_str());
|
||||
}
|
||||
else
|
||||
|
@ -329,7 +330,7 @@ void announce_immutable_items(node_impl& node, udp::endpoint const* eps
|
|||
if (parsed[3])
|
||||
{
|
||||
address_v4::bytes_type b;
|
||||
memcpy(&b[0], parsed[3]->string_ptr(), b.size());
|
||||
memcpy(&b[0], parsed[3].string_ptr(), b.size());
|
||||
address_v4 addr(b);
|
||||
TEST_EQUAL(addr, eps[i].address());
|
||||
}
|
||||
|
@ -339,16 +340,17 @@ void announce_immutable_items(node_impl& node, udp::endpoint const* eps
|
|||
|
||||
key_desc_t desc2[] =
|
||||
{
|
||||
{ "y", lazy_entry::string_t, 1, 0 }
|
||||
{ "y", bdecode_node::string_t, 1, 0 }
|
||||
};
|
||||
|
||||
ret = verify_message(&response, desc2, parsed, 1, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, desc2, parsed, 1, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
if (parsed[0]->string_value() != "r")
|
||||
if (parsed[0].string_value() != "r")
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
|
||||
TEST_EQUAL(parsed[0]->string_value(), "r");
|
||||
TEST_EQUAL(parsed[0].string_value(), "r");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -362,22 +364,23 @@ void announce_immutable_items(node_impl& node, udp::endpoint const* eps
|
|||
std::set<int> items_num;
|
||||
for (int j = 0; j < num_items; ++j)
|
||||
{
|
||||
lazy_entry response;
|
||||
bdecode_node response;
|
||||
send_dht_request(node, "get", eps[j], &response, "10", 0
|
||||
, 0, no, 0, (char const*)&items[j].target[0]);
|
||||
|
||||
key_desc_t desc[] =
|
||||
{
|
||||
{ "r", lazy_entry::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "v", lazy_entry::dict_t, 0, 0},
|
||||
{ "id", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{ "y", lazy_entry::string_t, 1, 0},
|
||||
{ "r", bdecode_node::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "v", bdecode_node::dict_t, 0, 0},
|
||||
{ "id", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
{ "y", bdecode_node::string_t, 1, 0},
|
||||
};
|
||||
|
||||
lazy_entry const* parsed[4];
|
||||
bdecode_node parsed[4];
|
||||
char error_string[200];
|
||||
|
||||
int ret = verify_message(&response, desc, parsed, 4, error_string, sizeof(error_string));
|
||||
int ret = verify_message(response, desc, parsed, 4, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
items_num.insert(items_num.begin(), j);
|
||||
|
@ -447,8 +450,8 @@ int test_main()
|
|||
dht::node_impl node(&ad, &s, sett, node_id(0), ext, 0, cnt);
|
||||
|
||||
// DHT should be running on port 48199 now
|
||||
lazy_entry response;
|
||||
lazy_entry const* parsed[11];
|
||||
bdecode_node response;
|
||||
bdecode_node parsed[11];
|
||||
char error_string[200];
|
||||
bool ret;
|
||||
|
||||
|
@ -457,19 +460,20 @@ int test_main()
|
|||
send_dht_request(node, "ping", source, &response, "10");
|
||||
|
||||
dht::key_desc_t pong_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"t", lazy_entry::string_t, 2, 0},
|
||||
{"r", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"t", bdecode_node::string_t, 2, 0},
|
||||
{"r", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
ret = dht::verify_message(&response, pong_desc, parsed, 4, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, pong_desc, parsed, 4, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "r");
|
||||
TEST_CHECK(parsed[1]->string_value() == "10");
|
||||
TEST_CHECK(parsed[0].string_value() == "r");
|
||||
TEST_CHECK(parsed[1].string_value() == "10");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -481,20 +485,21 @@ int test_main()
|
|||
send_dht_request(node, "find_node", source, &response, "10");
|
||||
|
||||
dht::key_desc_t err_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"e", lazy_entry::list_t, 2, 0}
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"e", bdecode_node::list_t, 2, 0}
|
||||
};
|
||||
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
ret = dht::verify_message(&response, err_desc, parsed, 2, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, err_desc, parsed, 2, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "e");
|
||||
if (parsed[1]->list_at(0)->type() == lazy_entry::int_t
|
||||
&& parsed[1]->list_at(1)->type() == lazy_entry::string_t)
|
||||
TEST_CHECK(parsed[0].string_value() == "e");
|
||||
if (parsed[1].list_at(0).type() == bdecode_node::int_t
|
||||
&& parsed[1].list_at(1).type() == bdecode_node::string_t)
|
||||
{
|
||||
TEST_CHECK(parsed[1]->list_at(1)->string_value() == "missing 'target' key");
|
||||
TEST_CHECK(parsed[1].list_at(1).string_value() == "missing 'target' key");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -511,20 +516,21 @@ int test_main()
|
|||
send_dht_request(node, "get_peers", source, &response, "10", "01010101010101010101");
|
||||
|
||||
dht::key_desc_t peer1_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"r", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"token", lazy_entry::string_t, 0, 0},
|
||||
{"id", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"r", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"token", bdecode_node::string_t, 0, 0},
|
||||
{"id", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
std::string token;
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
ret = dht::verify_message(&response, peer1_desc, parsed, 4, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, peer1_desc, parsed, 4, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "r");
|
||||
token = parsed[2]->string_value();
|
||||
TEST_CHECK(parsed[0].string_value() == "r");
|
||||
token = parsed[2].string_value();
|
||||
// fprintf(stderr, "got token: %s\n", token.c_str());
|
||||
}
|
||||
else
|
||||
|
@ -538,17 +544,18 @@ int test_main()
|
|||
send_dht_request(node, "announce_peer", source, &response, "10", "01010101010101010101", "test", token, 8080);
|
||||
|
||||
dht::key_desc_t ann_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"r", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"r", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
ret = dht::verify_message(&response, ann_desc, parsed, 3, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, ann_desc, parsed, 3, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "r");
|
||||
TEST_CHECK(parsed[0].string_value() == "r");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -561,12 +568,13 @@ int test_main()
|
|||
{
|
||||
source = udp::endpoint(rand_v4(), 6000);
|
||||
send_dht_request(node, "get_peers", source, &response, "10", "01010101010101010101");
|
||||
ret = dht::verify_message(&response, peer1_desc, parsed, 4, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, peer1_desc, parsed, 4, error_string
|
||||
, sizeof(error_string));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "r");
|
||||
token = parsed[2]->string_value();
|
||||
TEST_CHECK(parsed[0].string_value() == "r");
|
||||
token = parsed[2].string_value();
|
||||
// fprintf(stderr, "got token: %s\n", token.c_str());
|
||||
}
|
||||
else
|
||||
|
@ -586,25 +594,26 @@ int test_main()
|
|||
, 0, no, 0, 0, 0, true);
|
||||
|
||||
dht::key_desc_t peer2_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"r", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"BFpe", lazy_entry::string_t, 256, 0},
|
||||
{"BFsd", lazy_entry::string_t, 256, 0},
|
||||
{"id", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"r", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"BFpe", bdecode_node::string_t, 256, 0},
|
||||
{"BFsd", bdecode_node::string_t, 256, 0},
|
||||
{"id", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
ret = dht::verify_message(&response, peer2_desc, parsed, 5, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, peer2_desc, parsed, 5, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "r");
|
||||
TEST_EQUAL(parsed[1]->dict_find_string_value("n"), "test");
|
||||
TEST_CHECK(parsed[0].string_value() == "r");
|
||||
TEST_EQUAL(parsed[1].dict_find_string_value("n"), "test");
|
||||
|
||||
bloom_filter<256> downloaders;
|
||||
bloom_filter<256> seeds;
|
||||
downloaders.from_string(parsed[2]->string_ptr());
|
||||
seeds.from_string(parsed[3]->string_ptr());
|
||||
downloaders.from_string(parsed[2].string_ptr());
|
||||
seeds.from_string(parsed[3].string_ptr());
|
||||
|
||||
fprintf(stderr, "seeds: %f\n", seeds.size());
|
||||
fprintf(stderr, "downloaders: %f\n", downloaders.size());
|
||||
|
@ -644,17 +653,18 @@ int test_main()
|
|||
, 0, "0101010101010101010101010101010101010101", 0, false, false, std::string(), std::string(), -1, 0, &nid);
|
||||
|
||||
dht::key_desc_t nodes_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"r", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"r", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
ret = dht::verify_message(&response, nodes_desc, parsed, 3, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, nodes_desc, parsed, 3, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "r");
|
||||
TEST_CHECK(parsed[0].string_value() == "r");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -668,15 +678,16 @@ int test_main()
|
|||
send_dht_request(node, "find_node", source, &response, "10", 0, 0, std::string()
|
||||
, 0, "0101010101010101010101010101010101010101", 0, false, false, std::string(), std::string(), -1, 0, &nid);
|
||||
|
||||
ret = dht::verify_message(&response, err_desc, parsed, 2, error_string, sizeof(error_string));
|
||||
ret = dht::verify_message(response, err_desc, parsed, 2, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
if (ret)
|
||||
{
|
||||
TEST_CHECK(parsed[0]->string_value() == "e");
|
||||
if (parsed[1]->list_at(0)->type() == lazy_entry::int_t
|
||||
&& parsed[1]->list_at(1)->type() == lazy_entry::string_t)
|
||||
TEST_CHECK(parsed[0].string_value() == "e");
|
||||
if (parsed[1].list_at(0).type() == bdecode_node::int_t
|
||||
&& parsed[1].list_at(1).type() == bdecode_node::string_t)
|
||||
{
|
||||
TEST_CHECK(parsed[1]->list_at(1)->string_value() == "invalid node ID");
|
||||
TEST_CHECK(parsed[1].list_at(1).string_value() == "invalid node ID");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -761,13 +772,13 @@ int test_main()
|
|||
|
||||
key_desc_t desc2[] =
|
||||
{
|
||||
{ "y", lazy_entry::string_t, 1, 0 }
|
||||
{ "y", bdecode_node::string_t, 1, 0 }
|
||||
};
|
||||
|
||||
key_desc_t desc_error[] =
|
||||
{
|
||||
{ "e", lazy_entry::list_t, 2, 0 },
|
||||
{ "y", lazy_entry::string_t, 1, 0},
|
||||
{ "e", bdecode_node::list_t, 2, 0 },
|
||||
{ "y", bdecode_node::string_t, 1, 0},
|
||||
};
|
||||
|
||||
// ==== get / put mutable items ===
|
||||
|
@ -814,18 +825,19 @@ int test_main()
|
|||
|
||||
key_desc_t desc[] =
|
||||
{
|
||||
{ "r", lazy_entry::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "id", lazy_entry::string_t, 20, 0},
|
||||
{ "token", lazy_entry::string_t, 0, 0},
|
||||
{ "ip", lazy_entry::string_t, 0, key_desc_t::optional | key_desc_t::last_child},
|
||||
{ "y", lazy_entry::string_t, 1, 0},
|
||||
{ "r", bdecode_node::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "id", bdecode_node::string_t, 20, 0},
|
||||
{ "token", bdecode_node::string_t, 0, 0},
|
||||
{ "ip", bdecode_node::string_t, 0, key_desc_t::optional | key_desc_t::last_child},
|
||||
{ "y", bdecode_node::string_t, 1, 0},
|
||||
};
|
||||
|
||||
ret = verify_message(&response, desc, parsed, 5, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, desc, parsed, 5, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[4]->string_value(), "r");
|
||||
token = parsed[2]->string_value();
|
||||
TEST_EQUAL(parsed[4].string_value(), "r");
|
||||
token = parsed[2].string_value();
|
||||
fprintf(stderr, "get response: %s\n"
|
||||
, print_entry(response).c_str());
|
||||
fprintf(stderr, "got token: %s\n", to_hex(token).c_str());
|
||||
|
@ -850,12 +862,13 @@ int test_main()
|
|||
, std::string(public_key, item_pk_len)
|
||||
, std::string(signature, item_sig_len), seq, -1, NULL, salt.first);
|
||||
|
||||
ret = verify_message(&response, desc2, parsed, 1, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, desc2, parsed, 1, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr, "put response: %s\n"
|
||||
, print_entry(response).c_str());
|
||||
TEST_EQUAL(parsed[0]->string_value(), "r");
|
||||
TEST_EQUAL(parsed[0].string_value(), "r");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -873,16 +886,17 @@ int test_main()
|
|||
|
||||
key_desc_t desc3[] =
|
||||
{
|
||||
{ "r", lazy_entry::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "id", lazy_entry::string_t, 20, 0},
|
||||
{ "v", lazy_entry::none_t, 0, 0},
|
||||
{ "seq", lazy_entry::int_t, 0, 0},
|
||||
{ "sig", lazy_entry::string_t, 0, 0},
|
||||
{ "ip", lazy_entry::string_t, 0, key_desc_t::optional | key_desc_t::last_child},
|
||||
{ "y", lazy_entry::string_t, 1, 0},
|
||||
{ "r", bdecode_node::dict_t, 0, key_desc_t::parse_children },
|
||||
{ "id", bdecode_node::string_t, 20, 0},
|
||||
{ "v", bdecode_node::none_t, 0, 0},
|
||||
{ "seq", bdecode_node::int_t, 0, 0},
|
||||
{ "sig", bdecode_node::string_t, 0, 0},
|
||||
{ "ip", bdecode_node::string_t, 0, key_desc_t::optional | key_desc_t::last_child},
|
||||
{ "y", bdecode_node::string_t, 1, 0},
|
||||
};
|
||||
|
||||
ret = verify_message(&response, desc3, parsed, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, desc3, parsed, 7, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret == 0)
|
||||
{
|
||||
fprintf(stderr, "msg: %s\n", print_entry(response).c_str());
|
||||
|
@ -897,10 +911,10 @@ int test_main()
|
|||
char value[1020];
|
||||
char* ptr = value;
|
||||
int value_len = bencode(ptr, items[0].ent);
|
||||
TEST_EQUAL(value_len, parsed[2]->data_section().second);
|
||||
TEST_CHECK(memcmp(parsed[2]->data_section().first, value, value_len) == 0);
|
||||
TEST_EQUAL(value_len, parsed[2].data_section().second);
|
||||
TEST_CHECK(memcmp(parsed[2].data_section().first, value, value_len) == 0);
|
||||
|
||||
TEST_EQUAL(seq, parsed[3]->int_value());
|
||||
TEST_EQUAL(seq, parsed[3].int_value());
|
||||
}
|
||||
|
||||
// also test that invalid signatures fail!
|
||||
|
@ -923,13 +937,14 @@ int test_main()
|
|||
, std::string(public_key, item_pk_len)
|
||||
, std::string(signature, item_sig_len), seq, -1, NULL, salt.first);
|
||||
|
||||
ret = verify_message(&response, desc_error, parsed, 2, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, desc_error, parsed, 2, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr, "put response: %s\n", print_entry(response).c_str());
|
||||
TEST_EQUAL(parsed[1]->string_value(), "e");
|
||||
TEST_EQUAL(parsed[1].string_value(), "e");
|
||||
// 206 is the code for invalid signature
|
||||
TEST_EQUAL(parsed[0]->list_int_value_at(0), 206);
|
||||
TEST_EQUAL(parsed[0].list_int_value_at(0), 206);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -945,10 +960,10 @@ int test_main()
|
|||
, 0, false, false, std::string(), std::string(), seq-1);
|
||||
|
||||
{
|
||||
lazy_entry const* r = response.dict_find_dict("r");
|
||||
TEST_CHECK(r->dict_find("v"));
|
||||
TEST_CHECK(r->dict_find("k"));
|
||||
TEST_CHECK(r->dict_find("sig"));
|
||||
bdecode_node r = response.dict_find_dict("r");
|
||||
TEST_CHECK(r.dict_find("v"));
|
||||
TEST_CHECK(r.dict_find("k"));
|
||||
TEST_CHECK(r.dict_find("sig"));
|
||||
}
|
||||
|
||||
send_dht_request(node, "get", source, &response, "10", 0
|
||||
|
@ -956,10 +971,10 @@ int test_main()
|
|||
, 0, false, false, std::string(), std::string(), seq);
|
||||
|
||||
{
|
||||
lazy_entry const* r = response.dict_find_dict("r");
|
||||
TEST_CHECK(!r->dict_find("v"));
|
||||
TEST_CHECK(!r->dict_find("k"));
|
||||
TEST_CHECK(!r->dict_find("sig"));
|
||||
bdecode_node r = response.dict_find_dict("r");
|
||||
TEST_CHECK(!r.dict_find("v"));
|
||||
TEST_CHECK(!r.dict_find("k"));
|
||||
TEST_CHECK(!r.dict_find("sig"));
|
||||
}
|
||||
|
||||
// === test CAS put ===
|
||||
|
@ -987,12 +1002,13 @@ int test_main()
|
|||
, std::string(signature, item_sig_len), seq
|
||||
, cas, NULL, salt.first);
|
||||
|
||||
ret = verify_message(&response, desc2, parsed, 1, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, desc2, parsed, 1, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr, "put response: %s\n"
|
||||
, print_entry(response).c_str());
|
||||
TEST_EQUAL(parsed[0]->string_value(), "r");
|
||||
TEST_EQUAL(parsed[0].string_value(), "r");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1012,14 +1028,15 @@ int test_main()
|
|||
, std::string(signature, item_sig_len), seq
|
||||
, cas, NULL, salt.first);
|
||||
|
||||
ret = verify_message(&response, desc_error, parsed, 2, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, desc_error, parsed, 2, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr, "put response: %s\n"
|
||||
, print_entry(response).c_str());
|
||||
TEST_EQUAL(parsed[1]->string_value(), "e");
|
||||
TEST_EQUAL(parsed[1].string_value(), "e");
|
||||
// 301 is the error code for CAS hash mismatch
|
||||
TEST_EQUAL(parsed[0]->list_int_value_at(0), 301);
|
||||
TEST_EQUAL(parsed[0].list_int_value_at(0), 301);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1077,94 +1094,99 @@ int test_main()
|
|||
|
||||
// test verify_message
|
||||
const static key_desc_t msg_desc[] = {
|
||||
{"A", lazy_entry::string_t, 4, 0},
|
||||
{"B", lazy_entry::dict_t, 0, key_desc_t::optional | key_desc_t::parse_children},
|
||||
{"B1", lazy_entry::string_t, 0, 0},
|
||||
{"B2", lazy_entry::string_t, 0, key_desc_t::last_child},
|
||||
{"C", lazy_entry::dict_t, 0, key_desc_t::optional | key_desc_t::parse_children},
|
||||
{"C1", lazy_entry::string_t, 0, 0},
|
||||
{"C2", lazy_entry::string_t, 0, key_desc_t::last_child},
|
||||
{"A", bdecode_node::string_t, 4, 0},
|
||||
{"B", bdecode_node::dict_t, 0, key_desc_t::optional | key_desc_t::parse_children},
|
||||
{"B1", bdecode_node::string_t, 0, 0},
|
||||
{"B2", bdecode_node::string_t, 0, key_desc_t::last_child},
|
||||
{"C", bdecode_node::dict_t, 0, key_desc_t::optional | key_desc_t::parse_children},
|
||||
{"C1", bdecode_node::string_t, 0, 0},
|
||||
{"C2", bdecode_node::string_t, 0, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
lazy_entry const* msg_keys[7];
|
||||
bdecode_node msg_keys[7];
|
||||
|
||||
lazy_entry ent;
|
||||
bdecode_node ent;
|
||||
|
||||
error_code ec;
|
||||
char const test_msg[] = "d1:A4:test1:Bd2:B15:test22:B25:test3ee";
|
||||
lazy_bdecode(test_msg, test_msg + sizeof(test_msg)-1, ent, ec);
|
||||
bdecode(test_msg, test_msg + sizeof(test_msg)-1, ent, ec);
|
||||
fprintf(stderr, "%s\n", print_entry(ent).c_str());
|
||||
|
||||
ret = verify_message(&ent, msg_desc, msg_keys, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(ent, msg_desc, msg_keys, 7, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
TEST_CHECK(msg_keys[0]);
|
||||
if (msg_keys[0]) TEST_EQUAL(msg_keys[0]->string_value(), "test");
|
||||
if (msg_keys[0]) TEST_EQUAL(msg_keys[0].string_value(), "test");
|
||||
TEST_CHECK(msg_keys[1]);
|
||||
TEST_CHECK(msg_keys[2]);
|
||||
if (msg_keys[2]) TEST_EQUAL(msg_keys[2]->string_value(), "test2");
|
||||
if (msg_keys[2]) TEST_EQUAL(msg_keys[2].string_value(), "test2");
|
||||
TEST_CHECK(msg_keys[3]);
|
||||
if (msg_keys[3]) TEST_EQUAL(msg_keys[3]->string_value(), "test3");
|
||||
TEST_CHECK(msg_keys[4] == 0);
|
||||
TEST_CHECK(msg_keys[5] == 0);
|
||||
TEST_CHECK(msg_keys[6] == 0);
|
||||
if (msg_keys[3]) TEST_EQUAL(msg_keys[3].string_value(), "test3");
|
||||
TEST_CHECK(!msg_keys[4]);
|
||||
TEST_CHECK(!msg_keys[5]);
|
||||
TEST_CHECK(!msg_keys[6]);
|
||||
|
||||
char const test_msg2[] = "d1:A4:test1:Cd2:C15:test22:C25:test3ee";
|
||||
lazy_bdecode(test_msg2, test_msg2 + sizeof(test_msg2)-1, ent, ec);
|
||||
bdecode(test_msg2, test_msg2 + sizeof(test_msg2)-1, ent, ec);
|
||||
fprintf(stderr, "%s\n", print_entry(ent).c_str());
|
||||
|
||||
ret = verify_message(&ent, msg_desc, msg_keys, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(ent, msg_desc, msg_keys, 7, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(ret);
|
||||
TEST_CHECK(msg_keys[0]);
|
||||
if (msg_keys[0]) TEST_EQUAL(msg_keys[0]->string_value(), "test");
|
||||
TEST_CHECK(msg_keys[1] == 0);
|
||||
TEST_CHECK(msg_keys[2] == 0);
|
||||
TEST_CHECK(msg_keys[3] == 0);
|
||||
if (msg_keys[0]) TEST_EQUAL(msg_keys[0].string_value(), "test");
|
||||
TEST_CHECK(!msg_keys[1]);
|
||||
TEST_CHECK(!msg_keys[2]);
|
||||
TEST_CHECK(!msg_keys[3]);
|
||||
TEST_CHECK(msg_keys[4]);
|
||||
TEST_CHECK(msg_keys[5]);
|
||||
if (msg_keys[5]) TEST_EQUAL(msg_keys[5]->string_value(), "test2");
|
||||
if (msg_keys[5]) TEST_EQUAL(msg_keys[5].string_value(), "test2");
|
||||
TEST_CHECK(msg_keys[6]);
|
||||
if (msg_keys[6]) TEST_EQUAL(msg_keys[6]->string_value(), "test3");
|
||||
if (msg_keys[6]) TEST_EQUAL(msg_keys[6].string_value(), "test3");
|
||||
|
||||
|
||||
char const test_msg3[] = "d1:Cd2:C15:test22:C25:test3ee";
|
||||
lazy_bdecode(test_msg3, test_msg3 + sizeof(test_msg3)-1, ent, ec);
|
||||
bdecode(test_msg3, test_msg3 + sizeof(test_msg3)-1, ent, ec);
|
||||
fprintf(stderr, "%s\n", print_entry(ent).c_str());
|
||||
|
||||
ret = verify_message(&ent, msg_desc, msg_keys, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(ent, msg_desc, msg_keys, 7, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(!ret);
|
||||
fprintf(stderr, "%s\n", error_string);
|
||||
TEST_EQUAL(error_string, std::string("missing 'A' key"));
|
||||
|
||||
char const test_msg4[] = "d1:A6:foobare";
|
||||
lazy_bdecode(test_msg4, test_msg4 + sizeof(test_msg4)-1, ent, ec);
|
||||
bdecode(test_msg4, test_msg4 + sizeof(test_msg4)-1, ent, ec);
|
||||
fprintf(stderr, "%s\n", print_entry(ent).c_str());
|
||||
|
||||
ret = verify_message(&ent, msg_desc, msg_keys, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(ent, msg_desc, msg_keys, 7, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(!ret);
|
||||
fprintf(stderr, "%s\n", error_string);
|
||||
TEST_EQUAL(error_string, std::string("invalid value for 'A'"));
|
||||
|
||||
char const test_msg5[] = "d1:A4:test1:Cd2:C15:test2ee";
|
||||
lazy_bdecode(test_msg5, test_msg5 + sizeof(test_msg5)-1, ent, ec);
|
||||
bdecode(test_msg5, test_msg5 + sizeof(test_msg5)-1, ent, ec);
|
||||
fprintf(stderr, "%s\n", print_entry(ent).c_str());
|
||||
|
||||
ret = verify_message(&ent, msg_desc, msg_keys, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(ent, msg_desc, msg_keys, 7, error_string
|
||||
, sizeof(error_string));
|
||||
TEST_CHECK(!ret);
|
||||
fprintf(stderr, "%s\n", error_string);
|
||||
TEST_EQUAL(error_string, std::string("missing 'C2' key"));
|
||||
|
||||
// test empty strings [ { "":1 }, "" ]
|
||||
char const test_msg6[] = "ld0:i1ee0:e";
|
||||
lazy_bdecode(test_msg6, test_msg6 + sizeof(test_msg6)-1, ent, ec);
|
||||
bdecode(test_msg6, test_msg6 + sizeof(test_msg6)-1, ent, ec);
|
||||
fprintf(stderr, "%s\n", print_entry(ent).c_str());
|
||||
TEST_CHECK(ent.type() == lazy_entry::list_t);
|
||||
if (ent.type() == lazy_entry::list_t)
|
||||
TEST_CHECK(ent.type() == bdecode_node::list_t);
|
||||
if (ent.type() == bdecode_node::list_t)
|
||||
{
|
||||
TEST_CHECK(ent.list_size() == 2);
|
||||
if (ent.list_size() == 2)
|
||||
{
|
||||
TEST_CHECK(ent.list_at(0)->dict_find_int_value("") == 1);
|
||||
TEST_CHECK(ent.list_at(1)->string_value() == "");
|
||||
TEST_CHECK(ent.list_at(0).dict_find_int_value("") == 1);
|
||||
TEST_CHECK(ent.list_at(1).string_value() == "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1410,31 +1432,31 @@ int test_main()
|
|||
// test traversal algorithms
|
||||
|
||||
dht::key_desc_t find_node_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"t", lazy_entry::string_t, 2, 0},
|
||||
{"q", lazy_entry::string_t, 9, 0},
|
||||
{"a", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, 0},
|
||||
{"target", lazy_entry::string_t, 20, key_desc_t::optional},
|
||||
{"info_hash", lazy_entry::string_t, 20, key_desc_t::optional | key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"t", bdecode_node::string_t, 2, 0},
|
||||
{"q", bdecode_node::string_t, 9, 0},
|
||||
{"a", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, 0},
|
||||
{"target", bdecode_node::string_t, 20, key_desc_t::optional},
|
||||
{"info_hash", bdecode_node::string_t, 20, key_desc_t::optional | key_desc_t::last_child},
|
||||
};
|
||||
|
||||
dht::key_desc_t get_peers_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"t", lazy_entry::string_t, 2, 0},
|
||||
{"q", lazy_entry::string_t, 9, 0},
|
||||
{"a", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, 0},
|
||||
{"info_hash", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"t", bdecode_node::string_t, 2, 0},
|
||||
{"q", bdecode_node::string_t, 9, 0},
|
||||
{"a", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, 0},
|
||||
{"info_hash", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
dht::key_desc_t get_item_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"t", lazy_entry::string_t, 2, 0},
|
||||
{"q", lazy_entry::string_t, 3, 0},
|
||||
{"a", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, 0},
|
||||
{"target", lazy_entry::string_t, 20, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"t", bdecode_node::string_t, 2, 0},
|
||||
{"q", bdecode_node::string_t, 3, 0},
|
||||
{"a", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, 0},
|
||||
{"target", bdecode_node::string_t, 20, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
// bootstrap
|
||||
|
@ -1454,16 +1476,17 @@ int test_main()
|
|||
TEST_EQUAL(g_sent_packets.front().first, initial_node);
|
||||
|
||||
lazy_from_entry(g_sent_packets.front().second, response);
|
||||
ret = verify_message(&response, find_node_desc, parsed, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, find_node_desc, parsed, 7, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_CHECK(parsed[2]->string_value() == "find_node"
|
||||
|| parsed[2]->string_value() == "get_peers");
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_CHECK(parsed[2].string_value() == "find_node"
|
||||
|| parsed[2].string_value() == "get_peers");
|
||||
|
||||
if (parsed[0]->string_value() != "q"
|
||||
|| (parsed[2]->string_value() != "find_node"
|
||||
&& parsed[2]->string_value() != "get_peers")) break;
|
||||
if (parsed[0].string_value() != "q"
|
||||
|| (parsed[2].string_value() != "find_node"
|
||||
&& parsed[2].string_value() != "get_peers")) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1483,14 +1506,15 @@ int test_main()
|
|||
TEST_EQUAL(g_sent_packets.front().first, found_node);
|
||||
|
||||
lazy_from_entry(g_sent_packets.front().second, response);
|
||||
ret = verify_message(&response, find_node_desc, parsed, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, find_node_desc, parsed, 7, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_CHECK(parsed[2]->string_value() == "find_node"
|
||||
|| parsed[2]->string_value() == "get_peers");
|
||||
if (parsed[0]->string_value() != "q" || (parsed[2]->string_value() != "find_node"
|
||||
&& parsed[2]->string_value() == "get_peers")) break;
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_CHECK(parsed[2].string_value() == "find_node"
|
||||
|| parsed[2].string_value() == "get_peers");
|
||||
if (parsed[0].string_value() != "q" || (parsed[2].string_value() != "find_node"
|
||||
&& parsed[2].string_value() == "get_peers")) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1524,13 +1548,14 @@ int test_main()
|
|||
TEST_EQUAL(g_sent_packets.front().first, initial_node);
|
||||
|
||||
lazy_from_entry(g_sent_packets.front().second, response);
|
||||
ret = verify_message(&response, get_peers_desc, parsed, 6, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, get_peers_desc, parsed, 6, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_EQUAL(parsed[2]->string_value(), "get_peers");
|
||||
TEST_EQUAL(parsed[5]->string_value(), target.to_string());
|
||||
if (parsed[0]->string_value() != "q" || parsed[2]->string_value() != "get_peers") break;
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_EQUAL(parsed[2].string_value(), "get_peers");
|
||||
TEST_EQUAL(parsed[5].string_value(), target.to_string());
|
||||
if (parsed[0].string_value() != "q" || parsed[2].string_value() != "get_peers") break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1556,13 +1581,14 @@ int test_main()
|
|||
TEST_EQUAL(g_sent_packets.front().first, next_node);
|
||||
|
||||
lazy_from_entry(g_sent_packets.front().second, response);
|
||||
ret = verify_message(&response, get_peers_desc, parsed, 6, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, get_peers_desc, parsed, 6, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_EQUAL(parsed[2]->string_value(), "get_peers");
|
||||
TEST_EQUAL(parsed[5]->string_value(), target.to_string());
|
||||
if (parsed[0]->string_value() != "q" || parsed[2]->string_value() != "get_peers") break;
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_EQUAL(parsed[2].string_value(), "get_peers");
|
||||
TEST_EQUAL(parsed[5].string_value(), target.to_string());
|
||||
if (parsed[0].string_value() != "q" || parsed[2].string_value() != "get_peers") break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1615,13 +1641,14 @@ int test_main()
|
|||
TEST_EQUAL(g_sent_packets.front().first, initial_node);
|
||||
|
||||
lazy_from_entry(g_sent_packets.front().second, response);
|
||||
ret = verify_message(&response, get_item_desc, parsed, 6, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, get_item_desc, parsed, 6, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_EQUAL(parsed[2]->string_value(), "get");
|
||||
TEST_EQUAL(parsed[5]->string_value(), items[0].target.to_string());
|
||||
if (parsed[0]->string_value() != "q" || parsed[2]->string_value() != "get") break;
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_EQUAL(parsed[2].string_value(), "get");
|
||||
TEST_EQUAL(parsed[5].string_value(), items[0].target.to_string());
|
||||
if (parsed[0].string_value() != "q" || parsed[2].string_value() != "get") break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1661,13 +1688,14 @@ int test_main()
|
|||
TEST_EQUAL(g_sent_packets.front().first, initial_node);
|
||||
|
||||
lazy_from_entry(g_sent_packets.front().second, response);
|
||||
ret = verify_message(&response, get_item_desc, parsed, 6, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, get_item_desc, parsed, 6, error_string
|
||||
, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_EQUAL(parsed[2]->string_value(), "get");
|
||||
TEST_EQUAL(parsed[5]->string_value(), target.to_string());
|
||||
if (parsed[0]->string_value() != "q" || parsed[2]->string_value() != "get") break;
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_EQUAL(parsed[2].string_value(), "get");
|
||||
TEST_EQUAL(parsed[5].string_value(), target.to_string());
|
||||
if (parsed[0].string_value() != "q" || parsed[2].string_value() != "get") break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1696,27 +1724,27 @@ int test_main()
|
|||
} while (false);
|
||||
|
||||
dht::key_desc_t put_immutable_item_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"t", lazy_entry::string_t, 2, 0},
|
||||
{"q", lazy_entry::string_t, 3, 0},
|
||||
{"a", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, 0},
|
||||
{"token", lazy_entry::string_t, 2, 0},
|
||||
{"v", lazy_entry::none_t, 0, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"t", bdecode_node::string_t, 2, 0},
|
||||
{"q", bdecode_node::string_t, 3, 0},
|
||||
{"a", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, 0},
|
||||
{"token", bdecode_node::string_t, 2, 0},
|
||||
{"v", bdecode_node::none_t, 0, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
dht::key_desc_t put_mutable_item_desc[] = {
|
||||
{"y", lazy_entry::string_t, 1, 0},
|
||||
{"t", lazy_entry::string_t, 2, 0},
|
||||
{"q", lazy_entry::string_t, 3, 0},
|
||||
{"a", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", lazy_entry::string_t, 20, 0},
|
||||
{"cas", lazy_entry::string_t, 20, key_desc_t::optional},
|
||||
{"k", lazy_entry::string_t, item_pk_len, 0},
|
||||
{"seq", lazy_entry::int_t, 0, 0},
|
||||
{"sig", lazy_entry::string_t, item_sig_len, 0},
|
||||
{"token", lazy_entry::string_t, 2, 0},
|
||||
{"v", lazy_entry::none_t, 0, key_desc_t::last_child},
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"t", bdecode_node::string_t, 2, 0},
|
||||
{"q", bdecode_node::string_t, 3, 0},
|
||||
{"a", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, 0},
|
||||
{"cas", bdecode_node::string_t, 20, key_desc_t::optional},
|
||||
{"k", bdecode_node::string_t, item_pk_len, 0},
|
||||
{"seq", bdecode_node::int_t, 0, 0},
|
||||
{"sig", bdecode_node::string_t, item_sig_len, 0},
|
||||
{"token", bdecode_node::string_t, 2, 0},
|
||||
{"v", bdecode_node::none_t, 0, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
// immutable put
|
||||
|
@ -1745,7 +1773,8 @@ int test_main()
|
|||
if (packet == g_sent_packets.end()) continue;
|
||||
|
||||
lazy_from_entry(packet->second, response);
|
||||
ret = verify_message(&response, get_item_desc, parsed, 6, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, get_item_desc, parsed, 6, error_string
|
||||
, sizeof(error_string));
|
||||
if (!ret)
|
||||
{
|
||||
fprintf(stderr, " invalid get request: %s\n", print_entry(response).c_str());
|
||||
|
@ -1772,18 +1801,19 @@ int test_main()
|
|||
if (packet == g_sent_packets.end()) continue;
|
||||
|
||||
lazy_from_entry(packet->second, response);
|
||||
ret = verify_message(&response, put_immutable_item_desc, parsed, 7, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, put_immutable_item_desc, parsed, 7
|
||||
, error_string, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_EQUAL(parsed[2]->string_value(), "put");
|
||||
std::pair<const char*, int> v = parsed[6]->data_section();
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_EQUAL(parsed[2].string_value(), "put");
|
||||
std::pair<const char*, int> v = parsed[6].data_section();
|
||||
TEST_EQUAL(v.second, itemv.second);
|
||||
TEST_CHECK(memcmp(v.first, itemv.first, itemv.second) == 0);
|
||||
char t[10];
|
||||
snprintf(t, sizeof(t), "%02d", i);
|
||||
TEST_EQUAL(parsed[5]->string_value(), t);
|
||||
if (parsed[0]->string_value() != "q" || parsed[2]->string_value() != "put") continue;
|
||||
TEST_EQUAL(parsed[5].string_value(), t);
|
||||
if (parsed[0].string_value() != "q" || parsed[2].string_value() != "put") continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1827,7 +1857,8 @@ int test_main()
|
|||
if (packet == g_sent_packets.end()) continue;
|
||||
|
||||
lazy_from_entry(packet->second, response);
|
||||
ret = verify_message(&response, get_item_desc, parsed, 6, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, get_item_desc, parsed, 6
|
||||
, error_string, sizeof(error_string));
|
||||
if (!ret)
|
||||
{
|
||||
fprintf(stderr, " invalid mutable put request: %s\n", print_entry(response).c_str());
|
||||
|
@ -1854,21 +1885,22 @@ int test_main()
|
|||
if (packet == g_sent_packets.end()) continue;
|
||||
|
||||
lazy_from_entry(packet->second, response);
|
||||
ret = verify_message(&response, put_mutable_item_desc, parsed, 11, error_string, sizeof(error_string));
|
||||
ret = verify_message(response, put_mutable_item_desc, parsed, 11
|
||||
, error_string, sizeof(error_string));
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(parsed[0]->string_value(), "q");
|
||||
TEST_EQUAL(parsed[2]->string_value(), "put");
|
||||
TEST_EQUAL(parsed[6]->string_value(), std::string(public_key, item_pk_len));
|
||||
TEST_EQUAL(parsed[7]->int_value(), seq);
|
||||
TEST_EQUAL(parsed[8]->string_value(), sig);
|
||||
std::pair<const char*, int> v = parsed[10]->data_section();
|
||||
TEST_EQUAL(parsed[0].string_value(), "q");
|
||||
TEST_EQUAL(parsed[2].string_value(), "put");
|
||||
TEST_EQUAL(parsed[6].string_value(), std::string(public_key, item_pk_len));
|
||||
TEST_EQUAL(parsed[7].int_value(), seq);
|
||||
TEST_EQUAL(parsed[8].string_value(), sig);
|
||||
std::pair<const char*, int> v = parsed[10].data_section();
|
||||
TEST_EQUAL(v.second, itemv.second);
|
||||
TEST_CHECK(memcmp(v.first, itemv.first, itemv.second) == 0);
|
||||
char t[10];
|
||||
snprintf(t, sizeof(t), "%02d", i);
|
||||
TEST_EQUAL(parsed[9]->string_value(), t);
|
||||
if (parsed[0]->string_value() != "q" || parsed[2]->string_value() != "put") continue;
|
||||
TEST_EQUAL(parsed[9].string_value(), t);
|
||||
if (parsed[0].string_value() != "q" || parsed[2].string_value() != "put") continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/alloca.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/peer_info.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include <cstring>
|
||||
#include <boost/bind.hpp>
|
||||
#include <iostream>
|
||||
|
@ -476,20 +476,26 @@ void test_dont_have()
|
|||
int ext_msg = recv_buffer[1];
|
||||
if (ext_msg != 0) continue;
|
||||
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
int ret = lazy_bdecode(recv_buffer + 2, recv_buffer + len, e, ec);
|
||||
int pos = 0;
|
||||
int ret = bdecode(recv_buffer + 2, recv_buffer + len, e, ec, &pos);
|
||||
if (ret != 0)
|
||||
{
|
||||
fprintf(stderr, "failed to parse extension handshake: %s at pos %d\n"
|
||||
, ec.message().c_str(), pos);
|
||||
}
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
printf("extension handshake: %s\n", print_entry(e).c_str());
|
||||
lazy_entry const* m = e.dict_find_dict("m");
|
||||
bdecode_node m = e.dict_find_dict("m");
|
||||
TEST_CHECK(m);
|
||||
if (!m) return;
|
||||
lazy_entry const* dont_have = m->dict_find_int("lt_donthave");
|
||||
bdecode_node dont_have = m.dict_find_int("lt_donthave");
|
||||
TEST_CHECK(dont_have);
|
||||
if (!dont_have) return;
|
||||
|
||||
lt_dont_have = dont_have->int_value();
|
||||
lt_dont_have = dont_have.int_value();
|
||||
}
|
||||
|
||||
char* ptr = recv_buffer;
|
||||
|
|
|
@ -169,8 +169,8 @@ int test_main()
|
|||
|
||||
std::vector<char> buf;
|
||||
bencode(std::back_inserter(buf), session_state);
|
||||
lazy_entry session_state2;
|
||||
int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), session_state2, ec);
|
||||
bdecode_node session_state2;
|
||||
int ret = bdecode(&buf[0], &buf[0] + buf.size(), session_state2, ec);
|
||||
TEST_CHECK(ret == 0);
|
||||
|
||||
fprintf(stderr, "session_state\n%s\n", print_entry(session_state2).c_str());
|
||||
|
@ -204,7 +204,8 @@ int test_main()
|
|||
#endif
|
||||
|
||||
// make sure settings that haven't been changed from their defaults are not saved
|
||||
TEST_CHECK(session_state2.dict_find("settings")->dict_find("optimistic_disk_retry") == 0);
|
||||
TEST_CHECK(session_state2.dict_find("settings")
|
||||
.dict_find("optimistic_disk_retry") == 0);
|
||||
|
||||
s->load_state(session_state2);
|
||||
|
||||
|
|
|
@ -86,12 +86,12 @@ int test_main()
|
|||
#endif
|
||||
|
||||
char const eplist[] = "l6:\x10\x05\x80\x01\x05\x39" "18:\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\x05\x39" "e";
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
lazy_bdecode(eplist, eplist + sizeof(eplist)-1, e, ec);
|
||||
bdecode(eplist, eplist + sizeof(eplist)-1, e, ec);
|
||||
TEST_CHECK(!ec);
|
||||
std::vector<udp::endpoint> list;
|
||||
read_endpoint_list<udp::endpoint>(&e, list);
|
||||
read_endpoint_list<udp::endpoint>(e, list);
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
TEST_EQUAL(list.size(), 2);
|
||||
|
|
|
@ -459,7 +459,7 @@ void test_check_files(std::string const& test_path
|
|||
libtorrent::mutex lock;
|
||||
|
||||
bool done = false;
|
||||
lazy_entry frd;
|
||||
bdecode_node frd;
|
||||
io.async_check_fastresume(pm.get(), &frd, boost::bind(&on_check_resume_data, _1, &done));
|
||||
io.submit_jobs();
|
||||
ios.reset();
|
||||
|
|
|
@ -177,9 +177,9 @@ int main(int argc, char* argv[])
|
|||
state.resize(size);
|
||||
fread(&state[0], 1, state.size(), f);
|
||||
|
||||
lazy_entry e;
|
||||
bdecode_node e;
|
||||
error_code ec;
|
||||
lazy_bdecode(&state[0], &state[0] + state.size(), e, ec);
|
||||
bdecode(&state[0], &state[0] + state.size(), e, ec);
|
||||
if (ec)
|
||||
fprintf(stderr, "failed to parse .dht file: (%d) %s\n"
|
||||
, ec.value(), ec.message().c_str());
|
||||
|
|
|
@ -34,11 +34,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/cstdint.hpp>
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <boost/random/uniform_int_distribution.hpp>
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
|
||||
using libtorrent::lazy_entry;
|
||||
using libtorrent::bdecode_node;
|
||||
using boost::random::mt19937;
|
||||
using boost::random::uniform_int_distribution;
|
||||
|
||||
|
@ -233,52 +233,52 @@ void render_arbitrary_item(std::string& out)
|
|||
}
|
||||
}
|
||||
|
||||
void render_variant(std::string& out, lazy_entry const& e)
|
||||
void render_variant(std::string& out, bdecode_node const& e)
|
||||
{
|
||||
switch (e.type())
|
||||
{
|
||||
case lazy_entry::dict_t:
|
||||
case bdecode_node::dict_t:
|
||||
print_dict(out);
|
||||
for (int i = 0; i < e.dict_size(); ++i)
|
||||
{
|
||||
std::pair<std::string, lazy_entry const*> item = e.dict_at(i);
|
||||
std::pair<std::string, bdecode_node> item = e.dict_at(i);
|
||||
const bool duplicate = g_seed == 1;
|
||||
const bool skipped = g_seed == 2;
|
||||
g_seed -= 2;
|
||||
if (duplicate)
|
||||
{
|
||||
print_string(out, item.first);
|
||||
render_variant(out, *item.second);
|
||||
render_variant(out, item.second);
|
||||
}
|
||||
if (!skipped)
|
||||
{
|
||||
print_string(out, item.first);
|
||||
render_variant(out, *item.second);
|
||||
render_variant(out, item.second);
|
||||
}
|
||||
|
||||
render_arbitrary_item(out);
|
||||
}
|
||||
print_terminate(out);
|
||||
break;
|
||||
case lazy_entry::list_t:
|
||||
case bdecode_node::list_t:
|
||||
print_list(out);
|
||||
for (int i = 0; i < e.list_size(); ++i)
|
||||
{
|
||||
const bool duplicate = g_seed == 1;
|
||||
const bool skipped = g_seed == 2;
|
||||
g_seed -= 2;
|
||||
if (duplicate) render_variant(out, *e.list_at(i));
|
||||
if (duplicate) render_variant(out, e.list_at(i));
|
||||
|
||||
render_arbitrary_item(out);
|
||||
|
||||
if (!skipped) render_variant(out, *e.list_at(i));
|
||||
if (!skipped) render_variant(out, e.list_at(i));
|
||||
}
|
||||
print_terminate(out);
|
||||
break;
|
||||
case lazy_entry::int_t:
|
||||
case bdecode_node::int_t:
|
||||
print_int(out, e.int_value());
|
||||
break;
|
||||
case lazy_entry::string_t:
|
||||
case bdecode_node::string_t:
|
||||
print_string(out, e.string_value());
|
||||
break;
|
||||
default:
|
||||
|
@ -371,8 +371,8 @@ int main(int argc, char const* argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
lazy_entry e;
|
||||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
bdecode_node e;
|
||||
if (buf.size() == 0 || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR parsing file: %s\n%s\n"
|
||||
, *argv, ec.message().c_str());
|
||||
|
|
|
@ -3,10 +3,15 @@
|
|||
OBJECT_PATH=bin/gcc-4.8/debug/asserts-off/boost-source/debug-iterators-on/export-extra-on/invariant-checks-off/link-static/logging-on/test-coverage-on/threading-multi/src
|
||||
|
||||
function run_test {
|
||||
set +e
|
||||
rm $OBJECT_PATH/*.gcda
|
||||
set -e
|
||||
|
||||
cd test
|
||||
set +e
|
||||
rm -rf bin
|
||||
set -e
|
||||
|
||||
bjam asserts=off invariant-checks=off link=static boost=source test-coverage=on picker-debugging=off -j4 $1
|
||||
cd ..
|
||||
|
||||
|
@ -20,11 +25,16 @@ function run_test {
|
|||
|
||||
# force rebuilding and rerunning the unit tests
|
||||
cd test
|
||||
set +e
|
||||
rm -rf bin
|
||||
set -e
|
||||
cd ..
|
||||
|
||||
set +e
|
||||
mkdir test-coverage
|
||||
set -e
|
||||
|
||||
run_test test_bdecode "*/bdecode.*"
|
||||
run_test test_piece_picker "*/piece_picker.*"
|
||||
run_test test_torrent_info "*/torrent_info.*"
|
||||
run_test test_part_file "*/part_file.*"
|
||||
|
@ -40,5 +50,3 @@ run_test test_sliding_average "*/sliding_average.*"
|
|||
run_test test_string "*/escape_string.*"
|
||||
run_test test_utf8 "*/ConvertUTF.*"
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue