merged RC_1_1 into master
This commit is contained in:
commit
173951ec7f
|
@ -50,6 +50,11 @@
|
||||||
* resume data no longer has timestamps of files
|
* resume data no longer has timestamps of files
|
||||||
* require C++11 to build libtorrent
|
* require C++11 to build libtorrent
|
||||||
|
|
||||||
|
* storage optimization to peer classes
|
||||||
|
* fix torrent name in alerts of builds with deprecated functions
|
||||||
|
* make torrent_info::is_valid() return false if torrent failed to load
|
||||||
|
* fix per-torrent rate limits for >256 peer classes
|
||||||
|
* don't load user_agent and peer_fingerprint from session_state
|
||||||
* fix file rename issue with name prefix matching torrent name
|
* fix file rename issue with name prefix matching torrent name
|
||||||
* fix division by zero when setting tick_interval > 1000
|
* fix division by zero when setting tick_interval > 1000
|
||||||
* fix move_storage() to its own directory (would delete the files)
|
* fix move_storage() to its own directory (would delete the files)
|
||||||
|
|
|
@ -10,6 +10,8 @@ void bind_fingerprint()
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
def("generate_fingerprint", &generate_fingerprint);
|
||||||
|
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
|
|
@ -297,6 +297,9 @@ class test_session(unittest.TestCase):
|
||||||
self.assertEqual(s.get_settings()['num_want'], 66)
|
self.assertEqual(s.get_settings()['num_want'], 66)
|
||||||
self.assertEqual(s.get_settings()['user_agent'], 'test123')
|
self.assertEqual(s.get_settings()['user_agent'], 'test123')
|
||||||
|
|
||||||
|
def test_fingerprint(self):
|
||||||
|
self.assertEqual(lt.generate_fingerprint('LT', 0, 1, 2, 3), '-LT0123-')
|
||||||
|
self.assertEqual(lt.generate_fingerprint('..', 10, 1, 2, 3), '-..A123-')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(lt.__version__)
|
print(lt.__version__)
|
||||||
|
|
|
@ -164,11 +164,6 @@ namespace libtorrent
|
||||||
return bind_ep.address();
|
return bind_ep.address();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: function not used and not exported in release?
|
|
||||||
// returns true if the given device exists
|
|
||||||
TORRENT_EXTRA_EXPORT bool has_interface(char const* name, io_service& ios
|
|
||||||
, error_code& ec);
|
|
||||||
|
|
||||||
// returns the device name whose local address is ``addr``. If
|
// returns the device name whose local address is ``addr``. If
|
||||||
// no such device is found, an empty string is returned.
|
// no such device is found, an empty string is returned.
|
||||||
TORRENT_EXTRA_EXPORT std::string device_for_address(address addr
|
TORRENT_EXTRA_EXPORT std::string device_for_address(address addr
|
||||||
|
|
|
@ -37,13 +37,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
typedef std::uint16_t peer_class_t;
|
typedef std::uint32_t peer_class_t;
|
||||||
|
|
||||||
struct peer_class_info
|
struct peer_class_info
|
||||||
{
|
{
|
||||||
|
@ -82,12 +83,13 @@ namespace libtorrent
|
||||||
int download_priority;
|
int download_priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXTRA_EXPORT peer_class : std::enable_shared_from_this<peer_class>
|
struct TORRENT_EXTRA_EXPORT peer_class
|
||||||
{
|
{
|
||||||
friend struct peer_class_pool;
|
friend struct peer_class_pool;
|
||||||
|
|
||||||
explicit peer_class(std::string const& l)
|
explicit peer_class(std::string const& l)
|
||||||
: ignore_unchoke_slots(false)
|
: in_use(true)
|
||||||
|
, ignore_unchoke_slots(false)
|
||||||
, connection_limit_factor(100)
|
, connection_limit_factor(100)
|
||||||
, label(l)
|
, label(l)
|
||||||
, references(1)
|
, references(1)
|
||||||
|
@ -96,6 +98,12 @@ namespace libtorrent
|
||||||
priority[1] = 1;
|
priority[1] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
in_use = false;
|
||||||
|
label.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void set_info(peer_class_info const* pci);
|
void set_info(peer_class_info const* pci);
|
||||||
void get_info(peer_class_info* pci) const;
|
void get_info(peer_class_info* pci) const;
|
||||||
|
|
||||||
|
@ -106,6 +114,9 @@ namespace libtorrent
|
||||||
// keeps track of the current quotas
|
// keeps track of the current quotas
|
||||||
bandwidth_channel channel[2];
|
bandwidth_channel channel[2];
|
||||||
|
|
||||||
|
// this is set to false when this slot is not in use for a peer_class
|
||||||
|
bool in_use;
|
||||||
|
|
||||||
bool ignore_unchoke_slots;
|
bool ignore_unchoke_slots;
|
||||||
int connection_limit_factor;
|
int connection_limit_factor;
|
||||||
|
|
||||||
|
@ -119,7 +130,6 @@ namespace libtorrent
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int references;
|
int references;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXTRA_EXPORT peer_class_pool
|
struct TORRENT_EXTRA_EXPORT peer_class_pool
|
||||||
|
@ -134,7 +144,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// state for peer classes (a peer can belong to multiple classes)
|
// state for peer classes (a peer can belong to multiple classes)
|
||||||
// this can control
|
// this can control
|
||||||
std::vector<std::shared_ptr<peer_class>> m_peer_classes;
|
std::deque<peer_class> m_peer_classes;
|
||||||
|
|
||||||
// indices in m_peer_classes that are no longer used
|
// indices in m_peer_classes that are no longer used
|
||||||
std::vector<peer_class_t> m_free_list;
|
std::vector<peer_class_t> m_free_list;
|
||||||
|
|
|
@ -128,6 +128,11 @@ namespace libtorrent
|
||||||
// The ``flags`` argument is used to filter which parts of the session
|
// The ``flags`` argument is used to filter which parts of the session
|
||||||
// state to save or load. By default, all state is saved/restored (except
|
// state to save or load. By default, all state is saved/restored (except
|
||||||
// for the individual torrents). see save_state_flags_t
|
// for the individual torrents). see save_state_flags_t
|
||||||
|
//
|
||||||
|
// When saving settings, there are two fields that are *not* loaded.
|
||||||
|
// ``peer_fingerprint`` and ``user_agent``. Those are left as configured
|
||||||
|
// by the ``session_settings`` passed to the session constructor or
|
||||||
|
// subsequently set via apply_settings().
|
||||||
void save_state(entry& e, std::uint32_t flags = 0xffffffff) const;
|
void save_state(entry& e, std::uint32_t flags = 0xffffffff) const;
|
||||||
void load_state(bdecode_node const& e, std::uint32_t flags = 0xffffffff);
|
void load_state(bdecode_node const& e, std::uint32_t flags = 0xffffffff);
|
||||||
|
|
||||||
|
|
|
@ -87,8 +87,13 @@ namespace libtorrent
|
||||||
void set_int(int name, int val);
|
void set_int(int name, int val);
|
||||||
void set_bool(int name, bool val);
|
void set_bool(int name, bool val);
|
||||||
bool has_val(int name) const;
|
bool has_val(int name) const;
|
||||||
|
|
||||||
|
// clear the settings pack from all settings
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
// clear a specific setting from the pack
|
||||||
|
void clear(int name);
|
||||||
|
|
||||||
std::string const& get_str(int name) const;
|
std::string const& get_str(int name) const;
|
||||||
int get_int(int name) const;
|
int get_int(int name) const;
|
||||||
bool get_bool(int name) const;
|
bool get_bool(int name) const;
|
||||||
|
|
|
@ -77,17 +77,13 @@ namespace libtorrent {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
name = torrent_name();
|
name = m_alloc.get().ptr(m_name_idx);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char const* torrent_alert::torrent_name() const
|
char const* torrent_alert::torrent_name() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return name.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_name_idx);
|
return m_alloc.get().ptr(m_name_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string torrent_alert::message() const
|
std::string torrent_alert::message() const
|
||||||
|
@ -125,11 +121,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* tracker_alert::tracker_url() const
|
char const* tracker_alert::tracker_url() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return url.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_url_idx);
|
return m_alloc.get().ptr(m_url_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tracker_alert::message() const
|
std::string tracker_alert::message() const
|
||||||
|
@ -201,11 +193,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* file_renamed_alert::new_name() const
|
char const* file_renamed_alert::new_name() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return name.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_name_idx);
|
return m_alloc.get().ptr(m_name_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file_renamed_alert::message() const
|
std::string file_renamed_alert::message() const
|
||||||
|
@ -299,11 +287,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* tracker_error_alert::error_message() const
|
char const* tracker_error_alert::error_message() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return msg.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_msg_idx);
|
return m_alloc.get().ptr(m_msg_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tracker_error_alert::message() const
|
std::string tracker_error_alert::message() const
|
||||||
|
@ -329,11 +313,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* tracker_warning_alert::warning_message() const
|
char const* tracker_warning_alert::warning_message() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return msg.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_msg_idx);
|
return m_alloc.get().ptr(m_msg_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tracker_warning_alert::message() const
|
std::string tracker_warning_alert::message() const
|
||||||
|
@ -384,12 +364,8 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* scrape_failed_alert::error_message() const
|
char const* scrape_failed_alert::error_message() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return msg.c_str();
|
|
||||||
#else
|
|
||||||
if (m_msg_idx == aux::allocation_slot()) return "";
|
if (m_msg_idx == aux::allocation_slot()) return "";
|
||||||
else return m_alloc.get().ptr(m_msg_idx);
|
else return m_alloc.get().ptr(m_msg_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string scrape_failed_alert::message() const
|
std::string scrape_failed_alert::message() const
|
||||||
|
@ -655,11 +631,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* storage_moved_alert::storage_path() const
|
char const* storage_moved_alert::storage_path() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return path.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_path_idx);
|
return m_alloc.get().ptr(m_path_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
storage_moved_failed_alert::storage_moved_failed_alert(
|
storage_moved_failed_alert::storage_moved_failed_alert(
|
||||||
|
@ -676,11 +648,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* storage_moved_failed_alert::file_path() const
|
char const* storage_moved_failed_alert::file_path() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return file.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_file_idx);
|
return m_alloc.get().ptr(m_file_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string storage_moved_failed_alert::message() const
|
std::string storage_moved_failed_alert::message() const
|
||||||
|
@ -1032,11 +1000,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* portmap_log_alert::log_message() const
|
char const* portmap_log_alert::log_message() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return msg.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_log_idx);
|
return m_alloc.get().ptr(m_log_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string portmap_log_alert::message() const
|
std::string portmap_log_alert::message() const
|
||||||
|
@ -1075,11 +1039,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* fastresume_rejected_alert::file_path() const
|
char const* fastresume_rejected_alert::file_path() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return file.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_path_idx);
|
return m_alloc.get().ptr(m_path_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_blocked_alert::peer_blocked_alert(aux::stack_allocator& alloc
|
peer_blocked_alert::peer_blocked_alert(aux::stack_allocator& alloc
|
||||||
|
@ -1246,11 +1206,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* trackerid_alert::tracker_id() const
|
char const* trackerid_alert::tracker_id() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return trackerid.c_str();
|
|
||||||
#else
|
|
||||||
return m_alloc.get().ptr(m_tracker_idx);
|
return m_alloc.get().ptr(m_tracker_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string trackerid_alert::message() const
|
std::string trackerid_alert::message() const
|
||||||
|
@ -1837,12 +1793,8 @@ namespace libtorrent {
|
||||||
|
|
||||||
char const* url_seed_alert::error_message() const
|
char const* url_seed_alert::error_message() const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
return msg.c_str();
|
|
||||||
#else
|
|
||||||
if (m_msg_idx == aux::allocation_slot()) return "";
|
if (m_msg_idx == aux::allocation_slot()) return "";
|
||||||
return m_alloc.get().ptr(m_msg_idx);
|
return m_alloc.get().ptr(m_msg_idx);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file_error_alert::file_error_alert(aux::stack_allocator& alloc
|
file_error_alert::file_error_alert(aux::stack_allocator& alloc
|
||||||
|
|
|
@ -380,6 +380,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(ti.num_files() > 0);
|
TORRENT_ASSERT(ti.num_files() > 0);
|
||||||
TORRENT_ASSERT(ti.total_size() > 0);
|
TORRENT_ASSERT(ti.total_size() > 0);
|
||||||
|
|
||||||
|
if (!ti.is_valid()) return;
|
||||||
if (ti.creation_date() > 0) m_creation_date = ti.creation_date();
|
if (ti.creation_date() > 0) m_creation_date = ti.creation_date();
|
||||||
|
|
||||||
if (!ti.creator().empty()) set_creator(ti.creator().c_str());
|
if (!ti.creator().empty()) set_creator(ti.creator().c_str());
|
||||||
|
|
|
@ -1107,17 +1107,6 @@ namespace libtorrent
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if the given device exists
|
|
||||||
bool has_interface(char const* name, io_service& ios, error_code& ec)
|
|
||||||
{
|
|
||||||
std::vector<ip_interface> ifs = enum_net_interfaces(ios, ec);
|
|
||||||
if (ec) return false;
|
|
||||||
|
|
||||||
for (auto const& iface : ifs)
|
|
||||||
if (iface.name == name) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the device name whose local address is ``addr``. If
|
// returns the device name whose local address is ``addr``. If
|
||||||
// no such device is found, an empty string is returned.
|
// no such device is found, an empty string is returned.
|
||||||
std::string device_for_address(address addr, io_service& ios, error_code& ec)
|
std::string device_for_address(address addr, io_service& ios, error_code& ec)
|
||||||
|
|
|
@ -80,47 +80,47 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
ret = m_free_list.back();
|
ret = m_free_list.back();
|
||||||
m_free_list.pop_back();
|
m_free_list.pop_back();
|
||||||
|
m_peer_classes[ret] = peer_class(label);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_peer_classes.size() < 0x10000);
|
TORRENT_ASSERT(m_peer_classes.size() < 0x100000000);
|
||||||
ret = peer_class_t(m_peer_classes.size());
|
ret = peer_class_t(m_peer_classes.size());
|
||||||
m_peer_classes.push_back(std::shared_ptr<peer_class>());
|
m_peer_classes.push_back(peer_class(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_ASSERT(m_peer_classes[ret].get() == nullptr);
|
|
||||||
m_peer_classes[ret] = std::make_shared<peer_class>(label);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_class_pool::decref(peer_class_t c)
|
void peer_class_pool::decref(peer_class_t c)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(c < m_peer_classes.size());
|
TORRENT_ASSERT(c < m_peer_classes.size());
|
||||||
TORRENT_ASSERT(m_peer_classes[c].get());
|
TORRENT_ASSERT(m_peer_classes[c].in_use);
|
||||||
|
TORRENT_ASSERT(m_peer_classes[c].references > 0);
|
||||||
|
|
||||||
--m_peer_classes[c]->references;
|
--m_peer_classes[c].references;
|
||||||
if (m_peer_classes[c]->references) return;
|
if (m_peer_classes[c].references) return;
|
||||||
m_peer_classes[c].reset();
|
m_peer_classes[c].clear();
|
||||||
m_free_list.push_back(c);
|
m_free_list.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_class_pool::incref(peer_class_t c)
|
void peer_class_pool::incref(peer_class_t c)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(c < m_peer_classes.size());
|
TORRENT_ASSERT(c < m_peer_classes.size());
|
||||||
TORRENT_ASSERT(m_peer_classes[c].get());
|
TORRENT_ASSERT(m_peer_classes[c].in_use);
|
||||||
|
|
||||||
++m_peer_classes[c]->references;
|
++m_peer_classes[c].references;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_class* peer_class_pool::at(peer_class_t c)
|
peer_class* peer_class_pool::at(peer_class_t c)
|
||||||
{
|
{
|
||||||
if (c >= m_peer_classes.size()) return nullptr;
|
if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return nullptr;
|
||||||
return m_peer_classes[c].get();
|
return &m_peer_classes[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_class const* peer_class_pool::at(peer_class_t c) const
|
peer_class const* peer_class_pool::at(peer_class_t c) const
|
||||||
{
|
{
|
||||||
if (c >= m_peer_classes.size()) return nullptr;
|
if (c >= m_peer_classes.size() || !m_peer_classes[c].in_use) return nullptr;
|
||||||
return m_peer_classes[c].get();
|
return &m_peer_classes[c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -790,6 +790,12 @@ namespace aux {
|
||||||
{
|
{
|
||||||
// apply_settings_pack will update dht and proxy
|
// apply_settings_pack will update dht and proxy
|
||||||
settings_pack pack = load_pack_from_dict(settings);
|
settings_pack pack = load_pack_from_dict(settings);
|
||||||
|
|
||||||
|
// these settings are not loaded from state
|
||||||
|
// they are set by the client software, not configured by users
|
||||||
|
pack.clear(settings_pack::user_agent);
|
||||||
|
pack.clear(settings_pack::peer_fingerprint);
|
||||||
|
|
||||||
apply_settings_pack_impl(pack);
|
apply_settings_pack_impl(pack);
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
need_update_dht = false;
|
need_update_dht = false;
|
||||||
|
|
|
@ -666,4 +666,38 @@ namespace libtorrent
|
||||||
m_ints.clear();
|
m_ints.clear();
|
||||||
m_bools.clear();
|
m_bools.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void settings_pack::clear(int const name)
|
||||||
|
{
|
||||||
|
switch (name & type_mask)
|
||||||
|
{
|
||||||
|
case string_type_base:
|
||||||
|
{
|
||||||
|
std::pair<boost::uint16_t, std::string> v(name, std::string());
|
||||||
|
std::vector<std::pair<boost::uint16_t, std::string> >::iterator i
|
||||||
|
= std::lower_bound(m_strings.begin(), m_strings.end(), v
|
||||||
|
, &compare_first<std::string>);
|
||||||
|
if (i != m_strings.end() && i->first == name) m_strings.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case int_type_base:
|
||||||
|
{
|
||||||
|
std::pair<boost::uint16_t, int> v(name, 0);
|
||||||
|
std::vector<std::pair<boost::uint16_t, int> >::iterator i
|
||||||
|
= std::lower_bound(m_ints.begin(), m_ints.end(), v
|
||||||
|
, &compare_first<int>);
|
||||||
|
if (i != m_ints.end() && i->first == name) m_ints.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case bool_type_base:
|
||||||
|
{
|
||||||
|
std::pair<boost::uint16_t, bool> v(name, false);
|
||||||
|
std::vector<std::pair<boost::uint16_t, bool> >::iterator i
|
||||||
|
= std::lower_bound(m_bools.begin(), m_bools.end(), v
|
||||||
|
, &compare_first<bool>);
|
||||||
|
if (i != m_bools.end() && i->first == name) m_bools.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1081,6 +1081,8 @@ namespace libtorrent
|
||||||
if (!name_ent)
|
if (!name_ent)
|
||||||
{
|
{
|
||||||
ec = errors::torrent_missing_name;
|
ec = errors::torrent_missing_name;
|
||||||
|
// mark the torrent as invalid
|
||||||
|
m_files.set_piece_length(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,14 +1099,22 @@ namespace libtorrent
|
||||||
// this is the counter used to name pad files
|
// this is the counter used to name pad files
|
||||||
int pad_file_cnt = 0;
|
int pad_file_cnt = 0;
|
||||||
if (!extract_single_file(info, files, "", info_ptr_diff, true, pad_file_cnt, ec))
|
if (!extract_single_file(info, files, "", info_ptr_diff, true, pad_file_cnt, ec))
|
||||||
|
{
|
||||||
|
// mark the torrent as invalid
|
||||||
|
m_files.set_piece_length(0);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_flags &= ~multifile;
|
m_flags &= ~multifile;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!extract_files(files_node, files, name, info_ptr_diff, ec))
|
if (!extract_files(files_node, files, name, info_ptr_diff, ec))
|
||||||
|
{
|
||||||
|
// mark the torrent as invalid
|
||||||
|
m_files.set_piece_length(0);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
m_flags |= multifile;
|
m_flags |= multifile;
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(!files.name().empty());
|
TORRENT_ASSERT(!files.name().empty());
|
||||||
|
@ -1121,6 +1131,8 @@ namespace libtorrent
|
||||||
if (!pieces && !root_hash)
|
if (!pieces && !root_hash)
|
||||||
{
|
{
|
||||||
ec = errors::torrent_missing_pieces;
|
ec = errors::torrent_missing_pieces;
|
||||||
|
// mark the torrent as invalid
|
||||||
|
m_files.set_piece_length(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,6 +1141,8 @@ namespace libtorrent
|
||||||
if (pieces.string_length() != files.num_pieces() * 20)
|
if (pieces.string_length() != files.num_pieces() * 20)
|
||||||
{
|
{
|
||||||
ec = errors::torrent_invalid_hashes;
|
ec = errors::torrent_invalid_hashes;
|
||||||
|
// mark the torrent as invalid
|
||||||
|
m_files.set_piece_length(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,11 +1156,15 @@ namespace libtorrent
|
||||||
if (root_hash.string_length() != 20)
|
if (root_hash.string_length() != 20)
|
||||||
{
|
{
|
||||||
ec = errors::torrent_invalid_hashes;
|
ec = errors::torrent_invalid_hashes;
|
||||||
|
// mark the torrent as invalid
|
||||||
|
m_files.set_piece_length(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (files.num_pieces() >= std::numeric_limits<int>::max()/2)
|
if (files.num_pieces() >= std::numeric_limits<int>::max()/2)
|
||||||
{
|
{
|
||||||
ec = errors::too_many_pieces_in_torrent;
|
ec = errors::too_many_pieces_in_torrent;
|
||||||
|
// mark the torrent as invalid
|
||||||
|
m_files.set_piece_length(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int const num_leafs = merkle_num_leafs(files.num_pieces());
|
int const num_leafs = merkle_num_leafs(files.num_pieces());
|
||||||
|
|
|
@ -66,11 +66,11 @@ TORRENT_TEST(peer_class)
|
||||||
TEST_CHECK(id3 == id2 + 1);
|
TEST_CHECK(id3 == id2 + 1);
|
||||||
|
|
||||||
// make sure refcounting works
|
// make sure refcounting works
|
||||||
TEST_CHECK(class_name(id3, pool) == "test3");
|
TEST_EQUAL(class_name(id3, pool), "test3");
|
||||||
pool.incref(id3);
|
pool.incref(id3);
|
||||||
TEST_CHECK(class_name(id3, pool) == "test3");
|
TEST_EQUAL(class_name(id3, pool), "test3");
|
||||||
pool.decref(id3);
|
pool.decref(id3);
|
||||||
TEST_CHECK(class_name(id3, pool) == "test3");
|
TEST_EQUAL(class_name(id3, pool), "test3");
|
||||||
pool.decref(id3);
|
pool.decref(id3);
|
||||||
// it should have been deleted now
|
// it should have been deleted now
|
||||||
TEST_CHECK(pool.at(id3) == nullptr);
|
TEST_CHECK(pool.at(id3) == nullptr);
|
||||||
|
@ -81,8 +81,8 @@ TORRENT_TEST(peer_class)
|
||||||
|
|
||||||
peer_class_info i;
|
peer_class_info i;
|
||||||
pool.at(id2)->get_info(&i);
|
pool.at(id2)->get_info(&i);
|
||||||
TEST_CHECK(i.upload_limit == 1000);
|
TEST_EQUAL(i.upload_limit, 1000);
|
||||||
TEST_CHECK(i.download_limit == 2000);
|
TEST_EQUAL(i.download_limit, 2000);
|
||||||
|
|
||||||
// test peer_class_type_filter
|
// test peer_class_type_filter
|
||||||
peer_class_type_filter filter;
|
peer_class_type_filter filter;
|
||||||
|
|
|
@ -304,3 +304,47 @@ TORRENT_TEST(session_shutdown)
|
||||||
lt::session ses(pack);
|
lt::session ses(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure we don't restore peer_id from session state
|
||||||
|
TORRENT_TEST(save_state_peer_id)
|
||||||
|
{
|
||||||
|
lt::settings_pack pack;
|
||||||
|
pack.set_str(settings_pack::peer_fingerprint, "AAA");
|
||||||
|
lt::session ses(pack);
|
||||||
|
lt::peer_id const pid1 = ses.id();
|
||||||
|
TEST_CHECK(pid1[0] == 'A');
|
||||||
|
TEST_CHECK(pid1[1] == 'A');
|
||||||
|
TEST_CHECK(pid1[2] == 'A');
|
||||||
|
|
||||||
|
lt::entry st;
|
||||||
|
ses.save_state(st);
|
||||||
|
|
||||||
|
pack.set_str(settings_pack::peer_fingerprint, "foobar");
|
||||||
|
ses.apply_settings(pack);
|
||||||
|
|
||||||
|
lt::peer_id const pid2 = ses.id();
|
||||||
|
TEST_CHECK(pid2[0] == 'f');
|
||||||
|
TEST_CHECK(pid2[1] == 'o');
|
||||||
|
TEST_CHECK(pid2[2] == 'o');
|
||||||
|
TEST_CHECK(pid2[3] == 'b');
|
||||||
|
TEST_CHECK(pid2[4] == 'a');
|
||||||
|
TEST_CHECK(pid2[5] == 'r');
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<char> buf;
|
||||||
|
bencode(std::back_inserter(buf), st);
|
||||||
|
bdecode_node state;
|
||||||
|
error_code ec;
|
||||||
|
int ret = bdecode(buf.data(), buf.data() + buf.size()
|
||||||
|
, state, ec, nullptr, 100, 1000);
|
||||||
|
TEST_EQUAL(ret, 0);
|
||||||
|
ses.load_state(state);
|
||||||
|
|
||||||
|
lt::peer_id const pid3 = ses.id();
|
||||||
|
TEST_CHECK(pid3[0] == 'f');
|
||||||
|
TEST_CHECK(pid3[1] == 'o');
|
||||||
|
TEST_CHECK(pid3[2] == 'o');
|
||||||
|
TEST_CHECK(pid3[3] == 'b');
|
||||||
|
TEST_CHECK(pid3[4] == 'a');
|
||||||
|
TEST_CHECK(pid3[5] == 'r');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,42 @@ TORRENT_TEST(clear)
|
||||||
TEST_EQUAL(pack.has_val(settings_pack::user_agent), false);
|
TEST_EQUAL(pack.has_val(settings_pack::user_agent), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(clear_single_int)
|
||||||
|
{
|
||||||
|
settings_pack sp;
|
||||||
|
sp.set_int(settings_pack::max_out_request_queue, 1337);
|
||||||
|
|
||||||
|
TEST_EQUAL(sp.get_int(settings_pack::max_out_request_queue), 1337);
|
||||||
|
|
||||||
|
sp.clear(settings_pack::max_out_request_queue);
|
||||||
|
|
||||||
|
TEST_EQUAL(sp.get_int(settings_pack::max_out_request_queue), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(clear_single_bool)
|
||||||
|
{
|
||||||
|
settings_pack sp;
|
||||||
|
sp.set_bool(settings_pack::send_redundant_have, true);
|
||||||
|
|
||||||
|
TEST_EQUAL(sp.get_bool(settings_pack::send_redundant_have), true);
|
||||||
|
|
||||||
|
sp.clear(settings_pack::send_redundant_have);
|
||||||
|
|
||||||
|
TEST_EQUAL(sp.get_bool(settings_pack::send_redundant_have), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(clear_single_string)
|
||||||
|
{
|
||||||
|
settings_pack sp;
|
||||||
|
sp.set_str(settings_pack::user_agent, "foobar");
|
||||||
|
|
||||||
|
TEST_EQUAL(sp.get_str(settings_pack::user_agent), "foobar");
|
||||||
|
|
||||||
|
sp.clear(settings_pack::user_agent);
|
||||||
|
|
||||||
|
TEST_EQUAL(sp.get_str(settings_pack::user_agent), std::string());
|
||||||
|
}
|
||||||
|
|
||||||
TORRENT_TEST(duplicates)
|
TORRENT_TEST(duplicates)
|
||||||
{
|
{
|
||||||
settings_pack p;
|
settings_pack p;
|
||||||
|
|
|
@ -762,6 +762,7 @@ TORRENT_TEST(parse_torrents)
|
||||||
std::printf("E: \"%s\"\nexpected: \"%s\"\n", ec.message().c_str()
|
std::printf("E: \"%s\"\nexpected: \"%s\"\n", ec.message().c_str()
|
||||||
, test_error_torrents[i].error.message().c_str());
|
, test_error_torrents[i].error.message().c_str());
|
||||||
TEST_CHECK(ec.message() == test_error_torrents[i].error.message());
|
TEST_CHECK(ec.message() == test_error_torrents[i].error.message());
|
||||||
|
TEST_EQUAL(ti->is_valid(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue