2003-10-23 01:00:57 +02:00
|
|
|
/*
|
|
|
|
|
2016-01-18 00:57:46 +01:00
|
|
|
Copyright (c) 2003-2016, Arvid Norberg
|
2003-10-23 01:00:57 +02:00
|
|
|
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.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef TORRENT_TORRENT_HPP_INCLUDE
|
|
|
|
#define TORRENT_TORRENT_HPP_INCLUDE
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <vector>
|
|
|
|
#include <set>
|
|
|
|
#include <list>
|
2013-02-17 05:07:30 +01:00
|
|
|
#include <deque>
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2015-04-21 03:16:28 +02:00
|
|
|
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
2004-01-25 19:18:36 +01:00
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
#include <boost/limits.hpp>
|
2005-05-30 19:43:03 +02:00
|
|
|
#include <boost/tuple/tuple.hpp>
|
2005-10-13 09:59:05 +02:00
|
|
|
#include <boost/enable_shared_from_this.hpp>
|
2005-11-01 19:30:39 +01:00
|
|
|
#include <boost/scoped_ptr.hpp>
|
2014-07-06 21:18:00 +02:00
|
|
|
#include <boost/shared_ptr.hpp>
|
2012-02-23 05:32:50 +01:00
|
|
|
#include <boost/version.hpp>
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2015-04-21 03:16:28 +02:00
|
|
|
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
2004-01-25 19:18:36 +01:00
|
|
|
|
2003-10-26 18:35:23 +01:00
|
|
|
#include "libtorrent/torrent_handle.hpp"
|
2003-10-23 01:00:57 +02:00
|
|
|
#include "libtorrent/entry.hpp"
|
|
|
|
#include "libtorrent/torrent_info.hpp"
|
|
|
|
#include "libtorrent/socket.hpp"
|
2009-11-23 09:38:50 +01:00
|
|
|
#include "libtorrent/address.hpp"
|
2014-10-26 08:34:31 +01:00
|
|
|
#include "libtorrent/peer_list.hpp"
|
2004-01-31 11:46:15 +01:00
|
|
|
#include "libtorrent/tracker_manager.hpp"
|
2003-12-07 06:53:04 +01:00
|
|
|
#include "libtorrent/stat.hpp"
|
2003-12-22 08:14:35 +01:00
|
|
|
#include "libtorrent/alert.hpp"
|
2005-10-13 09:59:05 +02:00
|
|
|
#include "libtorrent/piece_picker.hpp"
|
2005-11-01 19:30:39 +01:00
|
|
|
#include "libtorrent/config.hpp"
|
2007-12-31 10:41:50 +01:00
|
|
|
#include "libtorrent/bandwidth_limit.hpp"
|
|
|
|
#include "libtorrent/bandwidth_queue_entry.hpp"
|
2009-11-23 09:38:50 +01:00
|
|
|
#include "libtorrent/storage_defs.hpp"
|
2007-06-10 22:46:09 +02:00
|
|
|
#include "libtorrent/hasher.hpp"
|
2007-09-10 08:12:41 +02:00
|
|
|
#include "libtorrent/assert.hpp"
|
2008-05-28 04:35:02 +02:00
|
|
|
#include "libtorrent/bitfield.hpp"
|
2014-07-06 21:18:00 +02:00
|
|
|
#include "libtorrent/aux_/session_interface.hpp"
|
2009-09-16 05:46:36 +02:00
|
|
|
#include "libtorrent/deadline_timer.hpp"
|
2014-07-06 21:18:00 +02:00
|
|
|
#include "libtorrent/peer_class_set.hpp"
|
|
|
|
#include "libtorrent/link.hpp"
|
|
|
|
#include "libtorrent/vector_utils.hpp"
|
|
|
|
#include "libtorrent/linked_list.hpp"
|
2014-09-22 19:41:06 +02:00
|
|
|
#include "libtorrent/debug.hpp"
|
2015-06-29 04:47:11 +02:00
|
|
|
#include "libtorrent/aux_/file_progress.hpp"
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2017-10-09 01:21:19 +02:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
|
|
|
// there is no forward declaration header for asio
|
|
|
|
namespace boost {
|
|
|
|
namespace asio {
|
|
|
|
namespace ssl {
|
|
|
|
struct context;
|
|
|
|
class verify_context;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-03-03 08:42:51 +01:00
|
|
|
#if TORRENT_COMPLETE_TYPES_REQUIRED
|
|
|
|
#include "libtorrent/peer_connection.hpp"
|
|
|
|
#endif
|
|
|
|
|
2014-06-06 03:26:18 +02:00
|
|
|
// define as 0 to disable. 1 enables debug output of the pieces and requested
|
|
|
|
// blocks. 2 also enables trace output of the time critical piece picking
|
|
|
|
// logic
|
|
|
|
#define TORRENT_DEBUG_STREAMING 0
|
2014-04-22 06:21:14 +02:00
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
namespace libtorrent
|
|
|
|
{
|
2011-02-21 06:24:41 +01:00
|
|
|
class http_parser;
|
2010-12-30 02:47:30 +01:00
|
|
|
|
2004-06-14 01:30:42 +02:00
|
|
|
class piece_manager;
|
2006-11-14 01:08:16 +01:00
|
|
|
struct torrent_plugin;
|
2008-05-28 04:35:02 +02:00
|
|
|
struct bitfield;
|
2008-11-29 09:38:40 +01:00
|
|
|
struct announce_entry;
|
|
|
|
struct tracker_request;
|
2009-02-03 08:46:24 +01:00
|
|
|
struct add_torrent_params;
|
2009-11-23 09:38:50 +01:00
|
|
|
struct storage_interface;
|
2011-02-21 06:24:41 +01:00
|
|
|
class bt_peer_connection;
|
2011-09-12 05:51:49 +02:00
|
|
|
struct listen_socket_t;
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2018-01-21 20:59:08 +01:00
|
|
|
peer_id generate_peer_id(aux::session_settings const& sett);
|
2014-11-08 19:36:54 +01:00
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
namespace aux
|
2003-10-23 01:00:57 +02:00
|
|
|
{
|
2004-06-14 01:30:42 +02:00
|
|
|
struct piece_checker_data;
|
2003-10-23 01:00:57 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
struct resume_data_t
|
|
|
|
{
|
|
|
|
std::vector<char> buf;
|
2015-03-12 06:20:12 +01:00
|
|
|
bdecode_node node;
|
2014-07-06 21:18:00 +02:00
|
|
|
};
|
|
|
|
|
2014-04-22 06:21:14 +02:00
|
|
|
struct time_critical_piece
|
|
|
|
{
|
|
|
|
// when this piece was first requested
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point first_requested;
|
2014-04-22 06:21:14 +02:00
|
|
|
// when this piece was last requested
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point last_requested;
|
2014-04-22 06:21:14 +02:00
|
|
|
// by what time we want this piece
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point deadline;
|
2014-04-22 06:21:14 +02:00
|
|
|
// 1 = send alert with piece data when available
|
|
|
|
int flags;
|
|
|
|
// how many peers it's been requested from
|
|
|
|
int peers;
|
|
|
|
// the piece index
|
|
|
|
int piece;
|
2014-06-06 03:26:18 +02:00
|
|
|
#if TORRENT_DEBUG_STREAMING > 0
|
2014-04-22 06:21:14 +02:00
|
|
|
// the number of multiple requests are allowed
|
|
|
|
// to blocks still not downloaded (debugging only)
|
|
|
|
int timed_out;
|
|
|
|
#endif
|
|
|
|
bool operator<(time_critical_piece const& rhs) const
|
|
|
|
{ return deadline < rhs.deadline; }
|
|
|
|
};
|
|
|
|
|
2014-12-31 23:05:34 +01:00
|
|
|
// this is the internal representation of web seeds
|
|
|
|
struct web_seed_t : web_seed_entry
|
|
|
|
{
|
|
|
|
web_seed_t(web_seed_entry const& wse);
|
|
|
|
web_seed_t(std::string const& url_, web_seed_entry::type_t type_
|
|
|
|
, std::string const& auth_ = std::string()
|
|
|
|
, web_seed_entry::headers_t const& extra_headers_ = web_seed_entry::headers_t());
|
|
|
|
|
|
|
|
// if this is > now, we can't reconnect yet
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point retry;
|
2014-12-31 23:05:34 +01:00
|
|
|
|
|
|
|
// if the hostname of the web seed has been resolved,
|
|
|
|
// these are its IP addresses
|
|
|
|
std::vector<tcp::endpoint> endpoints;
|
|
|
|
|
|
|
|
// this is the peer_info field used for the
|
|
|
|
// connection, just to count hash failures
|
|
|
|
// it's also used to hold the peer_connection
|
|
|
|
// pointer, when the web seed is connected
|
|
|
|
ipv4_peer peer_info;
|
|
|
|
|
|
|
|
// this is initialized to true, but if we discover the
|
|
|
|
// server not to support it, it's set to false, and we
|
|
|
|
// make larger requests.
|
|
|
|
bool supports_keepalive;
|
|
|
|
|
|
|
|
// this indicates whether or not we're resolving the
|
|
|
|
// hostname of this URL
|
|
|
|
bool resolving;
|
|
|
|
|
|
|
|
// if the user wanted to remove this while
|
|
|
|
// we were resolving it. In this case, we set
|
|
|
|
// the removed flag to true, to make the resolver
|
|
|
|
// callback remove it
|
|
|
|
bool removed;
|
|
|
|
|
|
|
|
// if the web server doesn't support keepalive or a block request was
|
|
|
|
// interrupted, the block received so far is kept here for the next
|
|
|
|
// connection to pick up
|
|
|
|
peer_request restart_request;
|
|
|
|
std::vector<char> restart_piece;
|
|
|
|
};
|
|
|
|
|
2015-11-19 01:51:17 +01:00
|
|
|
struct TORRENT_EXTRA_EXPORT torrent_hot_members
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
torrent_hot_members(aux::session_interface& ses
|
|
|
|
, add_torrent_params const& p, int block_size);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// the piece picker. This is allocated lazily. When we don't
|
|
|
|
// have anything in the torrent (for instance, if it hasn't
|
|
|
|
// been started yet) or if we have everything, there is no
|
|
|
|
// picker. It's allocated on-demand the first time we need
|
|
|
|
// it in torrent::need_picker(). In order to tell the
|
|
|
|
// difference between having everything and nothing in
|
|
|
|
// the case there is no piece picker, see m_have_all.
|
|
|
|
boost::scoped_ptr<piece_picker> m_picker;
|
|
|
|
|
2016-01-18 23:59:30 +01:00
|
|
|
// TODO: make this a raw pointer. perhaps keep the shared_ptr
|
2014-07-06 21:18:00 +02:00
|
|
|
// around further down the object to maintain an owner
|
|
|
|
boost::shared_ptr<torrent_info> m_torrent_file;
|
|
|
|
|
|
|
|
// a back reference to the session
|
|
|
|
// this torrent belongs to.
|
|
|
|
aux::session_interface& m_ses;
|
|
|
|
|
|
|
|
// this vector is sorted at all times, by the pointer value.
|
|
|
|
// use sorted_insert() and sorted_find() on it. The GNU STL
|
|
|
|
// implementation on Darwin uses significantly less memory to
|
|
|
|
// represent a vector than a set, and this set is typically
|
2016-01-18 23:59:30 +01:00
|
|
|
// relatively small, and it's cheap to copy pointers.
|
2014-07-06 21:18:00 +02:00
|
|
|
std::vector<peer_connection*> m_connections;
|
|
|
|
|
|
|
|
// the scrape data from the tracker response, this
|
|
|
|
// is optional and may be 0xffffff
|
|
|
|
boost::uint32_t m_complete:24;
|
|
|
|
|
|
|
|
// set to true when this torrent may not download anything
|
|
|
|
bool m_upload_mode:1;
|
|
|
|
|
|
|
|
// this is set to false as long as the connections
|
|
|
|
// of this torrent hasn't been initialized. If we
|
|
|
|
// have metadata from the start, connections are
|
|
|
|
// initialized immediately, if we didn't have metadata,
|
|
|
|
// they are initialized right after files_checked().
|
|
|
|
// valid_resume_data() will return false as long as
|
|
|
|
// the connections aren't initialized, to avoid
|
|
|
|
// them from altering the piece-picker before it
|
|
|
|
// has been initialized with files_checked().
|
|
|
|
bool m_connections_initialized:1;
|
|
|
|
|
|
|
|
// is set to true when the torrent has
|
|
|
|
// been aborted.
|
|
|
|
bool m_abort:1;
|
|
|
|
|
|
|
|
// is true if this torrent has allows having peers
|
|
|
|
bool m_allow_peers:1;
|
|
|
|
|
|
|
|
// this is set when the torrent is in share-mode
|
|
|
|
bool m_share_mode:1;
|
|
|
|
|
|
|
|
// this is true if we have all pieces. If it's false,
|
|
|
|
// it means we either don't have any pieces, or, if
|
|
|
|
// there is a piece_picker object present, it contans
|
|
|
|
// the state of how many pieces we have
|
|
|
|
bool m_have_all:1;
|
|
|
|
|
|
|
|
// set to true when this torrent has been paused but
|
|
|
|
// is waiting to finish all current download requests
|
2015-12-10 07:56:33 +01:00
|
|
|
// before actually closing all connections, When in graceful pause mode,
|
|
|
|
// m_allow_peers is also false.
|
2014-07-06 21:18:00 +02:00
|
|
|
bool m_graceful_pause_mode:1;
|
|
|
|
|
2018-01-27 01:48:22 +01:00
|
|
|
// state subscription. If set, a pointer to this torrent will be added
|
|
|
|
// to the session_impl::m_torrent_lists[torrent_state_updates]
|
2014-07-06 21:18:00 +02:00
|
|
|
// whenever this torrent's state changes (any state).
|
|
|
|
bool m_state_subscription:1;
|
|
|
|
|
|
|
|
// the maximum number of connections for this torrent
|
|
|
|
boost::uint32_t m_max_connections:24;
|
|
|
|
|
|
|
|
// the size of a request block
|
|
|
|
// each piece is divided into these
|
|
|
|
// blocks when requested. The block size is
|
|
|
|
// 1 << m_block_size_shift
|
|
|
|
boost::uint32_t m_block_size_shift:5;
|
|
|
|
|
|
|
|
// the state of this torrent (queued, checking, downloading, etc.)
|
|
|
|
boost::uint32_t m_state:3;
|
|
|
|
|
2014-10-26 08:34:31 +01:00
|
|
|
boost::scoped_ptr<peer_list> m_peer_list;
|
2014-07-06 21:18:00 +02:00
|
|
|
};
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// a torrent is a class that holds information
|
|
|
|
// for a specific download. It updates itself against
|
|
|
|
// the tracker
|
2014-07-06 21:18:00 +02:00
|
|
|
class TORRENT_EXTRA_EXPORT torrent
|
2015-05-16 08:33:37 +02:00
|
|
|
: private single_threaded
|
|
|
|
, private torrent_hot_members
|
2014-07-06 21:18:00 +02:00
|
|
|
, public request_callback
|
|
|
|
, public peer_class_set
|
2005-10-13 09:59:05 +02:00
|
|
|
, public boost::enable_shared_from_this<torrent>
|
2015-08-20 02:02:46 +02:00
|
|
|
, public list_node<torrent> // used for torrent activity LRU
|
2003-10-23 01:00:57 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
torrent(aux::session_interface& ses, int block_size
|
|
|
|
, int seq, add_torrent_params const& p
|
2010-12-30 02:47:30 +01:00
|
|
|
, sha1_hash const& info_hash);
|
2003-12-14 06:56:12 +01:00
|
|
|
~torrent();
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2014-11-12 17:57:59 +01:00
|
|
|
// This may be called from multiple threads
|
|
|
|
sha1_hash const& info_hash() const { return m_info_hash; }
|
2015-05-25 23:46:42 +02:00
|
|
|
|
2013-08-22 07:27:45 +02:00
|
|
|
bool is_deleted() const { return m_deleted; }
|
2008-08-21 01:05:12 +02:00
|
|
|
|
2007-04-11 19:44:15 +02:00
|
|
|
// starts the announce timer
|
2015-06-21 00:17:49 +02:00
|
|
|
void start(add_torrent_params const& p);
|
2007-04-11 19:44:15 +02:00
|
|
|
|
2010-12-30 02:47:30 +01:00
|
|
|
void start_download_url();
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// returns which stats gauge this torrent currently
|
|
|
|
// has incremented.
|
|
|
|
int current_stats_state() const;
|
|
|
|
|
2006-11-14 01:08:16 +01:00
|
|
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
|
|
|
void add_extension(boost::shared_ptr<torrent_plugin>);
|
2014-07-06 21:18:00 +02:00
|
|
|
void remove_extension(boost::shared_ptr<torrent_plugin>);
|
2015-07-25 18:39:25 +02:00
|
|
|
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent_handle const&, void*)> const& ext
|
2007-11-08 02:45:35 +01:00
|
|
|
, void* userdata);
|
2011-05-02 03:45:56 +02:00
|
|
|
void notify_extension_add_peer(tcp::endpoint const& ip, int src, int flags);
|
2006-11-14 01:08:16 +01:00
|
|
|
#endif
|
|
|
|
|
2012-12-31 07:54:54 +01:00
|
|
|
peer_connection* find_lowest_ranking_peer() const;
|
|
|
|
|
2014-01-19 20:45:50 +01:00
|
|
|
#if TORRENT_USE_ASSERTS
|
2014-07-06 21:18:00 +02:00
|
|
|
bool has_peer(peer_connection const* p) const
|
2015-08-02 05:57:11 +02:00
|
|
|
{ return sorted_find(m_connections, p) != m_connections.end(); }
|
2014-09-22 19:41:06 +02:00
|
|
|
bool is_single_thread() const { return single_threaded::is_single_thread(); }
|
2008-01-07 02:10:46 +01:00
|
|
|
#endif
|
|
|
|
|
2004-06-14 01:30:42 +02:00
|
|
|
// this is called when the torrent has metadata.
|
|
|
|
// it will initialize the storage and the piece-picker
|
|
|
|
void init();
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// called every time we actually need the torrent_info
|
|
|
|
// object to be fully loaded. If it isn't, this triggers
|
|
|
|
// loading it from disk
|
|
|
|
// the return value indicates success. If it failed to
|
|
|
|
// load, the torrent will be set to an error state and
|
|
|
|
// return false
|
|
|
|
bool need_loaded();
|
|
|
|
|
|
|
|
// unload the torrent file to save memory
|
|
|
|
void unload();
|
|
|
|
// returns true if parsed successfully
|
|
|
|
bool load(std::vector<char>& buffer);
|
|
|
|
|
|
|
|
// pinned torrents may not be unloaded
|
|
|
|
bool is_pinned() const { return m_pinned; }
|
|
|
|
void set_pinned(bool p);
|
|
|
|
bool is_loaded() const { return m_torrent_file->is_loaded(); }
|
|
|
|
bool should_be_loaded() const { return m_should_be_loaded; }
|
|
|
|
|
2010-11-29 02:33:05 +01:00
|
|
|
// find the peer that introduced us to the given endpoint. This is
|
|
|
|
// used when trying to holepunch. We need the introducer so that we
|
|
|
|
// can send a rendezvous connect message
|
|
|
|
bt_peer_connection* find_introducer(tcp::endpoint const& ep) const;
|
|
|
|
|
|
|
|
// if we're connected to a peer at ep, return its peer connection
|
|
|
|
// only count BitTorrent peers
|
|
|
|
bt_peer_connection* find_peer(tcp::endpoint const& ep) const;
|
2018-01-21 20:59:08 +01:00
|
|
|
peer_connection* find_peer(peer_id const& pid);
|
2010-11-29 02:33:05 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void on_resume_data_checked(disk_io_job const* j);
|
|
|
|
void on_force_recheck(disk_io_job const* j);
|
|
|
|
void on_piece_hashed(disk_io_job const* j);
|
2010-07-14 06:16:38 +02:00
|
|
|
void files_checked();
|
2008-03-08 07:06:31 +01:00
|
|
|
void start_checking();
|
|
|
|
|
2008-07-12 10:25:19 +02:00
|
|
|
void start_announcing();
|
|
|
|
void stop_announcing();
|
|
|
|
|
2010-09-05 18:01:36 +02:00
|
|
|
void send_share_mode();
|
2009-11-24 19:49:59 +01:00
|
|
|
void send_upload_only();
|
|
|
|
|
2010-09-05 18:01:36 +02:00
|
|
|
void set_share_mode(bool s);
|
|
|
|
bool share_mode() const { return m_share_mode; }
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// TOOD: make graceful pause also finish all sending blocks
|
|
|
|
// before disconnecting
|
2010-10-30 10:36:18 +02:00
|
|
|
bool graceful_pause() const { return m_graceful_pause_mode; }
|
|
|
|
|
2009-06-19 00:32:55 +02:00
|
|
|
void set_upload_mode(bool b);
|
2010-10-30 10:36:18 +02:00
|
|
|
bool upload_mode() const { return m_upload_mode || m_graceful_pause_mode; }
|
2011-04-10 01:57:56 +02:00
|
|
|
bool is_upload_only() const { return is_finished() || upload_mode(); }
|
2009-06-19 00:32:55 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
int seed_rank(aux::session_settings const& s) const;
|
2008-04-24 05:28:48 +02:00
|
|
|
|
2008-12-07 22:04:19 +01:00
|
|
|
enum flags_t { overwrite_existing = 1 };
|
|
|
|
void add_piece(int piece, char const* data, int flags = 0);
|
2014-07-06 21:18:00 +02:00
|
|
|
void on_disk_write_complete(disk_io_job const* j
|
2008-12-07 22:04:19 +01:00
|
|
|
, peer_request p);
|
2014-07-06 21:18:00 +02:00
|
|
|
void on_disk_cache_complete(disk_io_job const* j);
|
|
|
|
void on_disk_tick_done(disk_io_job const* j);
|
|
|
|
|
|
|
|
void schedule_storage_tick();
|
2008-12-07 22:04:19 +01:00
|
|
|
|
2010-12-30 02:47:30 +01:00
|
|
|
void set_progress_ppm(int p) { m_progress_ppm = p; }
|
2008-12-14 20:47:02 +01:00
|
|
|
struct read_piece_struct
|
|
|
|
{
|
|
|
|
boost::shared_array<char> piece_data;
|
|
|
|
int blocks_left;
|
|
|
|
bool fail;
|
2013-01-29 03:18:32 +01:00
|
|
|
error_code error;
|
2008-12-14 20:47:02 +01:00
|
|
|
};
|
|
|
|
void read_piece(int piece);
|
2015-05-03 05:28:39 +02:00
|
|
|
void on_disk_read_complete(disk_io_job const* j, peer_request r
|
|
|
|
, boost::shared_ptr<read_piece_struct> rp);
|
2008-12-14 20:47:02 +01:00
|
|
|
|
2015-09-18 06:23:45 +02:00
|
|
|
storage_mode_t storage_mode() const;
|
|
|
|
storage_interface* get_storage();
|
2008-09-04 18:20:19 +02:00
|
|
|
|
2004-03-28 19:45:37 +02:00
|
|
|
// this will flag the torrent as aborted. The main
|
|
|
|
// loop in session_impl will check for this state
|
|
|
|
// on all torrents once every second, and take
|
|
|
|
// the necessary actions then.
|
2005-03-05 15:17:17 +01:00
|
|
|
void abort();
|
2003-10-23 01:00:57 +02:00
|
|
|
bool is_aborted() const { return m_abort; }
|
|
|
|
|
2014-01-23 04:31:36 +01:00
|
|
|
void new_external_ip();
|
|
|
|
|
2014-09-24 02:02:00 +02:00
|
|
|
torrent_status::state_t state() const
|
2015-08-02 05:57:11 +02:00
|
|
|
{ return torrent_status::state_t(m_state); }
|
2008-07-03 12:05:51 +02:00
|
|
|
void set_state(torrent_status::state_t s);
|
2008-06-17 00:27:14 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
aux::session_settings const& settings() const;
|
|
|
|
aux::session_interface& session() { return m_ses; }
|
2015-05-18 01:32:13 +02:00
|
|
|
|
2008-01-31 18:52:29 +01:00
|
|
|
void set_sequential_download(bool sd);
|
2008-06-17 10:30:04 +02:00
|
|
|
bool is_sequential_download() const
|
2014-09-24 02:02:00 +02:00
|
|
|
{ return m_sequential_download || m_auto_sequential; }
|
2015-05-18 01:32:13 +02:00
|
|
|
|
2010-07-14 06:16:38 +02:00
|
|
|
void queue_up();
|
|
|
|
void queue_down();
|
2008-05-29 05:37:19 +02:00
|
|
|
void set_queue_position(int p);
|
|
|
|
int queue_position() const { return m_sequence_number; }
|
2014-07-06 21:18:00 +02:00
|
|
|
// used internally
|
|
|
|
void set_queue_position_impl(int p) { m_sequence_number = p; }
|
2008-05-29 05:37:19 +02:00
|
|
|
|
2015-08-29 22:07:19 +02:00
|
|
|
void second_tick(int tick_interval_ms);
|
2003-12-01 06:01:40 +01:00
|
|
|
|
2013-08-19 05:54:45 +02:00
|
|
|
// see if we need to connect to web seeds, and if so,
|
|
|
|
// connect to them
|
|
|
|
void maybe_connect_web_seeds();
|
|
|
|
|
2006-11-14 01:08:16 +01:00
|
|
|
std::string name() const;
|
|
|
|
|
2003-12-07 06:53:04 +01:00
|
|
|
stat statistics() const { return m_stat; }
|
2014-12-03 05:32:50 +01:00
|
|
|
boost::int64_t bytes_left() const;
|
2009-01-14 08:41:25 +01:00
|
|
|
int block_bytes_wanted(piece_block const& p) const;
|
2010-03-04 20:15:23 +01:00
|
|
|
void bytes_done(torrent_status& st, bool accurate) const;
|
2014-12-03 05:32:50 +01:00
|
|
|
boost::int64_t quantized_bytes_done() const;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void sent_bytes(int bytes_payload, int bytes_protocol);
|
|
|
|
void received_bytes(int bytes_payload, int bytes_protocol);
|
|
|
|
void trancieve_ip_packet(int bytes, bool ipv6);
|
|
|
|
void sent_syn(bool ipv6);
|
|
|
|
void received_synack(bool ipv6);
|
2007-07-26 09:04:35 +02:00
|
|
|
|
2015-05-16 08:33:37 +02:00
|
|
|
void set_ip_filter(boost::shared_ptr<const ip_filter> ipf);
|
2014-07-06 21:18:00 +02:00
|
|
|
void port_filter_updated();
|
2015-05-16 08:33:37 +02:00
|
|
|
ip_filter const* get_ip_filter() { return m_ip_filter.get(); }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
std::string resolve_filename(int file) const;
|
|
|
|
void handle_disk_error(disk_io_job const* j, peer_connection* c = 0);
|
2009-01-27 10:18:51 +01:00
|
|
|
void clear_error();
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
void set_error(error_code const& ec, int file);
|
2011-02-21 06:24:41 +01:00
|
|
|
bool has_error() const { return !!m_error; }
|
2011-01-29 11:37:21 +01:00
|
|
|
error_code error() const { return m_error; }
|
2010-01-09 22:17:52 +01:00
|
|
|
|
|
|
|
void flush_cache();
|
2010-10-30 10:36:18 +02:00
|
|
|
void pause(bool graceful = false);
|
2004-03-21 03:03:37 +01:00
|
|
|
void resume();
|
2016-03-07 03:42:18 +01:00
|
|
|
|
|
|
|
enum pause_flags_t
|
|
|
|
{
|
|
|
|
flag_graceful_pause = 1,
|
|
|
|
flag_clear_disk_cache = 2
|
|
|
|
};
|
|
|
|
void set_allow_peers(bool b, int flags = flag_clear_disk_cache);
|
2010-03-29 02:34:04 +02:00
|
|
|
void set_announce_to_dht(bool b) { m_announce_to_dht = b; }
|
|
|
|
void set_announce_to_trackers(bool b) { m_announce_to_trackers = b; }
|
|
|
|
void set_announce_to_lsd(bool b) { m_announce_to_lsd = b; }
|
2008-06-29 21:08:30 +02:00
|
|
|
|
2015-12-13 17:26:41 +01:00
|
|
|
void stop_when_ready(bool b);
|
2015-10-04 00:15:29 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
int started() const { return m_started; }
|
|
|
|
void step_session_time(int seconds);
|
2016-03-07 03:42:18 +01:00
|
|
|
void do_pause(bool clear_disk_cache = true);
|
2008-06-29 21:08:30 +02:00
|
|
|
void do_resume();
|
|
|
|
|
2014-08-27 08:36:28 +02:00
|
|
|
int finished_time() const;
|
|
|
|
int active_time() const;
|
|
|
|
int seeding_time() const;
|
|
|
|
|
2008-06-29 21:08:30 +02:00
|
|
|
bool is_paused() const;
|
2010-03-29 02:34:04 +02:00
|
|
|
bool allows_peers() const { return m_allow_peers; }
|
2010-10-30 10:36:18 +02:00
|
|
|
bool is_torrent_paused() const { return !m_allow_peers || m_graceful_pause_mode; }
|
2008-06-07 18:24:56 +02:00
|
|
|
void force_recheck();
|
2010-10-29 04:42:41 +02:00
|
|
|
void save_resume_data(int flags);
|
2014-07-06 21:18:00 +02:00
|
|
|
bool do_async_save_resume_data();
|
2012-06-21 05:51:39 +02:00
|
|
|
|
2010-10-29 04:42:41 +02:00
|
|
|
bool need_save_resume_data() const
|
2010-08-25 08:38:04 +02:00
|
|
|
{
|
|
|
|
// save resume data every 15 minutes regardless, just to
|
|
|
|
// keep stats up to date
|
2014-07-06 21:18:00 +02:00
|
|
|
return m_need_save_resume_data || m_ses.session_time() - m_last_saved_resume > 15 * 60;
|
2010-08-25 08:38:04 +02:00
|
|
|
}
|
2004-03-21 03:03:37 +01:00
|
|
|
|
2015-11-30 02:31:57 +01:00
|
|
|
void set_need_save_resume()
|
|
|
|
{
|
|
|
|
m_need_save_resume_data = true;
|
|
|
|
}
|
|
|
|
|
2008-04-24 05:28:48 +02:00
|
|
|
bool is_auto_managed() const { return m_auto_managed; }
|
|
|
|
void auto_managed(bool a);
|
|
|
|
|
2008-09-20 19:42:25 +02:00
|
|
|
bool should_check_files() const;
|
|
|
|
|
2016-03-13 08:50:37 +01:00
|
|
|
bool delete_files(int options);
|
2014-07-06 21:18:00 +02:00
|
|
|
void peers_erased(std::vector<torrent_peer*> const& peers);
|
2007-10-13 05:33:33 +02:00
|
|
|
|
2007-03-20 02:59:00 +01:00
|
|
|
// ============ start deprecation =============
|
2005-06-23 01:04:37 +02:00
|
|
|
void filter_piece(int index, bool filter);
|
|
|
|
void filter_pieces(std::vector<bool> const& bitmask);
|
2005-05-25 12:01:01 +02:00
|
|
|
bool is_piece_filtered(int index) const;
|
|
|
|
void filtered_pieces(std::vector<bool>& bitmask) const;
|
2005-07-04 01:33:47 +02:00
|
|
|
void filter_files(std::vector<bool> const& files);
|
2009-07-19 06:59:27 +02:00
|
|
|
#if !TORRENT_NO_FPU
|
2014-07-06 21:18:00 +02:00
|
|
|
void file_progress(std::vector<float>& fp);
|
2009-07-19 06:59:27 +02:00
|
|
|
#endif
|
2007-03-20 02:59:00 +01:00
|
|
|
// ============ end deprecation =============
|
|
|
|
|
2007-05-30 08:52:59 +02:00
|
|
|
void piece_availability(std::vector<int>& avail) const;
|
2015-10-04 00:15:29 +02:00
|
|
|
|
2007-03-20 02:59:00 +01:00
|
|
|
void set_piece_priority(int index, int priority);
|
|
|
|
int piece_priority(int index) const;
|
|
|
|
|
|
|
|
void prioritize_pieces(std::vector<int> const& pieces);
|
2014-07-06 21:18:00 +02:00
|
|
|
void prioritize_piece_list(std::vector<std::pair<int, int> > const& pieces);
|
2011-05-01 19:43:15 +02:00
|
|
|
void piece_priorities(std::vector<int>*) const;
|
2007-03-20 02:59:00 +01:00
|
|
|
|
2008-07-20 18:00:08 +02:00
|
|
|
void set_file_priority(int index, int priority);
|
|
|
|
int file_priority(int index) const;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void on_file_priority();
|
2007-03-20 02:59:00 +01:00
|
|
|
void prioritize_files(std::vector<int> const& files);
|
2011-05-01 19:43:15 +02:00
|
|
|
void file_priorities(std::vector<int>*) const;
|
2008-07-20 18:00:08 +02:00
|
|
|
|
2014-06-06 03:26:18 +02:00
|
|
|
void cancel_non_critical();
|
2009-12-05 08:24:22 +01:00
|
|
|
void set_piece_deadline(int piece, int t, int flags);
|
2011-08-05 08:31:46 +02:00
|
|
|
void reset_piece_deadline(int piece);
|
2014-05-23 04:23:11 +02:00
|
|
|
void clear_time_critical();
|
2008-07-20 18:00:08 +02:00
|
|
|
void update_piece_priorities();
|
2007-03-20 02:59:00 +01:00
|
|
|
|
2011-02-01 10:48:28 +01:00
|
|
|
void status(torrent_status* st, boost::uint32_t flags);
|
2008-07-12 15:38:22 +02:00
|
|
|
|
2011-11-15 03:34:00 +01:00
|
|
|
// this torrent changed state, if the user is subscribing to
|
|
|
|
// it, add it to the m_state_updates list in session_impl
|
|
|
|
void state_updated();
|
|
|
|
|
2014-12-03 05:32:50 +01:00
|
|
|
void file_progress(std::vector<boost::int64_t>& fp, int flags = 0);
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2015-01-01 21:25:39 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2010-07-14 06:16:38 +02:00
|
|
|
void use_interface(std::string net_interface);
|
2014-07-06 21:18:00 +02:00
|
|
|
#endif
|
2015-08-23 11:01:55 +02:00
|
|
|
|
2014-12-31 23:05:34 +01:00
|
|
|
void connect_to_url_seed(std::list<web_seed_t>::iterator url);
|
2014-07-06 21:18:00 +02:00
|
|
|
bool connect_to_peer(torrent_peer* peerinfo, bool ignore_limit = false);
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2017-12-16 16:37:16 +01:00
|
|
|
int priority() const;
|
|
|
|
void set_priority(int const prio);
|
2009-09-13 04:24:25 +02:00
|
|
|
|
2015-12-15 00:31:49 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
// deprecated in 1.1
|
|
|
|
|
2007-05-02 21:47:38 +02:00
|
|
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
2014-07-06 21:18:00 +02:00
|
|
|
void resolve_countries(bool r);
|
|
|
|
bool resolving_countries() const;
|
2007-01-29 08:39:33 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void resolve_peer_country(boost::shared_ptr<peer_connection> const& p) const;
|
|
|
|
void on_country_lookup(error_code const& error
|
|
|
|
, std::vector<address> const& host_list
|
|
|
|
, boost::shared_ptr<peer_connection> p) const;
|
2007-05-02 21:47:38 +02:00
|
|
|
#endif
|
2015-12-15 00:31:49 +01:00
|
|
|
#endif // TORRENT_NO_DEPRECATE
|
2007-01-29 08:39:33 +01:00
|
|
|
|
2007-01-10 16:02:25 +01:00
|
|
|
// --------------------------------------------
|
|
|
|
// BANDWIDTH MANAGEMENT
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void set_upload_limit(int limit);
|
|
|
|
int upload_limit() const;
|
|
|
|
void set_download_limit(int limit);
|
|
|
|
int download_limit() const;
|
2007-01-10 16:02:25 +01:00
|
|
|
|
2017-01-21 18:08:53 +01:00
|
|
|
peer_class_t peer_class() const { return m_peer_class; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
void set_max_uploads(int limit, bool state_update = true);
|
|
|
|
int max_uploads() const { return m_max_uploads; }
|
|
|
|
void set_max_connections(int limit, bool state_update = true);
|
|
|
|
int max_connections() const { return m_max_connections; }
|
2007-01-10 16:02:25 +01:00
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// --------------------------------------------
|
|
|
|
// PEER MANAGEMENT
|
2015-08-02 05:57:11 +02:00
|
|
|
|
2006-04-25 23:04:48 +02:00
|
|
|
// add or remove a url that will be attempted for
|
|
|
|
// finding the file(s) in this torrent.
|
2014-12-31 23:05:34 +01:00
|
|
|
void add_web_seed(std::string const& url, web_seed_t::type_t type);
|
|
|
|
void add_web_seed(std::string const& url, web_seed_t::type_t type
|
|
|
|
, std::string const& auth, web_seed_t::headers_t const& extra_headers);
|
2015-08-02 05:57:11 +02:00
|
|
|
|
2014-12-31 23:05:34 +01:00
|
|
|
void remove_web_seed(std::string const& url, web_seed_t::type_t type);
|
2012-03-24 02:29:31 +01:00
|
|
|
void disconnect_web_seed(peer_connection* p);
|
2010-02-12 07:10:20 +01:00
|
|
|
|
2010-04-14 08:22:00 +02:00
|
|
|
void retry_web_seed(peer_connection* p, int retry = 0);
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void remove_web_seed(peer_connection* p, error_code const& ec
|
2015-02-15 06:17:09 +01:00
|
|
|
, operation_t op, int error = 0);
|
2007-11-27 04:37:47 +01:00
|
|
|
|
2008-12-30 04:54:07 +01:00
|
|
|
std::set<std::string> web_seeds(web_seed_entry::type_t type) const;
|
|
|
|
|
2007-08-17 09:37:08 +02:00
|
|
|
bool free_upload_slots() const
|
|
|
|
{ return m_num_uploads < m_max_uploads; }
|
|
|
|
|
2009-07-23 06:38:52 +02:00
|
|
|
bool choke_peer(peer_connection& c);
|
2010-10-04 06:06:14 +02:00
|
|
|
bool unchoke_peer(peer_connection& c, bool optimistic = false);
|
2007-08-17 09:37:08 +02:00
|
|
|
|
2014-09-22 05:47:43 +02:00
|
|
|
void trigger_unchoke();
|
|
|
|
void trigger_optimistic_unchoke();
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// used by peer_connection to attach itself to a torrent
|
|
|
|
// since incoming connections don't know what torrent
|
|
|
|
// they're a part of until they have received an info_hash.
|
2008-04-07 04:51:21 +02:00
|
|
|
// false means attach failed
|
|
|
|
bool attach_peer(peer_connection* p);
|
2003-10-23 01:00:57 +02:00
|
|
|
|
|
|
|
// this will remove the peer and make sure all
|
|
|
|
// the pieces it had have their reference counter
|
|
|
|
// decreased in the piece_picker
|
|
|
|
void remove_peer(peer_connection* p);
|
|
|
|
|
2014-12-31 15:41:35 +01:00
|
|
|
// cancel requests to this block from any peer we're
|
|
|
|
// connected to on this torrent
|
2007-07-06 19:15:35 +02:00
|
|
|
void cancel_block(piece_block block);
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
bool want_tick() const;
|
|
|
|
void update_want_tick();
|
2015-05-25 23:46:42 +02:00
|
|
|
void update_state_list();
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
bool want_peers() const;
|
|
|
|
bool want_peers_download() const;
|
|
|
|
bool want_peers_finished() const;
|
|
|
|
|
|
|
|
void update_want_peers();
|
|
|
|
void update_want_scrape();
|
|
|
|
void update_gauge();
|
|
|
|
|
2007-05-25 23:00:35 +02:00
|
|
|
bool try_connect_peer();
|
2014-07-06 21:18:00 +02:00
|
|
|
torrent_peer* add_peer(tcp::endpoint const& adr, int source, int flags = 0);
|
|
|
|
bool ban_peer(torrent_peer* tp);
|
|
|
|
void update_peer_port(int port, torrent_peer* p, int src);
|
|
|
|
void set_seed(torrent_peer* p, bool s);
|
|
|
|
void clear_failcount(torrent_peer* p);
|
2014-10-26 08:34:31 +01:00
|
|
|
std::pair<peer_list::iterator, peer_list::iterator> find_peers(address const& a);
|
2007-05-02 19:38:37 +02:00
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// the number of peers that belong to this torrent
|
2015-08-02 05:57:11 +02:00
|
|
|
int num_peers() const { return int(m_connections.size()); }
|
2004-08-05 15:56:26 +02:00
|
|
|
int num_seeds() const;
|
2014-09-24 02:02:00 +02:00
|
|
|
int num_downloaders() const;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
typedef std::vector<peer_connection*>::iterator peer_iterator;
|
|
|
|
typedef std::vector<peer_connection*>::const_iterator const_peer_iterator;
|
2003-11-05 00:27:06 +01:00
|
|
|
|
2004-01-13 04:08:59 +01:00
|
|
|
const_peer_iterator begin() const { return m_connections.begin(); }
|
|
|
|
const_peer_iterator end() const { return m_connections.end(); }
|
2003-11-05 00:27:06 +01:00
|
|
|
|
|
|
|
peer_iterator begin() { return m_connections.begin(); }
|
|
|
|
peer_iterator end() { return m_connections.end(); }
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2008-04-13 08:32:48 +02:00
|
|
|
void get_full_peer_list(std::vector<peer_list_entry>& v) const;
|
2007-11-25 19:48:43 +01:00
|
|
|
void get_peer_info(std::vector<peer_info>& v);
|
2015-02-14 22:32:41 +01:00
|
|
|
void get_download_queue(std::vector<partial_piece_info>* queue) const;
|
2007-11-25 19:48:43 +01:00
|
|
|
|
2016-03-19 06:44:21 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2010-01-15 17:45:42 +01:00
|
|
|
void refresh_explicit_cache(int cache_size);
|
2016-03-18 17:15:03 +01:00
|
|
|
#endif
|
2010-01-15 17:45:42 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void add_suggest_piece(int piece);
|
|
|
|
void update_suggest_piece(int index, int change);
|
2014-09-24 02:02:00 +02:00
|
|
|
void update_auto_sequential();
|
2016-03-18 17:15:03 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void refresh_suggest_pieces();
|
|
|
|
void do_refresh_suggest_pieces();
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// --------------------------------------------
|
|
|
|
// TRACKER MANAGEMENT
|
|
|
|
|
2004-03-28 19:45:37 +02:00
|
|
|
// these are callbacks called by the tracker_connection instance
|
|
|
|
// (either http_tracker_connection or udp_tracker_connection)
|
2003-10-23 01:00:57 +02:00
|
|
|
// when this torrent got a response from its tracker request
|
2004-03-28 19:45:37 +02:00
|
|
|
// or when a failure occured
|
2005-03-24 13:13:47 +01:00
|
|
|
virtual void tracker_response(
|
|
|
|
tracker_request const& r
|
2008-12-01 09:48:54 +01:00
|
|
|
, address const& tracker_ip
|
2009-05-15 23:23:41 +02:00
|
|
|
, std::list<address> const& ip_list
|
2015-04-19 08:28:21 +02:00
|
|
|
, struct tracker_response const& resp) TORRENT_OVERRIDE;
|
2005-03-24 13:13:47 +01:00
|
|
|
virtual void tracker_request_error(tracker_request const& r
|
2010-02-23 22:53:45 +01:00
|
|
|
, int response_code, error_code const& ec, const std::string& msg
|
2015-04-19 08:28:21 +02:00
|
|
|
, int retry_interval) TORRENT_OVERRIDE;
|
2008-04-23 03:54:21 +02:00
|
|
|
virtual void tracker_warning(tracker_request const& req
|
2015-04-19 08:28:21 +02:00
|
|
|
, std::string const& msg) TORRENT_OVERRIDE;
|
2007-11-20 23:46:27 +01:00
|
|
|
virtual void tracker_scrape_response(tracker_request const& req
|
2015-04-19 08:28:21 +02:00
|
|
|
, int complete, int incomplete, int downloaded, int downloaders) TORRENT_OVERRIDE;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2013-02-04 08:17:31 +01:00
|
|
|
void update_scrape_state();
|
|
|
|
|
2004-03-28 19:45:37 +02:00
|
|
|
// if no password and username is set
|
|
|
|
// this will return an empty string, otherwise
|
|
|
|
// it will concatenate the login and password
|
|
|
|
// ready to be sent over http (but without
|
|
|
|
// base64 encoding).
|
|
|
|
std::string tracker_login() const;
|
|
|
|
|
2013-08-31 23:06:43 +02:00
|
|
|
// generate the tracker key for this torrent.
|
|
|
|
// The key is passed to http trackers as ``&key=``.
|
|
|
|
boost::uint32_t tracker_key() const;
|
|
|
|
|
2012-11-03 04:50:12 +01:00
|
|
|
// if we need a connect boost, connect some peers
|
|
|
|
// immediately
|
|
|
|
void do_connect_boost();
|
|
|
|
|
2004-03-28 19:45:37 +02:00
|
|
|
// forcefully sets next_announce to the current time
|
2015-03-12 05:34:54 +01:00
|
|
|
void force_tracker_request(time_point, int tracker_idx);
|
2016-01-25 06:51:20 +01:00
|
|
|
void scrape_tracker(int idx, bool user_triggered);
|
2014-07-06 21:18:00 +02:00
|
|
|
void announce_with_tracker(boost::uint8_t e
|
2017-11-06 01:55:15 +01:00
|
|
|
= tracker_request::none);
|
2014-11-08 17:58:18 +01:00
|
|
|
int seconds_since_last_scrape() const
|
2014-12-02 21:06:30 +01:00
|
|
|
{
|
|
|
|
return m_last_scrape == (std::numeric_limits<boost::int16_t>::min)()
|
2015-04-06 06:31:21 +02:00
|
|
|
? -1 : int(m_ses.session_time() - m_last_scrape);
|
2014-12-02 21:06:30 +01:00
|
|
|
}
|
|
|
|
|
2009-10-25 03:37:45 +01:00
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
2010-02-14 02:39:55 +01:00
|
|
|
void dht_announce();
|
2009-10-25 03:37:45 +01:00
|
|
|
#endif
|
|
|
|
|
2015-12-13 21:14:19 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2004-03-28 19:45:37 +02:00
|
|
|
// sets the username and password that will be sent to
|
|
|
|
// the tracker
|
|
|
|
void set_tracker_login(std::string const& name, std::string const& pw);
|
2015-12-13 21:14:19 +01:00
|
|
|
#endif
|
2004-03-28 19:45:37 +02:00
|
|
|
|
2008-11-29 09:38:40 +01:00
|
|
|
announce_entry* find_tracker(tracker_request const& r);
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// --------------------------------------------
|
|
|
|
// PIECE MANAGEMENT
|
|
|
|
|
2010-09-05 18:01:36 +02:00
|
|
|
void recalc_share_mode();
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
struct suggest_piece_t
|
|
|
|
{
|
|
|
|
int piece_index;
|
|
|
|
int num_peers;
|
|
|
|
bool operator<(suggest_piece_t const& p) const { return num_peers < p.num_peers; }
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<suggest_piece_t> const& get_suggested_pieces() const
|
|
|
|
{ return m_suggested_pieces; }
|
2010-01-15 17:45:42 +01:00
|
|
|
|
2008-12-08 07:36:22 +01:00
|
|
|
bool super_seeding() const
|
2012-04-23 07:48:46 +02:00
|
|
|
{
|
|
|
|
// we're not super seeding if we're not a seed
|
2017-01-27 07:28:35 +01:00
|
|
|
return m_super_seeding;
|
2012-04-23 07:48:46 +02:00
|
|
|
}
|
2015-05-18 07:04:55 +02:00
|
|
|
|
2008-12-08 07:36:22 +01:00
|
|
|
void super_seeding(bool on);
|
|
|
|
int get_piece_to_super_seed(bitfield const&);
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// returns true if we have downloaded the given piece
|
2004-01-25 05:18:08 +01:00
|
|
|
bool have_piece(int index) const
|
2004-01-25 13:37:15 +01:00
|
|
|
{
|
2012-04-21 18:58:21 +02:00
|
|
|
if (!valid_metadata()) return false;
|
2014-07-06 21:18:00 +02:00
|
|
|
if (!has_picker()) return m_have_all;
|
2012-04-21 18:58:21 +02:00
|
|
|
return m_picker->have_piece(index);
|
2004-01-25 13:37:15 +01:00
|
|
|
}
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// returns true if we have downloaded the given piece
|
|
|
|
bool has_piece_passed(int index) const
|
|
|
|
{
|
|
|
|
if (!valid_metadata()) return false;
|
2015-08-21 14:52:07 +02:00
|
|
|
if (index < 0 || index >= torrent_file().num_pieces()) return false;
|
2014-07-06 21:18:00 +02:00
|
|
|
if (!has_picker()) return m_have_all;
|
|
|
|
return m_picker->has_piece_passed(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
// a predictive piece is a piece that we might
|
|
|
|
// not have yet, but still announced to peers, anticipating that
|
|
|
|
// we'll have it very soon
|
|
|
|
bool is_predictive_piece(int index) const
|
|
|
|
{
|
|
|
|
return std::binary_search(m_predictive_pieces.begin(), m_predictive_pieces.end(), index);
|
|
|
|
}
|
|
|
|
|
2016-07-03 20:48:18 +02:00
|
|
|
private:
|
|
|
|
|
2009-07-04 06:58:24 +02:00
|
|
|
// called when we learn that we have a piece
|
|
|
|
// only once per piece
|
|
|
|
void we_have(int index);
|
|
|
|
|
2016-07-03 20:48:18 +02:00
|
|
|
public:
|
|
|
|
|
2008-06-07 16:03:21 +02:00
|
|
|
int num_have() const
|
2008-06-07 04:58:28 +02:00
|
|
|
{
|
2014-03-13 09:00:53 +01:00
|
|
|
// pretend we have every piece when in seed mode
|
|
|
|
if (m_seed_mode) {
|
|
|
|
return m_torrent_file->num_pieces();
|
|
|
|
}
|
|
|
|
|
2008-06-07 04:58:28 +02:00
|
|
|
return has_picker()
|
2010-09-05 18:01:36 +02:00
|
|
|
? m_picker->num_have()
|
2014-07-06 21:18:00 +02:00
|
|
|
: m_have_all ? m_torrent_file->num_pieces() : 0;
|
2008-06-07 04:58:28 +02:00
|
|
|
}
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// the number of pieces that have passed
|
|
|
|
// hash check, but aren't necessarily
|
|
|
|
// flushed to disk yet
|
|
|
|
int num_passed() const
|
2008-01-31 18:52:29 +01:00
|
|
|
{
|
2014-07-06 21:18:00 +02:00
|
|
|
return has_picker()
|
|
|
|
? m_picker->num_passed()
|
|
|
|
: m_have_all ? m_torrent_file->num_pieces() : 0;
|
2008-01-31 18:52:29 +01:00
|
|
|
}
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// when we get a have message, this is called for that piece
|
|
|
|
void peer_has(int index, peer_connection const* peer);
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// when we get a bitfield message, this is called for that piece
|
|
|
|
void peer_has(bitfield const& bits, peer_connection const* peer);
|
2012-05-02 03:08:25 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void peer_has_all(peer_connection const* peer);
|
|
|
|
|
|
|
|
void peer_lost(int index, peer_connection const* peer);
|
|
|
|
void peer_lost(bitfield const& bits, peer_connection const* peer);
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
int block_size() const { TORRENT_ASSERT(m_block_size_shift > 0); return 1 << m_block_size_shift; }
|
2010-02-23 17:26:24 +01:00
|
|
|
peer_request to_req(piece_block const& p) const;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2015-02-15 06:17:09 +01:00
|
|
|
void disconnect_all(error_code const& ec, operation_t op);
|
2010-10-03 12:07:38 +02:00
|
|
|
int disconnect_peers(int num, error_code const& ec);
|
2004-01-21 14:16:11 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// called every time a block is marked as finished in the
|
|
|
|
// piece picker. We might have completed the torrent and
|
|
|
|
// we can delete the piece picker
|
|
|
|
void maybe_done_flushing();
|
|
|
|
|
2004-01-21 14:16:11 +01:00
|
|
|
// this is called wheh the torrent has completed
|
|
|
|
// the download. It will post an event, disconnect
|
|
|
|
// all seeds and let the tracker know we're finished.
|
|
|
|
void completed();
|
2007-03-07 19:50:38 +01:00
|
|
|
|
2009-08-20 05:19:12 +02:00
|
|
|
#if TORRENT_USE_I2P
|
|
|
|
void on_i2p_resolve(error_code const& ec, char const* dest);
|
2014-07-06 21:18:00 +02:00
|
|
|
bool is_i2p() const { return m_torrent_file && m_torrent_file->is_i2p(); }
|
2009-08-20 05:19:12 +02:00
|
|
|
#endif
|
|
|
|
|
2007-03-07 19:50:38 +01:00
|
|
|
// this is the asio callback that is called when a name
|
|
|
|
// lookup for a PEER is completed.
|
2014-07-06 21:18:00 +02:00
|
|
|
void on_peer_name_lookup(error_code const& e
|
2014-10-05 03:23:22 +02:00
|
|
|
, std::vector<address> const& addrs
|
2014-07-06 21:18:00 +02:00
|
|
|
, int port);
|
2007-03-07 19:50:38 +01:00
|
|
|
|
2006-04-25 23:04:48 +02:00
|
|
|
// this is the asio callback that is called when a name
|
2007-03-07 19:50:38 +01:00
|
|
|
// lookup for a WEB SEED is completed.
|
2014-10-05 03:23:22 +02:00
|
|
|
void on_name_lookup(error_code const& e
|
|
|
|
, std::vector<address> const& addrs
|
|
|
|
, int port
|
2015-05-18 07:04:55 +02:00
|
|
|
, std::list<web_seed_t>::iterator web);
|
2007-02-12 06:46:29 +01:00
|
|
|
|
2014-12-31 23:05:34 +01:00
|
|
|
void connect_web_seed(std::list<web_seed_t>::iterator web, tcp::endpoint a);
|
2010-08-02 08:16:32 +02:00
|
|
|
|
2007-02-12 06:46:29 +01:00
|
|
|
// this is the asio callback that is called when a name
|
|
|
|
// lookup for a proxy for a web seed is completed.
|
2014-10-05 03:23:22 +02:00
|
|
|
void on_proxy_name_lookup(error_code const& e
|
|
|
|
, std::vector<address> const& addrs
|
2014-12-31 23:05:34 +01:00
|
|
|
, std::list<web_seed_t>::iterator web, int port);
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2014-10-06 00:30:09 +02:00
|
|
|
// re-evaluates whether this torrent should be considered inactive or not
|
|
|
|
void on_inactivity_tick(error_code const& ec);
|
|
|
|
|
|
|
|
|
2016-06-13 13:47:16 +02:00
|
|
|
// calculate the instantaneous inactive state (the externally facing
|
2014-10-06 00:30:09 +02:00
|
|
|
// inactive state is not instantaneous, but low-pass filtered)
|
|
|
|
bool is_inactive_internal() const;
|
|
|
|
|
2011-04-29 10:09:03 +02:00
|
|
|
// remove a web seed, or schedule it for removal in case there
|
|
|
|
// are outstanding operations on it
|
2014-12-31 23:05:34 +01:00
|
|
|
void remove_web_seed(std::list<web_seed_t>::iterator web);
|
2011-04-29 10:09:03 +02:00
|
|
|
|
2005-06-11 01:12:50 +02:00
|
|
|
// this is called when the torrent has finished. i.e.
|
|
|
|
// all the pieces we have not filtered have been downloaded.
|
|
|
|
// If no pieces are filtered, this is called first and then
|
|
|
|
// completed() is called immediately after it.
|
|
|
|
void finished();
|
|
|
|
|
2008-05-20 05:21:45 +02:00
|
|
|
// This is the opposite of finished. It is called if we used
|
|
|
|
// to be finished but enabled some files for download so that
|
|
|
|
// we wasn't finished anymore.
|
|
|
|
void resume_download();
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void verify_piece(int piece);
|
|
|
|
void on_piece_verified(disk_io_job const* j);
|
2003-12-07 06:53:04 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this is called whenever a peer in this swarm becomes interesting
|
|
|
|
// it is responsible for issuing a block request, if appropriate
|
|
|
|
void peer_is_interesting(peer_connection& c);
|
2008-06-23 20:54:58 +02:00
|
|
|
|
|
|
|
// piece_passed is called when a piece passes the hash check
|
|
|
|
// this will tell all peers that we just got his piece
|
|
|
|
// and also let the piece picker know that we have this piece
|
|
|
|
// so it wont pick it for download
|
|
|
|
void piece_passed(int index);
|
|
|
|
|
|
|
|
// piece_failed is called when a piece fails the hash check
|
2003-12-01 22:27:27 +01:00
|
|
|
void piece_failed(int index);
|
2008-06-23 16:45:01 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this is the handler for hash failure piece synchronization
|
|
|
|
// i.e. resetting the piece
|
|
|
|
void on_piece_sync(disk_io_job const* j);
|
|
|
|
|
|
|
|
// this is the handler for write failure piece synchronization
|
|
|
|
void on_piece_fail_sync(disk_io_job const* j, piece_block b);
|
2008-06-23 16:45:01 +02:00
|
|
|
|
2011-11-16 03:29:59 +01:00
|
|
|
enum wasted_reason_t
|
|
|
|
{
|
2014-07-29 07:59:00 +02:00
|
|
|
piece_timed_out, piece_cancelled, piece_unknown, piece_seed
|
|
|
|
, piece_end_game, piece_closing
|
2011-11-16 03:29:59 +01:00
|
|
|
, waste_reason_max
|
|
|
|
};
|
|
|
|
void add_redundant_bytes(int b, wasted_reason_t reason);
|
2008-07-11 09:30:04 +02:00
|
|
|
void add_failed_bytes(int b);
|
2003-12-01 22:27:27 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this is true if we have all the pieces, but not necessarily flushed them to disk
|
2015-09-25 23:22:38 +02:00
|
|
|
bool is_seed() const;
|
2003-12-09 19:09:34 +01:00
|
|
|
|
2007-04-12 00:27:58 +02:00
|
|
|
// this is true if we have all the pieces that we want
|
2014-07-06 21:18:00 +02:00
|
|
|
// the pieces don't necessarily need to be flushed to disk
|
2015-09-25 23:22:38 +02:00
|
|
|
bool is_finished() const;
|
2007-04-12 00:27:58 +02:00
|
|
|
|
2015-09-25 23:22:38 +02:00
|
|
|
bool is_inactive() const;
|
2014-05-19 00:17:51 +02:00
|
|
|
|
2009-10-26 02:29:39 +01:00
|
|
|
std::string save_path() const;
|
2004-01-07 01:48:02 +01:00
|
|
|
alert_manager& alerts() const;
|
2004-06-14 01:30:42 +02:00
|
|
|
piece_picker& picker()
|
|
|
|
{
|
2007-10-05 02:30:00 +02:00
|
|
|
TORRENT_ASSERT(m_picker.get());
|
2004-06-14 01:30:42 +02:00
|
|
|
return *m_picker;
|
|
|
|
}
|
2015-02-14 22:32:41 +01:00
|
|
|
piece_picker const& picker() const
|
|
|
|
{
|
|
|
|
TORRENT_ASSERT(m_picker.get());
|
|
|
|
return *m_picker;
|
|
|
|
}
|
2014-07-06 21:18:00 +02:00
|
|
|
void need_picker();
|
2007-03-17 00:28:26 +01:00
|
|
|
bool has_picker() const
|
|
|
|
{
|
2007-04-17 23:50:48 +02:00
|
|
|
return m_picker.get() != 0;
|
2007-03-17 00:28:26 +01:00
|
|
|
}
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2015-01-20 07:26:22 +01:00
|
|
|
void update_max_failcount()
|
|
|
|
{
|
|
|
|
if (!m_peer_list) return;
|
2015-06-30 01:56:39 +02:00
|
|
|
torrent_state st = get_peer_list_state();
|
2015-01-20 07:26:22 +01:00
|
|
|
m_peer_list->set_max_failcount(&st);
|
|
|
|
}
|
2014-10-26 08:34:31 +01:00
|
|
|
int num_known_peers() const { return m_peer_list ? m_peer_list->num_peers() : 0; }
|
|
|
|
int num_connect_candidates() const { return m_peer_list ? m_peer_list->num_connect_candidates() : 0; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
piece_manager& storage();
|
2015-04-26 03:45:23 +02:00
|
|
|
bool has_storage() const { return m_storage.get() != NULL; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2006-05-28 21:03:54 +02:00
|
|
|
torrent_info const& torrent_file() const
|
2007-09-01 05:00:31 +02:00
|
|
|
{ return *m_torrent_file; }
|
2004-02-22 23:40:45 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
boost::shared_ptr<const torrent_info> get_torrent_copy();
|
2012-10-02 18:07:55 +02:00
|
|
|
|
2011-01-18 04:41:54 +01:00
|
|
|
std::string const& uuid() const { return m_uuid; }
|
2011-03-23 03:46:22 +01:00
|
|
|
void set_uuid(std::string const& s) { m_uuid = s; }
|
2010-12-30 07:46:28 +01:00
|
|
|
std::string const& url() const { return m_url; }
|
2011-03-23 03:46:22 +01:00
|
|
|
void set_url(std::string const& s) { m_url = s; }
|
|
|
|
std::string const& source_feed_url() const { return m_source_feed_url; }
|
|
|
|
void set_source_feed_url(std::string const& s) { m_source_feed_url = s; }
|
2010-12-30 07:46:28 +01:00
|
|
|
|
2004-09-12 12:12:16 +02:00
|
|
|
std::vector<announce_entry> const& trackers() const
|
|
|
|
{ return m_trackers; }
|
|
|
|
|
|
|
|
void replace_trackers(std::vector<announce_entry> const& urls);
|
2014-01-26 02:17:58 +01:00
|
|
|
|
|
|
|
// returns true if the tracker was added, and false if it was already
|
|
|
|
// in the tracker list (in which case the source was added to the
|
|
|
|
// entry in the list)
|
|
|
|
bool add_tracker(announce_entry const& url);
|
2004-09-12 12:12:16 +02:00
|
|
|
|
2008-04-09 22:09:36 +02:00
|
|
|
torrent_handle get_handle();
|
2004-03-01 01:50:00 +01:00
|
|
|
|
2008-04-13 20:54:36 +02:00
|
|
|
void write_resume_data(entry& rd) const;
|
2015-03-12 06:20:12 +01:00
|
|
|
void read_resume_data(bdecode_node const& rd);
|
2008-04-13 20:54:36 +02:00
|
|
|
|
2010-03-19 19:39:51 +01:00
|
|
|
void seen_complete() { m_last_seen_complete = time(0); }
|
2010-10-16 17:24:45 +02:00
|
|
|
int time_since_complete() const { return int(time(0) - m_last_seen_complete); }
|
2010-03-19 19:39:51 +01:00
|
|
|
time_t last_seen_complete() const { return m_last_seen_complete; }
|
|
|
|
|
2005-03-19 13:22:40 +01:00
|
|
|
// LOGGING
|
2015-04-17 03:15:33 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2015-05-10 07:11:51 +02:00
|
|
|
virtual void debug_log(const char* fmt, ...) const TORRENT_OVERRIDE TORRENT_FORMAT(2,3);
|
2015-05-03 04:53:54 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void log_to_all_peers(char const* message);
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point m_dht_start_time;
|
2005-03-19 13:22:40 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// DEBUG
|
2014-01-21 20:26:09 +01:00
|
|
|
#if TORRENT_USE_INVARIANT_CHECKS
|
2004-06-14 01:30:42 +02:00
|
|
|
void check_invariant() const;
|
2003-11-20 20:58:29 +01:00
|
|
|
#endif
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2004-03-28 19:45:37 +02:00
|
|
|
// --------------------------------------------
|
|
|
|
// RESOURCE MANAGEMENT
|
|
|
|
|
2013-05-09 04:50:16 +02:00
|
|
|
// flags are defined in storage.hpp
|
|
|
|
void move_storage(std::string const& save_path, int flags);
|
2004-03-23 23:58:18 +01:00
|
|
|
|
2008-05-28 10:44:40 +02:00
|
|
|
// renames the file with the given index to the new name
|
|
|
|
// the name may include a directory path
|
2017-08-10 07:59:16 +02:00
|
|
|
// posts alert to indicate success or failure
|
2014-12-26 22:25:37 +01:00
|
|
|
void rename_file(int index, std::string const& name);
|
2008-05-28 10:44:40 +02:00
|
|
|
|
2005-10-16 22:15:54 +02:00
|
|
|
// unless this returns true, new connections must wait
|
|
|
|
// with their initialization.
|
|
|
|
bool ready_for_connections() const
|
|
|
|
{ return m_connections_initialized; }
|
2005-10-16 11:15:46 +02:00
|
|
|
bool valid_metadata() const
|
2007-09-01 05:00:31 +02:00
|
|
|
{ return m_torrent_file->is_valid(); }
|
2008-07-18 12:03:42 +02:00
|
|
|
bool are_files_checked() const
|
|
|
|
{ return m_files_checked; }
|
2014-07-06 21:18:00 +02:00
|
|
|
bool valid_storage() const
|
2015-11-19 01:51:17 +01:00
|
|
|
{ return m_storage.get() != NULL; }
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2006-11-14 01:08:16 +01:00
|
|
|
// parses the info section from the given
|
|
|
|
// bencoded tree and moves the torrent
|
|
|
|
// to the checker thread for initial checking
|
|
|
|
// of the storage.
|
2007-12-28 21:11:10 +01:00
|
|
|
// a return value of false indicates an error
|
2008-09-24 04:32:33 +02:00
|
|
|
bool set_metadata(char const* metadata_buf, int metadata_size);
|
2007-10-31 10:48:20 +01:00
|
|
|
|
2010-12-30 02:47:30 +01:00
|
|
|
void on_torrent_download(error_code const& ec, http_parser const& parser
|
|
|
|
, char const* data, int size);
|
|
|
|
|
2008-04-24 05:28:48 +02:00
|
|
|
int sequence_number() const { return m_sequence_number; }
|
|
|
|
|
2009-02-03 08:46:24 +01:00
|
|
|
bool seed_mode() const { return m_seed_mode; }
|
2015-07-21 19:12:37 +02:00
|
|
|
void leave_seed_mode(bool skip_checking);
|
2014-03-13 09:00:53 +01:00
|
|
|
|
2009-02-03 08:46:24 +01:00
|
|
|
bool all_verified() const
|
2013-01-20 09:36:34 +01:00
|
|
|
{ return int(m_num_verified) == m_torrent_file->num_pieces(); }
|
2014-07-06 21:18:00 +02:00
|
|
|
bool verifying_piece(int piece) const
|
|
|
|
{
|
|
|
|
TORRENT_ASSERT(piece < int(m_verifying.size()));
|
|
|
|
TORRENT_ASSERT(piece >= 0);
|
|
|
|
return m_verifying.get_bit(piece);
|
|
|
|
}
|
|
|
|
void verifying(int piece)
|
|
|
|
{
|
|
|
|
TORRENT_ASSERT(piece < int(m_verifying.size()));
|
|
|
|
TORRENT_ASSERT(piece >= 0);
|
|
|
|
TORRENT_ASSERT(m_verifying.get_bit(piece) == false);
|
|
|
|
m_verifying.set_bit(piece);
|
|
|
|
}
|
2009-02-03 08:46:24 +01:00
|
|
|
bool verified_piece(int piece) const
|
|
|
|
{
|
|
|
|
TORRENT_ASSERT(piece < int(m_verified.size()));
|
|
|
|
TORRENT_ASSERT(piece >= 0);
|
|
|
|
return m_verified.get_bit(piece);
|
|
|
|
}
|
2014-03-13 09:00:53 +01:00
|
|
|
void verified(int piece);
|
2009-02-03 08:46:24 +01:00
|
|
|
|
2009-03-13 07:09:39 +01:00
|
|
|
bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int piece);
|
|
|
|
|
2010-02-05 09:23:17 +01:00
|
|
|
// this is called once periodically for torrents
|
|
|
|
// that are not private
|
|
|
|
void lsd_announce();
|
|
|
|
|
2014-08-27 08:36:28 +02:00
|
|
|
void update_last_upload() { m_last_upload = m_ses.session_time(); }
|
2010-07-08 21:29:38 +02:00
|
|
|
|
2011-02-27 18:26:57 +01:00
|
|
|
void set_apply_ip_filter(bool b);
|
|
|
|
bool apply_ip_filter() const { return m_apply_ip_filter; }
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
std::vector<int> const& predictive_pieces() const
|
|
|
|
{ return m_predictive_pieces; }
|
|
|
|
|
|
|
|
// this is called whenever we predict to have this piece
|
|
|
|
// within one second
|
|
|
|
void predicted_have_piece(int index, int milliseconds);
|
2011-06-05 05:06:34 +02:00
|
|
|
|
2011-11-15 03:34:00 +01:00
|
|
|
void clear_in_state_update()
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT(m_links[aux::session_interface::torrent_state_updates].in_list());
|
|
|
|
m_links[aux::session_interface::torrent_state_updates].clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void dec_refcount(char const* purpose);
|
|
|
|
void inc_refcount(char const* purpose);
|
|
|
|
int refcount() const { return m_refcount; }
|
2011-11-15 03:34:00 +01:00
|
|
|
|
2017-02-01 07:39:09 +01:00
|
|
|
void inc_num_connecting(torrent_peer* pp)
|
|
|
|
{
|
|
|
|
++m_num_connecting;
|
|
|
|
TORRENT_ASSERT(m_num_connecting <= int(m_connections.size()));
|
|
|
|
if (pp->seed)
|
|
|
|
{
|
|
|
|
++m_num_connecting_seeds;
|
|
|
|
TORRENT_ASSERT(m_num_connecting_seeds <= int(m_connections.size()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void dec_num_connecting(torrent_peer* pp)
|
2012-01-23 06:14:12 +01:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT(m_num_connecting > 0);
|
|
|
|
--m_num_connecting;
|
2017-02-01 07:39:09 +01:00
|
|
|
if (pp->seed)
|
|
|
|
{
|
|
|
|
TORRENT_ASSERT(m_num_connecting_seeds > 0);
|
|
|
|
--m_num_connecting_seeds;
|
|
|
|
}
|
|
|
|
TORRENT_ASSERT(m_num_connecting <= int(m_connections.size()));
|
2012-01-23 06:14:12 +01:00
|
|
|
}
|
2013-07-28 17:06:28 +02:00
|
|
|
|
2015-09-20 17:59:00 +02:00
|
|
|
bool is_ssl_torrent() const { return m_ssl_torrent; }
|
2011-09-10 07:52:07 +02:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
2011-09-12 05:51:49 +02:00
|
|
|
void set_ssl_cert(std::string const& certificate
|
|
|
|
, std::string const& private_key
|
|
|
|
, std::string const& dh_params
|
|
|
|
, std::string const& passphrase);
|
2014-05-10 23:53:50 +02:00
|
|
|
void set_ssl_cert_buffer(std::string const& certificate
|
|
|
|
, std::string const& private_key
|
|
|
|
, std::string const& dh_params);
|
2017-02-01 07:39:09 +01:00
|
|
|
boost::asio::ssl::context* ssl_ctx() const { return m_ssl_ctx.get(); }
|
2011-09-10 07:52:07 +02:00
|
|
|
#endif
|
|
|
|
|
2014-04-22 06:21:14 +02:00
|
|
|
int num_time_critical_pieces() const
|
2015-11-19 01:51:17 +01:00
|
|
|
{ return int(m_time_critical_pieces.size()); }
|
2014-04-22 06:21:14 +02:00
|
|
|
|
2003-11-26 15:11:25 +01:00
|
|
|
private:
|
2007-06-10 22:46:09 +02:00
|
|
|
|
2015-05-16 08:33:37 +02:00
|
|
|
void ip_filter_updated();
|
|
|
|
|
2014-07-13 06:56:53 +02:00
|
|
|
void inc_stats_counter(int c, int value = 1);
|
|
|
|
|
2014-10-26 08:34:31 +01:00
|
|
|
// initialize the torrent_state structure passed to peer_list
|
2014-07-06 21:18:00 +02:00
|
|
|
// member functions. Don't forget to also call peers_erased()
|
2014-10-26 08:34:31 +01:00
|
|
|
// on the erased member after the peer_list call
|
2015-06-30 01:56:39 +02:00
|
|
|
torrent_state get_peer_list_state();
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
void construct_storage();
|
|
|
|
void update_list(int list, bool in);
|
|
|
|
|
|
|
|
void on_files_deleted(disk_io_job const* j);
|
|
|
|
void on_torrent_paused(disk_io_job const* j);
|
|
|
|
void on_storage_moved(disk_io_job const* j);
|
|
|
|
void on_save_resume_data(disk_io_job const* j);
|
|
|
|
void on_file_renamed(disk_io_job const* j);
|
|
|
|
void on_cache_flushed(disk_io_job const* j);
|
|
|
|
|
2017-07-11 06:35:34 +02:00
|
|
|
// this is used when a torrent is being removed.It synchronizes with the
|
|
|
|
// disk thread
|
|
|
|
void on_torrent_aborted();
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// upload and download rate limits for the torrent
|
|
|
|
void set_limit_impl(int limit, int channel, bool state_update = true);
|
|
|
|
int limit_impl(int channel) const;
|
|
|
|
|
|
|
|
void refresh_explicit_cache_impl(disk_io_job const* j, int cache_size);
|
2007-06-11 23:24:14 +02:00
|
|
|
|
2004-09-12 12:12:16 +02:00
|
|
|
int prioritize_tracker(int tracker_index);
|
2008-11-29 09:38:40 +01:00
|
|
|
int deprioritize_tracker(int tracker_index);
|
|
|
|
|
2007-02-19 01:01:39 +01:00
|
|
|
bool request_bandwidth_from_session(int channel) const;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2008-04-13 09:39:37 +02:00
|
|
|
void update_peer_interest(bool was_finished);
|
2008-12-08 10:13:21 +01:00
|
|
|
void prioritize_udp_trackers();
|
2007-03-21 03:09:50 +01:00
|
|
|
|
2015-03-12 05:34:54 +01:00
|
|
|
void update_tracker_timer(time_point now);
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
static void on_tracker_announce_disp(boost::weak_ptr<torrent> p
|
|
|
|
, error_code const& e);
|
2009-09-30 19:21:59 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
void on_tracker_announce();
|
|
|
|
|
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
|
|
|
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
|
|
|
, std::vector<tcp::endpoint> const& peers);
|
|
|
|
void on_dht_announce_response(std::vector<tcp::endpoint> const& peers);
|
|
|
|
bool should_announce_dht() const;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void remove_time_critical_piece(int piece, bool finished = false);
|
|
|
|
void remove_time_critical_pieces(std::vector<int> const& priority);
|
|
|
|
void request_time_critical_pieces();
|
|
|
|
|
2015-06-30 01:56:39 +02:00
|
|
|
void need_peer_list();
|
2004-03-21 03:03:37 +01:00
|
|
|
|
2015-05-16 08:33:37 +02:00
|
|
|
boost::shared_ptr<const ip_filter> m_ip_filter;
|
|
|
|
|
2008-05-19 04:52:32 +02:00
|
|
|
// all time totals of uploaded and downloaded payload
|
|
|
|
// stored in resume data
|
2014-12-03 05:32:50 +01:00
|
|
|
boost::int64_t m_total_uploaded;
|
|
|
|
boost::int64_t m_total_downloaded;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
2005-03-05 15:17:17 +01:00
|
|
|
// if this pointer is 0, the torrent is in
|
2004-06-14 01:30:42 +02:00
|
|
|
// a state where the metadata hasn't been
|
2013-08-12 02:51:49 +02:00
|
|
|
// received yet, or during shutdown.
|
2007-06-10 22:46:09 +02:00
|
|
|
// the piece_manager keeps the torrent object
|
|
|
|
// alive by holding a shared_ptr to it and
|
|
|
|
// the torrent keeps the piece manager alive
|
2014-07-06 21:18:00 +02:00
|
|
|
// with this shared_ptr. This cycle is
|
2007-06-10 22:46:09 +02:00
|
|
|
// broken when torrent::abort() is called
|
|
|
|
// Then the torrent releases the piece_manager
|
|
|
|
// and when the piece_manager is complete with all
|
|
|
|
// outstanding disk io jobs (that keeps
|
|
|
|
// the piece_manager alive) it will destruct
|
|
|
|
// and release the torrent file. The reason for
|
|
|
|
// this is that the torrent_info is used by
|
|
|
|
// the piece_manager, and stored in the
|
|
|
|
// torrent, so the torrent cannot destruct
|
|
|
|
// before the piece_manager.
|
2014-07-06 21:18:00 +02:00
|
|
|
boost::shared_ptr<piece_manager> m_storage;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2011-08-28 23:06:15 +02:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
2015-06-06 07:22:53 +02:00
|
|
|
boost::shared_ptr<boost::asio::ssl::context> m_ssl_ctx;
|
2011-09-12 05:51:49 +02:00
|
|
|
|
2012-02-26 01:01:53 +01:00
|
|
|
#if BOOST_VERSION >= 104700
|
2012-01-16 00:34:43 +01:00
|
|
|
bool verify_peer_cert(bool preverified, boost::asio::ssl::verify_context& ctx);
|
2012-02-23 05:32:50 +01:00
|
|
|
#endif
|
|
|
|
|
2011-09-12 05:51:49 +02:00
|
|
|
void init_ssl(std::string const& cert);
|
2011-08-28 23:06:15 +02:00
|
|
|
#endif
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void setup_peer_class();
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2015-08-23 11:01:55 +02:00
|
|
|
// The list of web seeds in this torrent. Seeds with fatal errors are
|
|
|
|
// removed from the set. It's important that iteratores are not
|
|
|
|
// invalidated as entries are added and removed from this list, hence the
|
|
|
|
// std::list
|
2014-12-31 23:05:34 +01:00
|
|
|
std::list<web_seed_t> m_web_seeds;
|
2006-04-25 23:04:48 +02:00
|
|
|
|
2008-05-19 04:52:32 +02:00
|
|
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
|
|
|
typedef std::list<boost::shared_ptr<torrent_plugin> > extension_list_t;
|
|
|
|
extension_list_t m_extensions;
|
|
|
|
#endif
|
|
|
|
|
2008-07-12 10:25:19 +02:00
|
|
|
// used for tracker announces
|
|
|
|
deadline_timer m_tracker_timer;
|
|
|
|
|
2014-10-06 00:30:09 +02:00
|
|
|
// used to detect when we are active or inactive for long enough
|
|
|
|
// to trigger the auto-manage logic
|
|
|
|
deadline_timer m_inactivity_timer;
|
|
|
|
|
2003-12-07 06:53:04 +01:00
|
|
|
// this is the upload and download statistics for the whole torrent.
|
|
|
|
// it's updated from all its peers once every second.
|
|
|
|
libtorrent::stat m_stat;
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
// -----------------------------
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this vector is allocated lazily. If no file priorities are
|
|
|
|
// ever changed, this remains empty. Any unallocated slot
|
|
|
|
// implicitly means the file has priority 1.
|
|
|
|
// TODO: this wastes 5 bits per file
|
2008-07-20 18:00:08 +02:00
|
|
|
std::vector<boost::uint8_t> m_file_priority;
|
|
|
|
|
2015-06-29 04:47:11 +02:00
|
|
|
// this object is used to track download progress of individual files
|
|
|
|
aux::file_progress m_file_progress;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// these are the pieces we're currently
|
|
|
|
// suggesting to peers.
|
|
|
|
std::vector<suggest_piece_t> m_suggested_pieces;
|
2015-08-23 11:01:55 +02:00
|
|
|
|
2004-09-12 12:12:16 +02:00
|
|
|
std::vector<announce_entry> m_trackers;
|
2007-07-03 01:48:06 +02:00
|
|
|
// this is an index into m_trackers
|
|
|
|
|
2009-03-17 10:34:44 +01:00
|
|
|
// this list is sorted by time_critical_piece::deadline
|
2014-07-06 21:18:00 +02:00
|
|
|
std::vector<time_critical_piece> m_time_critical_pieces;
|
2009-03-17 10:34:44 +01:00
|
|
|
|
2010-11-18 06:51:52 +01:00
|
|
|
std::string m_trackerid;
|
2015-12-13 21:14:19 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
// deprecated in 1.1
|
2004-02-22 23:40:45 +01:00
|
|
|
std::string m_username;
|
|
|
|
std::string m_password;
|
2015-12-13 21:14:19 +01:00
|
|
|
#endif
|
2004-03-23 23:58:18 +01:00
|
|
|
|
2009-10-26 02:29:39 +01:00
|
|
|
std::string m_save_path;
|
2005-05-13 02:39:39 +02:00
|
|
|
|
2010-12-30 02:47:30 +01:00
|
|
|
// if we don't have the metadata, this is a url to
|
|
|
|
// the torrent file
|
|
|
|
std::string m_url;
|
|
|
|
|
2011-01-18 04:41:54 +01:00
|
|
|
// if this was added from an RSS feed, this is the unique
|
|
|
|
// identifier in the feed.
|
|
|
|
std::string m_uuid;
|
|
|
|
|
|
|
|
// if this torrent was added by an RSS feed, this is the
|
|
|
|
// URL to that feed
|
|
|
|
std::string m_source_feed_url;
|
|
|
|
|
2010-12-30 02:47:30 +01:00
|
|
|
// this is used as temporary storage while downloading
|
|
|
|
// the .torrent file from m_url
|
2014-07-06 21:18:00 +02:00
|
|
|
// std::vector<char> m_torrent_file_buf;
|
|
|
|
|
|
|
|
// this is a list of all pieces that we have announced
|
|
|
|
// as having, without actually having yet. If we receive
|
|
|
|
// a request for a piece in this list, we need to hold off
|
|
|
|
// on responding until we have completed the piece and
|
|
|
|
// verified its hash. If the hash fails, send reject to
|
|
|
|
// peers with outstanding requests, and dont_have to other
|
|
|
|
// peers. This vector is ordered, to make lookups fast.
|
|
|
|
std::vector<int> m_predictive_pieces;
|
2010-12-30 02:47:30 +01:00
|
|
|
|
2014-07-29 07:59:00 +02:00
|
|
|
// the performance counters of this session
|
|
|
|
counters& m_stats_counters;
|
|
|
|
|
2009-02-03 08:46:24 +01:00
|
|
|
// each bit represents a piece. a set bit means
|
|
|
|
// the piece has had its hash verified. This
|
|
|
|
// is only used in seed mode (when m_seed_mode
|
|
|
|
// is true)
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
// TODO: These two bitfields should probably be coalesced into one
|
2009-02-03 08:46:24 +01:00
|
|
|
bitfield m_verified;
|
2014-07-06 21:18:00 +02:00
|
|
|
// this means there is an outstanding, async, operation
|
|
|
|
// to verify each piece that has a 1
|
|
|
|
bitfield m_verifying;
|
2008-03-08 07:06:31 +01:00
|
|
|
|
2009-02-23 02:21:19 +01:00
|
|
|
// set if there's an error on this torrent
|
|
|
|
error_code m_error;
|
2008-05-20 09:57:44 +02:00
|
|
|
|
2008-07-01 01:14:31 +02:00
|
|
|
// used if there is any resume data
|
2014-07-06 21:18:00 +02:00
|
|
|
boost::scoped_ptr<resume_data_t> m_resume_data;
|
2008-03-08 07:06:31 +01:00
|
|
|
|
2006-11-14 01:08:16 +01:00
|
|
|
// if the torrent is started without metadata, it may
|
|
|
|
// still be given a name until the metadata is received
|
|
|
|
// once the metadata is received this field will no
|
|
|
|
// longer be used and will be reset
|
|
|
|
boost::scoped_ptr<std::string> m_name;
|
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
storage_constructor_type m_storage_constructor;
|
|
|
|
|
2011-09-22 12:37:47 +02:00
|
|
|
// the posix time this torrent was added and when
|
|
|
|
// it was completed. If the torrent isn't yet
|
|
|
|
// completed, m_completed_time is 0
|
|
|
|
time_t m_added_time;
|
|
|
|
time_t m_completed_time;
|
|
|
|
|
2012-05-07 00:46:21 +02:00
|
|
|
// this was the last time _we_ saw a seed in this swarm
|
|
|
|
time_t m_last_seen_complete;
|
|
|
|
|
|
|
|
// this is the time last any of our peers saw a seed
|
|
|
|
// in this swarm
|
|
|
|
time_t m_swarm_last_seen_complete;
|
|
|
|
|
2014-11-12 17:57:59 +01:00
|
|
|
// keep a copy if the info-hash here, so it can be accessed from multiple
|
|
|
|
// threads, and be cheap to access from the client
|
|
|
|
sha1_hash m_info_hash;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
public:
|
|
|
|
// these are the lists this torrent belongs to. For more
|
|
|
|
// details about each list, see session_impl.hpp. Each list
|
|
|
|
// represents a group this torrent belongs to and makes it
|
|
|
|
// efficient to enumerate only torrents belonging to a specific
|
|
|
|
// group. Such as torrents that want peer connections or want
|
|
|
|
// to be ticked etc.
|
2015-05-25 23:46:42 +02:00
|
|
|
|
|
|
|
// TODO: 3 factor out the links (as well as update_list() to a separate
|
|
|
|
// class that torrent can inherit)
|
2014-07-06 21:18:00 +02:00
|
|
|
link m_links[aux::session_interface::num_torrent_lists];
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2013-01-20 09:36:34 +01:00
|
|
|
// m_num_verified = m_verified.count()
|
|
|
|
boost::uint32_t m_num_verified;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this timestamp is kept in session-time, to
|
|
|
|
// make it fit in 16 bits
|
|
|
|
boost::uint16_t m_last_saved_resume;
|
|
|
|
|
|
|
|
// if this torrent is running, this was the time
|
|
|
|
// when it was started. This is used to have a
|
|
|
|
// bias towards keeping seeding torrents that
|
|
|
|
// recently was started, to avoid oscillation
|
|
|
|
// this is specified at a second granularity
|
|
|
|
// in session-time. see session_impl for details.
|
|
|
|
// the reference point is stepped forward every 4
|
|
|
|
// hours to keep the timestamps fit in 16 bits
|
|
|
|
boost::uint16_t m_started;
|
|
|
|
|
2014-08-27 08:36:28 +02:00
|
|
|
// if we're a seed, this is the session time
|
|
|
|
// timestamp of when we became one
|
|
|
|
boost::uint16_t m_became_seed;
|
|
|
|
|
|
|
|
// if we're finished, this is the session time
|
|
|
|
// timestamp of when we finished
|
|
|
|
boost::uint16_t m_became_finished;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// when checking, this is the first piece we have not
|
|
|
|
// issued a hash job for
|
|
|
|
int m_checking_piece;
|
|
|
|
|
|
|
|
// the number of pieces we completed the check of
|
|
|
|
int m_num_checked_pieces;
|
|
|
|
|
|
|
|
// the number of async. operations that need this torrent
|
|
|
|
// loaded in RAM. having a refcount > 0 prevents it from
|
|
|
|
// being unloaded.
|
|
|
|
int m_refcount;
|
|
|
|
|
|
|
|
// if the error ocurred on a file, this is the index of that file
|
|
|
|
// there are a few special cases, when this is negative. See
|
|
|
|
// set_error()
|
|
|
|
int m_error_file;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// the average time it takes to download one time critical piece
|
|
|
|
boost::uint32_t m_average_piece_time;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// the average piece download time deviation
|
|
|
|
boost::uint32_t m_piece_time_deviation;
|
2006-04-25 23:04:48 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// the number of bytes that has been
|
|
|
|
// downloaded that failed the hash-test
|
|
|
|
boost::uint32_t m_total_failed_bytes;
|
|
|
|
boost::uint32_t m_total_redundant_bytes;
|
2007-10-31 10:48:20 +01:00
|
|
|
|
2011-12-23 20:30:23 +01:00
|
|
|
// the sequence number for this torrent, this is a
|
|
|
|
// monotonically increasing number for each added torrent
|
|
|
|
int m_sequence_number;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// for torrents who have a bandwidth limit, this is != 0
|
|
|
|
// and refers to a peer_class in the session.
|
2017-01-21 18:08:53 +01:00
|
|
|
peer_class_t m_peer_class;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
// of all peers in m_connections, this is the number
|
|
|
|
// of peers that are outgoing and still waiting to
|
|
|
|
// complete the connection. This is used to possibly
|
|
|
|
// kick out these connections when we get incoming
|
|
|
|
// connections (if we've reached the connection limit)
|
|
|
|
boost::uint16_t m_num_connecting;
|
|
|
|
|
2018-01-21 20:59:08 +01:00
|
|
|
// this is the peer id we generate when we add the torrent. Peers won't
|
|
|
|
// use this (they generate their own peer ids) but this is used in case
|
|
|
|
// the tracker returns peer IDs, to identify ourself in the peer list to
|
|
|
|
// avoid connecting back to it.
|
|
|
|
peer_id m_peer_id;
|
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// ==============================
|
|
|
|
// The following members are specifically
|
|
|
|
// ordered to make the 24 bit members
|
|
|
|
// properly 32 bit aligned by inserting
|
|
|
|
// 8 bits after each one
|
|
|
|
// ==============================
|
2008-04-16 08:31:05 +02:00
|
|
|
|
2014-08-27 08:36:28 +02:00
|
|
|
// the session time timestamp of when we entered upload mode
|
|
|
|
// if we're currently in upload-mode
|
|
|
|
boost::uint16_t m_upload_mode_time;
|
2008-04-16 08:31:05 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// true when this torrent should anncounce to
|
|
|
|
// trackers
|
|
|
|
bool m_announce_to_trackers:1;
|
|
|
|
|
|
|
|
// true when this torrent should anncounce to
|
|
|
|
// the local network
|
|
|
|
bool m_announce_to_lsd:1;
|
|
|
|
|
|
|
|
// is set to true every time there is an incoming
|
|
|
|
// connection to this torrent
|
|
|
|
bool m_has_incoming:1;
|
|
|
|
|
|
|
|
// this is set to true when the files are checked
|
|
|
|
// before the files are checked, we don't try to
|
|
|
|
// connect to peers
|
|
|
|
bool m_files_checked:1;
|
2008-05-06 20:03:41 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// determines the storage state for this torrent.
|
|
|
|
unsigned int m_storage_mode:2;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// this is true while tracker announcing is enabled
|
|
|
|
// is is disabled while paused and checking files
|
|
|
|
bool m_announcing:1;
|
2009-09-13 04:24:25 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// this is true while the tracker deadline timer
|
|
|
|
// is in use. i.e. one or more trackers are waiting
|
|
|
|
// for a reannounce
|
|
|
|
bool m_waiting_tracker:1;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
|
|
|
|
2015-09-19 23:49:01 +02:00
|
|
|
// total time we've been active on this torrent. i.e. either (trying to)
|
|
|
|
// download or seed. does not count time when the torrent is stopped or
|
|
|
|
// paused. specified in seconds. This only track time _before_ we started
|
|
|
|
// the torrent this last time. When the torrent is paused, this counter is
|
|
|
|
// incremented to include this current session.
|
2010-02-14 02:39:55 +01:00
|
|
|
unsigned int m_active_time:24;
|
2009-06-19 00:32:55 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// the index to the last tracker that worked
|
|
|
|
boost::int8_t m_last_working_tracker;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
|
|
|
|
2015-09-19 23:49:01 +02:00
|
|
|
// total time we've been finished with this torrent.
|
|
|
|
// does not count when the torrent is stopped or paused.
|
2010-02-14 02:39:55 +01:00
|
|
|
unsigned int m_finished_time:24;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
|
|
|
// in case the piece picker hasn't been constructed
|
|
|
|
// when this settings is set, this variable will keep
|
|
|
|
// its value until the piece picker is created
|
|
|
|
bool m_sequential_download:1;
|
|
|
|
|
2016-02-07 08:37:32 +01:00
|
|
|
// this is set if the auto_sequential setting is true and this swarm
|
|
|
|
// satisfies the criteria to be considered high-availability. i.e. if
|
|
|
|
// there's mostly seeds in the swarm, download the files sequentially
|
|
|
|
// for improved disk I/O performance.
|
|
|
|
bool m_auto_sequential:1;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this means we haven't verified the file content
|
|
|
|
// of the files we're seeding. the m_verified bitfield
|
|
|
|
// indicates which pieces have been verified and which
|
|
|
|
// haven't
|
|
|
|
bool m_seed_mode:1;
|
2008-05-19 04:52:32 +02:00
|
|
|
|
2008-12-08 07:36:22 +01:00
|
|
|
// if this is true, we're currently super seeding this
|
|
|
|
// torrent.
|
|
|
|
bool m_super_seeding:1;
|
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// this is set when we don't want to load seed_mode,
|
|
|
|
// paused or auto_managed from the resume data
|
2015-07-21 19:12:37 +02:00
|
|
|
const bool m_override_resume_data:1;
|
2010-02-14 02:39:55 +01:00
|
|
|
|
2016-02-08 23:56:59 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
2010-02-14 02:39:55 +01:00
|
|
|
// this is true while there is a country
|
|
|
|
// resolution in progress. To avoid flodding
|
|
|
|
// the DNS request queue, only one ip is resolved
|
|
|
|
// at a time.
|
|
|
|
mutable bool m_resolving_country:1;
|
2015-09-20 17:59:00 +02:00
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// this is true if the user has enabled
|
|
|
|
// country resolution in this torrent
|
|
|
|
bool m_resolve_countries:1;
|
2016-02-08 23:56:59 +01:00
|
|
|
#endif
|
|
|
|
#endif
|
2010-04-12 02:36:31 +02:00
|
|
|
|
|
|
|
// set to false when saving resume data. Set to true
|
|
|
|
// whenever something is downloaded
|
|
|
|
bool m_need_save_resume_data:1;
|
2010-02-14 02:39:55 +01:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
|
|
|
|
2015-09-19 23:49:01 +02:00
|
|
|
// total time we've been available as a seed on this torrent.
|
|
|
|
// does not count when the torrent is stopped or paused. This value only
|
|
|
|
// accounts for the time prior to the current start of the torrent. When
|
|
|
|
// the torrent is paused, this counter is incremented to account for the
|
|
|
|
// additional seeding time.
|
2010-02-14 02:39:55 +01:00
|
|
|
unsigned int m_seeding_time:24;
|
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// the maximum number of uploads for this torrent
|
|
|
|
unsigned int m_max_uploads:24;
|
|
|
|
|
2012-03-05 11:42:25 +01:00
|
|
|
// these are the flags sent in on a call to save_resume_data
|
|
|
|
// we need to save them to check them in write_resume_data
|
|
|
|
boost::uint8_t m_save_resume_flags;
|
2010-02-14 02:39:55 +01:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
// the number of unchoked peers in this torrent
|
|
|
|
unsigned int m_num_uploads:24;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// when this is set, second_tick will perform the actual
|
|
|
|
// work of refreshing the suggest pieces
|
|
|
|
bool m_need_suggest_pieces_refresh:1;
|
2009-02-03 08:46:24 +01:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// this is set to true when the torrent starts up
|
|
|
|
// The first tracker response, when this is true,
|
|
|
|
// will attempt to connect to a bunch of peers immediately
|
|
|
|
// and set this to false. We only do this once to get
|
|
|
|
// the torrent kick-started
|
|
|
|
bool m_need_connect_boost:1;
|
|
|
|
|
|
|
|
// rotating sequence number for LSD announces sent out.
|
|
|
|
// used to only use IP broadcast for every 8th lsd announce
|
|
|
|
boost::uint8_t m_lsd_seq:3;
|
|
|
|
|
|
|
|
// this is set to true if the torrent was started without
|
|
|
|
// metadata. It is used to save metadata in the resume file
|
|
|
|
// by default for such torrents. It does not necessarily
|
|
|
|
// have to be a magnet link.
|
|
|
|
bool m_magnet_link:1;
|
|
|
|
|
|
|
|
// set to true if the session IP filter applies to this
|
|
|
|
// torrent or not. Defaults to true.
|
|
|
|
bool m_apply_ip_filter:1;
|
2016-02-07 08:37:32 +01:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// if set to true, add tracker URLs loaded from resume
|
|
|
|
// data into this torrent instead of replacing them
|
|
|
|
bool m_merge_resume_trackers:1;
|
2016-02-07 08:37:32 +01:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
|
|
|
|
|
|
|
// the number of bytes of padding files
|
|
|
|
boost::uint32_t m_padding:24;
|
2010-02-14 02:39:55 +01:00
|
|
|
|
2017-12-28 22:12:40 +01:00
|
|
|
// TODO: gap of 8 bits available here
|
2013-11-26 08:47:48 +01:00
|
|
|
|
|
|
|
// ----
|
2010-02-14 02:39:55 +01:00
|
|
|
|
|
|
|
// the scrape data from the tracker response, this
|
|
|
|
// is optional and may be 0xffffff
|
2014-07-06 21:18:00 +02:00
|
|
|
boost::uint32_t m_incomplete:24;
|
2010-02-14 02:39:55 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// true when the torrent should announce to
|
|
|
|
// the DHT
|
|
|
|
bool m_announce_to_dht:1;
|
2013-11-26 08:47:48 +01:00
|
|
|
|
|
|
|
// these represent whether or not this torrent is counted
|
|
|
|
// in the total counters of active seeds and downloads
|
|
|
|
// in the session.
|
|
|
|
bool m_is_active_download:1;
|
|
|
|
bool m_is_active_finished:1;
|
|
|
|
|
|
|
|
// even if we're not built to support SSL torrents,
|
|
|
|
// remember that this is an SSL torrent, so that we don't
|
|
|
|
// accidentally start seeding it without any authentication.
|
|
|
|
bool m_ssl_torrent:1;
|
|
|
|
|
|
|
|
// this is set to true if we're trying to delete the
|
|
|
|
// files belonging to it. When set, don't write any
|
|
|
|
// more blocks to disk!
|
|
|
|
bool m_deleted:1;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// pinned torrents are locked in RAM and won't be unloaded
|
|
|
|
// in favor of more active torrents. When the torrent is added,
|
|
|
|
// the user may choose to initialize this to 1, in which case
|
|
|
|
// it will never be unloaded from RAM
|
|
|
|
bool m_pinned:1;
|
2014-01-01 03:04:26 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// when this is false, we should unload the torrent as soon
|
|
|
|
// as the no other async. job needs the torrent loaded
|
|
|
|
bool m_should_be_loaded:1;
|
2013-11-26 08:47:48 +01:00
|
|
|
|
|
|
|
// ----
|
|
|
|
|
2014-11-08 17:58:18 +01:00
|
|
|
// the timestamp of the last piece passed for this torrent specified in
|
|
|
|
// session_time. This is signed because it must be able to represent time
|
|
|
|
// before the session started
|
|
|
|
boost::int16_t m_last_download;
|
2014-08-27 08:36:28 +02:00
|
|
|
|
2014-09-24 11:03:57 +02:00
|
|
|
// the number of peer connections to seeds. This should be the same as
|
|
|
|
// counting the peer connections that say true for is_seed()
|
|
|
|
boost::uint16_t m_num_seeds;
|
|
|
|
|
2017-02-01 07:39:09 +01:00
|
|
|
// this is the number of peers that are seeds, and count against
|
|
|
|
// m_num_seeds, but have not yet been connected
|
|
|
|
boost::uint16_t m_num_connecting_seeds;
|
|
|
|
|
2014-11-08 17:58:18 +01:00
|
|
|
// the timestamp of the last byte uploaded from this torrent specified in
|
|
|
|
// session_time. This is signed because it must be able to represent time
|
2015-09-20 17:59:00 +02:00
|
|
|
// before the session started.
|
2014-11-08 17:58:18 +01:00
|
|
|
boost::int16_t m_last_upload;
|
2010-03-29 02:34:04 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this is a second count-down to when we should tick the
|
|
|
|
// storage for this torrent. Ticking the storage is used
|
|
|
|
// to periodically flush the partfile metadata and possibly
|
|
|
|
// other deferred flushing. Any disk operation starts this
|
|
|
|
// counter (unless it's already counting down). 0 means no
|
|
|
|
// ticking is needed.
|
|
|
|
boost::uint8_t m_storage_tick;
|
2010-03-29 02:34:04 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// ----
|
2010-02-14 02:39:55 +01:00
|
|
|
|
|
|
|
// if this is true, libtorrent may pause and resume
|
|
|
|
// this torrent depending on queuing rules. Torrents
|
|
|
|
// started with auto_managed flag set may be added in
|
|
|
|
// a paused state in case there are no available
|
|
|
|
// slots.
|
|
|
|
bool m_auto_managed:1;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
enum { no_gauge_state = 0xf };
|
|
|
|
// the current stats gauge this torrent counts against
|
|
|
|
boost::uint32_t m_current_gauge_state:4;
|
2013-11-26 08:47:48 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// set to true while moving the storage
|
|
|
|
bool m_moving_storage:1;
|
2013-11-26 08:47:48 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this is true if this torrent is considered inactive from the
|
|
|
|
// queuing mechanism's point of view. If a torrent doesn't transfer
|
|
|
|
// at high enough rates, it's inactive.
|
|
|
|
bool m_inactive:1;
|
2010-07-08 21:29:38 +02:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
2010-07-17 09:13:14 +02:00
|
|
|
|
2010-09-06 06:02:15 +02:00
|
|
|
// the scrape data from the tracker response, this
|
|
|
|
// is optional and may be 0xffffff
|
2013-02-04 08:17:31 +01:00
|
|
|
unsigned int m_downloaded:24;
|
2010-09-06 06:02:15 +02:00
|
|
|
|
2014-11-08 17:58:18 +01:00
|
|
|
// the timestamp of the last scrape request to one of the trackers in
|
|
|
|
// this torrent specified in session_time. This is signed because it must
|
|
|
|
// be able to represent time before the session started
|
|
|
|
boost::int16_t m_last_scrape;
|
2010-10-30 10:36:18 +02:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// ----
|
2013-02-09 06:56:31 +01:00
|
|
|
|
2013-11-26 08:47:48 +01:00
|
|
|
// progress parts per million (the number of
|
|
|
|
// millionths of completeness)
|
|
|
|
unsigned int m_progress_ppm:20;
|
2013-08-22 07:27:45 +02:00
|
|
|
|
2015-05-25 23:46:42 +02:00
|
|
|
// this is true when our effective inactive state is different from our
|
|
|
|
// actual inactive state. Whenever this state changes, there is a
|
|
|
|
// quarantine period until we change the effective state. This is to avoid
|
|
|
|
// flapping. If the state changes back during this period, we cancel the
|
|
|
|
// quarantine
|
|
|
|
bool m_pending_active_change:1;
|
2014-05-19 00:17:51 +02:00
|
|
|
|
2014-06-13 00:39:41 +02:00
|
|
|
// if this is set, accept the save path saved in the resume data, if
|
|
|
|
// present
|
|
|
|
bool m_use_resume_save_path:1;
|
|
|
|
|
2015-09-29 07:51:01 +02:00
|
|
|
// if set to true, add web seed URLs loaded from resume
|
|
|
|
// data into this torrent instead of replacing the ones from the .torrent
|
|
|
|
// file
|
|
|
|
bool m_merge_resume_http_seeds:1;
|
|
|
|
|
2015-10-04 00:15:29 +02:00
|
|
|
// if this is set, whenever transitioning into a downloading/seeding state
|
|
|
|
// from a non-downloading/seeding state, the torrent is paused.
|
|
|
|
bool m_stop_when_ready:1;
|
|
|
|
|
2014-01-19 20:45:50 +01:00
|
|
|
#if TORRENT_USE_ASSERTS
|
2011-06-05 22:48:00 +02:00
|
|
|
public:
|
|
|
|
// set to false until we've loaded resume data
|
|
|
|
bool m_resume_data_loaded;
|
2016-06-23 19:19:35 +02:00
|
|
|
|
|
|
|
// set to true when torrent is start()ed. It may only be started once
|
|
|
|
bool m_was_started;
|
2017-05-21 17:36:35 +02:00
|
|
|
|
|
|
|
// this is set to true while we're looping over m_connections. We may not
|
|
|
|
// mutate the list while doing this
|
|
|
|
mutable int m_iterating_connections;
|
2011-06-05 22:48:00 +02:00
|
|
|
#endif
|
2003-10-23 01:00:57 +02:00
|
|
|
};
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
struct torrent_ref_holder
|
|
|
|
{
|
|
|
|
torrent_ref_holder(torrent* t, char const* p)
|
|
|
|
: m_torrent(t)
|
|
|
|
, m_purpose(p)
|
|
|
|
{
|
|
|
|
if (m_torrent) m_torrent->inc_refcount(m_purpose);
|
|
|
|
}
|
|
|
|
|
|
|
|
~torrent_ref_holder()
|
|
|
|
{
|
|
|
|
if (m_torrent) m_torrent->dec_refcount(m_purpose);
|
|
|
|
}
|
|
|
|
torrent* m_torrent;
|
|
|
|
char const* m_purpose;
|
|
|
|
};
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // TORRENT_TORRENT_HPP_INCLUDED
|
2005-03-19 13:22:40 +01:00
|
|
|
|